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; } }
