Fixed a bug in enum registrations for GraphSON

There were cases where enums were not deserializing properly as types were 
being overriden by the values of the enums theremselves in the GraphSON type 
registry CTR


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

Branch: refs/heads/TINKERPOP-1545-tp32
Commit: 0bcbc7a26c1de65ffc40a903baa46f3a494b35b8
Parents: 94c35a0
Author: Stephen Mallette <[email protected]>
Authored: Thu Dec 22 12:59:22 2016 -0500
Committer: Stephen Mallette <[email protected]>
Committed: Thu Dec 22 12:59:22 2016 -0500

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   1 +
 .../structure/io/graphson/GraphSONModule.java   |  20 ++--
 .../io/graphson/GraphSONTypeSerializer.java     | 100 +++++++++++++------
 3 files changed, 80 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0bcbc7a2/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 33ce26e..36a0cdd 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -31,6 +31,7 @@ TinkerPop 3.2.4 (Release Date: NOT OFFICIALLY RELEASED YET)
 * Bumped to Netty 4.0.42.final.
 * Added `ByteBuffer`, `InetAddress`, `Timestamp` to the list of Gryo supported 
classes.
 * Fixed Gryo serialization of `Class`.
+* Fixed GraphSON serialization of enums like `T`, `P`, etc. where values were 
overriding each other in the GraphSON type registry.
 * Fixed a bug in Gremlin-Python around `__.__()` and `__.start()`.
 * Fixed a bug around long serialization in Gremlin-Python when using Python3.
 * Deprecated `TraversalSource.withBindings()` as it is no longer needed in 
