http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversalSideEffects.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversalSideEffects.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversalSideEffects.cs new file mode 100644 index 0000000..8ce495d --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Remote/DriverRemoteTraversalSideEffects.cs @@ -0,0 +1,126 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using Gremlin.Net.Driver.Messages; +using Gremlin.Net.Process.Traversal; + +namespace Gremlin.Net.Driver.Remote +{ + internal class DriverRemoteTraversalSideEffects : ITraversalSideEffects + { + private readonly IGremlinClient _gremlinClient; + private readonly List<string> _keys = new List<string>(); + private readonly Guid _serverSideEffectId; + private readonly Dictionary<string, object> _sideEffects = new Dictionary<string, object>(); + private bool _closed; + private bool _retrievedAllKeys; + + public DriverRemoteTraversalSideEffects(IGremlinClient gremlinClient, Guid serverSideEffectId) + { + _gremlinClient = gremlinClient; + _serverSideEffectId = serverSideEffectId; + } + + public void Dispose() + { + Close(); + } + + public IReadOnlyCollection<string> Keys() + { + if (_closed && !_retrievedAllKeys) + throw new InvalidOperationException("Traversal has been closed - side-effect keys cannot be retrieved"); + if (!_retrievedAllKeys) + { + _keys.AddRange(RetrieveKeys()); + _retrievedAllKeys = true; + } + return _keys; + } + + private IEnumerable<string> RetrieveKeys() + { + return _gremlinClient.SubmitAsync<string>(SideEffectKeysMessage()).Result; + } + + private RequestMessage SideEffectKeysMessage() + { + return RequestMessage.Build(Tokens.OpsKeys) + .AddArgument(Tokens.ArgsSideEffect, _serverSideEffectId) + .Processor(Tokens.ProcessorTraversal) + .Create(); + } + + public object Get(string key) + { + if (!Keys().Contains(key)) + throw new KeyNotFoundException($"Side effect key {key} does not exist"); + if (!_sideEffects.ContainsKey(key)) + { + if (_closed) + throw new InvalidOperationException( + "Traversal has been closed - no new side-effects can be retrieved"); + _sideEffects.Add(key, RetrieveSideEffectsForKey(key)); + } + return _sideEffects[key]; + } + + private object RetrieveSideEffectsForKey(string key) + { + return _gremlinClient.SubmitWithSingleResultAsync<object>(SideEffectGatherMessage(key)).Result; + } + + private RequestMessage SideEffectGatherMessage(string key) + { + return RequestMessage.Build(Tokens.OpsGather) + .AddArgument(Tokens.ArgsSideEffect, _serverSideEffectId) + .AddArgument(Tokens.ArgsSideEffectKey, key) + .AddArgument(Tokens.ArgsAliases, new Dictionary<string, string> {{"g", "g"}}) + .Processor(Tokens.ProcessorTraversal) + .Create(); + } + + public void Close() + { + if (_closed) return; + CloseSideEffects(); + _closed = true; + } + + private void CloseSideEffects() + { + _gremlinClient.SubmitAsync<object>(SideEffectCloseMessage()).Wait(); + } + + private RequestMessage SideEffectCloseMessage() + { + return RequestMessage.Build(Tokens.OpsClose) + .AddArgument(Tokens.ArgsSideEffect, _serverSideEffectId) + .Processor(Tokens.ProcessorTraversal) + .Create(); + } + } +} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/AggregatorFactory.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/AggregatorFactory.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/AggregatorFactory.cs new file mode 100644 index 0000000..26efb5d --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/AggregatorFactory.cs @@ -0,0 +1,44 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System.Collections.Generic; + +namespace Gremlin.Net.Driver.ResultsAggregation +{ + internal class AggregatorFactory + { + private readonly Dictionary<string, IAggregator> _aggregatorByAggregateToType = + new Dictionary<string, IAggregator> + { + {Tokens.ValAggregateToMap, new DictionaryAggregator()}, + {Tokens.ValAggregateToBulkSet, new TraverserAggregator()} + }; + + public IAggregator GetAggregatorFor(string aggregateTo) + { + if (_aggregatorByAggregateToType.ContainsKey(aggregateTo)) + return _aggregatorByAggregateToType[aggregateTo]; + return new DefaultAggregator(); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DefaultAggregator.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DefaultAggregator.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DefaultAggregator.cs new file mode 100644 index 0000000..82b247b --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DefaultAggregator.cs @@ -0,0 +1,42 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System.Collections.Generic; + +namespace Gremlin.Net.Driver.ResultsAggregation +{ + internal class DefaultAggregator : IAggregator + { + private readonly List<dynamic> _result = new List<dynamic>(); + + public void Add(object value) + { + _result.Add(value); + } + + public object GetAggregatedResult() + { + return _result; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DictionaryAggregator.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DictionaryAggregator.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DictionaryAggregator.cs new file mode 100644 index 0000000..75764e3 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/DictionaryAggregator.cs @@ -0,0 +1,44 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System.Collections.Generic; +using System.Linq; + +namespace Gremlin.Net.Driver.ResultsAggregation +{ + internal class DictionaryAggregator : IAggregator + { + private readonly Dictionary<string, dynamic> _result = new Dictionary<string, dynamic>(); + + public void Add(object value) + { + var newEntry = ((Dictionary<string, dynamic>) value).First(); + _result.Add(newEntry.Key, newEntry.Value); + } + + public object GetAggregatedResult() + { + return _result; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/IAggregator.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/IAggregator.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/IAggregator.cs new file mode 100644 index 0000000..bcc036a --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/IAggregator.cs @@ -0,0 +1,31 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +namespace Gremlin.Net.Driver.ResultsAggregation +{ + internal interface IAggregator + { + void Add(object value); + object GetAggregatedResult(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/TraverserAggregator.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/TraverserAggregator.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/TraverserAggregator.cs new file mode 100644 index 0000000..2d18804 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/ResultsAggregation/TraverserAggregator.cs @@ -0,0 +1,44 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System.Collections.Generic; +using Gremlin.Net.Process.Traversal; + +namespace Gremlin.Net.Driver.ResultsAggregation +{ + internal class TraverserAggregator : IAggregator + { + private readonly Dictionary<object, long> _result = new Dictionary<object, long>(); + + public void Add(object value) + { + var traverser = (Traverser) value; + _result.Add(traverser.Object, traverser.Bulk); + } + + public object GetAggregatedResult() + { + return _result; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs new file mode 100644 index 0000000..5a940cd --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs @@ -0,0 +1,114 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using Gremlin.Net.Driver.Messages; + +namespace Gremlin.Net.Driver +{ + /// <summary> + /// String constants used to configure a <see cref="RequestMessage" />. + /// </summary> + public class Tokens + { + /// <summary> + /// Operation used for a request that contains the Bytecode representation of a Traversal. + /// </summary> + public static string OpsBytecode = "bytecode"; + + /// <summary> + /// Operation used to evaluate a Gremlin script provided as a string. + /// </summary> + public static string OpsEval = "eval"; + + /// <summary> + /// Operation used to get a particular side-effect as produced by a previously executed Traversal. + /// </summary> + public static string OpsGather = "gather"; + + /// <summary> + /// Operation used to get all the keys of all side-effects as produced by a previously executed Traversal. + /// </summary> + public static string OpsKeys = "keys"; + + /// <summary> + /// Operation used to get all the keys of all side-effects as produced by a previously executed Traversal. + /// </summary> + public static string OpsClose = "close"; + + /// <summary> + /// Default OpProcessor. + /// </summary> + public static string ProcessorTraversal = "traversal"; + + /// <summary> + /// Argument name that allows to defines the number of iterations each ResponseMessage should contain - overrides the + /// resultIterationBatchSize server setting. + /// </summary> + public static string ArgsBatchSize = "batchSize"; + + /// <summary> + /// Argument name that allows to provide a map of key/value pairs to apply as variables in the context of the Gremlin + /// script. + /// </summary> + public static string ArgsBindings = "bindings"; + + /// <summary> + /// Argument name that allows to define aliases that represent globally bound Graph and TraversalSource objects. + /// </summary> + public static string ArgsAliases = "aliases"; + + /// <summary> + /// Argument name that corresponds to the Traversal to evaluate. + /// </summary> + public static string ArgsGremlin = "gremlin"; + + /// <summary> + /// Argument name that allows to specify the unique identifier for the request. + /// </summary> + public static string ArgsSideEffect = "sideEffect"; + + /// <summary> + /// Argument name that allows to specify the key for a specific side-effect. + /// </summary> + public static string ArgsSideEffectKey = "sideEffectKey"; + + /// <summary> + /// <see cref="ResponseMessage{T}" /> argument that describes how side-effect data should be treated. + /// </summary> + public static string ArgsAggregateTo = "aggregateTo"; + + /// <summary> + /// Argument name that allows to change the flavor of Gremlin used (e.g. gremlin-groovy). + /// </summary> + public static string ArgsLanguage = "language"; + + /// <summary> + /// Argument name that allows to override the server setting that determines the maximum time to wait for a script to + /// execute on the server. + /// </summary> + public static string ArgsEvalTimeout = "scriptEvaluationTimeout"; + + internal static string ValAggregateToMap = "map"; + internal static string ValAggregateToBulkSet = "bulkset"; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs new file mode 100644 index 0000000..5a20759 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/WebSocketConnection.cs @@ -0,0 +1,96 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; +using System.IO; +using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; + +namespace Gremlin.Net.Driver +{ + internal class WebSocketConnection : IDisposable + { + private const int ReceiveBufferSize = 1024; + private const WebSocketMessageType MessageType = WebSocketMessageType.Binary; + private ClientWebSocket _client; + + public async Task ConnectAsync(Uri uri) + { + _client = new ClientWebSocket(); + await _client.ConnectAsync(uri, CancellationToken.None).ConfigureAwait(false); + } + + public async Task CloseAsync() + { + await + _client.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None) + .ConfigureAwait(false); + } + + public async Task SendMessageAsync(byte[] message) + { + await + _client.SendAsync(new ArraySegment<byte>(message), MessageType, true, CancellationToken.None) + .ConfigureAwait(false); + } + + public async Task<byte[]> ReceiveMessageAsync() + { + using (var ms = new MemoryStream()) + { + WebSocketReceiveResult received; + do + { + var receiveBuffer = new ArraySegment<byte>(new byte[ReceiveBufferSize]); + received = await _client.ReceiveAsync(receiveBuffer, CancellationToken.None).ConfigureAwait(false); + ms.Write(receiveBuffer.Array, receiveBuffer.Offset, received.Count); + } while (!received.EndOfMessage); + + return ms.ToArray(); + } + } + + #region IDisposable Support + + private bool _disposed; + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + _client?.Dispose(); + _disposed = true; + } + } + + #endregion + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj b/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj new file mode 100644 index 0000000..a909ad1 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj @@ -0,0 +1,43 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <Description>Gremlin.Net is a cross-platform Gremlin Server driver for .NET that is written in C#. It uses WebSockets to communicate with Gremlin Server.</Description> + <AssemblyTitle>Gremlin.Net</AssemblyTitle> + <Authors>Apache TinkerPop</Authors> + <TargetFramework>netstandard1.3</TargetFramework> + <Version>3.2.5-SNAPSHOT</Version> + <GenerateDocumentationFile>true</GenerateDocumentationFile> + <AssemblyName>Gremlin.Net</AssemblyName> + <PackageId>Gremlin.Net</PackageId> + <PackageTags>gremlin-dotnet;gremlin;tinkerpop;tinkerpop3</PackageTags> + <PackageProjectUrl>http://tinkerpop.apache.org</PackageProjectUrl> + <PackageLicenseUrl>https://github.com/apache/tinkerpop/blob/master/LICENSE</PackageLicenseUrl> + <RepositoryUrl>https://github.com/apache/tinkerpop</RepositoryUrl> + <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> + <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> + <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> + <GeneratePackageOnBuild>False</GeneratePackageOnBuild> + </PropertyGroup> + + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> + <DocumentationFile /> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="System.Collections" Version="4.3.0" /> + <PackageReference Include="System.Linq" Version="4.3.0" /> + <PackageReference Include="System.Runtime" Version="4.3.0" /> + <PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" /> + <PackageReference Include="System.Threading" Version="4.3.0" /> + <PackageReference Include="Newtonsoft.Json" Version="9.0.1" /> + <PackageReference Include="System.Net.WebSockets" Version="4.3.0" /> + <PackageReference Include="System.Net.WebSockets.Client" Version="4.3.0" /> + <PackageReference Include="System.Collections.Concurrent" Version="4.3.0" /> + <PackageReference Include="System.Reflection.TypeExtensions" Version="4.3.0" /> + </ItemGroup> + + <ItemGroup> + <ProjectReference Include="..\Gremlin.Net.Process\Gremlin.Net.Process.csproj" /> + </ItemGroup> + +</Project> http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Properties/AssemblyInfo.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Properties/AssemblyInfo.cs b/gremlin-dotnet/src/Gremlin.Net/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..433db19 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Properties/AssemblyInfo.cs @@ -0,0 +1,44 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. + +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Gremlin.Net")] +[assembly: AssemblyTrademark("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. + +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM + +[assembly: Guid("6c1dd34d-e30f-4e37-aacc-beb8ad2320d8")] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/Edge.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/Edge.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/Edge.cs new file mode 100644 index 0000000..fddbd69 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/Edge.cs @@ -0,0 +1,61 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +namespace Gremlin.Net.Structure +{ + /// <summary> + /// Represents an edge between to vertices. + /// </summary> + public class Edge : Element + { + /// <summary> + /// Initializes a new instance of the <see cref="Edge" /> class. + /// </summary> + /// <param name="id">The id of the edge.</param> + /// <param name="outV">The outgoing/tail vertex of the edge.</param> + /// <param name="label">The label of the edge.</param> + /// <param name="inV">The incoming/head vertex of the edge.</param> + public Edge(object id, Vertex outV, string label, Vertex inV) + : base(id, label) + { + OutV = outV; + InV = inV; + } + + /// <summary> + /// Gets or sets the incoming/head vertex of this edge. + /// </summary> + public Vertex InV { get; set; } + + /// <summary> + /// Gets or sets the outgoing/tail vertex of this edge. + /// </summary> + public Vertex OutV { get; set; } + + /// <inheritdoc /> + public override string ToString() + { + return $"e[{Id}][{OutV.Id}-{Label}->{InV.Id}]"; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/Element.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/Element.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/Element.cs new file mode 100644 index 0000000..f4fc847 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/Element.cs @@ -0,0 +1,77 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; + +namespace Gremlin.Net.Structure +{ + /// <summary> + /// A common base class for Graph elements. + /// </summary> + public abstract class Element : IEquatable<Element> + { + /// <summary> + /// Initializes a new instance of the <see cref="Element" /> class. + /// </summary> + /// <param name="id">The id of the element.</param> + /// <param name="label">The label of the element.</param> + protected Element(object id, string label) + { + Id = id; + Label = label; + } + + /// <summary> + /// Gets the id of this <see cref="Element" />. + /// </summary> + public object Id { get; } + + /// <summary> + /// Gets the label of this <see cref="Element" />. + /// </summary> + public string Label { get; } + + /// <inheritdoc /> + public bool Equals(Element other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Equals(Id, other.Id); + } + + /// <inheritdoc /> + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals((Element) obj); + } + + /// <inheritdoc /> + public override int GetHashCode() + { + return Id.GetHashCode(); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BindingSerializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BindingSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BindingSerializer.cs new file mode 100644 index 0000000..d183447 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BindingSerializer.cs @@ -0,0 +1,42 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System.Collections.Generic; +using Gremlin.Net.Process.Traversal; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class BindingSerializer : IGraphSONSerializer + { + public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer) + { + var binding = (Binding) objectData; + var valueDict = new Dictionary<string, object> + { + {"value", writer.ToDict(binding.Value)}, + {"key", binding.Key} + }; + return GraphSONUtil.ToTypedValue(nameof(Binding), valueDict); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BytecodeSerializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BytecodeSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BytecodeSerializer.cs new file mode 100644 index 0000000..28cfe0a --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BytecodeSerializer.cs @@ -0,0 +1,58 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System.Collections.Generic; +using System.Linq; +using Gremlin.Net.Process.Traversal; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class BytecodeSerializer : IGraphSONSerializer + { + public Dictionary<string, dynamic> Dictify(dynamic bytecodeObj, GraphSONWriter writer) + { + Bytecode bytecode = bytecodeObj; + + var valueDict = new Dictionary<string, IEnumerable<IEnumerable<dynamic>>>(); + if (bytecode.SourceInstructions.Count > 0) + valueDict["source"] = DictifyInstructions(bytecode.SourceInstructions, writer); + if (bytecode.StepInstructions.Count > 0) + valueDict["step"] = DictifyInstructions(bytecode.StepInstructions, writer); + + return GraphSONUtil.ToTypedValue(nameof(Bytecode), valueDict); + } + + private IEnumerable<IEnumerable<dynamic>> DictifyInstructions(IEnumerable<Instruction> instructions, + GraphSONWriter writer) + { + return instructions.Select(instruction => DictifyInstruction(instruction, writer)); + } + + private IEnumerable<dynamic> DictifyInstruction(Instruction instruction, GraphSONWriter writer) + { + var result = new List<dynamic> {instruction.OperatorName}; + result.AddRange(instruction.Arguments.Select(arg => writer.ToDict(arg))); + return result; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateDeserializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateDeserializer.cs new file mode 100644 index 0000000..d8879f8 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateDeserializer.cs @@ -0,0 +1,43 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; +using Newtonsoft.Json.Linq; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class DateDeserializer : IGraphSONDeserializer + { + public dynamic Objectify(JToken graphsonObject, GraphSONReader reader) + { + var javaTimestamp = graphsonObject.ToObject<long>(); + return FromJavaTime(javaTimestamp); + } + + private DateTime FromJavaTime(long javaTimestamp) + { + var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + return epoch.AddMilliseconds(javaTimestamp); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateSerializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateSerializer.cs new file mode 100644 index 0000000..1438e02 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateSerializer.cs @@ -0,0 +1,43 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; +using System.Collections.Generic; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class DateSerializer : IGraphSONSerializer + { + public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer) + { + DateTime dateTime = objectData; + return GraphSONUtil.ToTypedValue("Date", ToJavaTimestamp(dateTime)); + } + + private long ToJavaTimestamp(DateTime dateTime) + { + var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + return Convert.ToInt64((dateTime - epoch).TotalMilliseconds); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DoubleConverter.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DoubleConverter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DoubleConverter.cs new file mode 100644 index 0000000..416423b --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DoubleConverter.cs @@ -0,0 +1,33 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class DoubleConverter : NumberConverter + { + protected override string GraphSONTypeName => "Double"; + protected override Type HandledType => typeof(double); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeDeserializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeDeserializer.cs new file mode 100644 index 0000000..6ec8694 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeDeserializer.cs @@ -0,0 +1,43 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using Newtonsoft.Json.Linq; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class EdgeDeserializer : IGraphSONDeserializer + { + public dynamic Objectify(JToken graphsonObject, GraphSONReader reader) + { + var outVId = reader.ToObject(graphsonObject["outV"]); + var outVLabel = (string) (graphsonObject["outVLabel"] ?? Vertex.DefaultLabel); + var outV = new Vertex(outVId, outVLabel); + var inVId = reader.ToObject(graphsonObject["inV"]); + var inVLabel = (string) (graphsonObject["inVLabel"] ?? Vertex.DefaultLabel); + var inV = new Vertex(inVId, inVLabel); + var edgeId = reader.ToObject(graphsonObject["id"]); + var edgeLabel = (string) graphsonObject["label"] ?? "edge"; + return new Edge(edgeId, outV, edgeLabel, inV); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeSerializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeSerializer.cs new file mode 100644 index 0000000..fd9f496 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeSerializer.cs @@ -0,0 +1,45 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System.Collections.Generic; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class EdgeSerializer : IGraphSONSerializer + { + public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer) + { + Edge edge = objectData; + var edgeDict = new Dictionary<string, dynamic> + { + {"id", writer.ToDict(edge.Id)}, + {"outV", writer.ToDict(edge.OutV.Id)}, + {"outVLabel", edge.OutV.Label}, + {"label", edge.Label}, + {"inV", writer.ToDict(edge.InV.Id)}, + {"inVLabel", edge.InV.Label} + }; + return GraphSONUtil.ToTypedValue(nameof(Edge), edgeDict); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EnumSerializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EnumSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EnumSerializer.cs new file mode 100644 index 0000000..6ed3cd4 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EnumSerializer.cs @@ -0,0 +1,37 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System.Collections.Generic; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class EnumSerializer : IGraphSONSerializer + { + public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer) + { + var enumName = objectData.GetType().Name; + var enumValue = objectData.ToString(); + return GraphSONUtil.ToTypedValue(enumName, enumValue); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/FloatConverter.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/FloatConverter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/FloatConverter.cs new file mode 100644 index 0000000..432aeab --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/FloatConverter.cs @@ -0,0 +1,33 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class FloatConverter : NumberConverter + { + protected override string GraphSONTypeName => "Float"; + protected override Type HandledType => typeof(float); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs new file mode 100644 index 0000000..aa1fc48 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs @@ -0,0 +1,123 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json.Linq; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + /// <summary> + /// Allows to deserialize GraphSON to objects. + /// </summary> + public class GraphSONReader + { + private readonly Dictionary<string, IGraphSONDeserializer> _deserializerByGraphSONType = new Dictionary + <string, IGraphSONDeserializer> + { + {"g:Traverser", new TraverserReader()}, + {"g:Int32", new Int32Converter()}, + {"g:Int64", new Int64Converter()}, + {"g:Float", new FloatConverter()}, + {"g:Double", new DoubleConverter()}, + {"g:UUID", new UuidDeserializer()}, + {"g:Date", new DateDeserializer()}, + {"g:Timestamp", new DateDeserializer()}, + {"g:Vertex", new VertexDeserializer()}, + {"g:Edge", new EdgeDeserializer()}, + {"g:Property", new PropertyDeserializer()}, + {"g:VertexProperty", new VertexPropertyDeserializer()}, + {"g:Path", new PathDeserializer()} + }; + + /// <summary> + /// Initializes a new instance of the <see cref="GraphSONReader" /> class. + /// </summary> + public GraphSONReader() + { + } + + /// <summary> + /// Initializes a new instance of the <see cref="GraphSONReader" /> class. + /// </summary> + /// <param name="deserializerByGraphSONType"> + /// <see cref="IGraphSONDeserializer" /> deserializers identified by their + /// GraphSON type. + /// </param> + public GraphSONReader(IReadOnlyDictionary<string, IGraphSONDeserializer> deserializerByGraphSONType) + { + foreach (var deserializerAndGraphSONType in deserializerByGraphSONType) + _deserializerByGraphSONType[deserializerAndGraphSONType.Key] = deserializerAndGraphSONType.Value; + } + + /// <summary> + /// Deserializes a GraphSON collection to an object. + /// </summary> + /// <param name="graphSonData">The GraphSON collection to deserialize.</param> + /// <returns>The deserialized object.</returns> + public dynamic ToObject(IEnumerable<JToken> graphSonData) + { + return graphSonData.Select(graphson => ToObject(graphson)); + } + + /// <summary> + /// Deserializes GraphSON to an object. + /// </summary> + /// <param name="jToken">The GraphSON to deserialize.</param> + /// <returns>The deserialized object.</returns> + public dynamic ToObject(JToken jToken) + { + if (jToken is JArray) + return jToken.Select(t => ToObject(t)); + if (!jToken.HasValues) return ((JValue) jToken).Value; + if (!HasTypeKey(jToken)) return ReadDictionary(jToken); + return ReadTypedValue(jToken); + } + + private bool HasTypeKey(JToken jToken) + { + var graphSONType = (string) jToken[GraphSONTokens.TypeKey]; + return graphSONType != null; + } + + private dynamic ReadTypedValue(JToken typedValue) + { + var graphSONType = (string) typedValue[GraphSONTokens.TypeKey]; + return _deserializerByGraphSONType[graphSONType].Objectify(typedValue[GraphSONTokens.ValueKey], this); + } + + private dynamic ReadDictionary(JToken jtokenDict) + { + var dict = new Dictionary<string, dynamic>(); + foreach (var e in jtokenDict) + { + var property = e as JProperty; + if (property == null) + throw new InvalidOperationException($"Cannot read graphson: {jtokenDict}"); + dict.Add(property.Name, ToObject(property.Value)); + } + return dict; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONTokens.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONTokens.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONTokens.cs new file mode 100644 index 0000000..8beb850 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONTokens.cs @@ -0,0 +1,32 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class GraphSONTokens + { + public static string TypeKey = "@type"; + public static string ValueKey = "@value"; + public static string GremlinTypeNamespace = "g"; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONUtil.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONUtil.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONUtil.cs new file mode 100644 index 0000000..037839b --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONUtil.cs @@ -0,0 +1,62 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System.Collections.Generic; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + /// <summary> + /// Provides helper methods for GraphSON serialization. + /// </summary> + public static class GraphSONUtil + { + /// <summary> + /// Transforms a value intos its GraphSON representation including type information. + /// </summary> + /// <param name="typename">The name of the type.</param> + /// <param name="value">The value to transform.</param> + /// <param name="prefix">A namespace prefix for the typename.</param> + /// <returns>The GraphSON representation including type information.</returns> + public static Dictionary<string, dynamic> ToTypedValue(string typename, dynamic value, string prefix = "g") + { + var typedValue = new Dictionary<string, dynamic> + { + {GraphSONTokens.TypeKey, FormatTypeName(prefix, typename)} + }; + if (value != null) + typedValue[GraphSONTokens.ValueKey] = value; + return typedValue; + } + + /// <summary> + /// Formats a type name with its prefix to a GraphSON TypeID. + /// </summary> + /// <param name="namespacePrefix">The namespace prefix (default is "g").</param> + /// <param name="typeName">The name of the type.</param> + /// <returns>The formatted TypeID.</returns> + public static string FormatTypeName(string namespacePrefix, string typeName) + { + return $"{namespacePrefix}:{typeName}"; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs new file mode 100644 index 0000000..ba632b1 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs @@ -0,0 +1,146 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Gremlin.Net.Driver.Messages; +using Gremlin.Net.Process.Traversal; +using Gremlin.Net.Process.Traversal.Strategy; +using Newtonsoft.Json; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + /// <summary> + /// Allows to serialize objects to GraphSON. + /// </summary> + public class GraphSONWriter + { + private readonly Dictionary<Type, IGraphSONSerializer> _serializerByType = new Dictionary + <Type, IGraphSONSerializer> + { + {typeof(ITraversal), new TraversalSerializer()}, + {typeof(Bytecode), new BytecodeSerializer()}, + {typeof(Binding), new BindingSerializer()}, + {typeof(RequestMessage), new RequestMessageSerializer()}, + {typeof(int), new Int32Converter()}, + {typeof(long), new Int64Converter()}, + {typeof(float), new FloatConverter()}, + {typeof(double), new DoubleConverter()}, + {typeof(Guid), new UuidSerializer()}, + {typeof(DateTime), new DateSerializer()}, + {typeof(Enum), new EnumSerializer()}, + {typeof(TraversalPredicate), new TraversalPredicateSerializer()}, + {typeof(Vertex), new VertexSerializer()}, + {typeof(Edge), new EdgeSerializer()}, + {typeof(Property), new PropertySerializer()}, + {typeof(VertexProperty), new VertexPropertySerializer()}, + {typeof(AbstractTraversalStrategy), new TraversalStrategySerializer()} + }; + + /// <summary> + /// Initializes a new instance of the <see cref="GraphSONWriter" /> class. + /// </summary> + public GraphSONWriter() + { + } + + /// <summary> + /// Initializes a new instance of the <see cref="GraphSONWriter" /> class. + /// </summary> + /// <param name="customSerializerByType"> + /// <see cref="IGraphSONSerializer" /> serializers identified by their + /// <see cref="Type" />. + /// </param> + public GraphSONWriter(IReadOnlyDictionary<Type, IGraphSONSerializer> customSerializerByType) + { + foreach (var serializerAndType in customSerializerByType) + _serializerByType[serializerAndType.Key] = serializerAndType.Value; + } + + /// <summary> + /// Serializes an object to GraphSON. + /// </summary> + /// <param name="objectData">The object to serialize.</param> + /// <returns>The serialized GraphSON.</returns> + public string WriteObject(dynamic objectData) + { + return JsonConvert.SerializeObject(ToDict(objectData)); + } + + internal dynamic ToDict(dynamic objectData) + { + var type = objectData.GetType(); + if (TryGetSerializerFor(out IGraphSONSerializer serializer, type)) + return serializer.Dictify(objectData, this); + if (IsDictionaryType(type)) + return DictToGraphSONDict(objectData); + if (IsCollectionType(type)) + return CollectionToGraphSONCollection(objectData); + return objectData; + } + + private bool TryGetSerializerFor(out IGraphSONSerializer serializer, Type type) + { + if (_serializerByType.ContainsKey(type)) + { + serializer = _serializerByType[type]; + return true; + } + foreach (var supportedType in _serializerByType.Keys) + if (supportedType.IsAssignableFrom(type)) + { + serializer = _serializerByType[supportedType]; + return true; + } + serializer = null; + return false; + } + + private bool IsDictionaryType(Type type) + { + return type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>); + } + + private Dictionary<string, dynamic> DictToGraphSONDict(dynamic dict) + { + var graphSONDict = new Dictionary<string, dynamic>(); + foreach (var keyValue in dict) + graphSONDict.Add(ToDict(keyValue.Key), ToDict(keyValue.Value)); + return graphSONDict; + } + + private bool IsCollectionType(Type type) + { + return type.GetInterfaces().Contains(typeof(ICollection)); + } + + private IEnumerable<dynamic> CollectionToGraphSONCollection(dynamic collection) + { + foreach (var e in collection) + yield return ToDict(e); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONDeserializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONDeserializer.cs new file mode 100644 index 0000000..b15b169 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONDeserializer.cs @@ -0,0 +1,41 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using Newtonsoft.Json.Linq; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + /// <summary> + /// Supports deserializing GraphSON into an object. + /// </summary> + public interface IGraphSONDeserializer + { + /// <summary> + /// Deserializes GraphSON to an object. + /// </summary> + /// <param name="graphsonObject">The GraphSON object to objectify.</param> + /// <param name="reader">A <see cref="GraphSONReader" /> that can be used to objectify properties of the GraphSON object.</param> + /// <returns>The deserialized object.</returns> + dynamic Objectify(JToken graphsonObject, GraphSONReader reader); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONSerializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONSerializer.cs new file mode 100644 index 0000000..f5faf84 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONSerializer.cs @@ -0,0 +1,41 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System.Collections.Generic; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + /// <summary> + /// Supports serializing of an object to GraphSON. + /// </summary> + public interface IGraphSONSerializer + { + /// <summary> + /// Transforms an object into a dictionary that resembles its GraphSON representation. + /// </summary> + /// <param name="objectData">The object to dictify.</param> + /// <param name="writer">A <see cref="GraphSONWriter" /> that can be used to dictify properties of the object.</param> + /// <returns>The GraphSON representation.</returns> + Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int32Converter.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int32Converter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int32Converter.cs new file mode 100644 index 0000000..052f938 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int32Converter.cs @@ -0,0 +1,33 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class Int32Converter : NumberConverter + { + protected override string GraphSONTypeName => "Int32"; + protected override Type HandledType => typeof(int); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int64Converter.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int64Converter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int64Converter.cs new file mode 100644 index 0000000..dd0160f --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int64Converter.cs @@ -0,0 +1,33 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class Int64Converter : NumberConverter + { + protected override string GraphSONTypeName => "Int64"; + protected override Type HandledType => typeof(long); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/NumberConverter.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/NumberConverter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/NumberConverter.cs new file mode 100644 index 0000000..579d202 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/NumberConverter.cs @@ -0,0 +1,45 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System; +using System.Collections.Generic; +using Newtonsoft.Json.Linq; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal abstract class NumberConverter : IGraphSONDeserializer, IGraphSONSerializer + { + protected abstract string GraphSONTypeName { get; } + protected abstract Type HandledType { get; } + + public dynamic Objectify(JToken graphsonObject, GraphSONReader reader) + { + return graphsonObject.ToObject(HandledType); + } + + public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer) + { + return GraphSONUtil.ToTypedValue(GraphSONTypeName, objectData); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PathDeserializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PathDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PathDeserializer.cs new file mode 100644 index 0000000..afdf07c --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PathDeserializer.cs @@ -0,0 +1,41 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System.Linq; +using Newtonsoft.Json.Linq; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class PathDeserializer : IGraphSONDeserializer + { + public dynamic Objectify(JToken graphsonObject, GraphSONReader reader) + { + var labels = + graphsonObject["labels"] + .Select(readObjLabels => readObjLabels.Select(l => (string) l).ToList()) + .ToList(); + var objects = graphsonObject["objects"].Select(o => reader.ToObject(o)).ToList(); + return new Path(labels, objects); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertyDeserializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertyDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertyDeserializer.cs new file mode 100644 index 0000000..11f160e --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertyDeserializer.cs @@ -0,0 +1,38 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using Newtonsoft.Json.Linq; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class PropertyDeserializer : IGraphSONDeserializer + { + public dynamic Objectify(JToken graphsonObject, GraphSONReader reader) + { + var key = (string) graphsonObject["key"]; + var value = reader.ToObject(graphsonObject["value"]); + var element = graphsonObject["element"] != null ? reader.ToObject(graphsonObject["element"]) : null; + return new Property(key, value, element); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertySerializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertySerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertySerializer.cs new file mode 100644 index 0000000..0a7e6f8 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertySerializer.cs @@ -0,0 +1,64 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System.Collections.Generic; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class PropertySerializer : IGraphSONSerializer + { + public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer) + { + Property property = objectData; + var elementDict = CreateElementDict(property.Element, writer); + var valueDict = new Dictionary<string, dynamic> + { + {"key", property.Key}, + {"value", writer.ToDict(property.Value)}, + {"element", elementDict} + }; + return GraphSONUtil.ToTypedValue(nameof(Property), valueDict); + } + + private dynamic CreateElementDict(Element element, GraphSONWriter writer) + { + if (element == null) + return null; + var serializedElement = writer.ToDict(element); + Dictionary<string, dynamic> elementDict = serializedElement; + if (elementDict.ContainsKey(GraphSONTokens.ValueKey)) + { + var elementValueSerialized = elementDict[GraphSONTokens.ValueKey]; + Dictionary<string, dynamic> elementValueDict = elementValueSerialized; + if (elementValueDict != null) + { + elementValueDict.Remove("outVLabel"); + elementValueDict.Remove("inVLabel"); + elementValueDict.Remove("properties"); + elementValueDict.Remove("value"); + } + } + return serializedElement; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/RequestMessageSerializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/RequestMessageSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/RequestMessageSerializer.cs new file mode 100644 index 0000000..b796423 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/RequestMessageSerializer.cs @@ -0,0 +1,43 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System.Collections.Generic; +using Gremlin.Net.Driver.Messages; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class RequestMessageSerializer : IGraphSONSerializer + { + public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer) + { + RequestMessage msg = objectData; + return new Dictionary<string, dynamic> + { + {"requestId", writer.ToDict(msg.RequestId)}, + {"op", msg.Operation}, + {"processor", msg.Processor}, + {"args", writer.ToDict(msg.Arguments)} + }; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/37a24719/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalPredicateSerializer.cs ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalPredicateSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalPredicateSerializer.cs new file mode 100644 index 0000000..937cb90 --- /dev/null +++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraversalPredicateSerializer.cs @@ -0,0 +1,45 @@ +#region License + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#endregion + +using System.Collections.Generic; +using Gremlin.Net.Process.Traversal; + +namespace Gremlin.Net.Structure.IO.GraphSON +{ + internal class TraversalPredicateSerializer : IGraphSONSerializer + { + public Dictionary<string, dynamic> Dictify(dynamic predicate, GraphSONWriter writer) + { + TraversalPredicate p = predicate; + var value = p.Other == null + ? writer.ToDict(p.Value) + : new List<dynamic> {writer.ToDict(p.Value), writer.ToDict(p.Other)}; + var dict = new Dictionary<string, dynamic> + { + {"predicate", p.OperatorName}, + {"value", value} + }; + return GraphSONUtil.ToTypedValue("P", dict); + } + } +} \ No newline at end of file
