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 2016/08/22 18:30:46 UTC
[09/19] tinkerpop git commit: TINKERPOP-1274: GraphSON 2.0.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeDeserializer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeDeserializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeDeserializer.java
new file mode 100644
index 0000000..e614a7a
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeDeserializer.java
@@ -0,0 +1,229 @@
+/*
+ * 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.JsonParser;
+import org.apache.tinkerpop.shaded.jackson.core.JsonToken;
+import org.apache.tinkerpop.shaded.jackson.databind.BeanProperty;
+import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
+import org.apache.tinkerpop.shaded.jackson.databind.JavaType;
+import org.apache.tinkerpop.shaded.jackson.databind.JsonDeserializer;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeDeserializer;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeIdResolver;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.impl.TypeDeserializerBase;
+import org.apache.tinkerpop.shaded.jackson.databind.type.TypeFactory;
+import org.apache.tinkerpop.shaded.jackson.databind.util.TokenBuffer;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Contains main logic for the whole JSON to Java deserialization. Handles types embedded with the version 2.0 of GraphSON.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ */
+public class GraphSONTypeDeserializer extends TypeDeserializerBase {
+ private final TypeIdResolver idRes;
+ private final String propertyName;
+ private final String valuePropertyName;
+ private final JavaType baseType;
+ private final TypeInfo typeInfo;
+
+ private static final JavaType mapJavaType = TypeFactory.defaultInstance().constructType(Map.class);
+ private static final JavaType arrayJavaType = TypeFactory.defaultInstance().constructType(List.class);
+
+
+ GraphSONTypeDeserializer(JavaType baseType, TypeIdResolver idRes, String typePropertyName,
+ TypeInfo typeInfo, String valuePropertyName){
+ super(baseType, idRes, typePropertyName, false, null);
+ this.baseType = baseType;
+ this.idRes = idRes;
+ this.propertyName = typePropertyName;
+ this.typeInfo = typeInfo;
+ this.valuePropertyName = valuePropertyName;
+ }
+
+ @Override
+ public TypeDeserializer forProperty(BeanProperty beanProperty) {
+ return this;
+ }
+
+ @Override
+ public JsonTypeInfo.As getTypeInclusion() {
+ return JsonTypeInfo.As.WRAPPER_ARRAY;
+ }
+
+
+ @Override
+ public TypeIdResolver getTypeIdResolver() {
+ return idRes;
+ }
+
+ @Override
+ public Class<?> getDefaultImpl() {
+ return null;
+ }
+
+ @Override
+ public Object deserializeTypedFromObject(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+ return deserialize(jsonParser, deserializationContext);
+ }
+
+ @Override
+ public Object deserializeTypedFromArray(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+ return deserialize(jsonParser, deserializationContext);
+ }
+
+ @Override
+ public Object deserializeTypedFromScalar(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+ return deserialize(jsonParser, deserializationContext);
+ }
+
+ @Override
+ public Object deserializeTypedFromAny(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+ return deserialize(jsonParser, deserializationContext);
+ }
+
+ /**
+ * Main logic for the deserialization.
+ */
+ private Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
+ TokenBuffer buf = new TokenBuffer(jsonParser.getCodec(), false);
+ TokenBuffer localCopy = new TokenBuffer(jsonParser.getCodec(), false);
+
+ // Detect type
+ try {
+ // The Type pattern is START_OBJECT -> TEXT_FIELD(propertyName) && TEXT_FIELD(valueProp).
+ if (jsonParser.getCurrentToken() == JsonToken.START_OBJECT) {
+ buf.writeStartObject();
+ String typeName = null;
+ boolean valueCalled = false;
+
+ for (int i = 0; i < 2; i++) {
+ String nextFieldName = jsonParser.nextFieldName();
+ if (nextFieldName == null) {
+ // empty map or less than 2 fields.
+ break;
+ }
+ if (!nextFieldName.equals(this.propertyName) && !nextFieldName.equals(this.valuePropertyName)) {
+ // no type, go out.
+ break;
+ }
+
+ if (nextFieldName.equals(this.propertyName)) {
+ typeName = jsonParser.nextTextValue();
+ // keeping the spare buffer up to date in case it's a false detection (only the "@type" property)
+ buf.writeStringField(this.propertyName, typeName);
+ continue;
+ }
+ if (nextFieldName.equals(this.valuePropertyName)) {
+ jsonParser.nextValue();
+ // keeping the spare buffer up to date in case it's a false detection (only the "@value" property)
+ buf.writeFieldName(this.valuePropertyName);
+ // this is not greatly efficient, would need to find better
+ // but the problem is that the fields "@value" and "@type" could be in any order
+ localCopy.copyCurrentStructure(jsonParser);
+ valueCalled = true;
+ continue;
+ }
+ }
+
+ if (typeName != null && valueCalled) {
+ // Type pattern detected.
+ JavaType typeFromId = idRes.typeFromId(typeName);
+
+ if (!baseType.isJavaLangObject() && baseType != typeFromId) {
+ throw new InstantiationException(
+ String.format("Cannot deserialize the value with the detected type contained in the JSON ('%s') " +
+ "to the type specified in parameter to the object mapper (%s). " +
+ "Those types are incompatible.", typeName, baseType.getRawClass().toString())
+ );
+ }
+
+ JsonDeserializer jsonDeserializer = deserializationContext.findContextualValueDeserializer(typeFromId, null);
+
+ JsonParser tokenParser = localCopy.asParser();
+ tokenParser.nextToken();
+ Object value = jsonDeserializer.deserialize(tokenParser, deserializationContext);
+
+ JsonToken t = jsonParser.nextToken();
+ if (t == JsonToken.END_OBJECT) {
+ // we're good to go
+ return value;
+ } else {
+ // detected the type pattern entirely but the Map contained other properties
+ // For now we error out because we assume that pattern is *only* reserved to
+ // typed values.
+ throw deserializationContext.mappingException("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.");
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw deserializationContext.mappingException("Could not deserialize the JSON value as required. Nested exception: " + e.toString());
+ }
+
+ // While searching for the type pattern, we may have moved the cursor of the original JsonParser in param.
+ // To compensate, we have filled consistently a TokenBuffer that should contain the equivalent of
+ // what we skipped while searching for the pattern.
+ // This has a huge positive impact on performances, since JsonParser does not have a 'rewind()',
+ // the only other solution would have been to copy the whole original JsonParser. Which we avoid here and use
+ // an efficient structure made of TokenBuffer + JsonParserSequence/Concat.
+
+ // Concatenate buf + localCopy + end of original content
+
+ JsonParser toUseParser;
+ JsonParser bufferParser = buf.asParser();
+ JsonParser localCopyParser = localCopy.asParser();
+
+
+ JsonParser[] array = {bufferParser, localCopyParser, jsonParser};
+
+ toUseParser = new JsonParserConcat(array);
+ toUseParser.nextToken();
+
+ // If a type has been specified in parameter :
+ if (!baseType.isJavaLangObject()) {
+ JsonDeserializer jsonDeserializer = deserializationContext.findContextualValueDeserializer(baseType, null);
+ return jsonDeserializer.deserialize(toUseParser, deserializationContext);
+ }
+ // Otherwise, detect the current structure :
+ else {
+ if (toUseParser.isExpectedStartArrayToken()) {
+ return deserializationContext.findContextualValueDeserializer(arrayJavaType, null).deserialize(toUseParser, deserializationContext);
+ } else if (toUseParser.isExpectedStartObjectToken()) {
+ return deserializationContext.findContextualValueDeserializer(mapJavaType, null).deserialize(toUseParser, deserializationContext);
+ } else {
+ // There's JavaLangObject in param, there's no type detected in the payload, the payload isn't a JSON Map or JSON List
+ // then consider it a simple type, even though we shouldn't be here if it was a simple type.
+ // TODO : maybe throw an error instead?
+ // throw deserializationContext.mappingException("Roger, we have a problem deserializing");
+ JsonDeserializer jsonDeserializer = deserializationContext.findContextualValueDeserializer(baseType, null);
+ return jsonDeserializer.deserialize(toUseParser, deserializationContext);
+ }
+ }
+ }
+
+ private boolean canReadTypeId() {
+ return this.typeInfo == TypeInfo.PARTIAL_TYPES;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeIdResolver.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeIdResolver.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeIdResolver.java
new file mode 100644
index 0000000..3edff73
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeIdResolver.java
@@ -0,0 +1,108 @@
+/*
+ * 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.databind.DatabindContext;
+import org.apache.tinkerpop.shaded.jackson.databind.JavaType;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeIdResolver;
+import org.apache.tinkerpop.shaded.jackson.databind.type.TypeFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Provides quick lookup for Type deserialization extracted from the JSON payload. As well as the Java Object to types
+ * compatible for the version 2.0 of GraphSON.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ */
+public class GraphSONTypeIdResolver implements TypeIdResolver {
+
+ private final Map<String, JavaType> idToType = new HashMap<>();
+
+ private final Map<Class, String> typeToId = new HashMap<>();
+
+ public Map<String, JavaType> getIdToType() {
+ return idToType;
+ }
+
+ public Map<Class, String> getTypeToId() {
+ return typeToId;
+ }
+
+ // Override manually a type definition.
+ public GraphSONTypeIdResolver addCustomType(String name, Class clasz) {
+ // May override types already registered, that's wanted.
+ getIdToType().put(name, TypeFactory.defaultInstance().constructType(clasz));
+ getTypeToId().put(clasz, name);
+ return this;
+ }
+
+ @Override
+ public void init(JavaType javaType) {
+ }
+
+ @Override
+ public String idFromValue(Object o) {
+ return idFromValueAndType(o, o.getClass());
+ }
+
+ @Override
+ public String idFromValueAndType(Object o, Class<?> aClass) {
+ if (!getTypeToId().containsKey(aClass)) {
+ // If one wants to serialize an object with a type, but hasn't registered
+ // a typeID for that class, fail.
+ throw new IllegalArgumentException(String.format("Could not find a type identifier for the class : %s. " +
+ "Make sure the value to serialize has a type identifier registered for its class.", aClass));
+ } else {
+ return getTypeToId().get(aClass);
+ }
+ }
+
+ @Override
+ public String idFromBaseType() {
+ return null;
+ }
+
+ @Override
+ public JavaType typeFromId(String s) {
+ return typeFromId(null, s);
+ }
+
+ @Override
+ public JavaType typeFromId(DatabindContext databindContext, String s) {
+ // Get the type from the string from the stored Map. If not found, default to deserialize as a String.
+ return getIdToType().containsKey(s)
+ ? getIdToType().get(s)
+ // TODO: shouldn't we fail instead, if the type is not found? Or log something?
+ : TypeFactory.defaultInstance().constructType(String.class);
+ }
+
+ @Override
+ public String getDescForKnownTypeIds() {
+ // TODO: Not sure what to put here.
+ return "GraphSON advanced typing system";
+ }
+
+ @Override
+ public JsonTypeInfo.Id getMechanism() {
+ return JsonTypeInfo.Id.CUSTOM;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeResolverBuilder.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeResolverBuilder.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeResolverBuilder.java
new file mode 100644
index 0000000..001dd02
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeResolverBuilder.java
@@ -0,0 +1,65 @@
+/*
+ * 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.DeserializationConfig;
+import org.apache.tinkerpop.shaded.jackson.databind.JavaType;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializationConfig;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.NamedType;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeDeserializer;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeIdResolver;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.impl.StdTypeResolverBuilder;
+
+import java.util.Collection;
+
+/**
+ * Creates the Type serializers as well as the Typed deserializers that will be provided to the serializers and
+ * deserializers. Contains the typeInfo level that should be provided by the GraphSONMapper.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ */
+public class GraphSONTypeResolverBuilder extends StdTypeResolverBuilder {
+
+ private TypeInfo typeInfo;
+ private String valuePropertyName;
+
+ @Override
+ public TypeDeserializer buildTypeDeserializer(DeserializationConfig config, JavaType baseType, Collection<NamedType> subtypes) {
+ TypeIdResolver idRes = this.idResolver(config, baseType, subtypes, false, true);
+ return new GraphSONTypeDeserializer(baseType, idRes, this.getTypeProperty(), typeInfo, valuePropertyName);
+ }
+
+
+ @Override
+ public TypeSerializer buildTypeSerializer(SerializationConfig config, JavaType baseType, Collection<NamedType> subtypes) {
+ TypeIdResolver idRes = this.idResolver(config, baseType, subtypes, true, false);
+ return new GraphSONTypeSerializer(idRes, this.getTypeProperty(), typeInfo, valuePropertyName);
+ }
+
+ public GraphSONTypeResolverBuilder valuePropertyName(String valuePropertyName) {
+ this.valuePropertyName = valuePropertyName;
+ return this;
+ }
+
+ public GraphSONTypeResolverBuilder typesEmbedding(TypeInfo typeInfo) {
+ this.typeInfo = typeInfo;
+ return this;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/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
new file mode 100644
index 0000000..98cf16a
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java
@@ -0,0 +1,197 @@
+/*
+ * 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.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.shaded.jackson.annotation.JsonTypeInfo;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+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.nio.ByteBuffer;
+
+/**
+ * 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)
+ */
+public class GraphSONTypeSerializer extends TypeSerializer {
+
+ private final TypeIdResolver idRes;
+ private final String propertyName;
+ private final TypeInfo typeInfo;
+ private final String valuePropertyName;
+
+ GraphSONTypeSerializer(TypeIdResolver idRes, String propertyName, TypeInfo typeInfo, String valuePropertyName) {
+ this.idRes = idRes;
+ this.propertyName = propertyName;
+ this.typeInfo = typeInfo;
+ this.valuePropertyName = valuePropertyName;
+ }
+
+ @Override
+ public TypeSerializer forProperty(BeanProperty beanProperty) {
+ return this;
+ }
+
+ @Override
+ public JsonTypeInfo.As getTypeInclusion() {
+ return null;
+ }
+
+ @Override
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ @Override
+ public TypeIdResolver getTypeIdResolver() {
+ return idRes;
+ }
+
+ @Override
+ public void writeTypePrefixForScalar(Object o, JsonGenerator jsonGenerator) throws IOException {
+ if (canWriteTypeId()) {
+ writeTypePrefix(jsonGenerator, getTypeIdResolver().idFromValueAndType(o, getClassFromObject(o)));
+ }
+ }
+
+ @Override
+ public void writeTypePrefixForObject(Object o, JsonGenerator jsonGenerator) throws IOException {
+ jsonGenerator.writeStartObject();
+ // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(Map);
+ }
+
+ @Override
+ public void writeTypePrefixForArray(Object o, JsonGenerator jsonGenerator) throws IOException {
+ jsonGenerator.writeStartArray();
+ // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(List);
+ }
+
+ @Override
+ public void writeTypeSuffixForScalar(Object o, JsonGenerator jsonGenerator) throws IOException {
+ if (canWriteTypeId()) {
+ writeTypeSuffix(jsonGenerator);
+ }
+ }
+
+ @Override
+ public void writeTypeSuffixForObject(Object o, JsonGenerator jsonGenerator) throws IOException {
+ jsonGenerator.writeEndObject();
+ // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(Map);
+ }
+
+ @Override
+ public void writeTypeSuffixForArray(Object o, JsonGenerator jsonGenerator) throws IOException {
+ jsonGenerator.writeEndArray();
+ // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(List);
+ }
+
+ @Override
+ public void writeCustomTypePrefixForScalar(Object o, JsonGenerator jsonGenerator, String s) throws IOException {
+ if (canWriteTypeId()) {
+ writeTypePrefix(jsonGenerator, s);
+ }
+ }
+
+ @Override
+ public void writeCustomTypePrefixForObject(Object o, JsonGenerator jsonGenerator, String s) throws IOException {
+ jsonGenerator.writeStartObject();
+ // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(s);
+ }
+
+ @Override
+ public void writeCustomTypePrefixForArray(Object o, JsonGenerator jsonGenerator, String s) throws IOException {
+ jsonGenerator.writeStartArray();
+ // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypePrefix(s);
+ }
+
+ @Override
+ public void writeCustomTypeSuffixForScalar(Object o, JsonGenerator jsonGenerator, String s) throws IOException {
+ if (canWriteTypeId()) {
+ writeTypeSuffix(jsonGenerator);
+ }
+ }
+
+ @Override
+ public void writeCustomTypeSuffixForObject(Object o, JsonGenerator jsonGenerator, String s) throws IOException {
+ jsonGenerator.writeEndObject();
+ // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(s);
+ }
+
+ @Override
+ public void writeCustomTypeSuffixForArray(Object o, JsonGenerator jsonGenerator, String s) throws IOException {
+ jsonGenerator.writeEndArray();
+ // TODO: FULL_TYPES should be implemented here as : if (fullTypesModeEnabled()) writeTypeSuffix(s);
+ }
+
+ private boolean canWriteTypeId() {
+ return typeInfo != null
+ && typeInfo == TypeInfo.PARTIAL_TYPES;
+ }
+
+ private void writeTypePrefix(JsonGenerator jsonGenerator, String s) throws IOException {
+ jsonGenerator.writeStartObject();
+ jsonGenerator.writeStringField(this.getPropertyName(), s);
+ jsonGenerator.writeFieldName(this.valuePropertyName);
+ }
+
+ private void writeTypeSuffix(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..)
+ */
+ private Class getClassFromObject(Object o) {
+ // not the most efficient
+ Class c = o.getClass();
+ if (Vertex.class.isAssignableFrom(c)) {
+ return Vertex.class;
+ } else if (Edge.class.isAssignableFrom(c)) {
+ return Edge.class;
+ } else if (Path.class.isAssignableFrom(c)) {
+ return Path.class;
+ } else if (VertexProperty.class.isAssignableFrom(c)) {
+ return VertexProperty.class;
+ } else if (Metrics.class.isAssignableFrom(c)) {
+ return Metrics.class;
+ } else if (TraversalMetrics.class.isAssignableFrom(c)) {
+ return TraversalMetrics.class;
+ } else if (Property.class.isAssignableFrom(c)) {
+ return Property.class;
+ } else if (ByteBuffer.class.isAssignableFrom(c)) {
+ return ByteBuffer.class;
+ }
+ return c;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java
index 9ff427c..548bca1 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java
@@ -55,4 +55,41 @@ public final class GraphSONUtil {
serializer.serialize(object, jsonGenerator, serializerProvider);
}
}
+
+ public static void writeStartObject(Object o, JsonGenerator jsonGenerator, TypeSerializer typeSerializer) throws IOException {
+ if (typeSerializer != null)
+ typeSerializer.writeTypePrefixForObject(o, jsonGenerator);
+ else
+ jsonGenerator.writeStartObject();
+ }
+
+ public static void writeEndObject(Object o, JsonGenerator jsonGenerator, TypeSerializer typeSerializer) throws IOException {
+ if (typeSerializer != null)
+ typeSerializer.writeTypeSuffixForObject(o, jsonGenerator);
+ else
+ jsonGenerator.writeEndObject();
+ }
+
+ public static void writeStartArray(Object o, JsonGenerator jsonGenerator, TypeSerializer typeSerializer) throws IOException {
+ if (typeSerializer != null)
+ typeSerializer.writeTypePrefixForArray(o, jsonGenerator);
+ else
+ jsonGenerator.writeStartArray();
+ }
+
+
+ public static void writeEndArray(Object o, JsonGenerator jsonGenerator, TypeSerializer typeSerializer) throws IOException {
+ if (typeSerializer != null)
+ typeSerializer.writeTypeSuffixForArray(o, jsonGenerator);
+ else
+ jsonGenerator.writeEndArray();
+ }
+
+ static void safeWriteObjectField(JsonGenerator jsonGenerator, String key, Object value) {
+ try {
+ jsonGenerator.writeObjectField(key, value);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONVersion.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONVersion.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONVersion.java
index 628ea22..7740b06 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONVersion.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONVersion.java
@@ -24,7 +24,8 @@ package org.apache.tinkerpop.gremlin.structure.io.graphson;
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
public enum GraphSONVersion {
- V1_0(GraphSONModule.GraphSONModuleV1d0.build(), "1.0");
+ V1_0(GraphSONModule.GraphSONModuleV1d0.build(), "1.0"),
+ V2_0(GraphSONModule.GraphSONModuleV2d0.build(), "2.0");
private final GraphSONModule.GraphSONModuleBuilder builder;
private final String versionNumber;
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONWriter.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONWriter.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONWriter.java
index 37ed9a0..6980b48 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONWriter.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONWriter.java
@@ -27,11 +27,16 @@ import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import org.apache.tinkerpop.gremlin.structure.io.GraphWriter;
import org.apache.tinkerpop.gremlin.structure.io.Mapper;
+import org.apache.tinkerpop.gremlin.structure.util.star.DirectionalStarGraph;
import org.apache.tinkerpop.gremlin.structure.util.star.StarGraph;
-import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializer;
import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
-import java.io.*;
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
import java.util.Iterator;
import java.util.function.Function;
@@ -74,7 +79,7 @@ public final class GraphSONWriter implements GraphWriter {
*/
@Override
public void writeVertex(final OutputStream outputStream, final Vertex v, final Direction direction) throws IOException {
- mapper.writeValue(outputStream, new StarGraphGraphSONSerializer.DirectionalStarGraph(StarGraph.of(v), direction));
+ mapper.writeValue(outputStream, new DirectionalStarGraph(StarGraph.of(v), direction));
}
/**
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializers.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializers.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializers.java
deleted file mode 100644
index 7ceae94..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializers.java
+++ /dev/null
@@ -1,326 +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.io.graphson;
-
-import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
-import org.apache.tinkerpop.shaded.jackson.core.JsonParser;
-import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
-import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
-import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer;
-import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
-import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
-
-import java.io.IOException;
-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;
-
-/**
- * GraphSON serializers for classes in {@code java.time.*}.
- */
-final class JavaTimeSerializers {
-
- private JavaTimeSerializers() {}
-
- /**
- * Base class for serializing the {@code java.time.*} to ISO-8061 formats.
- */
- static abstract class AbstractJavaTimeSerializer<T> extends StdSerializer<T> {
-
- public AbstractJavaTimeSerializer(final Class<T> clazz) {
- super(clazz);
- }
-
- @Override
- public void serialize(final T value, final JsonGenerator gen,
- final SerializerProvider serializerProvider) throws IOException {
- gen.writeString(value.toString());
- }
-
- @Override
- public void serializeWithType(final T value, final JsonGenerator gen,
- final SerializerProvider serializers, final TypeSerializer typeSer) throws IOException {
- typeSer.writeTypePrefixForObject(value, gen);
- gen.writeStringField(GraphSONTokens.VALUE, value.toString());
- typeSer.writeTypeSuffixForObject(value, gen);
- }
- }
- /**
- * Base class for serializing the {@code java.time.*} from ISO-8061 formats.
- */
- abstract static class AbstractJavaTimeJacksonDeserializer<T> extends StdDeserializer<T> {
- public AbstractJavaTimeJacksonDeserializer(final Class<T> clazz) {
- super(clazz);
- }
-
- public abstract T parse(final String val);
-
- @Override
- public T deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException {
- if (!jsonParser.getText().equals(GraphSONTokens.VALUE))
- throw new IOException(String.format("Invalid format for %s - expecting '%s' with a text value in ISO-8061 format", _valueClass.getSimpleName(), GraphSONTokens.VALUE));
-
- return parse(jsonParser.nextTextValue());
- }
- }
-
- final static class DurationJacksonSerializer extends AbstractJavaTimeSerializer<Duration> {
-
- public DurationJacksonSerializer() {
- super(Duration.class);
- }
- }
-
- final static class DurationJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Duration> {
- public DurationJacksonDeserializer() {
- super(Duration.class);
- }
-
- @Override
- public Duration parse(final String val) {
- return Duration.parse(val);
- }
- }
-
- final static class InstantJacksonSerializer extends AbstractJavaTimeSerializer<Instant> {
-
- public InstantJacksonSerializer() {
- super(Instant.class);
- }
- }
-
- final static class InstantJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Instant> {
- public InstantJacksonDeserializer() {
- super(Instant.class);
- }
-
- @Override
- public Instant parse(final String val) {
- return Instant.parse(val);
- }
- }
-
- final static class LocalDateJacksonSerializer extends AbstractJavaTimeSerializer<LocalDate> {
-
- public LocalDateJacksonSerializer() {
- super(LocalDate.class);
- }
- }
-
- final static class LocalDateJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalDate> {
- public LocalDateJacksonDeserializer() {
- super(LocalDate.class);
- }
-
- @Override
- public LocalDate parse(final String val) {
- return LocalDate.parse(val);
- }
- }
-
- final static class LocalDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<LocalDateTime> {
-
- public LocalDateTimeJacksonSerializer() {
- super(LocalDateTime.class);
- }
- }
-
- final static class LocalDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalDateTime> {
- public LocalDateTimeJacksonDeserializer() {
- super(LocalDateTime.class);
- }
-
- @Override
- public LocalDateTime parse(final String val) {
- return LocalDateTime.parse(val);
- }
- }
-
- final static class LocalTimeJacksonSerializer extends AbstractJavaTimeSerializer<LocalTime> {
-
- public LocalTimeJacksonSerializer() {
- super(LocalTime.class);
- }
- }
-
- final static class LocalTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalTime> {
- public LocalTimeJacksonDeserializer() {
- super(LocalTime.class);
- }
-
- @Override
- public LocalTime parse(final String val) {
- return LocalTime.parse(val);
- }
- }
-
- final static class MonthDayJacksonSerializer extends AbstractJavaTimeSerializer<MonthDay> {
-
- public MonthDayJacksonSerializer() {
- super(MonthDay.class);
- }
- }
-
- final static class MonthDayJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<MonthDay> {
- public MonthDayJacksonDeserializer() {
- super(MonthDay.class);
- }
-
- @Override
- public MonthDay parse(final String val) {
- return MonthDay.parse(val);
- }
- }
-
- final static class OffsetDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<OffsetDateTime> {
-
- public OffsetDateTimeJacksonSerializer() {
- super(OffsetDateTime.class);
- }
- }
-
- final static class OffsetDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<OffsetDateTime> {
- public OffsetDateTimeJacksonDeserializer() {
- super(OffsetDateTime.class);
- }
-
- @Override
- public OffsetDateTime parse(final String val) {
- return OffsetDateTime.parse(val);
- }
- }
-
- final static class OffsetTimeJacksonSerializer extends AbstractJavaTimeSerializer<OffsetTime> {
-
- public OffsetTimeJacksonSerializer() {
- super(OffsetTime.class);
- }
- }
-
- final static class OffsetTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<OffsetTime> {
- public OffsetTimeJacksonDeserializer() {
- super(OffsetTime.class);
- }
-
- @Override
- public OffsetTime parse(final String val) {
- return OffsetTime.parse(val);
- }
- }
-
- final static class PeriodJacksonSerializer extends AbstractJavaTimeSerializer<Period> {
-
- public PeriodJacksonSerializer() {
- super(Period.class);
- }
- }
-
- final static class PeriodJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Period> {
- public PeriodJacksonDeserializer() {
- super(Period.class);
- }
-
- @Override
- public Period parse(final String val) {
- return Period.parse(val);
- }
- }
-
- final static class YearJacksonSerializer extends AbstractJavaTimeSerializer<Year> {
-
- public YearJacksonSerializer() {
- super(Year.class);
- }
- }
-
- final static class YearJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Year> {
- public YearJacksonDeserializer() {
- super(Year.class);
- }
-
- @Override
- public Year parse(final String val) {
- return Year.parse(val);
- }
- }
-
- final static class YearMonthJacksonSerializer extends AbstractJavaTimeSerializer<YearMonth> {
-
- public YearMonthJacksonSerializer() {
- super(YearMonth.class);
- }
- }
-
- final static class YearMonthJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<YearMonth> {
- public YearMonthJacksonDeserializer() {
- super(YearMonth.class);
- }
-
- @Override
- public YearMonth parse(final String val) {
- return YearMonth.parse(val);
- }
- }
-
- final static class ZonedDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<ZonedDateTime> {
-
- public ZonedDateTimeJacksonSerializer() {
- super(ZonedDateTime.class);
- }
- }
-
- final static class ZonedDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<ZonedDateTime> {
- public ZonedDateTimeJacksonDeserializer() {
- super(ZonedDateTime.class);
- }
-
- @Override
- public ZonedDateTime parse(final String val) {
- return ZonedDateTime.parse(val);
- }
- }
-
- final static class ZoneOffsetJacksonSerializer extends AbstractJavaTimeSerializer<ZoneOffset> {
-
- public ZoneOffsetJacksonSerializer() {
- super(ZoneOffset.class);
- }
- }
-
- final static class ZoneOffsetJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<ZoneOffset> {
- public ZoneOffsetJacksonDeserializer() {
- super(ZoneOffset.class);
- }
-
- @Override
- public ZoneOffset parse(final String val) {
- return ZoneOffset.of(val);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV1d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV1d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV1d0.java
new file mode 100644
index 0000000..763c1d9
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV1d0.java
@@ -0,0 +1,326 @@
+/*
+ * 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.core.JsonParser;
+import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
+import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+
+import java.io.IOException;
+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;
+
+/**
+ * GraphSON serializers for classes in {@code java.time.*}.
+ */
+final class JavaTimeSerializersV1d0 {
+
+ private JavaTimeSerializersV1d0() {}
+
+ /**
+ * Base class for serializing the {@code java.time.*} to ISO-8061 formats.
+ */
+ static abstract class AbstractJavaTimeSerializer<T> extends StdSerializer<T> {
+
+ public AbstractJavaTimeSerializer(final Class<T> clazz) {
+ super(clazz);
+ }
+
+ @Override
+ public void serialize(final T value, final JsonGenerator gen,
+ final SerializerProvider serializerProvider) throws IOException {
+ gen.writeString(value.toString());
+ }
+
+ @Override
+ public void serializeWithType(final T value, final JsonGenerator gen,
+ final SerializerProvider serializers, final TypeSerializer typeSer) throws IOException {
+ typeSer.writeTypePrefixForObject(value, gen);
+ gen.writeStringField(GraphSONTokens.VALUE, value.toString());
+ typeSer.writeTypeSuffixForObject(value, gen);
+ }
+ }
+ /**
+ * Base class for serializing the {@code java.time.*} from ISO-8061 formats.
+ */
+ abstract static class AbstractJavaTimeJacksonDeserializer<T> extends StdDeserializer<T> {
+ public AbstractJavaTimeJacksonDeserializer(final Class<T> clazz) {
+ super(clazz);
+ }
+
+ public abstract T parse(final String val);
+
+ @Override
+ public T deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException {
+ if (!jsonParser.getText().equals(GraphSONTokens.VALUE))
+ throw new IOException(String.format("Invalid format for %s - expecting '%s' with a text value in ISO-8061 format", _valueClass.getSimpleName(), GraphSONTokens.VALUE));
+
+ return parse(jsonParser.nextTextValue());
+ }
+ }
+
+ final static class DurationJacksonSerializer extends AbstractJavaTimeSerializer<Duration> {
+
+ public DurationJacksonSerializer() {
+ super(Duration.class);
+ }
+ }
+
+ final static class DurationJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Duration> {
+ public DurationJacksonDeserializer() {
+ super(Duration.class);
+ }
+
+ @Override
+ public Duration parse(final String val) {
+ return Duration.parse(val);
+ }
+ }
+
+ final static class InstantJacksonSerializer extends AbstractJavaTimeSerializer<Instant> {
+
+ public InstantJacksonSerializer() {
+ super(Instant.class);
+ }
+ }
+
+ final static class InstantJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Instant> {
+ public InstantJacksonDeserializer() {
+ super(Instant.class);
+ }
+
+ @Override
+ public Instant parse(final String val) {
+ return Instant.parse(val);
+ }
+ }
+
+ final static class LocalDateJacksonSerializer extends AbstractJavaTimeSerializer<LocalDate> {
+
+ public LocalDateJacksonSerializer() {
+ super(LocalDate.class);
+ }
+ }
+
+ final static class LocalDateJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalDate> {
+ public LocalDateJacksonDeserializer() {
+ super(LocalDate.class);
+ }
+
+ @Override
+ public LocalDate parse(final String val) {
+ return LocalDate.parse(val);
+ }
+ }
+
+ final static class LocalDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<LocalDateTime> {
+
+ public LocalDateTimeJacksonSerializer() {
+ super(LocalDateTime.class);
+ }
+ }
+
+ final static class LocalDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalDateTime> {
+ public LocalDateTimeJacksonDeserializer() {
+ super(LocalDateTime.class);
+ }
+
+ @Override
+ public LocalDateTime parse(final String val) {
+ return LocalDateTime.parse(val);
+ }
+ }
+
+ final static class LocalTimeJacksonSerializer extends AbstractJavaTimeSerializer<LocalTime> {
+
+ public LocalTimeJacksonSerializer() {
+ super(LocalTime.class);
+ }
+ }
+
+ final static class LocalTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalTime> {
+ public LocalTimeJacksonDeserializer() {
+ super(LocalTime.class);
+ }
+
+ @Override
+ public LocalTime parse(final String val) {
+ return LocalTime.parse(val);
+ }
+ }
+
+ final static class MonthDayJacksonSerializer extends AbstractJavaTimeSerializer<MonthDay> {
+
+ public MonthDayJacksonSerializer() {
+ super(MonthDay.class);
+ }
+ }
+
+ final static class MonthDayJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<MonthDay> {
+ public MonthDayJacksonDeserializer() {
+ super(MonthDay.class);
+ }
+
+ @Override
+ public MonthDay parse(final String val) {
+ return MonthDay.parse(val);
+ }
+ }
+
+ final static class OffsetDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<OffsetDateTime> {
+
+ public OffsetDateTimeJacksonSerializer() {
+ super(OffsetDateTime.class);
+ }
+ }
+
+ final static class OffsetDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<OffsetDateTime> {
+ public OffsetDateTimeJacksonDeserializer() {
+ super(OffsetDateTime.class);
+ }
+
+ @Override
+ public OffsetDateTime parse(final String val) {
+ return OffsetDateTime.parse(val);
+ }
+ }
+
+ final static class OffsetTimeJacksonSerializer extends AbstractJavaTimeSerializer<OffsetTime> {
+
+ public OffsetTimeJacksonSerializer() {
+ super(OffsetTime.class);
+ }
+ }
+
+ final static class OffsetTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<OffsetTime> {
+ public OffsetTimeJacksonDeserializer() {
+ super(OffsetTime.class);
+ }
+
+ @Override
+ public OffsetTime parse(final String val) {
+ return OffsetTime.parse(val);
+ }
+ }
+
+ final static class PeriodJacksonSerializer extends AbstractJavaTimeSerializer<Period> {
+
+ public PeriodJacksonSerializer() {
+ super(Period.class);
+ }
+ }
+
+ final static class PeriodJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Period> {
+ public PeriodJacksonDeserializer() {
+ super(Period.class);
+ }
+
+ @Override
+ public Period parse(final String val) {
+ return Period.parse(val);
+ }
+ }
+
+ final static class YearJacksonSerializer extends AbstractJavaTimeSerializer<Year> {
+
+ public YearJacksonSerializer() {
+ super(Year.class);
+ }
+ }
+
+ final static class YearJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Year> {
+ public YearJacksonDeserializer() {
+ super(Year.class);
+ }
+
+ @Override
+ public Year parse(final String val) {
+ return Year.parse(val);
+ }
+ }
+
+ final static class YearMonthJacksonSerializer extends AbstractJavaTimeSerializer<YearMonth> {
+
+ public YearMonthJacksonSerializer() {
+ super(YearMonth.class);
+ }
+ }
+
+ final static class YearMonthJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<YearMonth> {
+ public YearMonthJacksonDeserializer() {
+ super(YearMonth.class);
+ }
+
+ @Override
+ public YearMonth parse(final String val) {
+ return YearMonth.parse(val);
+ }
+ }
+
+ final static class ZonedDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<ZonedDateTime> {
+
+ public ZonedDateTimeJacksonSerializer() {
+ super(ZonedDateTime.class);
+ }
+ }
+
+ final static class ZonedDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<ZonedDateTime> {
+ public ZonedDateTimeJacksonDeserializer() {
+ super(ZonedDateTime.class);
+ }
+
+ @Override
+ public ZonedDateTime parse(final String val) {
+ return ZonedDateTime.parse(val);
+ }
+ }
+
+ final static class ZoneOffsetJacksonSerializer extends AbstractJavaTimeSerializer<ZoneOffset> {
+
+ public ZoneOffsetJacksonSerializer() {
+ super(ZoneOffset.class);
+ }
+ }
+
+ final static class ZoneOffsetJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<ZoneOffset> {
+ public ZoneOffsetJacksonDeserializer() {
+ super(ZoneOffset.class);
+ }
+
+ @Override
+ public ZoneOffset parse(final String val) {
+ return ZoneOffset.of(val);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV2d0.java
new file mode 100644
index 0000000..2950a33
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV2d0.java
@@ -0,0 +1,323 @@
+/*
+ * 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.core.JsonParser;
+import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
+import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+
+import java.io.IOException;
+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;
+
+/**
+ * GraphSON serializers for classes in {@code java.time.*} for the version 2.0 of GraphSON.
+ */
+final class JavaTimeSerializersV2d0 {
+
+ private JavaTimeSerializersV2d0() {}
+
+ /**
+ * Base class for serializing the {@code java.time.*} to ISO-8061 formats.
+ */
+ static abstract class AbstractJavaTimeSerializer<T> extends StdSerializer<T> {
+
+ public AbstractJavaTimeSerializer(final Class<T> clazz) {
+ super(clazz);
+ }
+
+ @Override
+ public void serialize(final T value, final JsonGenerator gen,
+ final SerializerProvider serializerProvider) throws IOException {
+ gen.writeString(value.toString());
+ }
+
+ @Override
+ public void serializeWithType(final T value, final JsonGenerator gen,
+ final SerializerProvider serializers, final TypeSerializer typeSer) throws IOException {
+ typeSer.writeTypePrefixForScalar(value, gen);
+ gen.writeString(value.toString());
+ typeSer.writeTypeSuffixForScalar(value, gen);
+ }
+ }
+ /**
+ * Base class for serializing the {@code java.time.*} from ISO-8061 formats.
+ */
+ abstract static class AbstractJavaTimeJacksonDeserializer<T> extends StdDeserializer<T> {
+ public AbstractJavaTimeJacksonDeserializer(final Class<T> clazz) {
+ super(clazz);
+ }
+
+ public abstract T parse(final String val);
+
+ @Override
+ public T deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException {
+ return parse(jsonParser.getText());
+ }
+ }
+
+ final static class DurationJacksonSerializer extends AbstractJavaTimeSerializer<Duration> {
+
+ public DurationJacksonSerializer() {
+ super(Duration.class);
+ }
+ }
+
+ final static class DurationJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Duration> {
+ public DurationJacksonDeserializer() {
+ super(Duration.class);
+ }
+
+ @Override
+ public Duration parse(final String val) {
+ return Duration.parse(val);
+ }
+ }
+
+ final static class InstantJacksonSerializer extends AbstractJavaTimeSerializer<Instant> {
+
+ public InstantJacksonSerializer() {
+ super(Instant.class);
+ }
+ }
+
+ final static class InstantJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Instant> {
+ public InstantJacksonDeserializer() {
+ super(Instant.class);
+ }
+
+ @Override
+ public Instant parse(final String val) {
+ return Instant.parse(val);
+ }
+ }
+
+ final static class LocalDateJacksonSerializer extends AbstractJavaTimeSerializer<LocalDate> {
+
+ public LocalDateJacksonSerializer() {
+ super(LocalDate.class);
+ }
+ }
+
+ final static class LocalDateJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalDate> {
+ public LocalDateJacksonDeserializer() {
+ super(LocalDate.class);
+ }
+
+ @Override
+ public LocalDate parse(final String val) {
+ return LocalDate.parse(val);
+ }
+ }
+
+ final static class LocalDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<LocalDateTime> {
+
+ public LocalDateTimeJacksonSerializer() {
+ super(LocalDateTime.class);
+ }
+ }
+
+ final static class LocalDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalDateTime> {
+ public LocalDateTimeJacksonDeserializer() {
+ super(LocalDateTime.class);
+ }
+
+ @Override
+ public LocalDateTime parse(final String val) {
+ return LocalDateTime.parse(val);
+ }
+ }
+
+ final static class LocalTimeJacksonSerializer extends AbstractJavaTimeSerializer<LocalTime> {
+
+ public LocalTimeJacksonSerializer() {
+ super(LocalTime.class);
+ }
+ }
+
+ final static class LocalTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalTime> {
+ public LocalTimeJacksonDeserializer() {
+ super(LocalTime.class);
+ }
+
+ @Override
+ public LocalTime parse(final String val) {
+ return LocalTime.parse(val);
+ }
+ }
+
+ final static class MonthDayJacksonSerializer extends AbstractJavaTimeSerializer<MonthDay> {
+
+ public MonthDayJacksonSerializer() {
+ super(MonthDay.class);
+ }
+ }
+
+ final static class MonthDayJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<MonthDay> {
+ public MonthDayJacksonDeserializer() {
+ super(MonthDay.class);
+ }
+
+ @Override
+ public MonthDay parse(final String val) {
+ return MonthDay.parse(val);
+ }
+ }
+
+ final static class OffsetDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<OffsetDateTime> {
+
+ public OffsetDateTimeJacksonSerializer() {
+ super(OffsetDateTime.class);
+ }
+ }
+
+ final static class OffsetDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<OffsetDateTime> {
+ public OffsetDateTimeJacksonDeserializer() {
+ super(OffsetDateTime.class);
+ }
+
+ @Override
+ public OffsetDateTime parse(final String val) {
+ return OffsetDateTime.parse(val);
+ }
+ }
+
+ final static class OffsetTimeJacksonSerializer extends AbstractJavaTimeSerializer<OffsetTime> {
+
+ public OffsetTimeJacksonSerializer() {
+ super(OffsetTime.class);
+ }
+ }
+
+ final static class OffsetTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<OffsetTime> {
+ public OffsetTimeJacksonDeserializer() {
+ super(OffsetTime.class);
+ }
+
+ @Override
+ public OffsetTime parse(final String val) {
+ return OffsetTime.parse(val);
+ }
+ }
+
+ final static class PeriodJacksonSerializer extends AbstractJavaTimeSerializer<Period> {
+
+ public PeriodJacksonSerializer() {
+ super(Period.class);
+ }
+ }
+
+ final static class PeriodJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Period> {
+ public PeriodJacksonDeserializer() {
+ super(Period.class);
+ }
+
+ @Override
+ public Period parse(final String val) {
+ return Period.parse(val);
+ }
+ }
+
+ final static class YearJacksonSerializer extends AbstractJavaTimeSerializer<Year> {
+
+ public YearJacksonSerializer() {
+ super(Year.class);
+ }
+ }
+
+ final static class YearJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Year> {
+ public YearJacksonDeserializer() {
+ super(Year.class);
+ }
+
+ @Override
+ public Year parse(final String val) {
+ return Year.parse(val);
+ }
+ }
+
+ final static class YearMonthJacksonSerializer extends AbstractJavaTimeSerializer<YearMonth> {
+
+ public YearMonthJacksonSerializer() {
+ super(YearMonth.class);
+ }
+ }
+
+ final static class YearMonthJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<YearMonth> {
+ public YearMonthJacksonDeserializer() {
+ super(YearMonth.class);
+ }
+
+ @Override
+ public YearMonth parse(final String val) {
+ return YearMonth.parse(val);
+ }
+ }
+
+ final static class ZonedDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<ZonedDateTime> {
+
+ public ZonedDateTimeJacksonSerializer() {
+ super(ZonedDateTime.class);
+ }
+ }
+
+ final static class ZonedDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<ZonedDateTime> {
+ public ZonedDateTimeJacksonDeserializer() {
+ super(ZonedDateTime.class);
+ }
+
+ @Override
+ public ZonedDateTime parse(final String val) {
+ return ZonedDateTime.parse(val);
+ }
+ }
+
+ final static class ZoneOffsetJacksonSerializer extends AbstractJavaTimeSerializer<ZoneOffset> {
+
+ public ZoneOffsetJacksonSerializer() {
+ super(ZoneOffset.class);
+ }
+ }
+
+ final static class ZoneOffsetJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<ZoneOffset> {
+ public ZoneOffsetJacksonDeserializer() {
+ super(ZoneOffset.class);
+ }
+
+ @Override
+ public ZoneOffset parse(final String val) {
+ return ZoneOffset.of(val);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializers.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializers.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializers.java
deleted file mode 100644
index 4f2f5da..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializers.java
+++ /dev/null
@@ -1,86 +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.io.graphson;
-
-import org.apache.tinkerpop.gremlin.structure.Element;
-import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
-import org.apache.tinkerpop.shaded.jackson.databind.SerializationFeature;
-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.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * GraphSON serializers for classes in {@code java.util.*}.
- */
-final class JavaUtilSerializers {
-
- private JavaUtilSerializers() {}
-
- final static class MapEntryJacksonSerializer extends StdSerializer<Map.Entry> {
-
- public MapEntryJacksonSerializer() {
- super(Map.Entry.class);
- }
-
- @Override
- public void serialize(final Map.Entry entry, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
- throws IOException {
- ser(entry, jsonGenerator, serializerProvider, null);
- }
-
- @Override
- public void serializeWithType(final Map.Entry entry, final JsonGenerator jsonGenerator,
- final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
- ser(entry, jsonGenerator, serializerProvider, typeSerializer);
- }
-
- private static void ser(final Map.Entry entry, final JsonGenerator jsonGenerator,
- final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
- jsonGenerator.writeStartObject();
- if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
-
- // this treatment of keys is consistent with the current GraphSONKeySerializer which extends the
- // StdKeySerializer
- final Object key = entry.getKey();
- final Class cls = key.getClass();
- String k;
- if (cls == String.class)
- k = (String) key;
- else if (Element.class.isAssignableFrom(cls))
- k = ((Element) key).id().toString();
- else if(Date.class.isAssignableFrom(cls)) {
- if (serializerProvider.isEnabled(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS))
- k = String.valueOf(((Date) key).getTime());
- else
- k = serializerProvider.getConfig().getDateFormat().format((Date) key);
- } else if(cls == Class.class)
- k = ((Class) key).getName();
- else
- k = key.toString();
-
- serializerProvider.defaultSerializeField(k, entry.getValue(), jsonGenerator);
- jsonGenerator.writeEndObject();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV1d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV1d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV1d0.java
new file mode 100644
index 0000000..15dd3b9
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV1d0.java
@@ -0,0 +1,86 @@
+/*
+ * 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.structure.Element;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializationFeature;
+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.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * GraphSON serializers for classes in {@code java.util.*}.
+ */
+final class JavaUtilSerializersV1d0 {
+
+ private JavaUtilSerializersV1d0() {}
+
+ final static class MapEntryJacksonSerializer extends StdSerializer<Map.Entry> {
+
+ public MapEntryJacksonSerializer() {
+ super(Map.Entry.class);
+ }
+
+ @Override
+ public void serialize(final Map.Entry entry, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+ throws IOException {
+ ser(entry, jsonGenerator, serializerProvider, null);
+ }
+
+ @Override
+ public void serializeWithType(final Map.Entry entry, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+ ser(entry, jsonGenerator, serializerProvider, typeSerializer);
+ }
+
+ private static void ser(final Map.Entry entry, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+ jsonGenerator.writeStartObject();
+ if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+
+ // this treatment of keys is consistent with the current GraphSONKeySerializer which extends the
+ // StdKeySerializer
+ final Object key = entry.getKey();
+ final Class cls = key.getClass();
+ String k;
+ if (cls == String.class)
+ k = (String) key;
+ else if (Element.class.isAssignableFrom(cls))
+ k = ((Element) key).id().toString();
+ else if(Date.class.isAssignableFrom(cls)) {
+ if (serializerProvider.isEnabled(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS))
+ k = String.valueOf(((Date) key).getTime());
+ else
+ k = serializerProvider.getConfig().getDateFormat().format((Date) key);
+ } else if(cls == Class.class)
+ k = ((Class) key).getName();
+ else
+ k = key.toString();
+
+ serializerProvider.defaultSerializeField(k, entry.getValue(), jsonGenerator);
+ jsonGenerator.writeEndObject();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV2d0.java
new file mode 100644
index 0000000..8d867c9
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV2d0.java
@@ -0,0 +1,87 @@
+/*
+ * 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.structure.Element;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializationFeature;
+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.ByteBufferSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * GraphSON serializers for classes in {@code java.util.*} for the version 2.0 of GraphSON.
+ */
+final class JavaUtilSerializersV2d0 {
+
+ private JavaUtilSerializersV2d0() {}
+
+ final static class MapEntryJacksonSerializer extends StdSerializer<Map.Entry> {
+
+ public MapEntryJacksonSerializer() {
+ super(Map.Entry.class);
+ }
+
+ @Override
+ public void serialize(final Map.Entry entry, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+ throws IOException {
+ jsonGenerator.writeStartObject();
+ ser(entry, jsonGenerator, serializerProvider);
+ jsonGenerator.writeEndObject();
+ }
+
+ @Override
+ public void serializeWithType(final Map.Entry entry, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+ typeSerializer.writeTypePrefixForObject(entry, jsonGenerator);
+ ser(entry, jsonGenerator, serializerProvider);
+ typeSerializer.writeTypeSuffixForObject(entry, jsonGenerator);
+ }
+
+ private static void ser(final Map.Entry entry, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider) throws IOException {
+ // this treatment of keys is consistent with the current GraphSONKeySerializer which extends the
+ // StdKeySerializer
+ final Object key = entry.getKey();
+ final Class cls = key.getClass();
+ String k;
+ if (cls == String.class)
+ k = (String) key;
+ else if (Element.class.isAssignableFrom(cls))
+ k = ((Element) key).id().toString();
+ else if(Date.class.isAssignableFrom(cls)) {
+ if (serializerProvider.isEnabled(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS))
+ k = String.valueOf(((Date) key).getTime());
+ else
+ k = serializerProvider.getConfig().getDateFormat().format((Date) key);
+ } else if(cls == Class.class)
+ k = ((Class) key).getName();
+ else
+ k = key.toString();
+
+ serializerProvider.defaultSerializeField(k, entry.getValue(), jsonGenerator);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JsonParserConcat.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JsonParserConcat.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JsonParserConcat.java
new file mode 100644
index 0000000..6b19e48
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JsonParserConcat.java
@@ -0,0 +1,83 @@
+/*
+ * 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.JsonParseException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonParser;
+import org.apache.tinkerpop.shaded.jackson.core.JsonToken;
+import org.apache.tinkerpop.shaded.jackson.core.util.JsonParserSequence;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * Utility class to easily concatenate multiple JsonParsers. This class had to be implemented because the class it is
+ * extending, {@link JsonParserSequence}, inevitably skips a token when switching from one empty parser to a new one.
+ * I.e. it is automatically calling {@link JsonParser#nextToken()} when switching to the new parser, ignoring
+ * the current token.
+ *
+ * This class is used for high performance in GraphSON when trying to detect types.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ */
+public class JsonParserConcat extends JsonParserSequence {
+ protected JsonParserConcat(JsonParser[] parsers) {
+ super(parsers);
+ }
+
+ public static JsonParserConcat createFlattened(JsonParser first, JsonParser second) {
+ if (!(first instanceof JsonParserConcat) && !(second instanceof JsonParserConcat)) {
+ return new JsonParserConcat(new JsonParser[]{first, second});
+ } else {
+ ArrayList p = new ArrayList();
+ if (first instanceof JsonParserConcat) {
+ ((JsonParserConcat) first).addFlattenedActiveParsers(p);
+ } else {
+ p.add(first);
+ }
+
+ if (second instanceof JsonParserConcat) {
+ ((JsonParserConcat) second).addFlattenedActiveParsers(p);
+ } else {
+ p.add(second);
+ }
+ return new JsonParserConcat((JsonParser[]) p.toArray(new JsonParser[p.size()]));
+ }
+ }
+
+ @Override
+ public JsonToken nextToken() throws IOException, JsonParseException {
+ JsonToken t = this.delegate.nextToken();
+ if (t != null) {
+ return t;
+ } else {
+ do {
+ if (!this.switchToNext()) {
+ return null;
+ }
+ // call getCurrentToken() instead of nextToken() in JsonParserSequence.
+ t = this.delegate.getCurrentToken() == null
+ ? this.nextToken()
+ : this.getCurrentToken();
+ } while (t == null);
+
+ return t;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/LegacyGraphSONReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/LegacyGraphSONReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/LegacyGraphSONReader.java
index f015193..679c827 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/LegacyGraphSONReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/LegacyGraphSONReader.java
@@ -19,10 +19,10 @@
package org.apache.tinkerpop.gremlin.structure.io.graphson;
import org.apache.tinkerpop.gremlin.structure.Direction;
-import org.apache.tinkerpop.gremlin.structure.Property;
-import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Graph;
+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.structure.io.GraphReader;