Gremlin-Java and never was needed for other variants.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0bcbc7a2/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 dfbd3ee..7d65f9c 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
@@ -139,16 +139,16 @@ abstract class GraphSONModule extends 
TinkerPopJacksonModule {
                     put(OrP.class, "P");
                     put(P.class, "P");
                     Stream.of(
-                            VertexProperty.Cardinality.values(),
-                            Column.values(),
-                            Direction.values(),
-                            Operator.values(),
-                            Order.values(),
-                            Pop.values(),
-                            SackFunctions.Barrier.values(),
-                            TraversalOptionParent.Pick.values(),
-                            Scope.values(),
-                            T.values()).flatMap(Stream::of).forEach(e -> 
put(e.getClass(), e.getDeclaringClass().getSimpleName()));
+                            VertexProperty.Cardinality.class,
+                            Column.class,
+                            Direction.class,
+                            Operator.class,
+                            Order.class,
+                            Pop.class,
+                            SackFunctions.Barrier.class,
+                            TraversalOptionParent.Pick.class,
+                            Scope.class,
+                            T.class).forEach(e -> put(e, e.getSimpleName()));
                     Arrays.asList(
                             ConnectiveStrategy.class,
                             ElementIdStrategy.class,

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0bcbc7a2/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java
index 6198168..78c670a 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java
@@ -18,14 +18,24 @@
  */
 package org.apache.tinkerpop.gremlin.structure.io.graphson;
 
+import org.apache.tinkerpop.gremlin.process.traversal.Operator;
+import org.apache.tinkerpop.gremlin.process.traversal.Order;
 import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
+import org.apache.tinkerpop.gremlin.process.traversal.SackFunctions;
+import org.apache.tinkerpop.gremlin.process.traversal.Scope;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import 
org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent;
 import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
+import org.apache.tinkerpop.gremlin.structure.Column;
+import org.apache.tinkerpop.gremlin.structure.Direction;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
 import org.apache.tinkerpop.gremlin.util.function.Lambda;
 import org.apache.tinkerpop.shaded.jackson.annotation.JsonTypeInfo;
 import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
@@ -36,6 +46,8 @@ import 
org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
 import java.io.IOException;
 import java.net.InetAddress;
 import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Extension of the Jackson's default TypeSerializer. An instance of this 
object will be passed to the serializers
@@ -50,6 +62,7 @@ public class GraphSONTypeSerializer extends TypeSerializer {
     private final String propertyName;
     private final TypeInfo typeInfo;
     private final String valuePropertyName;
+    private final Map<Class, Class> classMap = new HashMap<>();
 
     GraphSONTypeSerializer(final TypeIdResolver idRes, final String 
propertyName, final TypeInfo typeInfo,
                            final String valuePropertyName) {
@@ -170,38 +183,63 @@ public class GraphSONTypeSerializer extends 
TypeSerializer {
         jsonGenerator.writeEndObject();
     }
 
-    /* We force only **one** translation of a Java object to a domain specific 
object.
-     i.e. users register typeIDs and serializers/deserializers for the 
predefined
-     types we have in the spec. Graph, Vertex, Edge, VertexProperty, etc... And
-     **not** their implementations (TinkerGraph, DetachedVertex, TinkerEdge,
-     etc..)
+    /**
+     *  We force only **one** translation of a Java object to a domain 
specific object. i.e. users register typeIDs
+     *  and serializers/deserializers for the predefined types we have in the 
spec. Graph, Vertex, Edge,
+     *  VertexProperty, etc... And **not** their implementations (TinkerGraph, 
DetachedVertex, TinkerEdge, etc..)
     */
     private Class getClassFromObject(final Object o) {
-        // not the most efficient
-        final  Class c = o.getClass();
-        if (Vertex.class.isAssignableFrom(c)) {
-            return Vertex.class;
-        } else if (Edge.class.isAssignableFrom(c)) {
-            return Edge.class;
-        } else if (Path.class.isAssignableFrom(c)) {
-            return Path.class;
-        } else if (VertexProperty.class.isAssignableFrom(c)) {
-            return VertexProperty.class;
-        } else if (Metrics.class.isAssignableFrom(c)) {
-            return Metrics.class;
-        } else if (TraversalMetrics.class.isAssignableFrom(c)) {
-            return TraversalMetrics.class;
-        } else if (Property.class.isAssignableFrom(c)) {
-            return Property.class;
-        } else if (ByteBuffer.class.isAssignableFrom(c)) {
-            return ByteBuffer.class;
-        } else if (InetAddress.class.isAssignableFrom(c)) {
-            return InetAddress.class;
-        } else if (Traverser.class.isAssignableFrom(c)) {
-            return Traverser.class;
-        } else if (Lambda.class.isAssignableFrom(c)) {
-            return Lambda.class;
-        }
-        return c;
+        final Class c = o.getClass();
+        if (classMap.containsKey(c))
+            return classMap.get(c);
+
+        final Class mapped;
+        if (Vertex.class.isAssignableFrom(c))
+            mapped = Vertex.class;
+        else if (Edge.class.isAssignableFrom(c))
+            mapped = Edge.class;
+        else if (Path.class.isAssignableFrom(c))
+            mapped = Path.class;
+        else if (VertexProperty.class.isAssignableFrom(c))
+            mapped = VertexProperty.class;
+        else if (Metrics.class.isAssignableFrom(c))
+            mapped = Metrics.class;
+        else if (TraversalMetrics.class.isAssignableFrom(c))
+            mapped = TraversalMetrics.class;
+        else if (Property.class.isAssignableFrom(c))
+            mapped = Property.class;
+        else if (ByteBuffer.class.isAssignableFrom(c))
+            mapped = ByteBuffer.class;
+        else if (InetAddress.class.isAssignableFrom(c))
+            mapped = InetAddress.class;
+        else if (Traverser.class.isAssignableFrom(c))
+            mapped = Traverser.class;
+        else if (Lambda.class.isAssignableFrom(c))
+            mapped = Lambda.class;
+        else if (VertexProperty.Cardinality.class.isAssignableFrom(c))
+            mapped = VertexProperty.Cardinality.class;
+        else if (Column.class.isAssignableFrom(c))
+            mapped = Column.class;
+        else if (Direction.class.isAssignableFrom(c))
+            mapped = Direction.class;
+        else if (Operator.class.isAssignableFrom(c))
+            mapped = Operator.class;
+        else if (Order.class.isAssignableFrom(c))
+            mapped = Order.class;
+        else if (Pop.class.isAssignableFrom(c))
+            mapped = Pop.class;
+        else if (SackFunctions.Barrier.class.isAssignableFrom(c))
+            mapped = SackFunctions.Barrier.class;
+        else if (TraversalOptionParent.Pick.class.isAssignableFrom(c))
+            mapped = TraversalOptionParent.Pick.class;
+        else if (Scope.class.isAssignableFrom(c))
+            mapped = Scope.class;
+        else if (T.class.isAssignableFrom(c))
+            mapped = T.class;
+        else
+            mapped = c;
+
+        classMap.put(c, mapped);
+        return mapped;
     }
 }

Reply via email to