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 2017/07/13 17:27:22 UTC
[05/34] tinkerpop git commit: TINKERPOP-1427 Added g:Map for GraphSON
3.0
TINKERPOP-1427 Added g:Map for GraphSON 3.0
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/60874a59
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/60874a59
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/60874a59
Branch: refs/heads/master
Commit: 60874a59dd0471bcad2c171dd37e5398b15e3f5b
Parents: 12bbbf4
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Sat Jul 1 14:16:57 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Jul 13 12:52:04 2017 -0400
----------------------------------------------------------------------
.../AbstractGraphSONTypeSerializer.java | 173 +++++++++++
.../structure/io/graphson/GraphSONMapper.java | 5 +-
.../structure/io/graphson/GraphSONModule.java | 11 +-
.../structure/io/graphson/GraphSONReader.java | 9 +-
.../io/graphson/GraphSONSerializerProvider.java | 1 -
.../io/graphson/GraphSONSerializersV2d0.java | 2 +-
.../io/graphson/GraphSONSerializersV3d0.java | 28 +-
.../graphson/GraphSONTypeResolverBuilder.java | 10 +-
.../io/graphson/GraphSONTypeSerializer.java | 245 ---------------
.../io/graphson/GraphSONTypeSerializerV2d0.java | 112 +++++++
.../io/graphson/GraphSONTypeSerializerV3d0.java | 139 +++++++++
.../io/graphson/GraphSONXModuleV2d0.java | 8 +-
.../io/graphson/GraphSONXModuleV3d0.java | 8 +-
.../io/graphson/JavaTimeSerializersV3d0.java | 5 +
.../io/graphson/JavaUtilSerializersV3d0.java | 109 +++++--
.../io/graphson/TraversalSerializersV3d0.java | 146 +++++++--
.../star/StarGraphGraphSONSerializerV3d0.java | 165 +++++++++++
.../GraphSONMapperEmbeddedTypeTest.java | 39 ++-
.../GraphSONMapperPartialEmbeddedTypeTest.java | 297 +++++++++++++++++++
.../io/graphson/GraphSONMapperTest.java | 3 +
...aphSONMapperV2d0PartialEmbeddedTypeTest.java | 278 -----------------
.../ser/GraphSONMessageSerializerV3d0Test.java | 25 +-
.../jsr223/PythonGraphSONJavaTranslator.java | 5 +-
.../server/GremlinDriverIntegrateTest.java | 34 +++
.../GremlinServerAuditLogIntegrateTest.java | 2 +
.../server/GremlinServerHttpIntegrateTest.java | 2 +-
.../server/GremlinServerIntegrateTest.java | 2 +-
.../gremlin/structure/io/IoCustomTest.java | 7 +-
.../tinkerpop/gremlin/structure/io/IoTest.java | 4 +-
.../gremlin/structure/io/util/CustomId.java | 64 +++-
.../GraphSONTypedCompatibilityTest.java | 7 +-
.../_3_3_0/authenticationchallenge-v3d0.json | 10 +-
.../_3_3_0/authenticationresponse-v3d0.json | 4 +-
.../io/graphson/_3_3_0/metrics-v3d0.json | 55 ++--
.../structure/io/graphson/_3_3_0/path-v3d0.json | 122 +-------
.../io/graphson/_3_3_0/sessionclose-v3d0.json | 5 +-
.../io/graphson/_3_3_0/sessioneval-v3d0.json | 15 +-
.../_3_3_0/sessionevalaliased-v3d0.json | 21 +-
.../graphson/_3_3_0/sessionlesseval-v3d0.json | 12 +-
.../_3_3_0/sessionlessevalaliased-v3d0.json | 18 +-
.../io/graphson/_3_3_0/standardresult-v3d0.json | 10 +-
.../graphson/_3_3_0/traversalmetrics-v3d0.json | 112 ++++---
.../structure/io/graphson/_3_3_0/tree-v3d0.json | 8 +-
.../structure/TinkerIoRegistryV3d0.java | 3 +-
44 files changed, 1443 insertions(+), 897 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/60874a59/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractGraphSONTypeSerializer.java
----------------------------------------------------------------------
diff --git 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
new file mode 100644
index 0000000..6eb65e1
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractGraphSONTypeSerializer.java
@@ -0,0 +1,173 @@
+/*
+ * 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.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;
+ }
+
+ @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);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/60874a59/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapper.java
index 6b6bbf7..eb3c9ad 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapper.java
@@ -94,9 +94,12 @@ public class GraphSONMapper implements Mapper<ObjectMapper> {
om.findAndRegisterModules();
// graphson 3.0 only allows type - there is no option to remove embedded types
+ if (version == GraphSONVersion.V3_0 && typeInfo == TypeInfo.NO_TYPES)
+ throw new IllegalStateException(String.format("GraphSON 3.0 does not support %s", TypeInfo.NO_TYPES));
+
if (version == GraphSONVersion.V3_0 || (version == GraphSONVersion.V2_0 && typeInfo != TypeInfo.NO_TYPES)) {
final GraphSONTypeIdResolver graphSONTypeIdResolver = new GraphSONTypeIdResolver();
- final TypeResolverBuilder typer = new GraphSONTypeResolverBuilder()
+ final TypeResolverBuilder typer = new GraphSONTypeResolverBuilder(version)
.typesEmbedding(getTypeInfo())
.valuePropertyName(GraphSONTokens.VALUEPROP)
.init(JsonTypeInfo.Id.CUSTOM, graphSONTypeIdResolver)
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/60874a59/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
index 019112b..22dc6b2 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java
@@ -71,6 +71,7 @@ import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import org.apache.tinkerpop.gremlin.structure.util.star.DirectionalStarGraph;
import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializerV1d0;
import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializerV2d0;
+import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializerV3d0;
import org.apache.tinkerpop.gremlin.util.function.Lambda;
import java.time.Duration;
@@ -122,6 +123,9 @@ abstract class GraphSONModule extends TinkerPopJacksonModule {
put(Double.class, "Double");
put(Float.class, "Float");
+ put(Map.Entry.class, "Entry");
+ put(Map.class, "Map");
+
// Tinkerpop Graph objects
put(Lambda.class, "Lambda");
put(Vertex.class, "Vertex");
@@ -196,11 +200,12 @@ abstract class GraphSONModule extends TinkerPopJacksonModule {
addSerializer(TraversalMetrics.class, new GraphSONSerializersV3d0.TraversalMetricsJacksonSerializer());
addSerializer(TraversalExplanation.class, new GraphSONSerializersV3d0.TraversalExplanationJacksonSerializer());
addSerializer(Path.class, new GraphSONSerializersV3d0.PathJacksonSerializer());
- addSerializer(DirectionalStarGraph.class, new StarGraphGraphSONSerializerV2d0(normalize));
+ addSerializer(DirectionalStarGraph.class, new StarGraphGraphSONSerializerV3d0(normalize));
addSerializer(Tree.class, new GraphSONSerializersV3d0.TreeJacksonSerializer());
// java.util
addSerializer(Map.Entry.class, new JavaUtilSerializersV3d0.MapEntryJacksonSerializer());
+ addSerializer(Map.class, new JavaUtilSerializersV3d0.MapJacksonSerializer());
// need to explicitly add serializers for those types because Jackson doesn't do it at all.
addSerializer(Integer.class, new GraphSONSerializersV3d0.IntegerGraphSONSerializer());
@@ -237,6 +242,10 @@ abstract class GraphSONModule extends TinkerPopJacksonModule {
addDeserializer(TraversalMetrics.class, new GraphSONSerializersV3d0.TraversalMetricsJacksonDeserializer());
addDeserializer(Tree.class, new GraphSONSerializersV3d0.TreeJacksonDeserializer());
+ // java.util
+ addDeserializer(Map.Entry.class, new JavaUtilSerializersV3d0.MapEntryJacksonDeserializer());
+ addDeserializer(Map.class, new JavaUtilSerializersV3d0.MapJacksonDeserializer());
+
// numbers
addDeserializer(Integer.class, new GraphSONSerializersV3d0.IntegerJackonsDeserializer());
addDeserializer(Double.class, new GraphSONSerializersV3d0.DoubleJackonsDeserializer());
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/60874a59/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
index 3f63b96..056d3c8 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
@@ -52,6 +52,7 @@ import java.io.OutputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
@@ -73,8 +74,8 @@ public final class GraphSONReader implements GraphReader {
private final GraphSONVersion version;
private boolean unwrapAdjacencyList = false;
- final TypeReference<Map<String, Object>> mapTypeReference = new TypeReference<Map<String, Object>>() {
- };
+ final TypeReference<Map<String, Object>> mapTypeReference = new TypeReference<Map<String, Object>>() {};
+ final TypeReference<LinkedHashMap<String, Object>> linkedHashMapTypeReference = new TypeReference<LinkedHashMap<String, Object>>() {};
private GraphSONReader(final Builder builder) {
mapper = builder.mapper.createMapper();
@@ -173,7 +174,9 @@ public final class GraphSONReader implements GraphReader {
final Function<Attachable<Vertex>, Vertex> vertexAttachMethod,
final Function<Attachable<Edge>, Edge> edgeAttachMethod,
final Direction attachEdgesOfThisDirection) throws IOException {
- final Map<String, Object> vertexData = mapper.readValue(inputStream, mapTypeReference);
+ // graphson v3 has special handling for generic Map instances, by forcing to linkedhashmap (which is probably
+ // what it should have been anyway) stargraph format can remain unchanged across all versions
+ final Map<String, Object> vertexData = mapper.readValue(inputStream, version == GraphSONVersion.V3_0 ? linkedHashMapTypeReference : mapTypeReference);
final StarGraph starGraph = StarGraphGraphSONDeserializer.readStarGraphVertex(vertexData);
if (vertexAttachMethod != null) vertexAttachMethod.apply(starGraph.getStarVertex());
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/60874a59/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializerProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializerProvider.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializerProvider.java
index bd7f966..7744b79 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializerProvider.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializerProvider.java
@@ -44,7 +44,6 @@ final class GraphSONSerializerProvider extends DefaultSerializerProvider {
setDefaultKeySerializer(new GraphSONSerializersV2d0.GraphSONKeySerializer());
unknownTypeSerializer = new ToStringGraphSONSerializer();
} else {
- setDefaultKeySerializer(new GraphSONSerializersV3d0.GraphSONKeySerializer());
unknownTypeSerializer = new ToStringGraphSONSerializer();
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/60874a59/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
index 095bfe6..717dcfa 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
@@ -703,4 +703,4 @@ class GraphSONSerializersV2d0 {
return true;
}
}
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/60874a59/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV3d0.java
index 6f6e011..5fe8e74 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV3d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV3d0.java
@@ -64,6 +64,7 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -610,20 +611,21 @@ class GraphSONSerializersV3d0 {
}
}
- static class MetricsJacksonDeserializer extends AbstractObjectDeserializer<Metrics> {
+ static class MetricsJacksonDeserializer extends StdDeserializer<Metrics> {
public MetricsJacksonDeserializer() {
super(Metrics.class);
}
@Override
- public Metrics createObject(final Map<String, Object> metricsData) {
+ public Metrics deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+ final Map<String, Object> metricsData = deserializationContext.readValue(jsonParser, Map.class);
final MutableMetrics m = new MutableMetrics((String)metricsData.get(GraphSONTokens.ID), (String)metricsData.get(GraphSONTokens.NAME));
m.setDuration(Math.round((Double) metricsData.get(GraphSONTokens.DURATION) * 1000000), TimeUnit.NANOSECONDS);
- for (Map.Entry<String, Long> count : ((Map<String, Long>)metricsData.getOrDefault(GraphSONTokens.COUNTS, new HashMap<>(0))).entrySet()) {
+ for (Map.Entry<String, Long> count : ((Map<String, Long>)metricsData.getOrDefault(GraphSONTokens.COUNTS, new LinkedHashMap<>(0))).entrySet()) {
m.setCount(count.getKey(), count.getValue());
}
- for (Map.Entry<String, Long> count : ((Map<String, Long>) metricsData.getOrDefault(GraphSONTokens.ANNOTATIONS, new HashMap<>(0))).entrySet()) {
+ for (Map.Entry<String, Long> count : ((Map<String, Long>) metricsData.getOrDefault(GraphSONTokens.ANNOTATIONS, new LinkedHashMap<>(0))).entrySet()) {
m.setAnnotation(count.getKey(), count.getValue());
}
for (MutableMetrics nested : (List<MutableMetrics>)metricsData.getOrDefault(GraphSONTokens.METRICS, new ArrayList<>(0))) {
@@ -631,21 +633,33 @@ class GraphSONSerializersV3d0 {
}
return m;
}
+
+ @Override
+ public boolean isCachable() {
+ return true;
+ }
}
- static class TraversalMetricsJacksonDeserializer extends AbstractObjectDeserializer<TraversalMetrics> {
+ static class TraversalMetricsJacksonDeserializer extends StdDeserializer<TraversalMetrics> {
public TraversalMetricsJacksonDeserializer() {
super(TraversalMetrics.class);
}
@Override
- public TraversalMetrics createObject(final Map<String, Object> traversalMetricsData) {
+ public TraversalMetrics deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+ final Map<String, Object> traversalMetricsData = deserializationContext.readValue(jsonParser, Map.class);
+
return new DefaultTraversalMetrics(
Math.round((Double) traversalMetricsData.get(GraphSONTokens.DURATION) * 1000000),
(List<MutableMetrics>) traversalMetricsData.get(GraphSONTokens.METRICS)
);
}
+
+ @Override
+ public boolean isCachable() {
+ return true;
+ }
}
static class TreeJacksonDeserializer extends StdDeserializer<Tree> {
@@ -703,4 +717,4 @@ class GraphSONSerializersV3d0 {
return true;
}
}
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/60874a59/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
index 7d3d03c..0da512e 100644
--- 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
@@ -34,11 +34,17 @@ import java.util.Collection;
* deserializers. Contains the typeInfo level that should be provided by the GraphSONMapper.
*
* @author Kevin Gallardo (https://kgdo.me)
+ * @author Stephen Mallette (http://stephen.genoprime.com)
*/
public class GraphSONTypeResolverBuilder extends StdTypeResolverBuilder {
private TypeInfo typeInfo;
private String valuePropertyName;
+ private final GraphSONVersion version;
+
+ public GraphSONTypeResolverBuilder(final GraphSONVersion version) {
+ this.version = version;
+ }
@Override
public TypeDeserializer buildTypeDeserializer(final DeserializationConfig config, final JavaType baseType,
@@ -52,7 +58,9 @@ public class GraphSONTypeResolverBuilder extends StdTypeResolverBuilder {
public TypeSerializer buildTypeSerializer(final SerializationConfig config, final JavaType baseType,
final Collection<NamedType> subtypes) {
final TypeIdResolver idRes = this.idResolver(config, baseType, subtypes, true, false);
- return new GraphSONTypeSerializer(idRes, this.getTypeProperty(), typeInfo, valuePropertyName);
+ return version == GraphSONVersion.V2_0 ?
+ new GraphSONTypeSerializerV2d0(idRes, this.getTypeProperty(), typeInfo, valuePropertyName) :
+ new GraphSONTypeSerializerV3d0(idRes, this.getTypeProperty(), typeInfo, valuePropertyName);
}
public GraphSONTypeResolverBuilder valuePropertyName(final String valuePropertyName) {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/60874a59/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
deleted file mode 100644
index 78c670a..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java
+++ /dev/null
@@ -1,245 +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.process.traversal.Operator;
-import org.apache.tinkerpop.gremlin.process.traversal.Order;
-import org.apache.tinkerpop.gremlin.process.traversal.Path;
-import org.apache.tinkerpop.gremlin.process.traversal.Pop;
-import org.apache.tinkerpop.gremlin.process.traversal.SackFunctions;
-import org.apache.tinkerpop.gremlin.process.traversal.Scope;
-import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
-import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent;
-import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
-import org.apache.tinkerpop.gremlin.structure.Column;
-import org.apache.tinkerpop.gremlin.structure.Direction;
-import org.apache.tinkerpop.gremlin.structure.Edge;
-import org.apache.tinkerpop.gremlin.structure.Property;
-import org.apache.tinkerpop.gremlin.structure.T;
-import org.apache.tinkerpop.gremlin.structure.Vertex;
-import org.apache.tinkerpop.gremlin.structure.VertexProperty;
-import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
-import org.apache.tinkerpop.gremlin.util.function.Lambda;
-import org.apache.tinkerpop.shaded.jackson.annotation.JsonTypeInfo;
-import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
-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.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Extension of the Jackson's default TypeSerializer. An instance of this object will be passed to the serializers
- * 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;
- private final Map<Class, Class> classMap = new HashMap<>();
-
- GraphSONTypeSerializer(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;
- }
-
- @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);
- }
-
- private boolean canWriteTypeId() {
- return typeInfo != null
- && typeInfo == TypeInfo.PARTIAL_TYPES;
- }
-
- private void writeTypePrefix(final JsonGenerator jsonGenerator, final String s) throws IOException {
- jsonGenerator.writeStartObject();
- jsonGenerator.writeStringField(this.getPropertyName(), s);
- jsonGenerator.writeFieldName(this.valuePropertyName);
- }
-
- private 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..)
- */
- private 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/60874a59/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV2d0.java
----------------------------------------------------------------------
diff --git 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
new file mode 100644
index 0000000..993f110
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV2d0.java
@@ -0,0 +1,112 @@
+/*
+ * 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.databind.jsontype.TypeIdResolver;
+
+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
+ 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/60874a59/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV3d0.java
----------------------------------------------------------------------
diff --git 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
new file mode 100644
index 0000000..246d38f
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializerV3d0.java
@@ -0,0 +1,139 @@
+/*
+ * 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.databind.jsontype.TypeIdResolver;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.util.Map;
+
+/**
+ * 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 || o instanceof Map.Entry) {
+ writeTypePrefix(jsonGenerator, getTypeIdResolver().idFromValueAndType(o, getClassFromObject(o)));
+ jsonGenerator.writeStartArray();
+ } else {
+ jsonGenerator.writeStartObject();
+ }
+ }
+
+ @Override
+ public void writeTypeSuffixForObject(final Object o, final JsonGenerator jsonGenerator) throws IOException {
+ if (o instanceof Map || o instanceof Map.Entry) {
+ jsonGenerator.writeEndArray();
+ writeTypeSuffix(jsonGenerator);
+ } else {
+ jsonGenerator.writeEndObject();
+ }
+ }
+
+ @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))
+ mapped = Map.class;
+ else if (Map.Entry.class.isAssignableFrom(c))
+ mapped = Map.Entry.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/60874a59/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV2d0.java
index 336d11c..0d4ba53 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV2d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV2d0.java
@@ -18,10 +18,6 @@
*/
package org.apache.tinkerpop.gremlin.structure.io.graphson;
-/**
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
@@ -45,6 +41,8 @@ import java.util.Map;
/**
* Version 2.0 of GraphSON extensions.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
*/
public final class GraphSONXModuleV2d0 extends GraphSONModule {
@@ -139,4 +137,4 @@ public final class GraphSONXModuleV2d0 extends GraphSONModule {
return new GraphSONXModuleV2d0(normalize);
}
}
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/60874a59/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV3d0.java
index 777c6c4..38caa09 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV3d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV3d0.java
@@ -18,10 +18,6 @@
*/
package org.apache.tinkerpop.gremlin.structure.io.graphson;
-/**
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
@@ -45,6 +41,8 @@ import java.util.Map;
/**
* Version 3.0 of GraphSON extensions.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
*/
public final class GraphSONXModuleV3d0 extends GraphSONModule {
@@ -139,4 +137,4 @@ public final class GraphSONXModuleV3d0 extends GraphSONModule {
return new GraphSONXModuleV3d0(normalize);
}
}
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/60874a59/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV3d0.java
index 1cb75e0..c1668e2 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV3d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV3d0.java
@@ -85,6 +85,11 @@ final class JavaTimeSerializersV3d0 {
public T deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException {
return parse(jsonParser.getText());
}
+
+ @Override
+ public boolean isCachable() {
+ return true;
+ }
}
final static class DurationJacksonSerializer extends AbstractJavaTimeSerializer<Duration> {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/60874a59/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV3d0.java
index 816a3f7..900eeb8 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV3d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV3d0.java
@@ -18,16 +18,22 @@
*/
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.core.JsonParser;
+import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonToken;
+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.StdScalarSerializer;
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.LinkedHashMap;
import java.util.Map;
+import java.util.Set;
/**
* GraphSON serializers for classes in {@code java.util.*} for the version 3.0 of GraphSON.
@@ -36,6 +42,31 @@ final class JavaUtilSerializersV3d0 {
private JavaUtilSerializersV3d0() {}
+ ////////////////////////////// SERIALIZERS /////////////////////////////////
+
+ final static class MapJacksonSerializer extends StdSerializer<Map> {
+ public MapJacksonSerializer() {
+ super(Map.class);
+ }
+
+ @Override
+ public void serialize(final Map map, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+ throws IOException {
+ for(Map.Entry entry : (Set<Map.Entry>) map.entrySet()) {
+ jsonGenerator.writeObject(entry.getKey());
+ jsonGenerator.writeObject(entry.getValue());
+ }
+ }
+
+ @Override
+ public void serializeWithType(final Map map, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+ typeSerializer.writeTypePrefixForObject(map, jsonGenerator);
+ serialize(map, jsonGenerator, serializerProvider);
+ typeSerializer.writeTypeSuffixForObject(map, jsonGenerator);
+ }
+ }
+
final static class MapEntryJacksonSerializer extends StdSerializer<Map.Entry> {
public MapEntryJacksonSerializer() {
@@ -45,41 +76,61 @@ final class JavaUtilSerializersV3d0 {
@Override
public void serialize(final Map.Entry entry, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
throws IOException {
- jsonGenerator.writeStartObject();
- ser(entry, jsonGenerator, serializerProvider);
- jsonGenerator.writeEndObject();
+ jsonGenerator.writeObject(entry.getKey());
+ jsonGenerator.writeObject(entry.getValue());
}
@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);
+ serialize(entry, jsonGenerator, serializerProvider);
typeSerializer.writeTypeSuffixForObject(entry, jsonGenerator);
}
+ }
+
+ ////////////////////////////// DESERIALIZERS /////////////////////////////////
+
+
+ static class MapJacksonDeserializer extends StdDeserializer<Map> {
+
+ protected MapJacksonDeserializer() {
+ super(Map.class);
+ }
+
+ @Override
+ public Map deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+ final Map<Object,Object> m = new LinkedHashMap<>();
+
+ while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
+ final Object key = deserializationContext.readValue(jsonParser, Object.class);
+ jsonParser.nextToken();
+ final Object val = deserializationContext.readValue(jsonParser, Object.class);
+ m.put(key, val);
+ }
+
+ return m;
+ }
+ }
+
+ static class MapEntryJacksonDeserializer extends StdDeserializer<Map.Entry> {
+
+ protected MapEntryJacksonDeserializer() {
+ super(Map.Entry.class);
+ }
+
+ @Override
+ public Map.Entry deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+ final Map<Object,Object> m = new HashMap<>();
+
+ while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
+ final Object key = deserializationContext.readValue(jsonParser, Object.class);
+ jsonParser.nextToken();
+ final Object val = deserializationContext.readValue(jsonParser, Object.class);
+ m.put(key, val);
+ }
- 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);
+ return m.entrySet().iterator().next();
}
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/60874a59/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java
index e4f6df9..57b6736 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java
@@ -35,14 +35,19 @@ import org.apache.tinkerpop.gremlin.util.function.Lambda;
import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
import org.apache.tinkerpop.shaded.jackson.core.JsonParser;
import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonToken;
import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
+import org.apache.tinkerpop.shaded.jackson.databind.JavaType;
+import org.apache.tinkerpop.shaded.jackson.databind.JsonNode;
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.StdScalarSerializer;
import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.type.TypeFactory;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@@ -242,29 +247,40 @@ final class TraversalSerializersV3d0 {
// DESERIALIZERS //
//////////////////
- final static class BytecodeJacksonDeserializer extends AbstractObjectDeserializer<Bytecode> {
+ final static class BytecodeJacksonDeserializer extends StdDeserializer<Bytecode> {
+ private static final JavaType listJavaType = TypeFactory.defaultInstance().constructCollectionType(ArrayList.class, Object.class);
+ private static final JavaType listListJavaType = TypeFactory.defaultInstance().constructCollectionType(ArrayList.class, listJavaType);
public BytecodeJacksonDeserializer() {
super(Bytecode.class);
}
@Override
- public Bytecode createObject(final Map<String, Object> data) {
+ public Bytecode deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
final Bytecode bytecode = new Bytecode();
- if (data.containsKey(GraphSONTokens.SOURCE)) {
- final List<List<Object>> instructions = (List) data.get(GraphSONTokens.SOURCE);
- for (final List<Object> instruction : instructions) {
- bytecode.addSource((String) instruction.get(0), Arrays.copyOfRange(instruction.toArray(), 1, instruction.size()));
- }
- }
- if (data.containsKey(GraphSONTokens.STEP)) {
- final List<List<Object>> instructions = (List) data.get(GraphSONTokens.STEP);
- for (final List<Object> instruction : instructions) {
- bytecode.addStep((String) instruction.get(0), Arrays.copyOfRange(instruction.toArray(), 1, instruction.size()));
+
+ while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+ if (jsonParser.getCurrentName().equals(GraphSONTokens.SOURCE)) {
+ jsonParser.nextToken();
+ final List<List<Object>> instructions = deserializationContext.readValue(jsonParser, listListJavaType);
+ for (final List<Object> instruction : instructions) {
+ bytecode.addSource((String) instruction.get(0), Arrays.copyOfRange(instruction.toArray(), 1, instruction.size()));
+ }
+ } else if (jsonParser.getCurrentName().equals(GraphSONTokens.STEP)) {
+ jsonParser.nextToken();
+ final List<List<Object>> instructions = deserializationContext.readValue(jsonParser, listListJavaType);
+ for (final List<Object> instruction : instructions) {
+ bytecode.addStep((String) instruction.get(0), Arrays.copyOfRange(instruction.toArray(), 1, instruction.size()));
+ }
}
}
return bytecode;
}
+
+ @Override
+ public boolean isCachable() {
+ return true;
+ }
}
final static class EnumJacksonDeserializer<A extends Enum> extends StdDeserializer<A> {
@@ -283,18 +299,34 @@ final class TraversalSerializersV3d0 {
}
throw new IOException("Unknown enum type: " + enumClass);
}
+
+ @Override
+ public boolean isCachable() {
+ return true;
+ }
}
- final static class PJacksonDeserializer extends AbstractObjectDeserializer<P> {
+ final static class PJacksonDeserializer extends StdDeserializer<P> {
public PJacksonDeserializer() {
super(P.class);
}
@Override
- public P createObject(final Map<String, Object> data) {
- final String predicate = (String) data.get(GraphSONTokens.PREDICATE);
- final Object value = data.get(GraphSONTokens.VALUE);
+ public P deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+ String predicate = null;
+ Object value = null;
+
+ while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+ if (jsonParser.getCurrentName().equals(GraphSONTokens.PREDICATE)) {
+ jsonParser.nextToken();
+ predicate = jsonParser.getText();
+ } else if (jsonParser.getCurrentName().equals(GraphSONTokens.VALUE)) {
+ jsonParser.nextToken();
+ value = deserializationContext.readValue(jsonParser, Object.class);
+ }
+ }
+
if (predicate.equals(GraphSONTokens.AND) || predicate.equals(GraphSONTokens.OR)) {
return predicate.equals(GraphSONTokens.AND) ? new AndP((List<P>) value) : new OrP((List<P>) value);
} else {
@@ -324,20 +356,38 @@ final class TraversalSerializersV3d0 {
}
}
}
+
+ @Override
+ public boolean isCachable() {
+ return true;
+ }
}
- final static class LambdaJacksonDeserializer extends AbstractObjectDeserializer<Lambda> {
+ final static class LambdaJacksonDeserializer extends StdDeserializer<Lambda> {
public LambdaJacksonDeserializer() {
super(Lambda.class);
}
@Override
- public Lambda createObject(final Map<String, Object> data) {
- final String script = (String) data.get(GraphSONTokens.SCRIPT);
- final String language = (String) data.get(GraphSONTokens.LANGUAGE);
- final int arguments = ((Number) data.getOrDefault(GraphSONTokens.ARGUMENTS, -1)).intValue();
- //
+ public Lambda deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+ String script = null;
+ String language = null;
+ int arguments = -1;
+
+ while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+ if (jsonParser.getCurrentName().equals(GraphSONTokens.SCRIPT)) {
+ jsonParser.nextToken();
+ script = jsonParser.getText();
+ } else if (jsonParser.getCurrentName().equals(GraphSONTokens.LANGUAGE)) {
+ jsonParser.nextToken();
+ language = jsonParser.getText();
+ } else if (jsonParser.getCurrentName().equals(GraphSONTokens.ARGUMENTS)) {
+ jsonParser.nextToken();
+ arguments = jsonParser.getIntValue();
+ }
+ }
+
if (-1 == arguments || arguments > 2)
return new Lambda.UnknownArgLambda(script, language, arguments);
else if (0 == arguments)
@@ -347,29 +397,69 @@ final class TraversalSerializersV3d0 {
else
return new Lambda.TwoArgLambda<>(script, language);
}
+
+ @Override
+ public boolean isCachable() {
+ return true;
+ }
}
- final static class BindingJacksonDeserializer extends AbstractObjectDeserializer<Bytecode.Binding> {
+ final static class BindingJacksonDeserializer extends StdDeserializer<Bytecode.Binding> {
public BindingJacksonDeserializer() {
super(Bytecode.Binding.class);
}
@Override
- public Bytecode.Binding createObject(final Map<String, Object> data) {
- return new Bytecode.Binding<>((String) data.get(GraphSONTokens.KEY), data.get(GraphSONTokens.VALUE));
+ public Bytecode.Binding deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+ String k = null;
+ Object v = null;
+
+ while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+ if (jsonParser.getCurrentName().equals(GraphSONTokens.KEY)) {
+ jsonParser.nextToken();
+ k = jsonParser.getText();
+ } else if (jsonParser.getCurrentName().equals(GraphSONTokens.VALUE)) {
+ jsonParser.nextToken();
+ v = deserializationContext.readValue(jsonParser, Object.class);
+ }
+ }
+ return new Bytecode.Binding<>(k, v);
+ }
+
+ @Override
+ public boolean isCachable() {
+ return true;
}
}
- static class TraverserJacksonDeserializer extends AbstractObjectDeserializer<Traverser> {
+ static class TraverserJacksonDeserializer extends StdDeserializer<Traverser> {
public TraverserJacksonDeserializer() {
super(Traverser.class);
}
@Override
- public Traverser createObject(final Map<String, Object> data) {
- return new DefaultRemoteTraverser<>(data.get(GraphSONTokens.VALUE), (Long) data.get(GraphSONTokens.BULK));
+ public Traverser deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+ long bulk = 1;
+ Object v = null;
+
+ while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+ if (jsonParser.getCurrentName().equals(GraphSONTokens.BULK)) {
+ jsonParser.nextToken();
+ bulk = deserializationContext.readValue(jsonParser, Long.class);
+ } else if (jsonParser.getCurrentName().equals(GraphSONTokens.VALUE)) {
+ jsonParser.nextToken();
+ v = deserializationContext.readValue(jsonParser, Object.class);
+ }
+ }
+
+ return new DefaultRemoteTraverser<>(v, bulk);
+ }
+
+ @Override
+ public boolean isCachable() {
+ return true;
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/60874a59/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV3d0.java
new file mode 100644
index 0000000..9a9682c
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV3d0.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.structure.util.star;
+
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONUtil;
+import org.apache.tinkerpop.gremlin.structure.util.Comparators;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerationException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class StarGraphGraphSONSerializerV3d0 extends StdSerializer<DirectionalStarGraph> {
+ private final boolean normalize;
+ public StarGraphGraphSONSerializerV3d0(final boolean normalize) {
+ super(DirectionalStarGraph.class);
+ this.normalize = normalize;
+ }
+
+ @Override
+ public void serialize(final DirectionalStarGraph starGraph, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider) throws IOException, JsonGenerationException {
+ ser(starGraph, jsonGenerator, serializerProvider, null);
+ }
+
+ @Override
+ public void serializeWithType(final DirectionalStarGraph starGraph, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider,
+ final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
+ ser(starGraph, jsonGenerator, serializerProvider, typeSerializer);
+ }
+
+ private void ser(final DirectionalStarGraph directionalStarGraph, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider,
+ final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
+ final StarGraph starGraph = directionalStarGraph.getStarGraphToSerialize();
+ GraphSONUtil.writeStartObject(starGraph, jsonGenerator, typeSerializer);
+ GraphSONUtil.writeWithType(GraphSONTokens.ID, starGraph.starVertex.id, jsonGenerator, serializerProvider, typeSerializer);
+ jsonGenerator.writeStringField(GraphSONTokens.LABEL, starGraph.starVertex.label);
+ if (directionalStarGraph.getDirection() != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.IN);
+ if (directionalStarGraph.getDirection() != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.OUT);
+ if (starGraph.starVertex.vertexProperties != null && !starGraph.starVertex.vertexProperties.isEmpty()) {
+ jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+ GraphSONUtil.writeStartObject(starGraph, jsonGenerator, typeSerializer);
+ final Set<String> keys = normalize ? new TreeSet<>(starGraph.starVertex.vertexProperties.keySet()) : starGraph.starVertex.vertexProperties.keySet();
+ for (final String k : keys) {
+ final List<VertexProperty> vp = starGraph.starVertex.vertexProperties.get(k);
+ jsonGenerator.writeFieldName(k);
+ GraphSONUtil.writeStartArray(k, jsonGenerator, typeSerializer);
+
+ final List<VertexProperty> vertexProperties = normalize ?sort(vp, Comparators.PROPERTY_COMPARATOR) : vp;
+ for (final VertexProperty property : vertexProperties) {
+ GraphSONUtil.writeStartObject(property, jsonGenerator, typeSerializer);
+ GraphSONUtil.writeWithType(GraphSONTokens.ID, property.id(), jsonGenerator, serializerProvider, typeSerializer);
+ GraphSONUtil.writeWithType(GraphSONTokens.VALUE, property.value(), jsonGenerator, serializerProvider, typeSerializer);
+
+ final Iterator<Property> metaProperties = normalize ?
+ IteratorUtils.list(property.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : property.properties();
+ if (metaProperties.hasNext()) {
+ jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+ GraphSONUtil.writeStartObject(metaProperties, jsonGenerator, typeSerializer);
+
+ while (metaProperties.hasNext()) {
+ final Property<Object> meta = metaProperties.next();
+ GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
+ }
+ GraphSONUtil.writeEndObject(metaProperties, jsonGenerator, typeSerializer);
+ }
+ GraphSONUtil.writeEndObject(property, jsonGenerator, typeSerializer);
+ }
+ GraphSONUtil.writeEndArray(k, jsonGenerator, typeSerializer);
+ }
+ GraphSONUtil.writeEndObject(starGraph, jsonGenerator, typeSerializer);
+ }
+ GraphSONUtil.writeEndObject(starGraph, jsonGenerator, typeSerializer);
+ }
+
+ private void writeEdges(final DirectionalStarGraph directionalStarGraph, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider,
+ final TypeSerializer typeSerializer,
+ final Direction direction) throws IOException, JsonProcessingException {
+ // only write edges if there are some AND if the user requested them to be serialized AND if they match
+ // the direction being serialized by the format
+ final StarGraph starGraph = directionalStarGraph.getStarGraphToSerialize();
+ final Direction edgeDirectionToSerialize = directionalStarGraph.getDirection();
+ final Map<String, List<Edge>> starEdges = direction.equals(Direction.OUT) ? starGraph.starVertex.outEdges : starGraph.starVertex.inEdges;
+ final boolean writeEdges = null != starEdges && edgeDirectionToSerialize != null
+ && (edgeDirectionToSerialize == direction || edgeDirectionToSerialize == Direction.BOTH);
+ if (writeEdges) {
+ jsonGenerator.writeFieldName(direction == Direction.IN ? GraphSONTokens.IN_E : GraphSONTokens.OUT_E);
+ GraphSONUtil.writeStartObject(directionalStarGraph, jsonGenerator, typeSerializer);
+ final Set<String> keys = normalize ? new TreeSet<>(starEdges.keySet()) : starEdges.keySet();
+ for (final String k : keys) {
+ final List<Edge> edges = starEdges.get(k);
+ jsonGenerator.writeFieldName(k);
+ GraphSONUtil.writeStartArray(k, jsonGenerator, typeSerializer);
+
+ final List<Edge> edgesToWrite = normalize ? sort(edges, Comparators.EDGE_COMPARATOR) : edges;
+ for (final Edge edge : edgesToWrite) {
+ GraphSONUtil.writeStartObject(edge, jsonGenerator, typeSerializer);
+ GraphSONUtil.writeWithType(GraphSONTokens.ID, edge.id(), jsonGenerator, serializerProvider, typeSerializer);
+ GraphSONUtil.writeWithType(direction.equals(Direction.OUT) ? GraphSONTokens.IN : GraphSONTokens.OUT,
+ direction.equals(Direction.OUT) ? edge.inVertex().id() : edge.outVertex().id(),
+ jsonGenerator, serializerProvider, typeSerializer);
+
+ final Iterator<Property<Object>> edgeProperties = normalize ?
+ IteratorUtils.list(edge.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : edge.properties();
+ if (edgeProperties.hasNext()) {
+ jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+ GraphSONUtil.writeStartObject(edge, jsonGenerator, typeSerializer);
+ while (edgeProperties.hasNext()) {
+ final Property<Object> meta = edgeProperties.next();
+ GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
+ }
+ GraphSONUtil.writeEndObject(edge, jsonGenerator, typeSerializer);
+ }
+ GraphSONUtil.writeEndObject(edge, jsonGenerator, typeSerializer);
+ }
+ GraphSONUtil.writeEndArray(k, jsonGenerator, typeSerializer);
+ }
+ GraphSONUtil.writeEndObject(directionalStarGraph, jsonGenerator, typeSerializer);
+ }
+ }
+
+ private static <S> List<S> sort(final List<S> listToSort, final Comparator comparator) {
+ Collections.sort(listToSort, comparator);
+ return listToSort;
+ }
+
+}