tinkerpop-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From spmalle...@apache.org
Subject [08/19] tinkerpop git commit: TINKERPOP-1274: GraphSON 2.0.
Date Mon, 22 Aug 2016 18:30:45 GMT
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TinkerPopJacksonModule.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TinkerPopJacksonModule.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TinkerPopJacksonModule.java
new file mode 100644
index 0000000..847027c
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TinkerPopJacksonModule.java
@@ -0,0 +1,48 @@
+/*
+ * 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.tinkerpop.shaded.jackson.databind.module.SimpleModule;
+
+import java.util.Map;
+
+/**
+ * A {@link SimpleModule} extension that does the necessary work to make the automatic typed deserialization
+ * without full canonical class names work.
+ *
+ * Users of custom modules with the GraphSONMapper that want their objects to be deserialized automatically by the
+ * mapper, must extend this class with their module. It is the only required step.
+ *
+ * Using this basis module allows the serialization and deserialization of typed objects without having the whole
+ * canonical name of the serialized classes included in the Json payload. This is also necessary because Java
+ * does not provide an agnostic way to search in a classpath a find a class by its simple name. Although that could
+ * be done with an external library, later if we deem it necessary.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ */
+public abstract class TinkerPopJacksonModule extends SimpleModule {
+
+    public TinkerPopJacksonModule(String name) {
+        super(name);
+    }
+
+    public abstract Map<Class, String> getTypeDefinitions();
+
+    public abstract String getTypeNamespace();
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/ToStringGraphSONSerializer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/ToStringGraphSONSerializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/ToStringGraphSONSerializer.java
new file mode 100644
index 0000000..fbd9e00
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/ToStringGraphSONSerializer.java
@@ -0,0 +1,41 @@
+/*
+ * 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.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.ToStringSerializer;
+
+import java.io.IOException;
+
+/**
+ * A different implementation of the {@link ToStringSerializer} that does not serialize types by calling
+ * `typeSerializer.writeTypePrefixForScalar()` for unknown objects, because it doesn't make sense when there is a
+ * custom types mechanism in place.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ */
+public class ToStringGraphSONSerializer extends ToStringSerializer {
+    @Override
+    public void serializeWithType(Object value, JsonGenerator gen, SerializerProvider provider, TypeSerializer typeSer) throws IOException {
+        this.serialize(value, gen, provider);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TypeInfo.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TypeInfo.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TypeInfo.java
new file mode 100644
index 0000000..34e0d2b
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TypeInfo.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+/**
+ * Defines how data types are handled in GraphSON through the {@link GraphSONMapper}.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public enum TypeInfo {
+    NO_TYPES,
+    PARTIAL_TYPES
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
index 776d313..ba05cca 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
@@ -79,12 +79,17 @@ public class DetachedEdge extends DetachedElement<Edge> implements Edge {
         super(id, label);
         this.outVertex = new DetachedVertex(outV.getValue0(), outV.getValue1(), Collections.emptyMap());
         this.inVertex = new DetachedVertex(inV.getValue0(), inV.getValue1(), Collections.emptyMap());
-        if (!properties.isEmpty()) {
+        if (properties != null && !properties.isEmpty()) {
             this.properties = new HashMap<>();
-            properties.entrySet().stream().forEach(entry -> this.properties.put(entry.getKey(), Collections.singletonList(new DetachedProperty<>(entry.getKey(), entry.getValue(), this))));
+            properties.entrySet().stream().forEach(entry -> {
+                if (Property.class.isAssignableFrom(entry.getValue().getClass())) {
+                    this.properties.put(entry.getKey(), Collections.singletonList((Property)entry.getValue()));
+                } else {
+                    this.properties.put(entry.getKey(), Collections.singletonList(new DetachedProperty<>(entry.getKey(), entry.getValue(), this)));
+                }
+            });
         }
     }
-
     @Override
     public String toString() {
         return StringFactory.edgeString(this);

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
index 371c091..70cce37 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
@@ -76,12 +76,14 @@ public class DetachedVertex extends DetachedElement<Vertex> implements Vertex {
 
     public DetachedVertex(final Object id, final String label, final Map<String, Object> properties) {
         super(id, label);
-        if (!properties.isEmpty()) {
+        if (properties != null && !properties.isEmpty()) {
             this.properties = new HashMap<>();
             properties.entrySet().stream().forEach(
-                    entry -> this.properties.put(entry.getKey(), ((List<Map<String, Object>>) entry.getValue()).stream()
-                            .map(m -> new DetachedVertexProperty<>(m.get(ID), entry.getKey(), m.get(VALUE), (Map<String, Object>) m.getOrDefault(PROPERTIES, new HashMap<>()), this))
-                            .collect(Collectors.toList())));
+                    entry -> this.properties.put(entry.getKey(), (List<VertexProperty>) ((List) entry.getValue()).stream()
+                                .map(m -> VertexProperty.class.isAssignableFrom(m.getClass())
+                                                ? m
+                                                : new DetachedVertexProperty<>(((Map) m).get(ID), entry.getKey(), ((Map) m).get(VALUE), (Map<String, Object>) ((Map) m).getOrDefault(PROPERTIES, new HashMap<>()), this))
+                                .collect(Collectors.toList())));
         }
     }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/DirectionalStarGraph.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/DirectionalStarGraph.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/DirectionalStarGraph.java
new file mode 100644
index 0000000..ed7b58c
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/DirectionalStarGraph.java
@@ -0,0 +1,39 @@
+/*
+ * 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.util.star;
+
+import org.apache.tinkerpop.gremlin.structure.Direction;
+
+public class DirectionalStarGraph {
+    private final Direction direction;
+    private final StarGraph starGraphToSerialize;
+
+    public DirectionalStarGraph(final StarGraph starGraphToSerialize, final Direction direction) {
+        this.direction = direction;
+        this.starGraphToSerialize = starGraphToSerialize;
+    }
+
+    public Direction getDirection() {
+        return direction;
+    }
+
+    public StarGraph getStarGraphToSerialize() {
+        return starGraphToSerialize;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONDeserializer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONDeserializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONDeserializer.java
new file mode 100644
index 0000000..84a3fd4
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONDeserializer.java
@@ -0,0 +1,91 @@
+/*
+ * 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.util.star;
+
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
+import org.apache.tinkerpop.gremlin.structure.util.Attachable;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+/**
+ * Provides helper functions for reading vertex and edges from their serialized GraphSON forms.
+ */
+public class StarGraphGraphSONDeserializer {
+
+    /**
+     * A helper function for reading vertex edges from a serialized {@link org.apache.tinkerpop.gremlin.structure.util.star.StarGraph} (i.e. a {@link java.util.Map}) generated by
+     * {@link org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializerV1d0}.
+     */
+    public static void readStarGraphEdges(final Function<Attachable<Edge>, Edge> edgeMaker,
+                                          final StarGraph starGraph,
+                                          final Map<String, Object> vertexData,
+                                          final String direction) throws IOException {
+        final Map<String, List<Map<String,Object>>> edgeDatas = (Map<String, List<Map<String,Object>>>) vertexData.get(direction);
+        for (Map.Entry<String, List<Map<String,Object>>> edgeData : edgeDatas.entrySet()) {
+            for (Map<String,Object> inner : edgeData.getValue()) {
+                final StarGraph.StarEdge starEdge;
+                if (direction.equals(GraphSONTokens.OUT_E))
+                    starEdge = (StarGraph.StarEdge) starGraph.getStarVertex().addOutEdge(edgeData.getKey(), starGraph.addVertex(T.id, inner.get(GraphSONTokens.IN)), T.id, inner.get(GraphSONTokens.ID));
+                else
+                    starEdge = (StarGraph.StarEdge) starGraph.getStarVertex().addInEdge(edgeData.getKey(), starGraph.addVertex(T.id, inner.get(GraphSONTokens.OUT)), T.id, inner.get(GraphSONTokens.ID));
+
+                if (inner.containsKey(GraphSONTokens.PROPERTIES)) {
+                    final Map<String, Object> edgePropertyData = (Map<String, Object>) inner.get(GraphSONTokens.PROPERTIES);
+                    for (Map.Entry<String, Object> epd : edgePropertyData.entrySet()) {
+                        starEdge.property(epd.getKey(), epd.getValue());
+                    }
+                }
+
+                if (edgeMaker != null) edgeMaker.apply(starEdge);
+            }
+        }
+    }
+
+    /**
+     * A helper function for reading a serialized {@link org.apache.tinkerpop.gremlin.structure.util.star.StarGraph} from a {@link java.util.Map} generated by
+     * {@link org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializerV1d0}.
+     */
+    public static StarGraph readStarGraphVertex(final Map<String, Object> vertexData) throws IOException {
+        final StarGraph starGraph = StarGraph.open();
+        starGraph.addVertex(T.id, vertexData.get(GraphSONTokens.ID), T.label, vertexData.get(GraphSONTokens.LABEL));
+        if (vertexData.containsKey(GraphSONTokens.PROPERTIES)) {
+            final Map<String, List<Map<String, Object>>> properties = (Map<String, List<Map<String, Object>>>) vertexData.get(GraphSONTokens.PROPERTIES);
+            for (Map.Entry<String, List<Map<String, Object>>> property : properties.entrySet()) {
+                for (Map<String, Object> p : property.getValue()) {
+                    final StarGraph.StarVertexProperty vp = (StarGraph.StarVertexProperty) starGraph.getStarVertex().property(VertexProperty.Cardinality.list, property.getKey(), p.get(GraphSONTokens.VALUE), T.id, p.get(GraphSONTokens.ID));
+                    if (p.containsKey(GraphSONTokens.PROPERTIES)) {
+                        final Map<String, Object> edgePropertyData = (Map<String, Object>) p.get(GraphSONTokens.PROPERTIES);
+                        for (Map.Entry<String, Object> epd : edgePropertyData.entrySet()) {
+                            vp.property(epd.getKey(), epd.getValue());
+                        }
+                    }
+                }
+            }
+        }
+
+        return starGraph;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializer.java
deleted file mode 100644
index 3d1a16a..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializer.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * 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.util.star;
-
-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.VertexProperty;
-import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
-import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONUtil;
-import org.apache.tinkerpop.gremlin.structure.util.Attachable;
-import org.apache.tinkerpop.gremlin.structure.util.Comparators;
-import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
-import org.apache.tinkerpop.shaded.jackson.core.JsonGenerationException;
-import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
-import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
-import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
-import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
-import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.function.Function;
-
-/**
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-public class StarGraphGraphSONSerializer extends StdSerializer<StarGraphGraphSONSerializer.DirectionalStarGraph> {
-    private final boolean normalize;
-    public StarGraphGraphSONSerializer(final boolean normalize) {
-        super(DirectionalStarGraph.class);
-        this.normalize = normalize;
-    }
-
-    @Override
-    public void serialize(final DirectionalStarGraph starGraph, final JsonGenerator jsonGenerator,
-                          final SerializerProvider serializerProvider) throws IOException, JsonGenerationException {
-        ser(starGraph, jsonGenerator, serializerProvider, null);
-    }
-
-    @Override
-    public void serializeWithType(final DirectionalStarGraph starGraph, final JsonGenerator jsonGenerator,
-                                  final SerializerProvider serializerProvider,
-                                  final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
-        ser(starGraph, jsonGenerator, serializerProvider, typeSerializer);
-    }
-
-    private void ser(final DirectionalStarGraph directionalStarGraph, final JsonGenerator jsonGenerator,
-                     final SerializerProvider serializerProvider,
-                     final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
-        final StarGraph starGraph = directionalStarGraph.getStarGraphToSerialize();
-        jsonGenerator.writeStartObject();
-        if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
-        GraphSONUtil.writeWithType(GraphSONTokens.ID, starGraph.starVertex.id, jsonGenerator, serializerProvider, typeSerializer);
-        jsonGenerator.writeStringField(GraphSONTokens.LABEL, starGraph.starVertex.label);
-        if (directionalStarGraph.direction != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.IN);
-        if (directionalStarGraph.direction != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.OUT);
-        if (starGraph.starVertex.vertexProperties != null && !starGraph.starVertex.vertexProperties.isEmpty()) {
-            jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
-            if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
-            final Set<String> keys = normalize ? new TreeSet<>(starGraph.starVertex.vertexProperties.keySet()) : starGraph.starVertex.vertexProperties.keySet();
-            for (final String k : keys) {
-                final List<VertexProperty> vp = starGraph.starVertex.vertexProperties.get(k);
-                jsonGenerator.writeArrayFieldStart(k);
-                if (typeSerializer != null) {
-                    jsonGenerator.writeString(ArrayList.class.getName());
-                    jsonGenerator.writeStartArray();
-                }
-
-                final List<VertexProperty> vertexProperties = normalize ?sort(vp, Comparators.PROPERTY_COMPARATOR) : vp;
-                for (final VertexProperty property : vertexProperties) {
-                    jsonGenerator.writeStartObject();
-                    if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
-                    GraphSONUtil.writeWithType(GraphSONTokens.ID, property.id(), jsonGenerator, serializerProvider, typeSerializer);
-                    GraphSONUtil.writeWithType(GraphSONTokens.VALUE, property.value(), jsonGenerator, serializerProvider, typeSerializer);
-
-                    final Iterator<Property> metaProperties = normalize ?
-                            IteratorUtils.list(property.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : property.properties();
-                    if (metaProperties.hasNext()) {
-                        jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
-                        if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
-                        while (metaProperties.hasNext()) {
-                            final Property<Object> meta = metaProperties.next();
-                            GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
-                        }
-                        jsonGenerator.writeEndObject();
-                    }
-                    jsonGenerator.writeEndObject();
-                }
-                jsonGenerator.writeEndArray();
-                if (typeSerializer != null) jsonGenerator.writeEndArray();
-            }
-            jsonGenerator.writeEndObject();
-        }
-    }
-
-    private void writeEdges(final DirectionalStarGraph directionalStarGraph, final JsonGenerator jsonGenerator,
-                            final SerializerProvider serializerProvider,
-                            final TypeSerializer typeSerializer,
-                            final Direction direction)  throws IOException, JsonProcessingException {
-        // only write edges if there are some AND if the user requested them to be serialized AND if they match
-        // the direction being serialized by the format
-        final StarGraph starGraph = directionalStarGraph.getStarGraphToSerialize();
-        final Direction edgeDirectionToSerialize = directionalStarGraph.getDirection();
-        final Map<String, List<Edge>> starEdges = direction.equals(Direction.OUT) ? starGraph.starVertex.outEdges : starGraph.starVertex.inEdges;
-        final boolean writeEdges = null != starEdges && edgeDirectionToSerialize != null
-                && (edgeDirectionToSerialize == direction || edgeDirectionToSerialize == Direction.BOTH);
-        if (writeEdges) {
-            jsonGenerator.writeObjectFieldStart(direction == Direction.IN ? GraphSONTokens.IN_E : GraphSONTokens.OUT_E);
-            if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
-            final Set<String> keys = normalize ? new TreeSet<>(starEdges.keySet()) : starEdges.keySet();
-            for (final String k : keys) {
-                final List<Edge> edges = starEdges.get(k);
-                jsonGenerator.writeArrayFieldStart(k);
-                if (typeSerializer != null) {
-                    jsonGenerator.writeString(ArrayList.class.getName());
-                    jsonGenerator.writeStartArray();
-                }
-
-                final List<Edge> edgesToWrite = normalize ? sort(edges, Comparators.EDGE_COMPARATOR) : edges;
-                for (final Edge edge : edgesToWrite) {
-                    jsonGenerator.writeStartObject();
-                    if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
-                    GraphSONUtil.writeWithType(GraphSONTokens.ID, edge.id(), jsonGenerator, serializerProvider, typeSerializer);
-                    GraphSONUtil.writeWithType(direction.equals(Direction.OUT) ? GraphSONTokens.IN : GraphSONTokens.OUT,
-                            direction.equals(Direction.OUT) ? edge.inVertex().id() : edge.outVertex().id(),
-                            jsonGenerator, serializerProvider, typeSerializer);
-
-                    final Iterator<Property<Object>> edgeProperties = normalize ?
-                            IteratorUtils.list(edge.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : edge.properties();
-                    if (edgeProperties.hasNext()) {
-                        jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
-                        if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
-                        while (edgeProperties.hasNext()) {
-                            final Property<Object> meta = edgeProperties.next();
-                            GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
-                        }
-                        jsonGenerator.writeEndObject();
-                    }
-                    jsonGenerator.writeEndObject();
-                }
-                jsonGenerator.writeEndArray();
-                if (typeSerializer != null) jsonGenerator.writeEndArray();
-            }
-            jsonGenerator.writeEndObject();
-        }
-    }
-
-    /**
-     * A helper function for reading vertex edges from a serialized {@link StarGraph} (i.e. a {@link Map}) generated by
-     * {@link StarGraphGraphSONSerializer}.
-     */
-    public static void readStarGraphEdges(final Function<Attachable<Edge>, Edge> edgeMaker,
-                                          final StarGraph starGraph,
-                                          final Map<String, Object> vertexData,
-                                          final String direction) throws IOException {
-        final Map<String, List<Map<String,Object>>> edgeDatas = (Map<String, List<Map<String,Object>>>) vertexData.get(direction);
-        for (Map.Entry<String, List<Map<String,Object>>> edgeData : edgeDatas.entrySet()) {
-            for (Map<String,Object> inner : edgeData.getValue()) {
-                final StarGraph.StarEdge starEdge;
-                if (direction.equals(GraphSONTokens.OUT_E))
-                    starEdge = (StarGraph.StarEdge) starGraph.getStarVertex().addOutEdge(edgeData.getKey(), starGraph.addVertex(T.id, inner.get(GraphSONTokens.IN)), T.id, inner.get(GraphSONTokens.ID));
-                else
-                    starEdge = (StarGraph.StarEdge) starGraph.getStarVertex().addInEdge(edgeData.getKey(), starGraph.addVertex(T.id, inner.get(GraphSONTokens.OUT)), T.id, inner.get(GraphSONTokens.ID));
-
-                if (inner.containsKey(GraphSONTokens.PROPERTIES)) {
-                    final Map<String, Object> edgePropertyData = (Map<String, Object>) inner.get(GraphSONTokens.PROPERTIES);
-                    for (Map.Entry<String, Object> epd : edgePropertyData.entrySet()) {
-                        starEdge.property(epd.getKey(), epd.getValue());
-                    }
-                }
-
-                if (edgeMaker != null) edgeMaker.apply(starEdge);
-            }
-        }
-    }
-
-    /**
-     * A helper function for reading a serialized {@link StarGraph} from a {@link Map} generated by
-     * {@link StarGraphGraphSONSerializer}.
-     */
-    public static StarGraph readStarGraphVertex(final Map<String, Object> vertexData) throws IOException {
-        final StarGraph starGraph = StarGraph.open();
-        starGraph.addVertex(T.id, vertexData.get(GraphSONTokens.ID), T.label, vertexData.get(GraphSONTokens.LABEL));
-        if (vertexData.containsKey(GraphSONTokens.PROPERTIES)) {
-            final Map<String, List<Map<String, Object>>> properties = (Map<String, List<Map<String, Object>>>) vertexData.get(GraphSONTokens.PROPERTIES);
-            for (Map.Entry<String, List<Map<String, Object>>> property : properties.entrySet()) {
-                for (Map<String, Object> p : property.getValue()) {
-                    final StarGraph.StarVertexProperty vp = (StarGraph.StarVertexProperty) starGraph.getStarVertex().property(VertexProperty.Cardinality.list, property.getKey(), p.get(GraphSONTokens.VALUE), T.id, p.get(GraphSONTokens.ID));
-                    if (p.containsKey(GraphSONTokens.PROPERTIES)) {
-                        final Map<String, Object> edgePropertyData = (Map<String, Object>) p.get(GraphSONTokens.PROPERTIES);
-                        for (Map.Entry<String, Object> epd : edgePropertyData.entrySet()) {
-                            vp.property(epd.getKey(), epd.getValue());
-                        }
-                    }
-                }
-            }
-        }
-
-        return starGraph;
-    }
-
-    private static <S> List<S> sort(final List<S> listToSort, final Comparator comparator) {
-        Collections.sort(listToSort, comparator);
-        return listToSort;
-    }
-
-    public static class DirectionalStarGraph {
-        private final Direction direction;
-        private final StarGraph starGraphToSerialize;
-
-        public DirectionalStarGraph(final StarGraph starGraphToSerialize, final Direction direction) {
-            this.direction = direction;
-            this.starGraphToSerialize = starGraphToSerialize;
-        }
-
-        public Direction getDirection() {
-            return direction;
-        }
-
-        public StarGraph getStarGraphToSerialize() {
-            return starGraphToSerialize;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV1d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV1d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV1d0.java
new file mode 100644
index 0000000..01cb6d6
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV1d0.java
@@ -0,0 +1,178 @@
+/*
+ * 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.util.star;
+
+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.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONUtil;
+import org.apache.tinkerpop.gremlin.structure.util.Comparators;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerationException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class StarGraphGraphSONSerializerV1d0 extends StdSerializer<DirectionalStarGraph> {
+    private final boolean normalize;
+    public StarGraphGraphSONSerializerV1d0(final boolean normalize) {
+        super(DirectionalStarGraph.class);
+        this.normalize = normalize;
+    }
+
+    @Override
+    public void serialize(final DirectionalStarGraph starGraph, final JsonGenerator jsonGenerator,
+                          final SerializerProvider serializerProvider) throws IOException, JsonGenerationException {
+        ser(starGraph, jsonGenerator, serializerProvider, null);
+    }
+
+    @Override
+    public void serializeWithType(final DirectionalStarGraph starGraph, final JsonGenerator jsonGenerator,
+                                  final SerializerProvider serializerProvider,
+                                  final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
+        ser(starGraph, jsonGenerator, serializerProvider, typeSerializer);
+    }
+
+    private void ser(final DirectionalStarGraph directionalStarGraph, final JsonGenerator jsonGenerator,
+                     final SerializerProvider serializerProvider,
+                     final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
+        final StarGraph starGraph = directionalStarGraph.getStarGraphToSerialize();
+        jsonGenerator.writeStartObject();
+        if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+        GraphSONUtil.writeWithType(GraphSONTokens.ID, starGraph.starVertex.id, jsonGenerator, serializerProvider, typeSerializer);
+        jsonGenerator.writeStringField(GraphSONTokens.LABEL, starGraph.starVertex.label);
+        if (directionalStarGraph.getDirection() != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.IN);
+        if (directionalStarGraph.getDirection() != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.OUT);
+        if (starGraph.starVertex.vertexProperties != null && !starGraph.starVertex.vertexProperties.isEmpty()) {
+            jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
+            if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+            final Set<String> keys = normalize ? new TreeSet<>(starGraph.starVertex.vertexProperties.keySet()) : starGraph.starVertex.vertexProperties.keySet();
+            for (final String k : keys) {
+                final List<VertexProperty> vp = starGraph.starVertex.vertexProperties.get(k);
+                jsonGenerator.writeArrayFieldStart(k);
+                if (typeSerializer != null) {
+                    jsonGenerator.writeString(ArrayList.class.getName());
+                    jsonGenerator.writeStartArray();
+                }
+
+                final List<VertexProperty> vertexProperties = normalize ? sort(vp, Comparators.PROPERTY_COMPARATOR) : vp;
+                for (final VertexProperty property : vertexProperties) {
+                    jsonGenerator.writeStartObject();
+                    if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+                    GraphSONUtil.writeWithType(GraphSONTokens.ID, property.id(), jsonGenerator, serializerProvider, typeSerializer);
+                    GraphSONUtil.writeWithType(GraphSONTokens.VALUE, property.value(), jsonGenerator, serializerProvider, typeSerializer);
+
+                    final Iterator<Property> metaProperties = normalize ?
+                            IteratorUtils.list(property.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : property.properties();
+                    if (metaProperties.hasNext()) {
+                        jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
+                        if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+                        while (metaProperties.hasNext()) {
+                            final Property<Object> meta = metaProperties.next();
+                            GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
+                        }
+                        jsonGenerator.writeEndObject();
+                    }
+                    jsonGenerator.writeEndObject();
+                }
+                jsonGenerator.writeEndArray();
+                if (typeSerializer != null) jsonGenerator.writeEndArray();
+            }
+            jsonGenerator.writeEndObject();
+        }
+        // For some reason, this wasn't closed.
+        jsonGenerator.writeEndObject();
+    }
+
+    private void writeEdges(final DirectionalStarGraph directionalStarGraph, final JsonGenerator jsonGenerator,
+                            final SerializerProvider serializerProvider,
+                            final TypeSerializer typeSerializer,
+                            final Direction direction)  throws IOException, JsonProcessingException {
+        // only write edges if there are some AND if the user requested them to be serialized AND if they match
+        // the direction being serialized by the format
+        final StarGraph starGraph = directionalStarGraph.getStarGraphToSerialize();
+        final Direction edgeDirectionToSerialize = directionalStarGraph.getDirection();
+        final Map<String, List<Edge>> starEdges = direction.equals(Direction.OUT) ? starGraph.starVertex.outEdges : starGraph.starVertex.inEdges;
+        final boolean writeEdges = null != starEdges && edgeDirectionToSerialize != null
+                && (edgeDirectionToSerialize == direction || edgeDirectionToSerialize == Direction.BOTH);
+        if (writeEdges) {
+            jsonGenerator.writeObjectFieldStart(direction == Direction.IN ? GraphSONTokens.IN_E : GraphSONTokens.OUT_E);
+            if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+            final Set<String> keys = normalize ? new TreeSet<>(starEdges.keySet()) : starEdges.keySet();
+            for (final String k : keys) {
+                final List<Edge> edges = starEdges.get(k);
+                jsonGenerator.writeArrayFieldStart(k);
+                if (typeSerializer != null) {
+                    jsonGenerator.writeString(ArrayList.class.getName());
+                    jsonGenerator.writeStartArray();
+                }
+
+                final List<Edge> edgesToWrite = normalize ? sort(edges, Comparators.EDGE_COMPARATOR) : edges;
+                for (final Edge edge : edgesToWrite) {
+                    jsonGenerator.writeStartObject();
+                    if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+                    GraphSONUtil.writeWithType(GraphSONTokens.ID, edge.id(), jsonGenerator, serializerProvider, typeSerializer);
+                    GraphSONUtil.writeWithType(direction.equals(Direction.OUT) ? GraphSONTokens.IN : GraphSONTokens.OUT,
+                            direction.equals(Direction.OUT) ? edge.inVertex().id() : edge.outVertex().id(),
+                            jsonGenerator, serializerProvider, typeSerializer);
+
+                    final Iterator<Property<Object>> edgeProperties = normalize ?
+                            IteratorUtils.list(edge.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : edge.properties();
+                    if (edgeProperties.hasNext()) {
+                        jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
+                        if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+                        while (edgeProperties.hasNext()) {
+                            final Property<Object> meta = edgeProperties.next();
+                            GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
+                        }
+                        jsonGenerator.writeEndObject();
+                    }
+                    jsonGenerator.writeEndObject();
+                }
+                jsonGenerator.writeEndArray();
+                if (typeSerializer != null) jsonGenerator.writeEndArray();
+            }
+            jsonGenerator.writeEndObject();
+        }
+    }
+
+    static <S> List<S> sort(final List<S> listToSort, final Comparator comparator) {
+        Collections.sort(listToSort, comparator);
+        return listToSort;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV2d0.java
new file mode 100644
index 0000000..04d65c5
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV2d0.java
@@ -0,0 +1,165 @@
+/*
+ * 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.util.star;
+
+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.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONUtil;
+import org.apache.tinkerpop.gremlin.structure.util.Comparators;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerationException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class StarGraphGraphSONSerializerV2d0 extends StdSerializer<DirectionalStarGraph> {
+    private final boolean normalize;
+    public StarGraphGraphSONSerializerV2d0(final boolean normalize) {
+        super(DirectionalStarGraph.class);
+        this.normalize = normalize;
+    }
+
+    @Override
+    public void serialize(final DirectionalStarGraph starGraph, final JsonGenerator jsonGenerator,
+                          final SerializerProvider serializerProvider) throws IOException, JsonGenerationException {
+        ser(starGraph, jsonGenerator, serializerProvider, null);
+    }
+
+    @Override
+    public void serializeWithType(final DirectionalStarGraph starGraph, final JsonGenerator jsonGenerator,
+                                  final SerializerProvider serializerProvider,
+                                  final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
+        ser(starGraph, jsonGenerator, serializerProvider, typeSerializer);
+    }
+
+    private void ser(final DirectionalStarGraph directionalStarGraph, final JsonGenerator jsonGenerator,
+                     final SerializerProvider serializerProvider,
+                     final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
+        final StarGraph starGraph = directionalStarGraph.getStarGraphToSerialize();
+        GraphSONUtil.writeStartObject(starGraph, jsonGenerator, typeSerializer);
+        GraphSONUtil.writeWithType(GraphSONTokens.ID, starGraph.starVertex.id, jsonGenerator, serializerProvider, typeSerializer);
+        jsonGenerator.writeStringField(GraphSONTokens.LABEL, starGraph.starVertex.label);
+        if (directionalStarGraph.getDirection() != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.IN);
+        if (directionalStarGraph.getDirection() != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.OUT);
+        if (starGraph.starVertex.vertexProperties != null && !starGraph.starVertex.vertexProperties.isEmpty()) {
+            jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+            GraphSONUtil.writeStartObject(starGraph, jsonGenerator, typeSerializer);
+            final Set<String> keys = normalize ? new TreeSet<>(starGraph.starVertex.vertexProperties.keySet()) : starGraph.starVertex.vertexProperties.keySet();
+            for (final String k : keys) {
+                final List<VertexProperty> vp = starGraph.starVertex.vertexProperties.get(k);
+                jsonGenerator.writeFieldName(k);
+                GraphSONUtil.writeStartArray(k, jsonGenerator, typeSerializer);
+
+                final List<VertexProperty> vertexProperties = normalize ?sort(vp, Comparators.PROPERTY_COMPARATOR) : vp;
+                for (final VertexProperty property : vertexProperties) {
+                    GraphSONUtil.writeStartObject(property, jsonGenerator, typeSerializer);
+                    GraphSONUtil.writeWithType(GraphSONTokens.ID, property.id(), jsonGenerator, serializerProvider, typeSerializer);
+                    GraphSONUtil.writeWithType(GraphSONTokens.VALUE, property.value(), jsonGenerator, serializerProvider, typeSerializer);
+
+                    final Iterator<Property> metaProperties = normalize ?
+                            IteratorUtils.list(property.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : property.properties();
+                    if (metaProperties.hasNext()) {
+                        jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+                        GraphSONUtil.writeStartObject(metaProperties, jsonGenerator, typeSerializer);
+
+                        while (metaProperties.hasNext()) {
+                            final Property<Object> meta = metaProperties.next();
+                            GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
+                        }
+                        GraphSONUtil.writeEndObject(metaProperties, jsonGenerator, typeSerializer);
+                    }
+                    GraphSONUtil.writeEndObject(property, jsonGenerator, typeSerializer);
+                }
+                GraphSONUtil.writeEndArray(k, jsonGenerator, typeSerializer);
+            }
+            GraphSONUtil.writeEndObject(starGraph, jsonGenerator, typeSerializer);
+        }
+        GraphSONUtil.writeEndObject(starGraph, jsonGenerator, typeSerializer);
+    }
+
+    private void writeEdges(final DirectionalStarGraph directionalStarGraph, final JsonGenerator jsonGenerator,
+                            final SerializerProvider serializerProvider,
+                            final TypeSerializer typeSerializer,
+                            final Direction direction)  throws IOException, JsonProcessingException {
+        // only write edges if there are some AND if the user requested them to be serialized AND if they match
+        // the direction being serialized by the format
+        final StarGraph starGraph = directionalStarGraph.getStarGraphToSerialize();
+        final Direction edgeDirectionToSerialize = directionalStarGraph.getDirection();
+        final Map<String, List<Edge>> starEdges = direction.equals(Direction.OUT) ? starGraph.starVertex.outEdges : starGraph.starVertex.inEdges;
+        final boolean writeEdges = null != starEdges && edgeDirectionToSerialize != null
+                && (edgeDirectionToSerialize == direction || edgeDirectionToSerialize == Direction.BOTH);
+        if (writeEdges) {
+            jsonGenerator.writeFieldName(direction == Direction.IN ? GraphSONTokens.IN_E : GraphSONTokens.OUT_E);
+            GraphSONUtil.writeStartObject(directionalStarGraph, jsonGenerator, typeSerializer);
+            final Set<String> keys = normalize ? new TreeSet<>(starEdges.keySet()) : starEdges.keySet();
+            for (final String k : keys) {
+                final List<Edge> edges = starEdges.get(k);
+                jsonGenerator.writeFieldName(k);
+                GraphSONUtil.writeStartArray(k, jsonGenerator, typeSerializer);
+
+                final List<Edge> edgesToWrite = normalize ? sort(edges, Comparators.EDGE_COMPARATOR) : edges;
+                for (final Edge edge : edgesToWrite) {
+                    GraphSONUtil.writeStartObject(edge, jsonGenerator, typeSerializer);
+                    GraphSONUtil.writeWithType(GraphSONTokens.ID, edge.id(), jsonGenerator, serializerProvider, typeSerializer);
+                    GraphSONUtil.writeWithType(direction.equals(Direction.OUT) ? GraphSONTokens.IN : GraphSONTokens.OUT,
+                            direction.equals(Direction.OUT) ? edge.inVertex().id() : edge.outVertex().id(),
+                            jsonGenerator, serializerProvider, typeSerializer);
+
+                    final Iterator<Property<Object>> edgeProperties = normalize ?
+                            IteratorUtils.list(edge.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : edge.properties();
+                    if (edgeProperties.hasNext()) {
+                        jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+                        GraphSONUtil.writeStartObject(edge, jsonGenerator, typeSerializer);
+                        while (edgeProperties.hasNext()) {
+                            final Property<Object> meta = edgeProperties.next();
+                            GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
+                        }
+                        GraphSONUtil.writeEndObject(edge, jsonGenerator, typeSerializer);
+                    }
+                    GraphSONUtil.writeEndObject(edge, jsonGenerator, typeSerializer);
+                }
+                GraphSONUtil.writeEndArray(k, jsonGenerator, typeSerializer);
+            }
+            GraphSONUtil.writeEndObject(directionalStarGraph, jsonGenerator, typeSerializer);
+        }
+    }
+
+    private static <S> List<S> sort(final List<S> listToSort, final Comparator comparator) {
+        Collections.sort(listToSort, comparator);
+        return listToSort;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
index c7549f9..4980adf 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
@@ -19,9 +19,9 @@
 package org.apache.tinkerpop.gremlin.structure.io.graphson;
 
 import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
-import org.apache.tinkerpop.shaded.kryo.io.Input;
-import org.apache.tinkerpop.shaded.kryo.io.Output;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -39,11 +39,26 @@ import java.time.Year;
 import java.time.YearMonth;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
 
 import static org.junit.Assert.assertEquals;
 
+@RunWith(Parameterized.class)
 public class GraphSONMapperEmbeddedTypeTest {
-    private final ObjectMapper mapper = GraphSONMapper.build().embedTypes(true).create().createMapper();
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Iterable<Object[]> data() {
+        return Arrays.asList(new Object[][]{
+                {GraphSONMapper.build().version(GraphSONVersion.V1_0).embedTypes(true).create().createMapper()},
+                {GraphSONMapper.build().version(GraphSONVersion.V2_0).typeInfo(TypeInfo.PARTIAL_TYPES).create()
+                        .createMapper()},
+        });
+    }
+
+    @Parameterized.Parameter
+    public ObjectMapper mapper;
 
     @Test
     public void shouldHandleDuration()throws Exception  {
@@ -122,6 +137,40 @@ public class GraphSONMapperEmbeddedTypeTest {
         assertEquals(o, serializeDeserialize(o, ZoneOffset.class));
     }
 
+    @Test
+    public void shouldHandleMapWithTypesUsingEmbedTypeSetting() throws Exception {
+        final ObjectMapper mapper = GraphSONMapper.build()
+                .version(GraphSONVersion.V1_0)
+                .typeInfo(TypeInfo.PARTIAL_TYPES)
+                .create()
+                .createMapper();
+
+        final Map<String,Object> m = new HashMap<>();
+        m.put("test", 100L);
+
+        final String json = mapper.writeValueAsString(m);
+        final Map read = mapper.readValue(json, HashMap.class);
+
+        assertEquals(100L, read.get("test"));
+    }
+
+    @Test
+    public void shouldNotHandleMapWithTypesUsingEmbedTypeSetting() throws Exception {
+        final ObjectMapper mapper = GraphSONMapper.build()
+                .version(GraphSONVersion.V1_0)
+                .typeInfo(TypeInfo.NO_TYPES)
+                .create()
+                .createMapper();
+
+        final Map<String,Object> m = new HashMap<>();
+        m.put("test", 100L);
+
+        final String json = mapper.writeValueAsString(m);
+        final Map read = mapper.readValue(json, HashMap.class);
+
+        assertEquals(100, read.get("test"));
+    }
+
     public <T> T serializeDeserialize(final Object o, final Class<T> clazz) throws Exception {
         try (final ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
             mapper.writeValue(stream, o);

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
index 41e24c6..4b2e98f 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
@@ -21,6 +21,8 @@ package org.apache.tinkerpop.gremlin.structure.io.graphson;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation;
 import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
 
 import java.time.Duration;
 import java.time.Instant;
@@ -35,12 +37,25 @@ import java.time.Year;
 import java.time.YearMonth;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
+import java.util.Arrays;
 
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.__;
 import static org.junit.Assert.assertEquals;
 
+@RunWith(Parameterized.class)
 public class GraphSONMapperTest {
-    private final ObjectMapper mapper = GraphSONMapper.build().embedTypes(false).create().createMapper();
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Iterable<Object[]> data() {
+        return Arrays.asList(new Object[][]{
+                {GraphSONMapper.build().version(GraphSONVersion.V1_0).embedTypes(false).create().createMapper()},
+                {GraphSONMapper.build().version(GraphSONVersion.V2_0).typeInfo(TypeInfo.NO_TYPES).create().createMapper()},
+        });
+    }
+
+    @Parameterized.Parameter
+    public ObjectMapper mapper;
+
 
     @Test
     public void shouldHandleTraversalExplanation() throws Exception {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java
new file mode 100644
index 0000000..c2ad05e
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java
@@ -0,0 +1,344 @@
+/*
+ * 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.tinkerpop.shaded.jackson.databind.ObjectMapper;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.MonthDay;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.Period;
+import java.time.Year;
+import java.time.YearMonth;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests automatic typed serialization/deserialization for GraphSON 2.0.
+ */
+public class GraphSONMapperV2d0PartialEmbeddedTypeTest {
+
+    private final ObjectMapper mapper = GraphSONMapper.build()
+            .version(GraphSONVersion.V2_0)
+            .typeInfo(TypeInfo.PARTIAL_TYPES)
+            .create()
+            .createMapper();
+
+    @Test
+    public void shouldHandleDurationAuto() throws Exception {
+        final Duration o = Duration.ZERO;
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleInstantAuto() throws Exception {
+        final Instant o = Instant.ofEpochMilli(System.currentTimeMillis());
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleLocalDateAuto() throws Exception {
+        final LocalDate o = LocalDate.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleLocalDateTimeAuto() throws Exception {
+        final LocalDateTime o = LocalDateTime.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleLocalTimeAuto() throws Exception {
+        final LocalTime o = LocalTime.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleMonthDayAuto() throws Exception {
+        final MonthDay o = MonthDay.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleOffsetDateTimeAuto() throws Exception {
+        final OffsetDateTime o = OffsetDateTime.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleOffsetTimeAuto() throws Exception {
+        final OffsetTime o = OffsetTime.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandlePeriodAuto() throws Exception {
+        final Period o = Period.ofDays(3);
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleYearAuto() throws Exception {
+        final Year o = Year.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleYearMonthAuto() throws Exception {
+        final YearMonth o = YearMonth.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleZonedDateTimeAuto() throws Exception {
+        final ZonedDateTime o = ZonedDateTime.now();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    public void shouldHandleZonedOffsetAuto() throws Exception {
+        final ZoneOffset o = ZonedDateTime.now().getOffset();
+        assertEquals(o, serializeDeserializeAuto(o));
+    }
+
+    @Test
+    // Trying to fail the TypeDeserializer type detection
+    public void shouldSerializeDeserializeNestedCollectionsAndMapAndTypedValuesCorrectly() throws Exception {
+        UUID uuid = UUID.randomUUID();
+        List myList = new ArrayList<>();
+
+        List myList2 = new ArrayList<>();
+        myList2.add(UUID.randomUUID());
+        myList2.add(33L);
+        myList2.add(84);
+        Map map2 = new HashMap<>();
+        map2.put("eheh", UUID.randomUUID());
+        map2.put("normal", "normal");
+        myList2.add(map2);
+
+        Map<String, Object> map1 = new HashMap<>();
+        map1.put("hello", "world");
+        map1.put("test", uuid);
+        map1.put("hehe", myList2);
+        myList.add(map1);
+
+        myList.add("kjkj");
+        myList.add(UUID.randomUUID());
+        assertEquals(myList, serializeDeserializeAuto(myList));
+
+        // no "@value" property
+        String s = "{\""+GraphSONTokens.VALUETYPE+"\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":uuid\", \"test\":2}";
+        Map map = new LinkedHashMap<>();
+        map.put(GraphSONTokens.VALUETYPE, "gremlin:uuid");
+        map.put("test", 2);
+        Object res = mapper.readValue(s, Object.class);
+        assertEquals(map, res);
+
+        // "@value" and "@type" property reversed
+        s = "{\""+GraphSONTokens.VALUEPROP+"\":2, \""+ GraphSONTokens.VALUETYPE+"\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":int64\"}";
+        res = mapper.readValue(s, Object.class);
+        assertEquals(res, 2L);
+        assertEquals(res.getClass(), Long.class);
+
+        // no "@type" property.
+        s = "{\""+GraphSONTokens.VALUEPROP+"\":2, \"id\":2}";
+        map = new LinkedHashMap<>();
+        map.put(GraphSONTokens.VALUEPROP, 2);
+        map.put("id", 2);
+        res = mapper.readValue(s, Object.class);
+        assertEquals(res, map);
+    }
+
+    @Test
+    public void shouldFailIfMoreThanTwoPropertiesInATypePattern() {
+        String s = "{\"" + GraphSONTokens.VALUEPROP + "\":2, \"" + GraphSONTokens.VALUETYPE + "\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":int64\", \"hello\": \"world\"}";
+        try {
+            mapper.readValue(s, Object.class);
+            fail("Should have failed deserializing because there's more than properties in the type.");
+        } catch (IOException e) {
+            assertThat(e.getMessage(), containsString("Detected the type pattern in the JSON payload but the map containing the types and values contains other fields. This is not allowed by the deserializer."));
+        }
+        s = "{\"" + GraphSONTokens.VALUETYPE + "\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":int64\",\"" + GraphSONTokens.VALUEPROP + "\":2, \"hello\": \"world\"}";
+        try {
+            mapper.readValue(s, Object.class);
+            fail("Should have failed deserializing because there's more than properties in the type.");
+        } catch (IOException e) {
+            assertThat(e.getMessage(), containsString("Detected the type pattern in the JSON payload but the map containing the types and values contains other fields. This is not allowed by the deserializer."));
+        }
+    }
+
+    @Test
+    public void shouldFailIfTypeSpecifiedIsNotSameTypeInPayload() {
+        final ZoneOffset o = ZonedDateTime.now().getOffset();
+        final ByteArrayOutputStream stream = new ByteArrayOutputStream();
+        try {
+            mapper.writeValue(stream, o);
+            final InputStream inputStream = new ByteArrayInputStream(stream.toByteArray());
+            // What has been serialized is a ZoneOffset with the type, but the user explicitly requires another type.
+            mapper.readValue(inputStream, Instant.class);
+            fail("Should have failed decoding the value");
+        } catch (Exception e) {
+            assertThat(e.getMessage(), containsString("Could not deserialize the JSON value as required. Nested exception: java.lang.InstantiationException: Cannot deserialize the value with the detected type contained in the JSON ('"+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":zoneoffset') to the type specified in parameter to the object mapper (class java.time.Instant). Those types are incompatible."));
+        }
+    }
+
+    @Test
+    public void shouldHandleRawPOJOs() throws Exception {
+        final FunObject funObject = new FunObject();
+        funObject.setVal("test");
+        assertEquals(funObject.toString(), serializeDeserialize(funObject, FunObject.class).toString());
+        assertEquals(funObject.getClass(), serializeDeserialize(funObject, FunObject.class).getClass());
+    }
+
+    @Test
+    public void shouldHandleMapWithTypesUsingEmbedTypeSetting() throws Exception {
+        final ObjectMapper mapper = GraphSONMapper.build()
+                .version(GraphSONVersion.V2_0)
+                .embedTypes(true)
+                .create()
+                .createMapper();
+
+        final Map<String,Object> m = new HashMap<>();
+        m.put("test", 100L);
+
+        final String json = mapper.writeValueAsString(m);
+        final Map read = mapper.readValue(json, HashMap.class);
+
+        assertEquals(100L, read.get("test"));
+    }
+
+    @Test
+    public void shouldNotHandleMapWithTypesUsingEmbedTypeSetting() throws Exception {
+        final ObjectMapper mapper = GraphSONMapper.build()
+                .version(GraphSONVersion.V2_0)
+                .embedTypes(false)
+                .create()
+                .createMapper();
+
+        final Map<String,Object> m = new HashMap<>();
+        m.put("test", 100L);
+
+        final String json = mapper.writeValueAsString(m);
+        final Map read = mapper.readValue(json, HashMap.class);
+
+        assertEquals(100, read.get("test"));
+    }
+
+    @Test
+    public void shouldLooseTypesInfoWithGraphSONNoType() throws Exception {
+        ObjectMapper mapper = GraphSONMapper.build()
+                .version(GraphSONVersion.V2_0)
+                .typeInfo(TypeInfo.NO_TYPES)
+                .create()
+                .createMapper();
+
+        UUID uuid = UUID.randomUUID();
+        List myList = new ArrayList<>();
+
+        List myList2 = new ArrayList<>();
+        myList2.add(UUID.randomUUID());
+        myList2.add(33L);
+        myList2.add(84);
+        Map map2 = new HashMap<>();
+        map2.put("eheh", UUID.randomUUID());
+        map2.put("normal", "normal");
+        myList2.add(map2);
+
+        Map<String, Object> map1 = new HashMap<>();
+        map1.put("hello", "world");
+        map1.put("test", uuid);
+        map1.put("hehe", myList2);
+        myList.add(map1);
+
+        myList.add("kjkj");
+        myList.add(UUID.randomUUID());
+
+        String json = mapper.writeValueAsString(myList);
+        Object read = mapper.readValue(json, Object.class);
+
+        // Not equals because of type loss
+        assertNotEquals(myList, read);
+    }
+
+
+    // Class needs to be defined as statics as it's a nested class.
+    public static class FunObject {
+        private String val;
+
+        public FunObject() {
+        }
+
+        public String getVal() {
+            return this.val;
+        }
+
+        public void setVal(String s) {
+            this.val = s;
+        }
+
+        public String toString() {
+            return this.val;
+        }
+    }
+
+    public <T> T serializeDeserialize(final Object o, final Class<T> clazz) throws Exception {
+        try (final ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
+            mapper.writeValue(stream, o);
+
+            try (final InputStream inputStream = new ByteArrayInputStream(stream.toByteArray())) {
+                return mapper.readValue(inputStream, clazz);
+            }
+        }
+    }
+
+    public <T> T serializeDeserializeAuto(final Object o) throws Exception {
+        try (final ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
+            mapper.writeValue(stream, o);
+
+            try (final InputStream inputStream = new ByteArrayInputStream(stream.toByteArray())) {
+                // Object.class is the wildcard that triggers the auto discovery.
+                return (T)mapper.readValue(inputStream, Object.class);
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractGraphSONMessageSerializerV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractGraphSONMessageSerializerV2d0.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractGraphSONMessageSerializerV2d0.java
new file mode 100644
index 0000000..d0303eb
--- /dev/null
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractGraphSONMessageSerializerV2d0.java
@@ -0,0 +1,248 @@
+/*
+ * 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.driver.ser;
+
+import groovy.json.JsonBuilder;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufAllocator;
+import io.netty.util.ReferenceCountUtil;
+import org.apache.tinkerpop.gremlin.driver.message.RequestMessage;
+import org.apache.tinkerpop.gremlin.driver.message.ResponseMessage;
+import org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONIo;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONMapper;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONUtil;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerationException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.core.type.TypeReference;
+import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.module.SimpleModule;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public abstract class AbstractGraphSONMessageSerializerV2d0 extends AbstractMessageSerializer {
+    private static final Logger logger = LoggerFactory.getLogger(AbstractGraphSONMessageSerializerV2d0.class);
+
+    protected ObjectMapper mapper;
+
+    protected static final String TOKEN_USE_MAPPER_FROM_GRAPH = "useMapperFromGraph";
+
+    protected final TypeReference<Map<String, Object>> mapTypeReference = new TypeReference<Map<String, Object>>() {
+    };
+
+    public AbstractGraphSONMessageSerializerV2d0() {
+        final GraphSONMapper.Builder builder = configureBuilder(GraphSONMapper.build());
+        mapper = builder.create().createMapper();
+    }
+
+    public AbstractGraphSONMessageSerializerV2d0(final GraphSONMapper mapper) {
+        this.mapper = mapper.createMapper();
+    }
+
+    abstract byte[] obtainHeader();
+
+    abstract GraphSONMapper.Builder configureBuilder(final GraphSONMapper.Builder builder);
+
+    @Override
+    public void configure(final Map<String, Object> config, final Map<String, Graph> graphs) {
+        final GraphSONMapper.Builder initialBuilder;
+        final Object graphToUseForMapper = config.get(TOKEN_USE_MAPPER_FROM_GRAPH);
+        if (graphToUseForMapper != null) {
+            if (null == graphs) throw new IllegalStateException(String.format(
+                    "No graphs have been provided to the serializer and therefore %s is not a valid configuration", TOKEN_USE_MAPPER_FROM_GRAPH));
+
+            final Graph g = graphs.get(graphToUseForMapper.toString());
+            if (null == g) throw new IllegalStateException(String.format(
+                    "There is no graph named [%s] configured to be used in the %s setting",
+                    graphToUseForMapper, TOKEN_USE_MAPPER_FROM_GRAPH));
+
+            // a graph was found so use the mapper it constructs.  this allows graphson to be auto-configured with any
+            // custom classes that the implementation allows for
+            initialBuilder = g.io(GraphSONIo.build()).mapper();
+        } else {
+            // no graph was supplied so just use the default - this will likely be the case when using a graph
+            // with no custom classes or a situation where the user needs complete control like when using two
+            // distinct implementations each with their own custom classes.
+            initialBuilder = GraphSONMapper.build();
+        }
+
+        addIoRegistries(config, initialBuilder);
+
+        mapper = configureBuilder(initialBuilder).create().createMapper();
+    }
+
+    @Override
+    public ByteBuf serializeResponseAsBinary(final ResponseMessage responseMessage, final ByteBufAllocator allocator) throws SerializationException {
+        ByteBuf encodedMessage = null;
+        try {
+            final byte[] payload = mapper.writeValueAsBytes(responseMessage);
+            encodedMessage = allocator.buffer(payload.length);
+            encodedMessage.writeBytes(payload);
+
+            return encodedMessage;
+        } catch (Exception ex) {
+            if (encodedMessage != null) ReferenceCountUtil.release(encodedMessage);
+
+            logger.warn("Response [{}] could not be serialized by {}.", responseMessage.toString(), AbstractGraphSONMessageSerializerV2d0.class.getName());
+            throw new SerializationException(ex);
+        }
+    }
+
+    @Override
+    public ByteBuf serializeRequestAsBinary(final RequestMessage requestMessage, final ByteBufAllocator allocator) throws SerializationException {
+        ByteBuf encodedMessage = null;
+        try {
+            final byte[] header = obtainHeader();
+            final byte[] payload = mapper.writeValueAsBytes(requestMessage);
+
+            encodedMessage = allocator.buffer(header.length + payload.length);
+            encodedMessage.writeBytes(header);
+            encodedMessage.writeBytes(payload);
+
+            return encodedMessage;
+        } catch (Exception ex) {
+            if (encodedMessage != null) ReferenceCountUtil.release(encodedMessage);
+
+            logger.warn("Request [{}] could not be serialized by {}.", requestMessage.toString(), AbstractGraphSONMessageSerializerV2d0.class.getName());
+            throw new SerializationException(ex);
+        }
+    }
+
+    @Override
+    public RequestMessage deserializeRequest(final ByteBuf msg) throws SerializationException {
+        try {
+            final byte[] payload = new byte[msg.readableBytes()];
+            msg.readBytes(payload);
+            return mapper.readValue(payload, RequestMessage.class);
+        } catch (Exception ex) {
+            logger.warn("Request [{}] could not be deserialized by {}.", msg, AbstractGraphSONMessageSerializerV2d0.class.getName());
+            throw new SerializationException(ex);
+        }
+    }
+
+    @Override
+    public ResponseMessage deserializeResponse(final ByteBuf msg) throws SerializationException {
+        try {
+            final byte[] payload = new byte[msg.readableBytes()];
+            msg.readBytes(payload);
+            final Map<String, Object> responseData = mapper.readValue(payload, mapTypeReference);
+            final Map<String, Object> status = (Map<String, Object>) responseData.get(SerTokens.TOKEN_STATUS);
+            final Map<String, Object> result = (Map<String, Object>) responseData.get(SerTokens.TOKEN_RESULT);
+            return ResponseMessage.build(UUID.fromString(responseData.get(SerTokens.TOKEN_REQUEST).toString()))
+                    .code(ResponseStatusCode.getFromValue((Integer) status.get(SerTokens.TOKEN_CODE)))
+                    .statusMessage(status.get(SerTokens.TOKEN_MESSAGE).toString())
+                    .statusAttributes((Map<String, Object>) status.get(SerTokens.TOKEN_ATTRIBUTES))
+                    .result(result.get(SerTokens.TOKEN_DATA))
+                    .responseMetaData((Map<String, Object>) result.get(SerTokens.TOKEN_META))
+                    .create();
+        } catch (Exception ex) {
+            logger.warn("Response [{}] could not be deserialized by {}.", msg, AbstractGraphSONMessageSerializerV2d0.class.getName());
+            throw new SerializationException(ex);
+        }
+    }
+
+    public final static class GremlinServerModule extends SimpleModule {
+        public GremlinServerModule() {
+            super("graphson-gremlin-server");
+            addSerializer(JsonBuilder.class, new JsonBuilderJacksonSerializer());
+            addSerializer(ResponseMessage.class, new ResponseMessageSerializer());
+        }
+    }
+
+    public final static class JsonBuilderJacksonSerializer extends StdSerializer<JsonBuilder> {
+        public JsonBuilderJacksonSerializer() {
+            super(JsonBuilder.class);
+        }
+
+        @Override
+        public void serialize(final JsonBuilder json, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+                throws IOException, JsonGenerationException {
+            // the JSON from the builder will already be started/ended as array or object...just need to surround it
+            // with appropriate chars to fit into the serialization pattern.
+            jsonGenerator.writeRaw(":");
+            jsonGenerator.writeRaw(json.toString());
+            jsonGenerator.writeRaw(",");
+        }
+    }
+
+    public final static class ResponseMessageSerializer extends StdSerializer<ResponseMessage> {
+        public ResponseMessageSerializer() {
+            super(ResponseMessage.class);
+        }
+
+        @Override
+        public void serialize(final ResponseMessage responseMessage, final JsonGenerator jsonGenerator,
+                              final SerializerProvider serializerProvider) throws IOException {
+            ser(responseMessage, jsonGenerator, serializerProvider, null);
+        }
+
+        @Override
+        public void serializeWithType(final ResponseMessage responseMessage, final JsonGenerator jsonGenerator,
+                                      final SerializerProvider serializerProvider,
+                                      final TypeSerializer typeSerializer) throws IOException {
+            ser(responseMessage, jsonGenerator, serializerProvider, typeSerializer);
+        }
+
+        public void ser(final ResponseMessage responseMessage, final JsonGenerator jsonGenerator,
+                        final SerializerProvider serializerProvider,
+                        final TypeSerializer typeSerializer) throws IOException {
+            GraphSONUtil.writeStartObject(responseMessage, jsonGenerator, typeSerializer);
+
+            jsonGenerator.writeStringField(SerTokens.TOKEN_REQUEST, responseMessage.getRequestId() != null ? responseMessage.getRequestId().toString() : null);
+            jsonGenerator.writeFieldName(SerTokens.TOKEN_STATUS);
+
+            GraphSONUtil.writeStartObject(responseMessage, jsonGenerator, typeSerializer);
+            jsonGenerator.writeStringField(SerTokens.TOKEN_MESSAGE, responseMessage.getStatus().getMessage());
+            jsonGenerator.writeNumberField(SerTokens.TOKEN_CODE, responseMessage.getStatus().getCode().getValue());
+            jsonGenerator.writeObjectField(SerTokens.TOKEN_ATTRIBUTES, responseMessage.getStatus().getAttributes());
+            GraphSONUtil.writeEndObject(responseMessage, jsonGenerator, typeSerializer);
+
+            jsonGenerator.writeFieldName(SerTokens.TOKEN_RESULT);
+
+            GraphSONUtil.writeStartObject(responseMessage, jsonGenerator, typeSerializer);
+
+            if (null == responseMessage.getResult().getData())
+            {
+                jsonGenerator.writeNullField(SerTokens.TOKEN_DATA);
+            }
+            else
+            {
+                jsonGenerator.writeFieldName(SerTokens.TOKEN_DATA);
+                Object result = responseMessage.getResult().getData();
+                serializerProvider.findTypedValueSerializer(result.getClass(), true, null).serialize(result, jsonGenerator, serializerProvider);
+            }
+
+            jsonGenerator.writeObjectField(SerTokens.TOKEN_META, responseMessage.getResult().getMeta());
+            GraphSONUtil.writeEndObject(responseMessage, jsonGenerator, typeSerializer);
+
+            GraphSONUtil.writeEndObject(responseMessage, jsonGenerator, typeSerializer);
+        }
+    }
+}


Mime
View raw message