TINKERPOP-1565 Added a 3.0 TraversalSerializer class

Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/9dc30cd5
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/9dc30cd5
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/9dc30cd5

Branch: refs/heads/TINKERPOP-1612
Commit: 9dc30cd5d29f98681f4d33abbf991574ed7a97d8
Parents: 7ca3a29
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Jan 18 13:49:18 2017 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Jan 19 15:15:33 2017 -0500

----------------------------------------------------------------------
 .../structure/io/graphson/GraphSONModule.java   |  30 +-
 .../io/graphson/TraversalSerializersV3d0.java   | 390 +++++++++++++++++++
 2 files changed, 405 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/9dc30cd5/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
index f4acf12..91df42a 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
@@ -207,8 +207,8 @@ abstract class GraphSONModule extends 
TinkerPopJacksonModule {
             addSerializer(Double.class, new 
GraphSONSerializersV3d0.DoubleGraphSONSerializer());
 
             // traversal
-            addSerializer(Traversal.class, new 
GraphSONTraversalSerializersV2d0.TraversalJacksonSerializer());
-            addSerializer(Bytecode.class, new 
GraphSONTraversalSerializersV2d0.BytecodeJacksonSerializer());
+            addSerializer(Traversal.class, new 
TraversalSerializersV3d0.TraversalJacksonSerializer());
+            addSerializer(Bytecode.class, new 
TraversalSerializersV3d0.BytecodeJacksonSerializer());
             Stream.of(VertexProperty.Cardinality.class,
                     Column.class,
                     Direction.class,
@@ -218,12 +218,12 @@ abstract class GraphSONModule extends 
TinkerPopJacksonModule {
                     SackFunctions.Barrier.class,
                     Scope.class,
                     TraversalOptionParent.Pick.class,
-                    T.class).forEach(e -> addSerializer(e, new 
GraphSONTraversalSerializersV2d0.EnumJacksonSerializer()));
-            addSerializer(P.class, new 
GraphSONTraversalSerializersV2d0.PJacksonSerializer());
-            addSerializer(Lambda.class, new 
GraphSONTraversalSerializersV2d0.LambdaJacksonSerializer());
-            addSerializer(Bytecode.Binding.class, new 
GraphSONTraversalSerializersV2d0.BindingJacksonSerializer());
-            addSerializer(Traverser.class, new 
GraphSONTraversalSerializersV2d0.TraverserJacksonSerializer());
-            addSerializer(TraversalStrategy.class, new 
GraphSONTraversalSerializersV2d0.TraversalStrategyJacksonSerializer());
+                    T.class).forEach(e -> addSerializer(e, new 
TraversalSerializersV3d0.EnumJacksonSerializer()));
+            addSerializer(P.class, new 
TraversalSerializersV3d0.PJacksonSerializer());
+            addSerializer(Lambda.class, new 
TraversalSerializersV3d0.LambdaJacksonSerializer());
+            addSerializer(Bytecode.Binding.class, new 
TraversalSerializersV3d0.BindingJacksonSerializer());
+            addSerializer(Traverser.class, new 
TraversalSerializersV3d0.TraverserJacksonSerializer());
+            addSerializer(TraversalStrategy.class, new 
TraversalSerializersV3d0.TraversalStrategyJacksonSerializer());
 
             /////////////////////// DESERIALIZERS ////////////////////////////
 
@@ -242,8 +242,8 @@ abstract class GraphSONModule extends 
TinkerPopJacksonModule {
             addDeserializer(Double.class, new 
GraphSONSerializersV3d0.DoubleJackonsDeserializer());
 
             // traversal
-            addDeserializer(Bytecode.class, new 
GraphSONTraversalSerializersV2d0.BytecodeJacksonDeserializer());
-            addDeserializer(Bytecode.Binding.class, new 
GraphSONTraversalSerializersV2d0.BindingJacksonDeserializer());
+            addDeserializer(Bytecode.class, new 
TraversalSerializersV3d0.BytecodeJacksonDeserializer());
+            addDeserializer(Bytecode.Binding.class, new 
TraversalSerializersV3d0.BindingJacksonDeserializer());
             Stream.of(VertexProperty.Cardinality.values(),
                     Column.values(),
                     Direction.values(),
@@ -253,10 +253,10 @@ abstract class GraphSONModule extends 
TinkerPopJacksonModule {
                     SackFunctions.Barrier.values(),
                     Scope.values(),
                     TraversalOptionParent.Pick.values(),
-                    T.values()).flatMap(Stream::of).forEach(e -> 
addDeserializer(e.getClass(), new 
GraphSONTraversalSerializersV2d0.EnumJacksonDeserializer(e.getDeclaringClass())));
-            addDeserializer(P.class, new 
GraphSONTraversalSerializersV2d0.PJacksonDeserializer());
-            addDeserializer(Lambda.class, new 
GraphSONTraversalSerializersV2d0.LambdaJacksonDeserializer());
-            addDeserializer(Traverser.class, new 
GraphSONTraversalSerializersV2d0.TraverserJacksonDeserializer());
+                    T.values()).flatMap(Stream::of).forEach(e -> 
addDeserializer(e.getClass(), new 
TraversalSerializersV3d0.EnumJacksonDeserializer(e.getDeclaringClass())));
+            addDeserializer(P.class, new 
TraversalSerializersV3d0.PJacksonDeserializer());
+            addDeserializer(Lambda.class, new 
TraversalSerializersV3d0.LambdaJacksonDeserializer());
+            addDeserializer(Traverser.class, new 
TraversalSerializersV3d0.TraverserJacksonDeserializer());
             Arrays.asList(
                     ConnectiveStrategy.class,
                     ElementIdStrategy.class,
@@ -284,7 +284,7 @@ abstract class GraphSONModule extends 
TinkerPopJacksonModule {
                     //
                     GraphFilterStrategy.class,
                     VertexProgramStrategy.class
-            ).forEach(strategy -> addDeserializer(strategy, new 
GraphSONTraversalSerializersV2d0.TraversalStrategyProxyJacksonDeserializer(strategy)));
+            ).forEach(strategy -> addDeserializer(strategy, new 
TraversalSerializersV3d0.TraversalStrategyProxyJacksonDeserializer(strategy)));
         }
 
         public static Builder build() {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/9dc30cd5/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java
new file mode 100644
index 0000000..e4f6df9
--- /dev/null
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java
@@ -0,0 +1,390 @@
+/*
+ *  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.
+ */
+
+package org.apache.tinkerpop.gremlin.structure.io.graphson;
+
+import org.apache.commons.configuration.ConfigurationConverter;
+import org.apache.commons.configuration.MapConfiguration;
+import 
org.apache.tinkerpop.gremlin.process.remote.traversal.DefaultRemoteTraverser;
+import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import 
org.apache.tinkerpop.gremlin.process.traversal.strategy.TraversalStrategyProxy;
+import org.apache.tinkerpop.gremlin.process.traversal.util.AndP;
+import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP;
+import org.apache.tinkerpop.gremlin.process.traversal.util.OrP;
+import org.apache.tinkerpop.gremlin.util.function.Lambda;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.core.JsonParser;
+import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
+import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
+import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import 
org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdScalarSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+final class TraversalSerializersV3d0 {
+
+    private TraversalSerializersV3d0() {
+    }
+
+    /////////////////
+    // SERIALIZERS //
+    ////////////////
+
+    final static class TraversalJacksonSerializer extends 
StdSerializer<Traversal> {
+
+        public TraversalJacksonSerializer() {
+            super(Traversal.class);
+        }
+
+        @Override
+        public void serialize(final Traversal traversal, final JsonGenerator 
jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            jsonGenerator.writeObject(traversal.asAdmin().getBytecode());
+        }
+
+        @Override
+        public void serializeWithType(final Traversal traversal, final 
JsonGenerator jsonGenerator, final SerializerProvider serializerProvider, final 
TypeSerializer typeSerializer)
+                throws IOException {
+            serialize(traversal, jsonGenerator, serializerProvider);
+        }
+
+    }
+
+    final static class BytecodeJacksonSerializer extends 
StdScalarSerializer<Bytecode> {
+
+        public BytecodeJacksonSerializer() {
+            super(Bytecode.class);
+        }
+
+        @Override
+        public void serialize(final Bytecode bytecode, final JsonGenerator 
jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            jsonGenerator.writeStartObject();
+            if (bytecode.getSourceInstructions().iterator().hasNext()) {
+                jsonGenerator.writeArrayFieldStart(GraphSONTokens.SOURCE);
+                for (final Bytecode.Instruction instruction : 
bytecode.getSourceInstructions()) {
+                    jsonGenerator.writeStartArray();
+                    jsonGenerator.writeString(instruction.getOperator());
+                    for (final Object argument : instruction.getArguments()) {
+                        jsonGenerator.writeObject(argument);
+                    }
+                    jsonGenerator.writeEndArray();
+                }
+                jsonGenerator.writeEndArray();
+            }
+            if (bytecode.getStepInstructions().iterator().hasNext()) {
+                jsonGenerator.writeArrayFieldStart(GraphSONTokens.STEP);
+                for (final Bytecode.Instruction instruction : 
bytecode.getStepInstructions()) {
+                    jsonGenerator.writeStartArray();
+                    jsonGenerator.writeString(instruction.getOperator());
+                    for (final Object argument : instruction.getArguments()) {
+                        jsonGenerator.writeObject(argument);
+                    }
+                    jsonGenerator.writeEndArray();
+                }
+                jsonGenerator.writeEndArray();
+            }
+
+            jsonGenerator.writeEndObject();
+        }
+    }
+
+    static class EnumJacksonSerializer extends StdScalarSerializer<Enum> {
+
+        public EnumJacksonSerializer() {
+            super(Enum.class);
+        }
+
+        @Override
+        public void serialize(final Enum enumInstance, final JsonGenerator 
jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            jsonGenerator.writeString(enumInstance.name());
+        }
+
+    }
+
+    final static class PJacksonSerializer extends StdScalarSerializer<P> {
+
+        public PJacksonSerializer() {
+            super(P.class);
+        }
+
+        @Override
+        public void serialize(final P p, final JsonGenerator jsonGenerator, 
final SerializerProvider serializerProvider)
+                throws IOException {
+            jsonGenerator.writeStartObject();
+            jsonGenerator.writeStringField(GraphSONTokens.PREDICATE,
+                    p instanceof ConnectiveP ?
+                            p instanceof AndP ?
+                                    GraphSONTokens.AND :
+                                    GraphSONTokens.OR :
+                            p.getBiPredicate().toString());
+            if (p instanceof ConnectiveP) {
+                jsonGenerator.writeArrayFieldStart(GraphSONTokens.VALUE);
+                for (final P<?> predicate : ((ConnectiveP<?>) 
p).getPredicates()) {
+                    jsonGenerator.writeObject(predicate);
+                }
+                jsonGenerator.writeEndArray();
+            } else {
+                if (p.getValue() instanceof Collection) {
+                    jsonGenerator.writeArrayFieldStart(GraphSONTokens.VALUE);
+                    for (final Object object : (Collection) p.getValue()) {
+                        jsonGenerator.writeObject(object);
+                    }
+                    jsonGenerator.writeEndArray();
+                } else
+                    jsonGenerator.writeObjectField(GraphSONTokens.VALUE, 
p.getValue());
+            }
+            jsonGenerator.writeEndObject();
+        }
+
+    }
+
+    final static class LambdaJacksonSerializer extends 
StdScalarSerializer<Lambda> {
+
+        public LambdaJacksonSerializer() {
+            super(Lambda.class);
+        }
+
+        @Override
+        public void serialize(final Lambda lambda, final JsonGenerator 
jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            jsonGenerator.writeStartObject();
+            jsonGenerator.writeStringField(GraphSONTokens.SCRIPT, 
lambda.getLambdaScript());
+            jsonGenerator.writeStringField(GraphSONTokens.LANGUAGE, 
lambda.getLambdaLanguage());
+            jsonGenerator.writeNumberField(GraphSONTokens.ARGUMENTS, 
lambda.getLambdaArguments());
+            jsonGenerator.writeEndObject();
+        }
+
+    }
+
+    final static class BindingJacksonSerializer extends 
StdScalarSerializer<Bytecode.Binding> {
+
+        public BindingJacksonSerializer() {
+            super(Bytecode.Binding.class);
+        }
+
+        @Override
+        public void serialize(final Bytecode.Binding binding, final 
JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            jsonGenerator.writeStartObject();
+            jsonGenerator.writeStringField(GraphSONTokens.KEY, 
binding.variable());
+            jsonGenerator.writeObjectField(GraphSONTokens.VALUE, 
binding.value());
+            jsonGenerator.writeEndObject();
+        }
+
+    }
+
+    final static class TraverserJacksonSerializer extends 
StdScalarSerializer<Traverser> {
+
+        public TraverserJacksonSerializer() {
+            super(Traverser.class);
+        }
+
+        @Override
+        public void serialize(final Traverser traverserInstance, final 
JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            jsonGenerator.writeStartObject();
+            jsonGenerator.writeObjectField(GraphSONTokens.BULK, 
traverserInstance.bulk());
+            jsonGenerator.writeObjectField(GraphSONTokens.VALUE, 
traverserInstance.get());
+            jsonGenerator.writeEndObject();
+        }
+    }
+
+    final static class TraversalStrategyJacksonSerializer extends 
StdScalarSerializer<TraversalStrategy> {
+
+        public TraversalStrategyJacksonSerializer() {
+            super(TraversalStrategy.class);
+        }
+
+        @Override
+        public void serialize(final TraversalStrategy traversalStrategy, final 
JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException {
+            jsonGenerator.writeStartObject();
+            for (final Map.Entry<Object, Object> entry : 
ConfigurationConverter.getMap(traversalStrategy.getConfiguration()).entrySet()) 
{
+                jsonGenerator.writeObjectField((String) entry.getKey(), 
entry.getValue());
+            }
+            jsonGenerator.writeEndObject();
+        }
+    }
+
+    ///////////////////
+    // DESERIALIZERS //
+    //////////////////
+
+    final static class BytecodeJacksonDeserializer extends 
AbstractObjectDeserializer<Bytecode> {
+
+        public BytecodeJacksonDeserializer() {
+            super(Bytecode.class);
+        }
+
+        @Override
+        public Bytecode createObject(final Map<String, Object> data) {
+            final Bytecode bytecode = new Bytecode();
+            if (data.containsKey(GraphSONTokens.SOURCE)) {
+                final List<List<Object>> instructions = (List) 
data.get(GraphSONTokens.SOURCE);
+                for (final List<Object> instruction : instructions) {
+                    bytecode.addSource((String) instruction.get(0), 
Arrays.copyOfRange(instruction.toArray(), 1, instruction.size()));
+                }
+            }
+            if (data.containsKey(GraphSONTokens.STEP)) {
+                final List<List<Object>> instructions = (List) 
data.get(GraphSONTokens.STEP);
+                for (final List<Object> instruction : instructions) {
+                    bytecode.addStep((String) instruction.get(0), 
Arrays.copyOfRange(instruction.toArray(), 1, instruction.size()));
+                }
+            }
+            return bytecode;
+        }
+    }
+
+    final static class EnumJacksonDeserializer<A extends Enum> extends 
StdDeserializer<A> {
+
+        public EnumJacksonDeserializer(final Class<A> enumClass) {
+            super(enumClass);
+        }
+
+        @Override
+        public A deserialize(final JsonParser jsonParser, final 
DeserializationContext deserializationContext) throws IOException, 
JsonProcessingException {
+            final Class<A> enumClass = (Class<A>) this._valueClass;
+            final String enumName = jsonParser.getText();
+            for (final Enum a : enumClass.getEnumConstants()) {
+                if (a.name().equals(enumName))
+                    return (A) a;
+            }
+            throw new IOException("Unknown enum type: " + enumClass);
+        }
+    }
+
+    final static class PJacksonDeserializer extends 
AbstractObjectDeserializer<P> {
+
+        public PJacksonDeserializer() {
+            super(P.class);
+        }
+
+        @Override
+        public P createObject(final Map<String, Object> data) {
+            final String predicate = (String) 
data.get(GraphSONTokens.PREDICATE);
+            final Object value = data.get(GraphSONTokens.VALUE);
+            if (predicate.equals(GraphSONTokens.AND) || 
predicate.equals(GraphSONTokens.OR)) {
+                return predicate.equals(GraphSONTokens.AND) ? new 
AndP((List<P>) value) : new OrP((List<P>) value);
+            } else {
+                try {
+                    if (value instanceof Collection) {
+                        if (predicate.equals("between"))
+                            return P.between(((List) value).get(0), ((List) 
value).get(1));
+                        else if (predicate.equals("inside"))
+                            return P.between(((List) value).get(0), ((List) 
value).get(1));
+                        else if (predicate.equals("outside"))
+                            return P.outside(((List) value).get(0), ((List) 
value).get(1));
+                        else if (predicate.equals("within"))
+                            return P.within((Collection) value);
+                        else if (predicate.equals("without"))
+                            return P.without((Collection) value);
+                        else
+                            return (P) P.class.getMethod(predicate, 
Collection.class).invoke(null, (Collection) value);
+                    } else {
+                        try {
+                            return (P) P.class.getMethod(predicate, 
Object.class).invoke(null, value);
+                        } catch (final NoSuchMethodException e) {
+                            return (P) P.class.getMethod(predicate, 
Object[].class).invoke(null, (Object) new Object[]{value});
+                        }
+                    }
+                } catch (final Exception e) {
+                    throw new IllegalStateException(e.getMessage(), e);
+                }
+            }
+        }
+    }
+
+    final static class LambdaJacksonDeserializer extends 
AbstractObjectDeserializer<Lambda> {
+
+        public LambdaJacksonDeserializer() {
+            super(Lambda.class);
+        }
+
+        @Override
+        public Lambda createObject(final Map<String, Object> data) {
+            final String script = (String) data.get(GraphSONTokens.SCRIPT);
+            final String language = (String) data.get(GraphSONTokens.LANGUAGE);
+            final int arguments = ((Number) 
data.getOrDefault(GraphSONTokens.ARGUMENTS, -1)).intValue();
+            //
+            if (-1 == arguments || arguments > 2)
+                return new Lambda.UnknownArgLambda(script, language, 
arguments);
+            else if (0 == arguments)
+                return new Lambda.ZeroArgLambda<>(script, language);
+            else if (1 == arguments)
+                return new Lambda.OneArgLambda<>(script, language);
+            else
+                return new Lambda.TwoArgLambda<>(script, language);
+        }
+    }
+
+    final static class BindingJacksonDeserializer extends 
AbstractObjectDeserializer<Bytecode.Binding> {
+
+        public BindingJacksonDeserializer() {
+            super(Bytecode.Binding.class);
+        }
+
+        @Override
+        public Bytecode.Binding createObject(final Map<String, Object> data) {
+            return new Bytecode.Binding<>((String) 
data.get(GraphSONTokens.KEY), data.get(GraphSONTokens.VALUE));
+        }
+    }
+
+    static class TraverserJacksonDeserializer extends 
AbstractObjectDeserializer<Traverser> {
+
+        public TraverserJacksonDeserializer() {
+            super(Traverser.class);
+        }
+
+        @Override
+        public Traverser createObject(final Map<String, Object> data) {
+            return new 
DefaultRemoteTraverser<>(data.get(GraphSONTokens.VALUE), (Long) 
data.get(GraphSONTokens.BULK));
+        }
+    }
+
+    final static class TraversalStrategyProxyJacksonDeserializer<T extends 
TraversalStrategy> extends AbstractObjectDeserializer<TraversalStrategyProxy> {
+
+        private final Class<T> clazz;
+
+        public TraversalStrategyProxyJacksonDeserializer(final Class<T> clazz) 
{
+            super(TraversalStrategyProxy.class);
+            this.clazz = clazz;
+        }
+
+        @Override
+        public TraversalStrategyProxy<T> createObject(final Map<String, 
Object> data) {
+            return new TraversalStrategyProxy<>(this.clazz, new 
MapConfiguration(data));
+        }
+    }
+}

Reply via email to