You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2018/03/08 13:09:02 UTC

[1/4] tinkerpop git commit: TINKERPOP-1738 Bump to jackson 2.9.4

Repository: tinkerpop
Updated Branches:
  refs/heads/master 25ae1a1ea -> cfa5c50a7


TINKERPOP-1738 Bump to jackson 2.9.4

This fixes a problem where Jackson was missing an error in GraphSON type information depending on the order of the JSON elements. It required some internal changes to the GraphSONTypeSerializer given API shifts in jackson - should not really affect TinkerPop  users. Modified the original test that demonstrated this problem to be a bit more robust.


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

Branch: refs/heads/master
Commit: f35f04a8da88280e8b121356ac5839fc0b8ac859
Parents: a61dd58
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Feb 13 10:16:46 2018 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Fri Mar 2 09:11:34 2018 -0500

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |  1 +
 .../io/graphson/GraphSONTypeSerializer.java     | 94 ++++++--------------
 ...aphSONMapperV2d0PartialEmbeddedTypeTest.java | 32 +++++++
 gremlin-shaded/pom.xml                          |  2 +-
 4 files changed, 61 insertions(+), 68 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f35f04a8/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index a24b1fb..f99d1a2 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -27,6 +27,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 * Modified `GremlinDslProcessor` so that it generated the `getAnonymousTraversalClass()` method to return the DSL version of `__`.
 * Added the "Kitchen Sink" test data set.
 * Fixed deserialization of `P.not()` for GraphSON.
+* Bumped to Jackson 2.9.4.
 * Added `idleConnectionTimeout` and `keepAliveInterval` to Gremlin Server that enables a "ping" and auto-close for seemingly dead clients.
 * Fixed a bug in `NumberHelper` that led to wrong min/max results if numbers exceeded the Integer limits.
 * Delayed setting of the request identifier until `RequestMessage` construction by the builder.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f35f04a8/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 78c670a..8b1ba25 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
@@ -39,6 +39,8 @@ 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;
+import org.apache.tinkerpop.shaded.jackson.core.JsonToken;
+import org.apache.tinkerpop.shaded.jackson.core.type.WritableTypeId;
 import org.apache.tinkerpop.shaded.jackson.databind.BeanProperty;
 import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeIdResolver;
 import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
