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/06/30 17:34:10 UTC
[41/50] [abbrv] tinkerpop git commit: TINKERPOP-1274: GraphSON 2.0.
TINKERPOP-1274: GraphSON 2.0.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/b44ec666
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/b44ec666
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/b44ec666
Branch: refs/heads/TINKERPOP-1274
Commit: b44ec666f846d9acc7b0223887cb0b5e2e0789bd
Parents: 0554b59
Author: Kevin Gallardo <ke...@datastax.com>
Authored: Tue Jun 28 19:38:32 2016 +0100
Committer: Kevin Gallardo <ke...@datastax.com>
Committed: Thu Jun 30 10:39:47 2016 +0100
----------------------------------------------------------------------
.../structure/io/graphson/GraphSONIo.java | 6 +-
.../structure/io/graphson/GraphSONMapper.java | 78 ++-
.../structure/io/graphson/GraphSONModule.java | 106 ++---
.../structure/io/graphson/GraphSONReader.java | 23 +-
.../io/graphson/GraphSONSerializerProvider.java | 28 +-
.../io/graphson/GraphSONSerializersV1d0.java | 16 +-
.../io/graphson/GraphSONSerializersV2d0.java | 467 ++++++++++++++++++
.../io/graphson/GraphSONTypeDeserializer.java | 201 ++++++++
.../io/graphson/GraphSONTypeIdResolver.java | 134 ++++++
.../graphson/GraphSONTypeResolverBuilder.java | 60 +++
.../io/graphson/GraphSONTypeSerializer.java | 160 +++++++
.../structure/io/graphson/GraphSONUtil.java | 29 ++
.../structure/io/graphson/GraphSONWriter.java | 12 +-
.../io/graphson/JavaTimeSerializersV1d0.java | 14 +-
.../io/graphson/JavaTimeSerializersV2d0.java | 311 ++++++++++++
.../io/graphson/JavaUtilSerializersV2d0.java | 116 +++++
.../structure/io/graphson/JsonParserConcat.java | 81 ++++
.../io/graphson/LegacyGraphSONReader.java | 14 +-
.../io/graphson/TinkerPopJacksonModule.java | 59 +++
.../io/graphson/ToStringGraphSONSerializer.java | 41 ++
.../util/star/DirectionalStarGraph.java | 39 ++
.../star/StarGraphGraphSONDeserializer.java | 91 ++++
.../util/star/StarGraphGraphSONSerializer.java | 250 ----------
.../star/StarGraphGraphSONSerializerV1d0.java | 167 +++++++
.../star/StarGraphGraphSONSerializerV2d0.java | 158 +++++++
...aphSONMapperV2d0PartialEmbeddedTypeTest.java | 292 ++++++++++++
.../io/graphson/GraphSONMapperV2d0Test.java | 171 +++++++
.../AbstractGraphSONMessageSerializerV2d0.java | 248 ++++++++++
.../GraphSONMessageSerializerGremlinV2d0.java | 68 +++
.../ser/GraphSONMessageSerializerV2d0.java | 124 +++++
...raphSONMessageSerializerGremlinV2d0Test.java | 321 +++++++++++++
.../ser/GraphSONMessageSerializerV2d0Test.java | 474 +++++++++++++++++++
.../structure/TinkerIoRegistryV2d0.java | 227 +++++++++
.../structure/IoDataGenerationTest.java | 109 ++++-
.../TinkerGraphGraphSONSerializerV2d0Test.java | 156 ++++++
35 files changed, 4444 insertions(+), 407 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONIo.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONIo.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONIo.java
index 0354a11..31cc6f2 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONIo.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONIo.java
@@ -22,11 +22,7 @@ import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.io.Io;
import org.apache.tinkerpop.gremlin.structure.io.IoRegistry;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.*;
/**
* Constructs GraphSON IO implementations given a {@link Graph} and {@link IoRegistry}. Implementers of the {@link Graph}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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 be5377a..8f20ef7 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
@@ -33,6 +33,7 @@ import org.javatuples.Pair;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
/**
* An extension to the standard Jackson {@code ObjectMapper} which automatically registers the standard
@@ -60,14 +61,17 @@ public class GraphSONMapper implements Mapper<ObjectMapper> {
private final boolean normalize;
private final boolean embedTypes;
private final GraphSONVersion version;
+ private final TypeInfo typeInfo;
private GraphSONMapper(final List<SimpleModule> customModules, final boolean loadCustomSerializers,
- final boolean normalize, final boolean embedTypes, final GraphSONVersion version) {
+ final boolean normalize, final boolean embedTypes, final GraphSONVersion version,
+ final TypeInfo typeInfo) {
this.customModules = customModules;
this.loadCustomSerializers = loadCustomSerializers;
this.normalize = normalize;
this.embedTypes = embedTypes;
this.version = version;
+ this.typeInfo = typeInfo;
}
@Override
@@ -75,6 +79,16 @@ public class GraphSONMapper implements Mapper<ObjectMapper> {
final ObjectMapper om = new ObjectMapper();
om.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
+ GraphSONModule graphSONModule = version.getBuilder().create(normalize);
+ om.registerModule(graphSONModule);
+ customModules.forEach(om::registerModule);
+
+
+ // plugin external serialization modules
+ if (loadCustomSerializers)
+ om.findAndRegisterModules();
+
+
if (version == GraphSONVersion.V1_0) {
if (embedTypes) {
final TypeResolverBuilder<?> typer = new StdTypeResolverBuilder()
@@ -84,29 +98,41 @@ public class GraphSONMapper implements Mapper<ObjectMapper> {
om.setDefaultTyping(typer);
}
} else if (version == GraphSONVersion.V2_0) {
+ if (typeInfo != TypeInfo.NO_TYPES) {
+ GraphSONTypeIdResolver graphSONTypeIdResolver = new GraphSONTypeIdResolver();
+ final TypeResolverBuilder typer = new GraphSONTypeResolverBuilder()
+ .typesEmbedding(getTypeInfo())
+ .init(JsonTypeInfo.Id.CUSTOM, graphSONTypeIdResolver)
+ .typeProperty(GraphSONTokens.CLASS);
+ // Register types to typeResolver for the GraphSON module
+ for (Map.Entry<String, Class> typeDeser : graphSONModule.getAddedDeserializers().entrySet()) {
+ graphSONTypeIdResolver.addCustomType(typeDeser.getKey(), typeDeser.getValue());
+ }
+
+ // Register types to typeResolver for the Custom modules
+ customModules.forEach(e -> {
+ if (e instanceof TinkerPopJacksonModule) {
+ for (Map.Entry<String, Class> typeDeser : ((TinkerPopJacksonModule) e).getAddedDeserializers().entrySet()) {
+ graphSONTypeIdResolver.addCustomType(typeDeser.getKey(), typeDeser.getValue());
+ }
+ }
+ });
+ om.setDefaultTyping(typer);
+ }
} else {
- throw new IllegalStateException("Unknown GraphSONVersion");
+ throw new IllegalStateException("Unknown GraphSONVersion : " + version);
}
- if (normalize)
- om.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS);
-
// this provider toStrings all unknown classes and converts keys in Map objects that are Object to String.
- final DefaultSerializerProvider provider = new GraphSONSerializerProvider();
- provider.setDefaultKeySerializer(new GraphSONSerializersV1d0.GraphSONKeySerializer());
+ final DefaultSerializerProvider provider = new GraphSONSerializerProvider(version);
om.setSerializerProvider(provider);
- om.registerModule(version.getBuilder().create(normalize));
- customModules.forEach(om::registerModule);
-
- // plugin external serialization modules
- if (loadCustomSerializers)
- om.findAndRegisterModules();
+ if (normalize)
+ om.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS);
// keep streams open to accept multiple values (e.g. multiple vertices)
om.getFactory().disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
-
return om;
}
@@ -118,6 +144,15 @@ public class GraphSONMapper implements Mapper<ObjectMapper> {
return new Builder();
}
+ public TypeInfo getTypeInfo() {
+ return this.typeInfo;
+ }
+
+ public enum TypeInfo {
+ NO_TYPES,
+ PARTIAL_TYPES
+ }
+
public static class Builder implements Mapper.Builder<Builder> {
private List<SimpleModule> customModules = new ArrayList<>();
private boolean loadCustomModules = false;
@@ -125,6 +160,8 @@ public class GraphSONMapper implements Mapper<ObjectMapper> {
private boolean embedTypes = false;
private List<IoRegistry> registries = new ArrayList<>();
private GraphSONVersion version = GraphSONVersion.V1_0;
+ // GraphSON 2.0 should have types activated by default, otherwise use there's no point in using it instead of 1.0.
+ private TypeInfo typeInfo = TypeInfo.PARTIAL_TYPES;
private Builder() {
}
@@ -187,13 +224,24 @@ public class GraphSONMapper implements Mapper<ObjectMapper> {
return this;
}
+ /**
+ * Specify if the values are going to be typed or not, and at which level.
+ *
+ * The level can be NO_TYPES or PARTIAL_TYPES, and could be extended in the future.
+ */
+ public Builder typeInfo(final TypeInfo typeInfo) {
+ this.typeInfo = typeInfo;
+ return this;
+ }
+
public GraphSONMapper create() {
registries.forEach(registry -> {
final List<Pair<Class, SimpleModule>> simpleModules = registry.find(GraphSONIo.class, SimpleModule.class);
simpleModules.stream().map(Pair::getValue1).forEach(this.customModules::add);
});
- return new GraphSONMapper(customModules, loadCustomModules, normalize, embedTypes, version);
+ return new GraphSONMapper(customModules, loadCustomModules, normalize, embedTypes, version, typeInfo);
}
+
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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 639e90d..06630f4 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
@@ -19,30 +19,20 @@
package org.apache.tinkerpop.gremlin.structure.io.graphson;
import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation;
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.gremlin.structure.util.star.StarGraphGraphSONSerializer;
-import org.apache.tinkerpop.shaded.jackson.databind.module.SimpleModule;
-
-import java.time.Duration;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.MonthDay;
-import java.time.OffsetDateTime;
-import java.time.OffsetTime;
-import java.time.Period;
-import java.time.Year;
-import java.time.YearMonth;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
+import 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 java.nio.ByteBuffer;
+import java.time.*;
import java.util.Map;
-import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
/**
* The set of serializers that handle the core graph interfaces. These serializers support normalization which
@@ -54,7 +44,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
*
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
-abstract class GraphSONModule extends SimpleModule {
+abstract class GraphSONModule extends TinkerPopJacksonModule {
GraphSONModule(final String name) {
super(name);
@@ -64,54 +54,55 @@ abstract class GraphSONModule extends SimpleModule {
* Version 2.0 of GraphSON.
*/
static final class GraphSONModuleV2d0 extends GraphSONModule {
-
/**
* Constructs a new object.
*/
protected GraphSONModuleV2d0(final boolean normalize) {
super("graphson-2.0");
+
// graph
- addSerializer(Edge.class, new GraphSONSerializersV1d0.EdgeJacksonSerializer(normalize));
- addSerializer(Vertex.class, new GraphSONSerializersV1d0.VertexJacksonSerializer(normalize));
- addSerializer(VertexProperty.class, new GraphSONSerializersV1d0.VertexPropertyJacksonSerializer(normalize));
- addSerializer(Property.class, new GraphSONSerializersV1d0.PropertyJacksonSerializer());
- addSerializer(TraversalMetrics.class, new GraphSONSerializersV1d0.TraversalMetricsJacksonSerializer());
- addSerializer(TraversalExplanation.class, new GraphSONSerializersV1d0.TraversalExplanationJacksonSerializer());
- addSerializer(Path.class, new GraphSONSerializersV1d0.PathJacksonSerializer());
- addSerializer(StarGraphGraphSONSerializer.DirectionalStarGraph.class, new StarGraphGraphSONSerializer(normalize));
- addSerializer(Tree.class, new GraphSONSerializersV1d0.TreeJacksonSerializer());
+ addSerializer(Edge.class, new GraphSONSerializersV2d0.EdgeJacksonSerializer(normalize));
+ addSerializer(Vertex.class, new GraphSONSerializersV2d0.VertexJacksonSerializer(normalize));
+ addSerializer(VertexProperty.class, new GraphSONSerializersV2d0.VertexPropertyJacksonSerializer(normalize));
+ addSerializer(Property.class, new GraphSONSerializersV2d0.PropertyJacksonSerializer());
+ addSerializer(TraversalMetrics.class, new GraphSONSerializersV2d0.TraversalMetricsJacksonSerializer());
+ addSerializer(TraversalExplanation.class, new GraphSONSerializersV2d0.TraversalExplanationJacksonSerializer());
+ addSerializer(Path.class, new GraphSONSerializersV2d0.PathJacksonSerializer());
+ addSerializer(DirectionalStarGraph.class, new StarGraphGraphSONSerializerV2d0(normalize));
+ addSerializer(Tree.class, new GraphSONSerializersV2d0.TreeJacksonSerializer());
// java.util
- addSerializer(Map.Entry.class, new JavaUtilSerializersV1d0.MapEntryJacksonSerializer());
+ addSerializer(Map.Entry.class, new JavaUtilSerializersV2d0.MapEntryJacksonSerializer());
+ addSerializer(ByteBuffer.class, new JavaUtilSerializersV2d0.GraphSONByteBufferSerializer());
// java.time
- addSerializer(Duration.class, new JavaTimeSerializersV1d0.DurationJacksonSerializer());
- addSerializer(Instant.class, new JavaTimeSerializersV1d0.InstantJacksonSerializer());
- addSerializer(LocalDate.class, new JavaTimeSerializersV1d0.LocalDateJacksonSerializer());
- addSerializer(LocalDateTime.class, new JavaTimeSerializersV1d0.LocalDateTimeJacksonSerializer());
- addSerializer(LocalTime.class, new JavaTimeSerializersV1d0.LocalTimeJacksonSerializer());
- addSerializer(MonthDay.class, new JavaTimeSerializersV1d0.MonthDayJacksonSerializer());
- addSerializer(OffsetDateTime.class, new JavaTimeSerializersV1d0.OffsetDateTimeJacksonSerializer());
- addSerializer(OffsetTime.class, new JavaTimeSerializersV1d0.OffsetTimeJacksonSerializer());
- addSerializer(Period.class, new JavaTimeSerializersV1d0.PeriodJacksonSerializer());
- addSerializer(Year.class, new JavaTimeSerializersV1d0.YearJacksonSerializer());
- addSerializer(YearMonth.class, new JavaTimeSerializersV1d0.YearMonthJacksonSerializer());
- addSerializer(ZonedDateTime.class, new JavaTimeSerializersV1d0.ZonedDateTimeJacksonSerializer());
- addSerializer(ZoneOffset.class, new JavaTimeSerializersV1d0.ZoneOffsetJacksonSerializer());
-
- addDeserializer(Duration.class, new JavaTimeSerializersV1d0.DurationJacksonDeserializer());
- addDeserializer(Instant.class, new JavaTimeSerializersV1d0.InstantJacksonDeserializer());
- addDeserializer(LocalDate.class, new JavaTimeSerializersV1d0.LocalDateJacksonDeserializer());
- addDeserializer(LocalDateTime.class, new JavaTimeSerializersV1d0.LocalDateTimeJacksonDeserializer());
- addDeserializer(LocalTime.class, new JavaTimeSerializersV1d0.LocalTimeJacksonDeserializer());
- addDeserializer(MonthDay.class, new JavaTimeSerializersV1d0.MonthDayJacksonDeserializer());
- addDeserializer(OffsetDateTime.class, new JavaTimeSerializersV1d0.OffsetDateTimeJacksonDeserializer());
- addDeserializer(OffsetTime.class, new JavaTimeSerializersV1d0.OffsetTimeJacksonDeserializer());
- addDeserializer(Period.class, new JavaTimeSerializersV1d0.PeriodJacksonDeserializer());
- addDeserializer(Year.class, new JavaTimeSerializersV1d0.YearJacksonDeserializer());
- addDeserializer(YearMonth.class, new JavaTimeSerializersV1d0.YearMonthJacksonDeserializer());
- addDeserializer(ZonedDateTime.class, new JavaTimeSerializersV1d0.ZonedDateTimeJacksonDeserializer());
- addDeserializer(ZoneOffset.class, new JavaTimeSerializersV1d0.ZoneOffsetJacksonDeserializer());
+ addSerializer(Duration.class, new JavaTimeSerializersV2d0.DurationJacksonSerializer());
+ addSerializer(Instant.class, new JavaTimeSerializersV2d0.InstantJacksonSerializer());
+ addSerializer(LocalDate.class, new JavaTimeSerializersV2d0.LocalDateJacksonSerializer());
+ addSerializer(LocalDateTime.class, new JavaTimeSerializersV2d0.LocalDateTimeJacksonSerializer());
+ addSerializer(LocalTime.class, new JavaTimeSerializersV2d0.LocalTimeJacksonSerializer());
+ addSerializer(MonthDay.class, new JavaTimeSerializersV2d0.MonthDayJacksonSerializer());
+ addSerializer(OffsetDateTime.class, new JavaTimeSerializersV2d0.OffsetDateTimeJacksonSerializer());
+ addSerializer(OffsetTime.class, new JavaTimeSerializersV2d0.OffsetTimeJacksonSerializer());
+ addSerializer(Period.class, new JavaTimeSerializersV2d0.PeriodJacksonSerializer());
+ addSerializer(Year.class, new JavaTimeSerializersV2d0.YearJacksonSerializer());
+ addSerializer(YearMonth.class, new JavaTimeSerializersV2d0.YearMonthJacksonSerializer());
+ addSerializer(ZonedDateTime.class, new JavaTimeSerializersV2d0.ZonedDateTimeJacksonSerializer());
+ addSerializer(ZoneOffset.class, new JavaTimeSerializersV2d0.ZoneOffsetJacksonSerializer());
+
+ addDeserializer(Duration.class, new JavaTimeSerializersV2d0.DurationJacksonDeserializer());
+ addDeserializer(Instant.class, new JavaTimeSerializersV2d0.InstantJacksonDeserializer());
+ addDeserializer(LocalDate.class, new JavaTimeSerializersV2d0.LocalDateJacksonDeserializer());
+ addDeserializer(LocalDateTime.class, new JavaTimeSerializersV2d0.LocalDateTimeJacksonDeserializer());
+ addDeserializer(LocalTime.class, new JavaTimeSerializersV2d0.LocalTimeJacksonDeserializer());
+ addDeserializer(MonthDay.class, new JavaTimeSerializersV2d0.MonthDayJacksonDeserializer());
+ addDeserializer(OffsetDateTime.class, new JavaTimeSerializersV2d0.OffsetDateTimeJacksonDeserializer());
+ addDeserializer(OffsetTime.class, new JavaTimeSerializersV2d0.OffsetTimeJacksonDeserializer());
+ addDeserializer(Period.class, new JavaTimeSerializersV2d0.PeriodJacksonDeserializer());
+ addDeserializer(Year.class, new JavaTimeSerializersV2d0.YearJacksonDeserializer());
+ addDeserializer(YearMonth.class, new JavaTimeSerializersV2d0.YearMonthJacksonDeserializer());
+ addDeserializer(ZonedDateTime.class, new JavaTimeSerializersV2d0.ZonedDateTimeJacksonDeserializer());
+ addDeserializer(ZoneOffset.class, new JavaTimeSerializersV2d0.ZoneOffsetJacksonDeserializer());
}
public static Builder build() {
@@ -126,6 +117,7 @@ abstract class GraphSONModule extends SimpleModule {
public GraphSONModule create(final boolean normalize) {
return new GraphSONModuleV2d0(normalize);
}
+
}
}
@@ -147,7 +139,7 @@ abstract class GraphSONModule extends SimpleModule {
addSerializer(TraversalMetrics.class, new GraphSONSerializersV1d0.TraversalMetricsJacksonSerializer());
addSerializer(TraversalExplanation.class, new GraphSONSerializersV1d0.TraversalExplanationJacksonSerializer());
addSerializer(Path.class, new GraphSONSerializersV1d0.PathJacksonSerializer());
- addSerializer(StarGraphGraphSONSerializer.DirectionalStarGraph.class, new StarGraphGraphSONSerializer(normalize));
+ addSerializer(DirectionalStarGraph.class, new StarGraphGraphSONSerializerV1d0(normalize));
addSerializer(Tree.class, new GraphSONSerializersV1d0.TreeJacksonSerializer());
// java.util
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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 d95fdff..6f15979 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
@@ -18,13 +18,7 @@
*/
package org.apache.tinkerpop.gremlin.structure.io.graphson;
-import org.apache.tinkerpop.gremlin.structure.Direction;
-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.*;
import org.apache.tinkerpop.gremlin.structure.io.GraphReader;
import org.apache.tinkerpop.gremlin.structure.io.GraphWriter;
import org.apache.tinkerpop.gremlin.structure.io.Mapper;
@@ -35,7 +29,7 @@ import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdge;
import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedProperty;
import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty;
import org.apache.tinkerpop.gremlin.structure.util.star.StarGraph;
-import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializer;
+import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONDeserializer;
import org.apache.tinkerpop.gremlin.util.function.FunctionUtils;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
import org.apache.tinkerpop.shaded.jackson.core.type.TypeReference;
@@ -44,12 +38,7 @@ import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
import org.apache.tinkerpop.shaded.jackson.databind.node.JsonNodeType;
import org.javatuples.Pair;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
+import java.io.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
@@ -169,14 +158,14 @@ public final class GraphSONReader implements GraphReader {
final Function<Attachable<Edge>, Edge> edgeAttachMethod,
final Direction attachEdgesOfThisDirection) throws IOException {
final Map<String, Object> vertexData = mapper.readValue(inputStream, mapTypeReference);
- final StarGraph starGraph = StarGraphGraphSONSerializer.readStarGraphVertex(vertexData);
+ final StarGraph starGraph = StarGraphGraphSONDeserializer.readStarGraphVertex(vertexData);
if (vertexAttachMethod != null) vertexAttachMethod.apply(starGraph.getStarVertex());
if (vertexData.containsKey(GraphSONTokens.OUT_E) && (attachEdgesOfThisDirection == Direction.BOTH || attachEdgesOfThisDirection == Direction.OUT))
- StarGraphGraphSONSerializer.readStarGraphEdges(edgeAttachMethod, starGraph, vertexData, GraphSONTokens.OUT_E);
+ StarGraphGraphSONDeserializer.readStarGraphEdges(edgeAttachMethod, starGraph, vertexData, GraphSONTokens.OUT_E);
if (vertexData.containsKey(GraphSONTokens.IN_E) && (attachEdgesOfThisDirection == Direction.BOTH || attachEdgesOfThisDirection == Direction.IN))
- StarGraphGraphSONSerializer.readStarGraphEdges(edgeAttachMethod, starGraph, vertexData, GraphSONTokens.IN_E);
+ StarGraphGraphSONDeserializer.readStarGraphEdges(edgeAttachMethod, starGraph, vertexData, GraphSONTokens.IN_E);
return starGraph.getStarVertex();
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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 ed20fd9..c4dcddd 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
@@ -26,32 +26,48 @@ import org.apache.tinkerpop.shaded.jackson.databind.ser.SerializerFactory;
import org.apache.tinkerpop.shaded.jackson.databind.ser.std.ToStringSerializer;
/**
- * Implementation of the {@code DefaultSerializerProvider} for Jackson that users the {@code ToStringSerializer} for
+ * Implementation of the {@code DefaultSerializerProvider} for Jackson that uses the {@code ToStringSerializer} for
* unknown types.
*
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
final class GraphSONSerializerProvider extends DefaultSerializerProvider {
private static final long serialVersionUID = 1L;
- private static final ToStringSerializer toStringSerializer = new ToStringSerializer();
+ private final JsonSerializer<Object> unknownTypeSerializer;
- public GraphSONSerializerProvider() {
+ public GraphSONSerializerProvider(GraphSONVersion version) {
super();
+ if (version == GraphSONVersion.V1_0) {
+ setDefaultKeySerializer(new GraphSONSerializersV1d0.GraphSONKeySerializer());
+ unknownTypeSerializer = new ToStringSerializer();
+ } else {
+ setDefaultKeySerializer(new GraphSONSerializersV2d0.GraphSONKeySerializer());
+ unknownTypeSerializer = new ToStringGraphSONSerializer();
+ }
}
protected GraphSONSerializerProvider(final SerializerProvider src,
- final SerializationConfig config, final SerializerFactory f) {
+ final SerializationConfig config, final SerializerFactory f,
+ final GraphSONVersion version) {
super(src, config, f);
+ if (version == GraphSONVersion.V1_0) {
+ setDefaultKeySerializer(new GraphSONSerializersV1d0.GraphSONKeySerializer());
+ unknownTypeSerializer = new ToStringSerializer();
+ } else {
+ setDefaultKeySerializer(new GraphSONSerializersV2d0.GraphSONKeySerializer());
+ unknownTypeSerializer = new ToStringGraphSONSerializer();
+ }
+
}
@Override
public JsonSerializer<Object> getUnknownTypeSerializer(final Class<?> aClass) {
- return toStringSerializer;
+ return unknownTypeSerializer;
}
@Override
public GraphSONSerializerProvider createInstance(final SerializationConfig config,
final SerializerFactory jsf) {
- return new GraphSONSerializerProvider(this, config, jsf);
+ return new GraphSONSerializerProvider(this, config, jsf, GraphSONVersion.V1_0);
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV1d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV1d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV1d0.java
index 2411d8f..7e78222 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV1d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV1d0.java
@@ -21,14 +21,11 @@ package org.apache.tinkerpop.gremlin.structure.io.graphson;
import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
-import org.apache.tinkerpop.gremlin.structure.Edge;
-import org.apache.tinkerpop.gremlin.structure.Element;
-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.gremlin.structure.*;
import org.apache.tinkerpop.gremlin.structure.util.Comparators;
import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
@@ -42,15 +39,8 @@ import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
import org.javatuples.Pair;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
import java.util.concurrent.TimeUnit;
-import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
/**
* GraphSON serializers for graph-based objects such as vertices, edges, properties, and paths. These serializers
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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
new file mode 100644
index 0000000..e4f8280
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
@@ -0,0 +1,467 @@
+/*
+ * 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.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
+import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics;
+import org.apache.tinkerpop.gremlin.structure.*;
+import org.apache.tinkerpop.gremlin.structure.util.Comparators;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty;
+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.StdKeySerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+import org.javatuples.Pair;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+import static org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONUtil.*;
+
+/**
+ * GraphSON serializers for graph-based objects such as vertices, edges, properties, and paths. These serializers
+ * present a generalized way to serialize the implementations of core interfaces.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class GraphSONSerializersV2d0 {
+
+ private GraphSONSerializersV2d0() {
+ }
+
+ final static class VertexPropertyJacksonSerializer extends StdSerializer<VertexProperty> {
+
+ private final boolean normalize;
+
+ public VertexPropertyJacksonSerializer(final boolean normalize) {
+ super(VertexProperty.class);
+ this.normalize = normalize;
+ }
+
+ @Override
+ public void serialize(final VertexProperty property, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+ throws IOException {
+ serializerVertexProperty(property, jsonGenerator, serializerProvider, null, normalize, true);
+ }
+
+ @Override
+ public void serializeWithType(final VertexProperty property, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+ serializerVertexProperty(property, jsonGenerator, serializerProvider, typeSerializer, normalize, true);
+ }
+ }
+
+ final static class PropertyJacksonSerializer extends StdSerializer<Property> {
+
+ public PropertyJacksonSerializer() {
+ super(Property.class);
+ }
+
+ @Override
+ public void serialize(final Property property, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+ throws IOException {
+ ser(property, jsonGenerator, serializerProvider, null);
+ }
+
+ @Override
+ public void serializeWithType(final Property property, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+ ser(property, jsonGenerator, serializerProvider, typeSerializer);
+ }
+
+ private static void ser(final Property property, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+ writeStartObject(property, jsonGenerator, typeSerializer);
+
+ serializerProvider.defaultSerializeField(GraphSONTokens.KEY, property.key(), jsonGenerator);
+ serializerProvider.defaultSerializeField(GraphSONTokens.VALUE, property.value(), jsonGenerator);
+
+ writeEndObject(property, jsonGenerator, typeSerializer);
+ }
+ }
+
+ final static class EdgeJacksonSerializer extends StdSerializer<Edge> {
+
+ private final boolean normalize;
+
+ public EdgeJacksonSerializer(final boolean normalize) {
+ super(Edge.class);
+ this.normalize = normalize;
+ }
+
+
+ @Override
+ public void serialize(final Edge edge, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+ throws IOException {
+ ser(edge, jsonGenerator, serializerProvider, null);
+ }
+
+ @Override
+ public void serializeWithType(final Edge edge, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+ ser(edge, jsonGenerator, serializerProvider, typeSerializer);
+ }
+
+ private void ser(final Edge edge, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+ writeStartObject(edge, jsonGenerator, typeSerializer);
+
+ GraphSONUtil.writeWithType(GraphSONTokens.ID, edge.id(), jsonGenerator, serializerProvider, typeSerializer);
+ jsonGenerator.writeStringField(GraphSONTokens.LABEL, edge.label());
+ jsonGenerator.writeStringField(GraphSONTokens.TYPE, GraphSONTokens.EDGE);
+ jsonGenerator.writeStringField(GraphSONTokens.IN_LABEL, edge.inVertex().label());
+ jsonGenerator.writeStringField(GraphSONTokens.OUT_LABEL, edge.outVertex().label());
+ GraphSONUtil.writeWithType(GraphSONTokens.IN, edge.inVertex().id(), jsonGenerator, serializerProvider, typeSerializer);
+ GraphSONUtil.writeWithType(GraphSONTokens.OUT, edge.outVertex().id(), jsonGenerator, serializerProvider, typeSerializer);
+ writeProperties(edge, jsonGenerator, serializerProvider, typeSerializer);
+
+ writeEndObject(edge, jsonGenerator, typeSerializer);
+ }
+
+ private void writeProperties(final Edge edge, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider,
+ final TypeSerializer typeSerializer) throws IOException {
+ final Iterator<Property<Object>> elementProperties = normalize ?
+ IteratorUtils.list(edge.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : edge.properties();
+ if (elementProperties.hasNext()) {
+ jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+ writeStartObject(edge, jsonGenerator, typeSerializer);
+
+ while (elementProperties.hasNext()) {
+ final Property<Object> elementProperty = elementProperties.next();
+ GraphSONUtil.writeWithType(elementProperty.key(), elementProperty.value(), jsonGenerator, serializerProvider, typeSerializer);
+ }
+
+ writeEndObject(edge, jsonGenerator, typeSerializer);
+ }
+ }
+
+ }
+
+ final static class VertexJacksonSerializer extends StdSerializer<Vertex> {
+
+ private final boolean normalize;
+
+ public VertexJacksonSerializer(final boolean normalize) {
+ super(Vertex.class);
+ this.normalize = normalize;
+ }
+
+ @Override
+ public void serialize(final Vertex vertex, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+ throws IOException {
+ ser(vertex, jsonGenerator, serializerProvider, null);
+ }
+
+ @Override
+ public void serializeWithType(final Vertex vertex, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+ ser(vertex, jsonGenerator, serializerProvider, typeSerializer);
+ }
+
+ private void ser(final Vertex vertex, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider, final TypeSerializer typeSerializer)
+ throws IOException {
+ writeStartObject(vertex, jsonGenerator, typeSerializer);
+
+ GraphSONUtil.writeWithType(GraphSONTokens.ID, vertex.id(), jsonGenerator, serializerProvider, typeSerializer);
+ jsonGenerator.writeStringField(GraphSONTokens.LABEL, vertex.label());
+ jsonGenerator.writeStringField(GraphSONTokens.TYPE, GraphSONTokens.VERTEX);
+ writeProperties(vertex, jsonGenerator, serializerProvider, typeSerializer);
+
+ writeEndObject(vertex, jsonGenerator, typeSerializer);
+ }
+
+ private void writeProperties(final Vertex vertex, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+ jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+ writeStartObject(vertex, jsonGenerator, typeSerializer);
+
+ final List<String> keys = normalize ?
+ IteratorUtils.list(vertex.keys().iterator(), Comparator.naturalOrder()) : new ArrayList<>(vertex.keys());
+ for (String key : keys) {
+ final Iterator<VertexProperty<Object>> vertexProperties = normalize ?
+ IteratorUtils.list(vertex.properties(key), Comparators.PROPERTY_COMPARATOR).iterator() : vertex.properties(key);
+ if (vertexProperties.hasNext()) {
+ jsonGenerator.writeFieldName(key);
+ writeStartArray(vertex, jsonGenerator, typeSerializer);
+
+ while (vertexProperties.hasNext()) {
+ serializerVertexProperty(vertexProperties.next(), jsonGenerator, serializerProvider, typeSerializer, normalize, false);
+ }
+
+ writeEndArray(vertex, jsonGenerator, typeSerializer);
+ }
+ }
+
+ writeEndObject(vertex, jsonGenerator, typeSerializer);
+ }
+
+ }
+
+ final static class PathJacksonSerializer extends StdSerializer<Path> {
+
+ public PathJacksonSerializer() {
+ super(Path.class);
+ }
+
+ @Override
+ public void serialize(final Path path, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+ throws IOException, JsonGenerationException {
+ ser(path, jsonGenerator, null);
+ }
+
+ @Override
+ public void serializeWithType(final Path path, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider, final TypeSerializer typeSerializer)
+ throws IOException, JsonProcessingException {
+ ser(path, jsonGenerator, typeSerializer);
+ }
+
+ private static void ser(final Path path, final JsonGenerator jsonGenerator, final TypeSerializer typeSerializer)
+ throws IOException {
+ writeStartObject(path, jsonGenerator, typeSerializer);
+
+ jsonGenerator.writeObjectField(GraphSONTokens.LABELS, path.labels());
+ jsonGenerator.writeObjectField(GraphSONTokens.OBJECTS, path.objects());
+
+ writeEndObject(path, jsonGenerator, typeSerializer);
+ }
+
+ }
+
+ final static class TreeJacksonSerializer extends StdSerializer<Tree> {
+
+ public TreeJacksonSerializer() {
+ super(Tree.class);
+ }
+
+ @Override
+ public void serialize(final Tree tree, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) throws IOException, JsonGenerationException {
+ ser(tree, jsonGenerator, null);
+ }
+
+ @Override
+ public void serializeWithType(final Tree tree, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider, final TypeSerializer typeSerializer)
+ throws IOException, JsonProcessingException {
+ ser(tree, jsonGenerator, typeSerializer);
+ }
+
+ private static void ser(final Tree tree, final JsonGenerator jsonGenerator, final TypeSerializer typeSerializer)
+ throws IOException {
+ writeStartObject(tree, jsonGenerator, typeSerializer);
+
+ Set<Map.Entry<Element, Tree>> set = tree.entrySet();
+ for (Map.Entry<Element, Tree> entry : set) {
+ jsonGenerator.writeFieldName(entry.getKey().id().toString());
+ writeStartObject(entry, jsonGenerator, typeSerializer);
+ jsonGenerator.writeObjectField(GraphSONTokens.KEY, entry.getKey());
+ jsonGenerator.writeObjectField(GraphSONTokens.VALUE, entry.getValue());
+ writeEndObject(entry, jsonGenerator, typeSerializer);
+ }
+
+ writeEndObject(tree, jsonGenerator, typeSerializer);
+ }
+ }
+
+ /**
+ * Maps in the JVM can have {@link Object} as a key, but in JSON they must be a {@link String}.
+ */
+ final static class GraphSONKeySerializer extends StdKeySerializer {
+
+ @Override
+ public void serialize(final Object o, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) throws IOException {
+ ser(o, jsonGenerator, serializerProvider);
+ }
+
+ @Override
+ public void serializeWithType(final Object o, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+ ser(o, jsonGenerator, serializerProvider);
+ }
+
+ private void ser(final Object o, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider) throws IOException {
+ if (Element.class.isAssignableFrom(o.getClass()))
+ jsonGenerator.writeFieldName((((Element) o).id()).toString());
+ else
+ super.serialize(o, jsonGenerator, serializerProvider);
+ }
+ }
+
+ final static class TraversalExplanationJacksonSerializer extends StdSerializer<TraversalExplanation> {
+ public TraversalExplanationJacksonSerializer() {
+ super(TraversalExplanation.class);
+ }
+
+ @Override
+ public void serialize(final TraversalExplanation traversalExplanation, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider) throws IOException {
+ ser(traversalExplanation, jsonGenerator);
+ }
+
+ @Override
+ public void serializeWithType(final TraversalExplanation value, final JsonGenerator gen,
+ final SerializerProvider serializers, final TypeSerializer typeSer) throws IOException {
+ ser(value, gen);
+ }
+
+ public void ser(final TraversalExplanation te, final JsonGenerator jsonGenerator) throws IOException {
+ final Map<String, Object> m = new HashMap<>();
+ m.put(GraphSONTokens.ORIGINAL, getStepsAsList(te.getOriginalTraversal()));
+
+ final List<Pair<TraversalStrategy, Traversal.Admin<?, ?>>> strategyTraversals = te.getStrategyTraversals();
+
+ final List<Map<String, Object>> intermediates = new ArrayList<>();
+ for (final Pair<TraversalStrategy, Traversal.Admin<?, ?>> pair : strategyTraversals) {
+ final Map<String, Object> intermediate = new HashMap<>();
+ intermediate.put(GraphSONTokens.STRATEGY, pair.getValue0().toString());
+ intermediate.put(GraphSONTokens.CATEGORY, pair.getValue0().getTraversalCategory().getSimpleName());
+ intermediate.put(GraphSONTokens.TRAVERSAL, getStepsAsList(pair.getValue1()));
+ intermediates.add(intermediate);
+ }
+ m.put(GraphSONTokens.INTERMEDIATE, intermediates);
+
+ if (strategyTraversals.isEmpty())
+ m.put(GraphSONTokens.FINAL, getStepsAsList(te.getOriginalTraversal()));
+ else
+ m.put(GraphSONTokens.FINAL, getStepsAsList(strategyTraversals.get(strategyTraversals.size() - 1).getValue1()));
+
+ jsonGenerator.writeObject(m);
+ }
+
+ private List<String> getStepsAsList(final Traversal.Admin<?, ?> t) {
+ final List<String> steps = new ArrayList<>();
+ t.getSteps().iterator().forEachRemaining(s -> steps.add(s.toString()));
+ return steps;
+ }
+ }
+
+ final static class TraversalMetricsJacksonSerializer extends StdSerializer<TraversalMetrics> {
+ public TraversalMetricsJacksonSerializer() {
+ super(TraversalMetrics.class);
+ }
+
+ @Override
+ public void serialize(final TraversalMetrics property, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+ throws IOException {
+ serializeInternal(property, jsonGenerator);
+ }
+
+ @Override
+ public void serializeWithType(final TraversalMetrics property, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
+ serializeInternal(property, jsonGenerator);
+ }
+
+ private static void serializeInternal(final TraversalMetrics traversalMetrics, final JsonGenerator jsonGenerator) throws IOException {
+ // creation of the map enables all the fields to be properly written with their type if required
+ final Map<String, Object> m = new HashMap<>();
+ m.put(GraphSONTokens.DURATION, traversalMetrics.getDuration(TimeUnit.NANOSECONDS) / 1000000d);
+ final List<Map<String, Object>> metrics = new ArrayList<>();
+ traversalMetrics.getMetrics().forEach(it -> metrics.add(metricsToMap(it)));
+ m.put(GraphSONTokens.METRICS, metrics);
+
+ jsonGenerator.writeObject(m);
+ }
+
+ private static Map<String, Object> metricsToMap(final Metrics metrics) {
+ final Map<String, Object> m = new HashMap<>();
+ m.put(GraphSONTokens.ID, metrics.getId());
+ m.put(GraphSONTokens.NAME, metrics.getName());
+ m.put(GraphSONTokens.COUNTS, metrics.getCounts());
+ m.put(GraphSONTokens.DURATION, metrics.getDuration(TimeUnit.NANOSECONDS) / 1000000d);
+
+ if (!metrics.getAnnotations().isEmpty()) {
+ m.put(GraphSONTokens.ANNOTATIONS, metrics.getAnnotations());
+ }
+
+ if (!metrics.getNested().isEmpty()) {
+ final List<Map<String, Object>> nested = new ArrayList<>();
+ metrics.getNested().forEach(it -> nested.add(metricsToMap(it)));
+ m.put(GraphSONTokens.METRICS, nested);
+ }
+ return m;
+ }
+ }
+
+ private static void serializerVertexProperty(final VertexProperty property, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider,
+ final TypeSerializer typeSerializer, final boolean normalize,
+ final boolean includeLabel) throws IOException {
+ writeStartObject(property, jsonGenerator, typeSerializer);
+
+ GraphSONUtil.writeWithType(GraphSONTokens.ID, property.id(), jsonGenerator, serializerProvider, typeSerializer);
+ GraphSONUtil.writeWithType(GraphSONTokens.VALUE, property.value(), jsonGenerator, serializerProvider, typeSerializer);
+ if (includeLabel) jsonGenerator.writeStringField(GraphSONTokens.LABEL, property.label());
+ tryWriteMetaProperties(property, jsonGenerator, serializerProvider, typeSerializer, normalize);
+
+ writeEndObject(property, jsonGenerator, typeSerializer);
+ }
+
+ private static void tryWriteMetaProperties(final VertexProperty property, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider,
+ final TypeSerializer typeSerializer, final boolean normalize) throws IOException {
+ // when "detached" you can't check features of the graph it detached from so it has to be
+ // treated differently from a regular VertexProperty implementation.
+ if (property instanceof DetachedVertexProperty) {
+ // only write meta properties key if they exist
+ if (property.properties().hasNext()) {
+ writeMetaProperties(property, jsonGenerator, serializerProvider, typeSerializer, normalize);
+ }
+ } else {
+ // still attached - so we can check the features to see if it's worth even trying to write the
+ // meta properties key
+ if (property.graph().features().vertex().supportsMetaProperties() && property.properties().hasNext()) {
+ writeMetaProperties(property, jsonGenerator, serializerProvider, typeSerializer, normalize);
+ }
+ }
+ }
+
+ private static void writeMetaProperties(final VertexProperty property, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider,
+ final TypeSerializer typeSerializer, final boolean normalize) throws IOException {
+ jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+ writeStartObject(property, jsonGenerator, typeSerializer);
+
+ final Iterator<Property<Object>> metaProperties = normalize ?
+ IteratorUtils.list((Iterator<Property<Object>>) property.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : property.properties();
+ while (metaProperties.hasNext()) {
+ final Property<Object> metaProperty = metaProperties.next();
+ GraphSONUtil.writeWithType(metaProperty.key(), metaProperty.value(), jsonGenerator, serializerProvider, typeSerializer);
+ }
+
+ writeEndObject(property, jsonGenerator, typeSerializer);
+ }
+
+}
+
+
+
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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..a7583fc
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeDeserializer.java
@@ -0,0 +1,201 @@
+/*
+ * 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.io.graphson.GraphSONMapper.TypeInfo;
+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 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){
+ super(baseType, idRes, typePropertyName, false, null);
+ this.baseType = baseType;
+ this.idRes = idRes;
+ this.propertyName = typePropertyName;
+ this.typeInfo = typeInfo;
+ }
+
+ @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);
+
+ // Detect type
+ try {
+ // The Type pattern is START_ARRAY -> START_OBJECT -> TEXT_FIELD(propertyName).
+ if (jsonParser.getCurrentToken() == JsonToken.START_ARRAY) {
+ buf.writeStartArray();
+ JsonToken t1 = jsonParser.nextToken();
+
+ if (t1 == JsonToken.START_OBJECT) {
+ buf.writeStartObject();
+ String nextFieldName = jsonParser.nextFieldName();
+
+ if (nextFieldName != null) {
+ if (nextFieldName.equals(propertyName)) {
+ // Detected type pattern
+ // Find deserializer
+ // Deserialize with deserializer
+ String typeName = jsonParser.nextTextValue();
+ JavaType typeFromId = idRes.typeFromId(typeName);
+
+ // Detected a type and extracted the value, but still want to make sure that the extracted type
+ // corresponds to what was given in parameter, if a type has been explicitly specified in param.
+ 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);
+
+ // Position the next token right on the value
+ if (jsonParser.nextToken() == JsonToken.END_OBJECT) {
+ // Locate the cursor on the value to deser
+ jsonParser.nextValue();
+ Object value = jsonDeserializer.deserialize(jsonParser, deserializationContext);
+ // IMPORTANT - Close the JSON ARRAY
+ jsonParser.nextToken();
+ return value;
+ }
+ }
+ }
+
+ }
+ }
+ } catch (Exception e) {
+ throw deserializationContext.mappingException("Could not deserialize the JSON value as required. " + e.getMessage());
+ }
+
+ JsonParser toUseParser;
+ JsonParser bufferParser = buf.asParser();
+ JsonToken t = bufferParser.nextToken();
+
+ // 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 an 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.
+ if (t != null)
+ toUseParser = JsonParserConcat.createFlattened(bufferParser, jsonParser);
+
+ // If the cursor hasn't been moved, no need to concatenate the original JsonParser with the TokenBuffer's one.
+ else
+ toUseParser = jsonParser;
+
+ // 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/b44ec666/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..97790ef
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeIdResolver.java
@@ -0,0 +1,134 @@
+/*
+ * 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 org.apache.tinkerpop.shaded.jackson.databind.util.TokenBuffer;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.sql.Timestamp;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * 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<>();
+
+ GraphSONTypeIdResolver() {
+ // Need to add all the "Standard typed scalar" classes manually...
+ Arrays.asList(
+ Float.class,
+ Long.class,
+ Short.class,
+ BigInteger.class,
+ BigDecimal.class,
+ Byte.class,
+ Character.class,
+ UUID.class,
+ InetAddress.class,
+ InetSocketAddress.class,
+ ByteBuffer.class,
+ Class.class,
+ Calendar.class,
+ Date.class,
+ TimeZone.class,
+ Timestamp.class,
+ AtomicBoolean.class,
+ AtomicReference.class,
+ TokenBuffer.class
+ ).forEach(e -> idToType.put(e.getSimpleName(), TypeFactory.defaultInstance().constructType(e)));
+ }
+
+ public Map<String, JavaType> getIdToType() {
+ return idToType;
+ }
+
+ public GraphSONTypeIdResolver addCustomType(Class clasz) {
+ // May override types already registered, that's wanted.
+ getIdToType().put(clasz.getSimpleName(), TypeFactory.defaultInstance().constructType(clasz));
+ return this;
+ }
+
+ // 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));
+ return this;
+ }
+
+ @Override
+ public void init(JavaType javaType) {
+ }
+
+ @Override
+ public String idFromValue(Object o) {
+ return idFromValueAndType(o, null);
+ }
+
+ @Override
+ public String idFromValueAndType(Object o, Class<?> aClass) {
+ // May be improved later
+ return o.getClass().getSimpleName();
+ }
+
+ @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().get(s) != null
+ ? 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 (?)
+ return "GraphSON advanced typing system";
+ }
+
+ @Override
+ public JsonTypeInfo.Id getMechanism() {
+ return JsonTypeInfo.Id.CUSTOM;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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..87ab3a3
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeResolverBuilder.java
@@ -0,0 +1,60 @@
+/*
+ * 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.io.graphson.GraphSONMapper.TypeInfo;
+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;
+
+ @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);
+ }
+
+
+ @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);
+ }
+
+ public StdTypeResolverBuilder typesEmbedding(TypeInfo typeInfo) {
+ this.typeInfo = typeInfo;
+ return this;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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..5511b10
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeSerializer.java
@@ -0,0 +1,160 @@
+/*
+ * 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.io.graphson.GraphSONMapper.TypeInfo;
+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;
+
+/**
+ * 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;
+
+ GraphSONTypeSerializer(TypeIdResolver idRes, String propertyName, TypeInfo typeInfo) {
+ this.idRes = idRes;
+ this.propertyName = propertyName;
+ this.typeInfo = typeInfo;
+ }
+
+ @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().idFromValue(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.writeStartArray();
+ jsonGenerator.writeStartObject();
+ jsonGenerator.writeStringField(this.getPropertyName(), s);
+ jsonGenerator.writeEndObject();
+ }
+
+ private void writeTypeSuffix(JsonGenerator jsonGenerator) throws IOException {
+ jsonGenerator.writeEndArray();
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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..3b3ad79 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,33 @@ 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();
+ }
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b44ec666/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..1dd2c9c 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
@@ -18,17 +18,11 @@
*/
package org.apache.tinkerpop.gremlin.structure.io.graphson;
-import org.apache.tinkerpop.gremlin.structure.Direction;
-import org.apache.tinkerpop.gremlin.structure.Edge;
-import org.apache.tinkerpop.gremlin.structure.Element;
-import org.apache.tinkerpop.gremlin.structure.Graph;
-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.gremlin.structure.*;
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.*;
@@ -74,7 +68,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/b44ec666/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
index 763c1d9..ba4b056 100644
--- 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
@@ -27,19 +27,7 @@ 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;
+import java.time.*;
/**
* GraphSON serializers for classes in {@code java.time.*}.