@@ -79,7 +81,7 @@ public class GraphSONTypeSerializer extends TypeSerializer {
 
     @Override
     public JsonTypeInfo.As getTypeInclusion() {
-        return null;
+        return JsonTypeInfo.As.WRAPPER_OBJECT;
     }
 
     @Override
@@ -93,79 +95,37 @@ public class GraphSONTypeSerializer extends TypeSerializer {
     }
 
     @Override
-    public void writeTypePrefixForScalar(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-        if (canWriteTypeId()) {
-            writeTypePrefix(jsonGenerator, getTypeIdResolver().idFromValueAndType(o, getClassFromObject(o)));
+    public WritableTypeId writeTypePrefix(final JsonGenerator jsonGenerator, final WritableTypeId writableTypeId) throws IOException {
+        if (writableTypeId.valueShape == JsonToken.VALUE_STRING) {
+            if (canWriteTypeId()) {
+                writeTypePrefix(jsonGenerator, getTypeIdResolver().idFromValueAndType(writableTypeId.forValue, getClassFromObject(writableTypeId.forValue)));
+            }
+        } else if (writableTypeId.valueShape == JsonToken.START_OBJECT) {
+            jsonGenerator.writeStartObject();
+        } else if (writableTypeId.valueShape == JsonToken.START_ARRAY) {
+            jsonGenerator.writeStartArray();
+        } else {
+            throw new IllegalStateException("Could not write prefix");
         }
-    }
-
-    @Override
-    public void writeTypePrefixForObject(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-        jsonGenerator.writeStartObject();
-        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(Map);
-    }
-
-    @Override
-    public void writeTypePrefixForArray(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-        jsonGenerator.writeStartArray();
-        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(List);
-    }
-
-    @Override
-    public void writeTypeSuffixForScalar(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-        if (canWriteTypeId()) {
-            writeTypeSuffix(jsonGenerator);
-        }
-    }
-
-    @Override
-    public void writeTypeSuffixForObject(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-        jsonGenerator.writeEndObject();
-        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(Map);
-    }
-
-    @Override
-    public void writeTypeSuffixForArray(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-        jsonGenerator.writeEndArray();
-        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(List);
-    }
 
-    @Override
-    public void writeCustomTypePrefixForScalar(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
-        if (canWriteTypeId()) {
-            writeTypePrefix(jsonGenerator, s);
-        }
+        return writableTypeId;
     }
 
     @Override
-    public void writeCustomTypePrefixForObject(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
-        jsonGenerator.writeStartObject();
-        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(s);
-    }
-
-    @Override
-    public void writeCustomTypePrefixForArray(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
-        jsonGenerator.writeStartArray();
-        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(s);
-    }
-
-    @Override
-    public void writeCustomTypeSuffixForScalar(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
-        if (canWriteTypeId()) {
-            writeTypeSuffix(jsonGenerator);
+    public WritableTypeId writeTypeSuffix(final JsonGenerator jsonGenerator, final WritableTypeId writableTypeId) throws IOException {
+        if (writableTypeId.valueShape == JsonToken.VALUE_STRING) {
+            if (canWriteTypeId()) {
+                writeTypeSuffix(jsonGenerator);
+            }
+        } else if (writableTypeId.valueShape == JsonToken.START_OBJECT) {
+            jsonGenerator.writeEndObject();
+        } else if (writableTypeId.valueShape == JsonToken.START_ARRAY) {
+            jsonGenerator.writeEndArray();
+        } else {
+            throw new IllegalStateException("Could not write suffix");
         }
-    }
-
-    @Override
-    public void writeCustomTypeSuffixForObject(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
-        jsonGenerator.writeEndObject();
-        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(s);
-    }
 
-    @Override
-    public void writeCustomTypeSuffixForArray(final Object o, final JsonGenerator jsonGenerator,final  String s) throws IOException {
-        jsonGenerator.writeEndArray();
-        // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(s);
+        return writableTypeId;
     }
 
     private boolean canWriteTypeId() {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f35f04a8/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
index 5b009e1..c388e61 100644
--- 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
@@ -19,8 +19,10 @@
 package org.apache.tinkerpop.gremlin.structure.io.graphson;
 
 import org.apache.tinkerpop.gremlin.process.remote.traversal.DefaultRemoteTraverser;
+import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
 import org.apache.tinkerpop.gremlin.process.traversal.P;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.shaded.jackson.databind.JsonMappingException;
 import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
 import org.junit.Test;
 
@@ -40,6 +42,7 @@ import java.util.Map;
 import java.util.UUID;
 
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
 import static org.hamcrest.core.StringContains.containsString;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
@@ -56,6 +59,35 @@ public class GraphSONMapperV2d0PartialEmbeddedTypeTest extends AbstractGraphSONT
             .typeInfo(TypeInfo.PARTIAL_TYPES)
             .create()
             .createMapper();
+    @Test
+    public void elementOrderShouldNotMatter() throws Exception {
+        final String bytecodeJSONFail1 = "{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"addV\",\"poc_int\"],[\"property\",\"bigint1value\",{\"@type\":\"g:Int32\",\"@value\":-4294967295}]]}}";
+        final String bytecodeJSONFail2 = "{\"@value\":{\"step\":[[\"addV\",\"poc_int\"],[\"property\",\"bigint1value\",{\"@value\":-4294967295,\"@type\":\"g:Int32\"}]]},\"@type\":\"g:Bytecode\"}";
+
+        // first validate the failures of TINKERPOP-1738 - prior to the jackson fix on 2.9.4 one of these would have
+        // passed based on the ordering of the properties
+        try {
+            mapper.readValue(bytecodeJSONFail1, Bytecode.class);
+            fail("Should have thrown an error because 'bigint1value' is not an int32");
+        } catch (Exception ex) {
+            assertThat(ex, instanceOf(JsonMappingException.class));
+        }
+
+        try {
+            mapper.readValue(bytecodeJSONFail2, Bytecode.class);
+            fail("Should have thrown an error because 'bigint1value' is not an int32");
+        } catch (Exception ex) {
+            assertThat(ex, instanceOf(JsonMappingException.class));
+        }
+
+        // now do a legit parsing based on order
+        final String bytecodeJSON1 = "{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"addV\",\"poc_int\"],[\"property\",\"bigint1value\",{\"@type\":\"g:Int64\",\"@value\":-4294967295}]]}}";
+        final String bytecodeJSON2 = "{\"@value\":{\"step\":[[\"addV\",\"poc_int\"],[\"property\",\"bigint1value\",{\"@value\":-4294967295,\"@type\":\"g:Int64\"}]]},\"@type\":\"g:Bytecode\"}";
+
+        final Bytecode bytecode1 = mapper.readValue(bytecodeJSON1, Bytecode.class);
+        final Bytecode bytecode2 = mapper.readValue(bytecodeJSON2, Bytecode.class);
+        assertEquals(bytecode1, bytecode2);
+    }
 
     @Test
     public void shouldSerializeDeserializeNestedCollectionsAndMapAndTypedValuesCorrectly() throws Exception {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f35f04a8/gremlin-shaded/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-shaded/pom.xml b/gremlin-shaded/pom.xml
index 2219a4e..aeda3d4 100644
--- a/gremlin-shaded/pom.xml
+++ b/gremlin-shaded/pom.xml
@@ -50,7 +50,7 @@ limitations under the License.
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>
             <!-- Update the shade plugin config whenever you change this version -->
-            <version>2.8.10</version>
+            <version>2.9.4</version>
             <optional>true</optional>
         </dependency>
     </dependencies>


[3/4] tinkerpop git commit: Merge branch 'tp32' into tp33

Posted by sp...@apache.org.
Merge branch 'tp32' into tp33

Conflicts:
	gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractGraphSONTypeSerializer.java
	gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java


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

Branch: refs/heads/master
Commit: a3624f7e2f23d290ac2ad475f88716f98eeb8b7c
Parents: dd3a54e 7bff988
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Mar 8 08:08:40 2018 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Mar 8 08:08:40 2018 -0500

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |  1 +
 .../AbstractGraphSONTypeSerializer.java         | 80 +-------------------
 .../io/graphson/GraphSONTypeSerializerV2d0.java | 38 ++++++++++
 .../io/graphson/GraphSONTypeSerializerV3d0.java | 72 +++++++++++-------
 .../GraphSONMapperPartialEmbeddedTypeTest.java  | 33 ++++++++
 gremlin-shaded/pom.xml                          |  2 +-
 6 files changed, 120 insertions(+), 106 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a3624f7e/CHANGELOG.asciidoc
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a3624f7e/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractGraphSONTypeSerializer.java
----------------------------------------------------------------------
diff --cc gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractGraphSONTypeSerializer.java
index 6eb65e1,0000000..fa90b2c
mode 100644,000000..100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractGraphSONTypeSerializer.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractGraphSONTypeSerializer.java
@@@ -1,173 -1,0 +1,99 @@@
 +/*
 + * 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.annotation.JsonTypeInfo;
 +import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
++import org.apache.tinkerpop.shaded.jackson.core.JsonToken;
++import org.apache.tinkerpop.shaded.jackson.core.type.WritableTypeId;
 +import org.apache.tinkerpop.shaded.jackson.databind.BeanProperty;
 +import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeIdResolver;
 +import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
 +
 +import java.io.IOException;
 +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
 + * on which they can safely call the utility methods to serialize types and making it compatible with the version
 + * 2.0+ of GraphSON.
 + *
 + * @author Kevin Gallardo (https://kgdo.me)
 + * @author Stephen Mallette (http://stephen.genoprime.com)
 + */
 +public abstract class AbstractGraphSONTypeSerializer extends TypeSerializer {
 +
 +    protected final TypeIdResolver idRes;
 +    protected final String propertyName;
 +    protected final TypeInfo typeInfo;
 +    protected final String valuePropertyName;
 +    protected final Map<Class, Class> classMap = new HashMap<>();
 +
 +    AbstractGraphSONTypeSerializer(final TypeIdResolver idRes, final String propertyName, final TypeInfo typeInfo,
 +                                   final String valuePropertyName) {
 +        this.idRes = idRes;
 +        this.propertyName = propertyName;
 +        this.typeInfo = typeInfo;
 +        this.valuePropertyName = valuePropertyName;
 +    }
 +
 +
 +    @Override
 +    public TypeSerializer forProperty(final BeanProperty beanProperty) {
 +        return this;
 +    }
 +
 +    @Override
 +    public JsonTypeInfo.As getTypeInclusion() {
-         return null;
++        return JsonTypeInfo.As.WRAPPER_OBJECT;
 +    }
 +
 +    @Override
 +    public String getPropertyName() {
 +        return propertyName;
 +    }
 +
 +    @Override
 +    public TypeIdResolver getTypeIdResolver() {
 +        return idRes;
 +    }
 +
-     @Override
-     public void writeTypePrefixForScalar(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-         if (canWriteTypeId()) {
-             writeTypePrefix(jsonGenerator, getTypeIdResolver().idFromValueAndType(o, getClassFromObject(o)));
-         }
-     }
- 
-     @Override
-     public void writeTypePrefixForObject(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-         jsonGenerator.writeStartObject();
-         // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(Map);
-     }
- 
-     @Override
-     public void writeTypePrefixForArray(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-         jsonGenerator.writeStartArray();
-         // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(List);
-     }
- 
-     @Override
-     public void writeTypeSuffixForScalar(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-         if (canWriteTypeId()) {
-             writeTypeSuffix(jsonGenerator);
-         }
-     }
- 
-     @Override
-     public void writeTypeSuffixForObject(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-         jsonGenerator.writeEndObject();
-         // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(Map);
-     }
- 
-     @Override
-     public void writeTypeSuffixForArray(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-         jsonGenerator.writeEndArray();
-         // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(List);
-     }
- 
-     @Override
-     public void writeCustomTypePrefixForScalar(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
-         if (canWriteTypeId()) {
-             writeTypePrefix(jsonGenerator, s);
-         }
-     }
- 
-     @Override
-     public void writeCustomTypePrefixForObject(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
-         jsonGenerator.writeStartObject();
-         // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(s);
-     }
- 
-     @Override
-     public void writeCustomTypePrefixForArray(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
-         jsonGenerator.writeStartArray();
-         // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(s);
-     }
- 
-     @Override
-     public void writeCustomTypeSuffixForScalar(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
-         if (canWriteTypeId()) {
-             writeTypeSuffix(jsonGenerator);
-         }
-     }
- 
-     @Override
-     public void writeCustomTypeSuffixForObject(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
-         jsonGenerator.writeEndObject();
-         // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(s);
-     }
- 
-     @Override
-     public void writeCustomTypeSuffixForArray(final Object o, final JsonGenerator jsonGenerator, final String s) throws IOException {
-         jsonGenerator.writeEndArray();
-         // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(s);
-     }
- 
 +    protected boolean canWriteTypeId() {
 +        return typeInfo != null
 +                && typeInfo == TypeInfo.PARTIAL_TYPES;
 +    }
 +
 +    protected void writeTypePrefix(final JsonGenerator jsonGenerator, final String s) throws IOException {
 +        jsonGenerator.writeStartObject();
 +        jsonGenerator.writeStringField(this.getPropertyName(), s);
 +        jsonGenerator.writeFieldName(this.valuePropertyName);
 +    }
 +
 +    protected void writeTypeSuffix(final JsonGenerator jsonGenerator) throws IOException {
 +        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..)
 +     */
 +    protected abstract Class getClassFromObject(final Object o);
 +}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a3624f7e/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV2d0.java
----------------------------------------------------------------------
diff --cc gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV2d0.java
index 993f110,0000000..f0d437f
mode 100644,000000..100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV2d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV2d0.java
@@@ -1,112 -1,0 +1,150 @@@
 +/*
 + * 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.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.Lambda;
++import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
++import org.apache.tinkerpop.shaded.jackson.core.JsonToken;
++import org.apache.tinkerpop.shaded.jackson.core.type.WritableTypeId;
 +import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeIdResolver;
 +
++import java.io.IOException;
 +import java.net.InetAddress;
 +import java.nio.ByteBuffer;
 +
 +/**
 + * GraphSON 2.0 {@code TypeSerializer}.
 + *
 + * @author Kevin Gallardo (https://kgdo.me)
 + * @author Stephen Mallette (http://stephen.genoprime.com)
 + */
 +public class GraphSONTypeSerializerV2d0 extends AbstractGraphSONTypeSerializer {
 +
 +    GraphSONTypeSerializerV2d0(final TypeIdResolver idRes, final String propertyName, final TypeInfo typeInfo,
 +                               final String valuePropertyName) {
 +        super(idRes, propertyName, typeInfo, valuePropertyName);
 +    }
 +
 +    @Override
++    public WritableTypeId writeTypePrefix(final JsonGenerator jsonGenerator, final WritableTypeId writableTypeId) throws IOException {
++        if (writableTypeId.valueShape == JsonToken.VALUE_STRING) {
++            if (canWriteTypeId()) {
++                writeTypePrefix(jsonGenerator, getTypeIdResolver().idFromValueAndType(writableTypeId.forValue, getClassFromObject(writableTypeId.forValue)));
++            }
++        } else if (writableTypeId.valueShape == JsonToken.START_OBJECT) {
++            jsonGenerator.writeStartObject();
++        } else if (writableTypeId.valueShape == JsonToken.START_ARRAY) {
++            jsonGenerator.writeStartArray();
++        } else {
++            throw new IllegalStateException("Could not write prefix");
++        }
++
++        return writableTypeId;
++    }
++
++    @Override
++    public WritableTypeId writeTypeSuffix(final JsonGenerator jsonGenerator, final WritableTypeId writableTypeId) throws IOException {
++        if (writableTypeId.valueShape == JsonToken.VALUE_STRING) {
++            if (canWriteTypeId()) {
++                writeTypeSuffix(jsonGenerator);
++            }
++        } else if (writableTypeId.valueShape == JsonToken.START_OBJECT) {
++            jsonGenerator.writeEndObject();
++        } else if (writableTypeId.valueShape == JsonToken.START_ARRAY) {
++            jsonGenerator.writeEndArray();
++        } else {
++            throw new IllegalStateException("Could not write suffix");
++        }
++
++        return writableTypeId;
++    }
++
++    @Override
 +    protected Class getClassFromObject(final Object o) {
 +        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;
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a3624f7e/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV3d0.java
----------------------------------------------------------------------
diff --cc gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV3d0.java
index 0724e25,0000000..ae1df47
mode 100644,000000..100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV3d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV3d0.java
@@@ -1,167 -1,0 +1,183 @@@
 +/*
 + * 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.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.step.util.Tree;
 +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.Lambda;
 +import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
++import org.apache.tinkerpop.shaded.jackson.core.JsonToken;
++import org.apache.tinkerpop.shaded.jackson.core.type.WritableTypeId;
 +import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeIdResolver;
 +
 +import java.io.IOException;
 +import java.net.InetAddress;
 +import java.nio.ByteBuffer;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Set;
 +
 +/**
 + * GraphSON 2.0 {@code TypeSerializer}.
 + *
 + * @author Kevin Gallardo (https://kgdo.me)
 + * @author Stephen Mallette (http://stephen.genoprime.com)
 + */
 +public class GraphSONTypeSerializerV3d0 extends AbstractGraphSONTypeSerializer {
 +
 +    GraphSONTypeSerializerV3d0(final TypeIdResolver idRes, final String propertyName, final TypeInfo typeInfo,
 +                               final String valuePropertyName) {
 +        super(idRes, propertyName, typeInfo, valuePropertyName);
 +    }
 +
 +    @Override
-     public void writeTypePrefixForObject(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-         if (o instanceof Map) {
-             writeTypePrefix(jsonGenerator, getTypeIdResolver().idFromValueAndType(o, getClassFromObject(o)));
-             jsonGenerator.writeStartArray();
++    public WritableTypeId writeTypePrefix(final JsonGenerator jsonGenerator, final WritableTypeId writableTypeId) throws IOException {
++        if (writableTypeId.valueShape == JsonToken.VALUE_STRING) {
++            if (canWriteTypeId()) {
++                writeTypePrefix(jsonGenerator, getTypeIdResolver().idFromValueAndType(writableTypeId.forValue, getClassFromObject(writableTypeId.forValue)));
++            }
++        } else if (writableTypeId.valueShape == JsonToken.START_OBJECT) {
++            if (writableTypeId.forValue instanceof Map) {
++                writeTypePrefix(jsonGenerator, getTypeIdResolver().idFromValueAndType(writableTypeId.forValue, getClassFromObject(writableTypeId.forValue)));
++                jsonGenerator.writeStartArray();
++            } else {
++                jsonGenerator.writeStartObject();
++            }
++        } else if (writableTypeId.valueShape == JsonToken.START_ARRAY) {
++            if (writableTypeId.forValue instanceof List || writableTypeId.forValue instanceof Set) {
++                writeTypePrefix(jsonGenerator, getTypeIdResolver().idFromValueAndType(writableTypeId.forValue, getClassFromObject(writableTypeId.forValue)));
++                jsonGenerator.writeStartArray();
++            } else {
++                jsonGenerator.writeStartArray();
++            }
 +        } else {
-             jsonGenerator.writeStartObject();
++            throw new IllegalStateException("Could not write prefix");
 +        }
-     }
 +
-     @Override
-     public void writeTypeSuffixForObject(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-         if (o instanceof Map) {
-             jsonGenerator.writeEndArray();
-             writeTypeSuffix(jsonGenerator);
-         } else {
-             jsonGenerator.writeEndObject();
-         }
++        return writableTypeId;
 +    }
 +
 +    @Override
-     public void writeTypePrefixForArray(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-         if (o instanceof List || o instanceof Set) {
-             writeTypePrefix(jsonGenerator, getTypeIdResolver().idFromValueAndType(o, getClassFromObject(o)));
-             jsonGenerator.writeStartArray();
++    public WritableTypeId writeTypeSuffix(final JsonGenerator jsonGenerator, final WritableTypeId writableTypeId) throws IOException {
++        if (writableTypeId.valueShape == JsonToken.VALUE_STRING) {
++            if (canWriteTypeId()) {
++                writeTypeSuffix(jsonGenerator);
++            }
++        } else if (writableTypeId.valueShape == JsonToken.START_OBJECT) {
++            if (writableTypeId.forValue instanceof Map) {
++                jsonGenerator.writeEndArray();
++                writeTypeSuffix(jsonGenerator);
++            } else {
++                jsonGenerator.writeEndObject();
++            }
++        } else if (writableTypeId.valueShape == JsonToken.START_ARRAY) {
++            if (writableTypeId.forValue instanceof List || writableTypeId.forValue instanceof Set) {
++                jsonGenerator.writeEndArray();
++                writeTypeSuffix(jsonGenerator);
++            } else {
++                jsonGenerator.writeEndArray();
++            }
 +        } else {
-             jsonGenerator.writeStartArray();
++            throw new IllegalStateException("Could not write suffix");
 +        }
-     }
 +
-     @Override
-     public void writeTypeSuffixForArray(final Object o, final JsonGenerator jsonGenerator) throws IOException {
-         if (o instanceof List || o instanceof Set) {
-             jsonGenerator.writeEndArray();
-             writeTypeSuffix(jsonGenerator);
-         } else {
-             jsonGenerator.writeEndArray();
-         }
++        return writableTypeId;
 +    }
 +
 +    @Override
 +    protected Class getClassFromObject(final Object o) {
 +        final Class c = o.getClass();
 +        if (classMap.containsKey(c))
 +            return classMap.get(c);
 +
 +        final Class mapped;
 +        if (Map.class.isAssignableFrom(c)) {
 +            if (Tree.class.isAssignableFrom(c))
 +                mapped = Tree.class;
 +            else
 +                mapped = Map.class;
 +        } else if (List.class.isAssignableFrom(c))
 +            mapped = List.class;
 +        else if (Set.class.isAssignableFrom(c))
 +            mapped = Set.class;
 +        else 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;
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a3624f7e/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java
----------------------------------------------------------------------
diff --cc gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java
index 7935050,0000000..4e86ebd
mode 100644,000000..100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java
@@@ -1,325 -1,0 +1,358 @@@
 +/*
 + * 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.gremlin.process.remote.traversal.DefaultRemoteTraverser;
++import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
 +import org.apache.tinkerpop.gremlin.process.traversal.P;
 +import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
++import org.apache.tinkerpop.shaded.jackson.databind.JsonMappingException;
 +import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
 +import org.junit.Test;
 +import org.junit.runner.RunWith;
 +import org.junit.runners.Parameterized;
 +
 +import java.io.ByteArrayInputStream;
 +import java.io.ByteArrayOutputStream;
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.time.Instant;
 +import java.time.ZoneOffset;
 +import java.time.ZonedDateTime;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.HashMap;
 +import java.util.LinkedHashMap;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.UUID;
 +
 +import static org.hamcrest.MatcherAssert.assertThat;
++import static org.hamcrest.core.IsInstanceOf.instanceOf;
 +import static org.hamcrest.core.StringContains.containsString;
 +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+.
 + *
 + * @author Kevin Gallardo (https://kgdo.me)
 + * @author Stephen Mallette (http://stephen.genoprime.com)
 + */
 +@RunWith(Parameterized.class)
 +public class GraphSONMapperPartialEmbeddedTypeTest extends AbstractGraphSONTest {
 +
 +    @Parameterized.Parameters(name = "{0}")
 +    public static Iterable<Object[]> data() {
 +        return Arrays.asList(new Object[][]{
 +                {"v2", GraphSONMapper.build().version(GraphSONVersion.V2_0)
 +                        .addCustomModule(GraphSONXModuleV2d0.build().create(false))
 +                        .typeInfo(TypeInfo.PARTIAL_TYPES).create().createMapper()},
 +                {"v3", GraphSONMapper.build().version(GraphSONVersion.V3_0)
 +                        .addCustomModule(GraphSONXModuleV3d0.build().create(false))
 +                        .typeInfo(TypeInfo.PARTIAL_TYPES).create().createMapper()}
 +        });
 +    }
 +
 +    @Parameterized.Parameter(1)
 +    public ObjectMapper mapper;
 +
 +
 +    @Parameterized.Parameter(0)
 +    public String version;
 +
 +    @Test
++    public void elementOrderShouldNotMatter() throws Exception {
++        final String bytecodeJSONFail1 = "{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"addV\",\"poc_int\"],[\"property\",\"bigint1value\",{\"@type\":\"g:Int32\",\"@value\":-4294967295}]]}}";
++        final String bytecodeJSONFail2 = "{\"@value\":{\"step\":[[\"addV\",\"poc_int\"],[\"property\",\"bigint1value\",{\"@value\":-4294967295,\"@type\":\"g:Int32\"}]]},\"@type\":\"g:Bytecode\"}";
++
++        // first validate the failures of TINKERPOP-1738 - prior to the jackson fix on 2.9.4 one of these would have
++        // passed based on the ordering of the properties
++        try {
++            mapper.readValue(bytecodeJSONFail1, Bytecode.class);
++            fail("Should have thrown an error because 'bigint1value' is not an int32");
++        } catch (Exception ex) {
++            assertThat(ex, instanceOf(JsonMappingException.class));
++        }
++
++        try {
++            mapper.readValue(bytecodeJSONFail2, Bytecode.class);
++            fail("Should have thrown an error because 'bigint1value' is not an int32");
++        } catch (Exception ex) {
++            assertThat(ex, instanceOf(JsonMappingException.class));
++        }
++
++        // now do a legit parsing based on order
++        final String bytecodeJSON1 = "{\"@type\":\"g:Bytecode\",\"@value\":{\"step\":[[\"addV\",\"poc_int\"],[\"property\",\"bigint1value\",{\"@type\":\"g:Int64\",\"@value\":-4294967295}]]}}";
++        final String bytecodeJSON2 = "{\"@value\":{\"step\":[[\"addV\",\"poc_int\"],[\"property\",\"bigint1value\",{\"@value\":-4294967295,\"@type\":\"g:Int64\"}]]},\"@type\":\"g:Bytecode\"}";
++
++        final Bytecode bytecode1 = mapper.readValue(bytecodeJSON1, Bytecode.class);
++        final Bytecode bytecode2 = mapper.readValue(bytecodeJSON2, Bytecode.class);
++        assertEquals(bytecode1, bytecode2);
++    }
++
++    @Test
 +    public void shouldSerializeDeserializeNestedCollectionsAndMapAndTypedValuesCorrectly() throws Exception {
 +        // Trying to fail the TypeDeserializer type detection
 +        final UUID uuid = UUID.randomUUID();
 +        final List<Object> myList = new ArrayList<>();
 +
 +        final List<Object> myList2 = new ArrayList<>();
 +        myList2.add(UUID.randomUUID());
 +        myList2.add(33L);
 +        myList2.add(84);
 +        final Map<String,Object> map2 = new HashMap<>();
 +        map2.put("eheh", UUID.randomUUID());
 +        map2.put("normal", "normal");
 +        myList2.add(map2);
 +
 +        final 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(mapper, myList));
 +
 +        // no "@value" property
 +        String s = "{\""+GraphSONTokens.VALUETYPE+"\":\"" + GraphSONTokens.GREMLIN_TYPE_NAMESPACE + ":UUID\", \"test\":2}";
 +        Map<String,Object> map = new LinkedHashMap<>();
 +        map.put(GraphSONTokens.VALUETYPE, GraphSONTokens.GREMLIN_TYPE_NAMESPACE + ":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.GREMLINX_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(mapper, funObject, FunObject.class).toString());
 +        assertEquals(funObject.getClass(), serializeDeserialize(mapper, funObject, FunObject.class).getClass());
 +    }
 +
 +    @Test
 +    public void shouldHandleMapWithTypesUsingEmbedTypeSettingV2d0() throws Exception {
 +        final ObjectMapper mapper = GraphSONMapper.build()
 +                .version(GraphSONVersion.V2_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 shouldNotHandleMapWithTypesUsingEmbedTypeSettingV2d0() throws Exception {
 +        final ObjectMapper mapper = GraphSONMapper.build()
 +                .version(GraphSONVersion.V2_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"));
 +    }
 +
 +    @Test
 +    public void shouldHandleMapWithTypesUsingEmbedTypeSettingV1d0() 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 shouldNotHandleMapWithTypesUsingEmbedTypeSettingV1d0() 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"));
 +    }
 +
 +    @Test
 +    public void shouldLooseTypesInfoWithGraphSONNoType() throws Exception {
 +        final ObjectMapper mapper = GraphSONMapper.build()
 +                .version(GraphSONVersion.V2_0)
 +                .typeInfo(TypeInfo.NO_TYPES)
 +                .create()
 +                .createMapper();
 +
 +        final UUID uuid = UUID.randomUUID();
 +        final List<Object> myList = new ArrayList<>();
 +
 +        final List<Object> myList2 = new ArrayList<>();
 +        myList2.add(UUID.randomUUID());
 +        myList2.add(33L);
 +        myList2.add(84);
 +        final Map<String,Object> map2 = new HashMap<>();
 +        map2.put("eheh", UUID.randomUUID());
 +        map2.put("normal", "normal");
 +        myList2.add(map2);
 +
 +        final 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());
 +
 +        final String json = mapper.writeValueAsString(myList);
 +        final Object read = mapper.readValue(json, Object.class);
 +
 +        // Not equals because of type loss
 +        assertNotEquals(myList, read);
 +    }
 +
 +    @Test
 +    public void shouldHandleDefaultRemoteTraverser() throws Exception {
 +        final DefaultRemoteTraverser<String> o = new DefaultRemoteTraverser<>("test", 100);
 +        assertEquals(o, serializeDeserialize(mapper, o, Traverser.class));
 +    }
 +
 +    @Test
 +    public void shouldHandleVariantsOfP() throws Exception {
 +        final List<P> variantsOfP = Arrays.asList(
 +                P.between(1,2),
 +                P.eq(1),
 +                P.gt(1),
 +                P.gte(1),
 +                P.inside(1,2),
 +                P.lt(1),
 +                P.lte(1),
 +                P.neq(1),
 +                P.not(P.eq(1)),
 +                P.outside(1,2),
 +                P.within(1),
 +                P.within(1,2,3,4),
 +                P.within(Arrays.asList(1,2,3,4)),
 +                P.without(1),
 +                P.without(1,2,3,4),
 +                P.without(Arrays.asList(1,2,3,4)),
 +                P.eq(1).and(P.eq(2)),
 +                P.eq(1).or(P.eq(2)));
 +
 +        for (P p : variantsOfP) {
 +            assertEquals(p, serializeDeserialize(mapper, p, P.class));
 +        }
 +    }
 +
 +    // 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;
 +        }
 +    }
 +
 +
 +}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a3624f7e/gremlin-shaded/pom.xml
----------------------------------------------------------------------


[4/4] tinkerpop git commit: Merge branch 'tp33'

Posted by sp...@apache.org.
Merge branch 'tp33'


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

Branch: refs/heads/master
Commit: cfa5c50a74be2faf51ec8d1511c1b9478d4dbcd1
Parents: 25ae1a1 a3624f7
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Mar 8 08:08:49 2018 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Mar 8 08:08:49 2018 -0500

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |  1 +
 .../AbstractGraphSONTypeSerializer.java         | 80 +-------------------
 .../io/graphson/GraphSONTypeSerializerV2d0.java | 38 ++++++++++
 .../io/graphson/GraphSONTypeSerializerV3d0.java | 72 +++++++++++-------
 .../GraphSONMapperPartialEmbeddedTypeTest.java  | 33 ++++++++
 gremlin-shaded/pom.xml                          |  2 +-
 6 files changed, 120 insertions(+), 106 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cfa5c50a/CHANGELOG.asciidoc
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cfa5c50a/gremlin-shaded/pom.xml
----------------------------------------------------------------------


[2/4] tinkerpop git commit: Merge branch 'TINKERPOP-1738' into tp32

Posted by sp...@apache.org.
Merge branch 'TINKERPOP-1738' into tp32


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

Branch: refs/heads/master
Commit: 7bff988961587c0bcf9644b520faa3ed72a79952
Parents: 03a96f8 f35f04a
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Mar 8 07:22:04 2018 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Mar 8 07:22:04 2018 -0500

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |  1 +
 .../io/graphson/GraphSONTypeSerializer.java     | 94 ++++++--------------
 ...aphSONMapperV2d0PartialEmbeddedTypeTest.java | 32 +++++++
 gremlin-shaded/pom.xml                          |  2 +-
 4 files changed, 61 insertions(+), 68 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7bff9889/CHANGELOG.asciidoc
----------------------------------------------------------------------