Frame up for 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/0554b59b Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/0554b59b Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/0554b59b Branch: refs/heads/TINKERPOP-1274 Commit: 0554b59bfcc5944e8b1c007cce178c8945fc040c Parents: 5395aae Author: Stephen Mallette <[email protected]> Authored: Wed May 18 08:41:26 2016 -0400 Committer: Kevin Gallardo <[email protected]> Committed: Thu Jun 30 10:39:41 2016 +0100 ---------------------------------------------------------------------- .../structure/io/graphson/GraphSONMapper.java | 20 +- .../structure/io/graphson/GraphSONModule.java | 141 ++++-- .../io/graphson/GraphSONSerializers.java | 465 ------------------- .../io/graphson/GraphSONSerializersV1d0.java | 465 +++++++++++++++++++ .../structure/io/graphson/GraphSONVersion.java | 3 +- .../io/graphson/JavaTimeSerializers.java | 326 ------------- .../io/graphson/JavaTimeSerializersV1d0.java | 326 +++++++++++++ .../io/graphson/JavaUtilSerializers.java | 86 ---- .../io/graphson/JavaUtilSerializersV1d0.java | 86 ++++ 9 files changed, 997 insertions(+), 921 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0554b59b/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 73e9552..be5377a 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 @@ -75,12 +75,18 @@ public class GraphSONMapper implements Mapper<ObjectMapper> { final ObjectMapper om = new ObjectMapper(); om.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); - if (embedTypes) { - final TypeResolverBuilder<?> typer = new StdTypeResolverBuilder() - .init(JsonTypeInfo.Id.CLASS, null) - .inclusion(JsonTypeInfo.As.PROPERTY) - .typeProperty(GraphSONTokens.CLASS); - om.setDefaultTyping(typer); + if (version == GraphSONVersion.V1_0) { + if (embedTypes) { + final TypeResolverBuilder<?> typer = new StdTypeResolverBuilder() + .init(JsonTypeInfo.Id.CLASS, null) + .inclusion(JsonTypeInfo.As.PROPERTY) + .typeProperty(GraphSONTokens.CLASS); + om.setDefaultTyping(typer); + } + } else if (version == GraphSONVersion.V2_0) { + + } else { + throw new IllegalStateException("Unknown GraphSONVersion"); } if (normalize) @@ -88,7 +94,7 @@ public class GraphSONMapper implements Mapper<ObjectMapper> { // 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 GraphSONSerializers.GraphSONKeySerializer()); + provider.setDefaultKeySerializer(new GraphSONSerializersV1d0.GraphSONKeySerializer()); om.setSerializerProvider(provider); om.registerModule(version.getBuilder().create(normalize)); http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0554b59b/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 7cc6c91..639e90d 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 @@ -61,6 +61,75 @@ 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()); + + // java.util + addSerializer(Map.Entry.class, new JavaUtilSerializersV1d0.MapEntryJacksonSerializer()); + + // 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()); + } + + public static Builder build() { + return new Builder(); + } + + static final class Builder implements GraphSONModuleBuilder { + + private Builder() {} + + @Override + public GraphSONModule create(final boolean normalize) { + return new GraphSONModuleV2d0(normalize); + } + } + } + + /** * Version 1.0 of GraphSON. */ static final class GraphSONModuleV1d0 extends GraphSONModule { @@ -71,47 +140,47 @@ abstract class GraphSONModule extends SimpleModule { protected GraphSONModuleV1d0(final boolean normalize) { super("graphson-1.0"); // graph - addSerializer(Edge.class, new GraphSONSerializers.EdgeJacksonSerializer(normalize)); - addSerializer(Vertex.class, new GraphSONSerializers.VertexJacksonSerializer(normalize)); - addSerializer(VertexProperty.class, new GraphSONSerializers.VertexPropertyJacksonSerializer(normalize)); - addSerializer(Property.class, new GraphSONSerializers.PropertyJacksonSerializer()); - addSerializer(TraversalMetrics.class, new GraphSONSerializers.TraversalMetricsJacksonSerializer()); - addSerializer(TraversalExplanation.class, new GraphSONSerializers.TraversalExplanationJacksonSerializer()); - addSerializer(Path.class, new GraphSONSerializers.PathJacksonSerializer()); + 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 GraphSONSerializers.TreeJacksonSerializer()); + addSerializer(Tree.class, new GraphSONSerializersV1d0.TreeJacksonSerializer()); // java.util - addSerializer(Map.Entry.class, new JavaUtilSerializers.MapEntryJacksonSerializer()); + addSerializer(Map.Entry.class, new JavaUtilSerializersV1d0.MapEntryJacksonSerializer()); // java.time - addSerializer(Duration.class, new JavaTimeSerializers.DurationJacksonSerializer()); - addSerializer(Instant.class, new JavaTimeSerializers.InstantJacksonSerializer()); - addSerializer(LocalDate.class, new JavaTimeSerializers.LocalDateJacksonSerializer()); - addSerializer(LocalDateTime.class, new JavaTimeSerializers.LocalDateTimeJacksonSerializer()); - addSerializer(LocalTime.class, new JavaTimeSerializers.LocalTimeJacksonSerializer()); - addSerializer(MonthDay.class, new JavaTimeSerializers.MonthDayJacksonSerializer()); - addSerializer(OffsetDateTime.class, new JavaTimeSerializers.OffsetDateTimeJacksonSerializer()); - addSerializer(OffsetTime.class, new JavaTimeSerializers.OffsetTimeJacksonSerializer()); - addSerializer(Period.class, new JavaTimeSerializers.PeriodJacksonSerializer()); - addSerializer(Year.class, new JavaTimeSerializers.YearJacksonSerializer()); - addSerializer(YearMonth.class, new JavaTimeSerializers.YearMonthJacksonSerializer()); - addSerializer(ZonedDateTime.class, new JavaTimeSerializers.ZonedDateTimeJacksonSerializer()); - addSerializer(ZoneOffset.class, new JavaTimeSerializers.ZoneOffsetJacksonSerializer()); - - addDeserializer(Duration.class, new JavaTimeSerializers.DurationJacksonDeserializer()); - addDeserializer(Instant.class, new JavaTimeSerializers.InstantJacksonDeserializer()); - addDeserializer(LocalDate.class, new JavaTimeSerializers.LocalDateJacksonDeserializer()); - addDeserializer(LocalDateTime.class, new JavaTimeSerializers.LocalDateTimeJacksonDeserializer()); - addDeserializer(LocalTime.class, new JavaTimeSerializers.LocalTimeJacksonDeserializer()); - addDeserializer(MonthDay.class, new JavaTimeSerializers.MonthDayJacksonDeserializer()); - addDeserializer(OffsetDateTime.class, new JavaTimeSerializers.OffsetDateTimeJacksonDeserializer()); - addDeserializer(OffsetTime.class, new JavaTimeSerializers.OffsetTimeJacksonDeserializer()); - addDeserializer(Period.class, new JavaTimeSerializers.PeriodJacksonDeserializer()); - addDeserializer(Year.class, new JavaTimeSerializers.YearJacksonDeserializer()); - addDeserializer(YearMonth.class, new JavaTimeSerializers.YearMonthJacksonDeserializer()); - addDeserializer(ZonedDateTime.class, new JavaTimeSerializers.ZonedDateTimeJacksonDeserializer()); - addDeserializer(ZoneOffset.class, new JavaTimeSerializers.ZoneOffsetJacksonDeserializer()); + 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()); } public static Builder build() { http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0554b59b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializers.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializers.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializers.java deleted file mode 100644 index aaca316..0000000 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializers.java +++ /dev/null @@ -1,465 +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.Path; -import org.apache.tinkerpop.gremlin.process.traversal.Traversal; -import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy; -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.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.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.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 - * present a generalized way to serialize the implementations of core interfaces. - * - * @author Stephen Mallette (http://stephen.genoprime.com) - */ -final class GraphSONSerializers { - - private GraphSONSerializers() {} - - 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 { - jsonGenerator.writeStartObject(); - if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); - serializerProvider.defaultSerializeField(GraphSONTokens.KEY, property.key(), jsonGenerator); - serializerProvider.defaultSerializeField(GraphSONTokens.VALUE, property.value(), jsonGenerator); - jsonGenerator.writeEndObject(); - } - } - - 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 { - jsonGenerator.writeStartObject(); - if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); - 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); - jsonGenerator.writeEndObject(); - } - - 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.writeObjectFieldStart(GraphSONTokens.PROPERTIES); - if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); - while (elementProperties.hasNext()) { - final Property<Object> elementProperty = elementProperties.next(); - GraphSONUtil.writeWithType(elementProperty.key(), elementProperty.value(), jsonGenerator, serializerProvider, typeSerializer); - } - jsonGenerator.writeEndObject(); - } - } - - } - - 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 { - jsonGenerator.writeStartObject(); - if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); - 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); - jsonGenerator.writeEndObject(); - } - - private void writeProperties(final Vertex vertex, final JsonGenerator jsonGenerator, - final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException { - jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES); - if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); - - 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.writeArrayFieldStart(key); - if (typeSerializer != null) { - jsonGenerator.writeString(ArrayList.class.getName()); - jsonGenerator.writeStartArray(); - } - - while (vertexProperties.hasNext()) { - serializerVertexProperty(vertexProperties.next(), jsonGenerator, serializerProvider, typeSerializer, normalize, false); - } - - jsonGenerator.writeEndArray(); - if (typeSerializer != null) jsonGenerator.writeEndArray(); - } - } - - jsonGenerator.writeEndObject(); - } - - } - - 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 { - jsonGenerator.writeStartObject(); - if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); - jsonGenerator.writeObjectField(GraphSONTokens.LABELS, path.labels()); - jsonGenerator.writeObjectField(GraphSONTokens.OBJECTS, path.objects()); - jsonGenerator.writeEndObject(); - } - - } - - 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 { - jsonGenerator.writeStartObject(); - if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); - - Set<Map.Entry<Element, Tree>> set = tree.entrySet(); - for(Map.Entry<Element, Tree> entry : set) - { - jsonGenerator.writeObjectFieldStart(entry.getKey().id().toString()); - if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); - jsonGenerator.writeObjectField(GraphSONTokens.KEY, entry.getKey()); - jsonGenerator.writeObjectField(GraphSONTokens.VALUE, entry.getValue()); - jsonGenerator.writeEndObject(); - } - jsonGenerator.writeEndObject(); - } - } - - /** - * 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 { - jsonGenerator.writeStartObject(); - if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); - GraphSONUtil.writeWithType(GraphSONTokens.ID, property.id(), jsonGenerator, serializerProvider, typeSerializer); - GraphSONUtil.writeWithType(GraphSONTokens.VALUE, property.value(), jsonGenerator, serializerProvider, typeSerializer); - if (includeLabel) jsonGenerator.writeStringField(GraphSONTokens.LABEL, property.label()); - tryWriteMetaProperties(property, jsonGenerator, serializerProvider, typeSerializer, normalize); - jsonGenerator.writeEndObject(); - } - - 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.writeObjectFieldStart(GraphSONTokens.PROPERTIES); - if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); - 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); - } - jsonGenerator.writeEndObject(); - } - -} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0554b59b/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 new file mode 100644 index 0000000..2411d8f --- /dev/null +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV1d0.java @@ -0,0 +1,465 @@ +/* + * 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.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.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.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.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 + * present a generalized way to serialize the implementations of core interfaces. + * + * @author Stephen Mallette (http://stephen.genoprime.com) + */ +final class GraphSONSerializersV1d0 { + + private GraphSONSerializersV1d0() {} + + 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 { + jsonGenerator.writeStartObject(); + if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); + serializerProvider.defaultSerializeField(GraphSONTokens.KEY, property.key(), jsonGenerator); + serializerProvider.defaultSerializeField(GraphSONTokens.VALUE, property.value(), jsonGenerator); + jsonGenerator.writeEndObject(); + } + } + + 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 { + jsonGenerator.writeStartObject(); + if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); + 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); + jsonGenerator.writeEndObject(); + } + + 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.writeObjectFieldStart(GraphSONTokens.PROPERTIES); + if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); + while (elementProperties.hasNext()) { + final Property<Object> elementProperty = elementProperties.next(); + GraphSONUtil.writeWithType(elementProperty.key(), elementProperty.value(), jsonGenerator, serializerProvider, typeSerializer); + } + jsonGenerator.writeEndObject(); + } + } + + } + + 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 { + jsonGenerator.writeStartObject(); + if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); + 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); + jsonGenerator.writeEndObject(); + } + + private void writeProperties(final Vertex vertex, final JsonGenerator jsonGenerator, + final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException { + jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES); + if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); + + 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.writeArrayFieldStart(key); + if (typeSerializer != null) { + jsonGenerator.writeString(ArrayList.class.getName()); + jsonGenerator.writeStartArray(); + } + + while (vertexProperties.hasNext()) { + serializerVertexProperty(vertexProperties.next(), jsonGenerator, serializerProvider, typeSerializer, normalize, false); + } + + jsonGenerator.writeEndArray(); + if (typeSerializer != null) jsonGenerator.writeEndArray(); + } + } + + jsonGenerator.writeEndObject(); + } + + } + + 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 { + jsonGenerator.writeStartObject(); + if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); + jsonGenerator.writeObjectField(GraphSONTokens.LABELS, path.labels()); + jsonGenerator.writeObjectField(GraphSONTokens.OBJECTS, path.objects()); + jsonGenerator.writeEndObject(); + } + + } + + 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 { + jsonGenerator.writeStartObject(); + if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); + + Set<Map.Entry<Element, Tree>> set = tree.entrySet(); + for(Map.Entry<Element, Tree> entry : set) + { + jsonGenerator.writeObjectFieldStart(entry.getKey().id().toString()); + if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); + jsonGenerator.writeObjectField(GraphSONTokens.KEY, entry.getKey()); + jsonGenerator.writeObjectField(GraphSONTokens.VALUE, entry.getValue()); + jsonGenerator.writeEndObject(); + } + jsonGenerator.writeEndObject(); + } + } + + /** + * 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 { + jsonGenerator.writeStartObject(); + if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); + GraphSONUtil.writeWithType(GraphSONTokens.ID, property.id(), jsonGenerator, serializerProvider, typeSerializer); + GraphSONUtil.writeWithType(GraphSONTokens.VALUE, property.value(), jsonGenerator, serializerProvider, typeSerializer); + if (includeLabel) jsonGenerator.writeStringField(GraphSONTokens.LABEL, property.label()); + tryWriteMetaProperties(property, jsonGenerator, serializerProvider, typeSerializer, normalize); + jsonGenerator.writeEndObject(); + } + + 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.writeObjectFieldStart(GraphSONTokens.PROPERTIES); + if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName()); + 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); + } + jsonGenerator.writeEndObject(); + } + +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0554b59b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONVersion.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONVersion.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONVersion.java index 628ea22..7740b06 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONVersion.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONVersion.java @@ -24,7 +24,8 @@ package org.apache.tinkerpop.gremlin.structure.io.graphson; * @author Stephen Mallette (http://stephen.genoprime.com) */ public enum GraphSONVersion { - V1_0(GraphSONModule.GraphSONModuleV1d0.build(), "1.0"); + V1_0(GraphSONModule.GraphSONModuleV1d0.build(), "1.0"), + V2_0(GraphSONModule.GraphSONModuleV2d0.build(), "2.0"); private final GraphSONModule.GraphSONModuleBuilder builder; private final String versionNumber; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0554b59b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializers.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializers.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializers.java deleted file mode 100644 index 7ceae94..0000000 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializers.java +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tinkerpop.gremlin.structure.io.graphson; - -import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator; -import org.apache.tinkerpop.shaded.jackson.core.JsonParser; -import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext; -import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider; -import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer; -import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer; -import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer; - -import java.io.IOException; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.MonthDay; -import java.time.OffsetDateTime; -import java.time.OffsetTime; -import java.time.Period; -import java.time.Year; -import java.time.YearMonth; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; - -/** - * GraphSON serializers for classes in {@code java.time.*}. - */ -final class JavaTimeSerializers { - - private JavaTimeSerializers() {} - - /** - * Base class for serializing the {@code java.time.*} to ISO-8061 formats. - */ - static abstract class AbstractJavaTimeSerializer<T> extends StdSerializer<T> { - - public AbstractJavaTimeSerializer(final Class<T> clazz) { - super(clazz); - } - - @Override - public void serialize(final T value, final JsonGenerator gen, - final SerializerProvider serializerProvider) throws IOException { - gen.writeString(value.toString()); - } - - @Override - public void serializeWithType(final T value, final JsonGenerator gen, - final SerializerProvider serializers, final TypeSerializer typeSer) throws IOException { - typeSer.writeTypePrefixForObject(value, gen); - gen.writeStringField(GraphSONTokens.VALUE, value.toString()); - typeSer.writeTypeSuffixForObject(value, gen); - } - } - /** - * Base class for serializing the {@code java.time.*} from ISO-8061 formats. - */ - abstract static class AbstractJavaTimeJacksonDeserializer<T> extends StdDeserializer<T> { - public AbstractJavaTimeJacksonDeserializer(final Class<T> clazz) { - super(clazz); - } - - public abstract T parse(final String val); - - @Override - public T deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException { - if (!jsonParser.getText().equals(GraphSONTokens.VALUE)) - throw new IOException(String.format("Invalid format for %s - expecting '%s' with a text value in ISO-8061 format", _valueClass.getSimpleName(), GraphSONTokens.VALUE)); - - return parse(jsonParser.nextTextValue()); - } - } - - final static class DurationJacksonSerializer extends AbstractJavaTimeSerializer<Duration> { - - public DurationJacksonSerializer() { - super(Duration.class); - } - } - - final static class DurationJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Duration> { - public DurationJacksonDeserializer() { - super(Duration.class); - } - - @Override - public Duration parse(final String val) { - return Duration.parse(val); - } - } - - final static class InstantJacksonSerializer extends AbstractJavaTimeSerializer<Instant> { - - public InstantJacksonSerializer() { - super(Instant.class); - } - } - - final static class InstantJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Instant> { - public InstantJacksonDeserializer() { - super(Instant.class); - } - - @Override - public Instant parse(final String val) { - return Instant.parse(val); - } - } - - final static class LocalDateJacksonSerializer extends AbstractJavaTimeSerializer<LocalDate> { - - public LocalDateJacksonSerializer() { - super(LocalDate.class); - } - } - - final static class LocalDateJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalDate> { - public LocalDateJacksonDeserializer() { - super(LocalDate.class); - } - - @Override - public LocalDate parse(final String val) { - return LocalDate.parse(val); - } - } - - final static class LocalDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<LocalDateTime> { - - public LocalDateTimeJacksonSerializer() { - super(LocalDateTime.class); - } - } - - final static class LocalDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalDateTime> { - public LocalDateTimeJacksonDeserializer() { - super(LocalDateTime.class); - } - - @Override - public LocalDateTime parse(final String val) { - return LocalDateTime.parse(val); - } - } - - final static class LocalTimeJacksonSerializer extends AbstractJavaTimeSerializer<LocalTime> { - - public LocalTimeJacksonSerializer() { - super(LocalTime.class); - } - } - - final static class LocalTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalTime> { - public LocalTimeJacksonDeserializer() { - super(LocalTime.class); - } - - @Override - public LocalTime parse(final String val) { - return LocalTime.parse(val); - } - } - - final static class MonthDayJacksonSerializer extends AbstractJavaTimeSerializer<MonthDay> { - - public MonthDayJacksonSerializer() { - super(MonthDay.class); - } - } - - final static class MonthDayJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<MonthDay> { - public MonthDayJacksonDeserializer() { - super(MonthDay.class); - } - - @Override - public MonthDay parse(final String val) { - return MonthDay.parse(val); - } - } - - final static class OffsetDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<OffsetDateTime> { - - public OffsetDateTimeJacksonSerializer() { - super(OffsetDateTime.class); - } - } - - final static class OffsetDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<OffsetDateTime> { - public OffsetDateTimeJacksonDeserializer() { - super(OffsetDateTime.class); - } - - @Override - public OffsetDateTime parse(final String val) { - return OffsetDateTime.parse(val); - } - } - - final static class OffsetTimeJacksonSerializer extends AbstractJavaTimeSerializer<OffsetTime> { - - public OffsetTimeJacksonSerializer() { - super(OffsetTime.class); - } - } - - final static class OffsetTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<OffsetTime> { - public OffsetTimeJacksonDeserializer() { - super(OffsetTime.class); - } - - @Override - public OffsetTime parse(final String val) { - return OffsetTime.parse(val); - } - } - - final static class PeriodJacksonSerializer extends AbstractJavaTimeSerializer<Period> { - - public PeriodJacksonSerializer() { - super(Period.class); - } - } - - final static class PeriodJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Period> { - public PeriodJacksonDeserializer() { - super(Period.class); - } - - @Override - public Period parse(final String val) { - return Period.parse(val); - } - } - - final static class YearJacksonSerializer extends AbstractJavaTimeSerializer<Year> { - - public YearJacksonSerializer() { - super(Year.class); - } - } - - final static class YearJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Year> { - public YearJacksonDeserializer() { - super(Year.class); - } - - @Override - public Year parse(final String val) { - return Year.parse(val); - } - } - - final static class YearMonthJacksonSerializer extends AbstractJavaTimeSerializer<YearMonth> { - - public YearMonthJacksonSerializer() { - super(YearMonth.class); - } - } - - final static class YearMonthJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<YearMonth> { - public YearMonthJacksonDeserializer() { - super(YearMonth.class); - } - - @Override - public YearMonth parse(final String val) { - return YearMonth.parse(val); - } - } - - final static class ZonedDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<ZonedDateTime> { - - public ZonedDateTimeJacksonSerializer() { - super(ZonedDateTime.class); - } - } - - final static class ZonedDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<ZonedDateTime> { - public ZonedDateTimeJacksonDeserializer() { - super(ZonedDateTime.class); - } - - @Override - public ZonedDateTime parse(final String val) { - return ZonedDateTime.parse(val); - } - } - - final static class ZoneOffsetJacksonSerializer extends AbstractJavaTimeSerializer<ZoneOffset> { - - public ZoneOffsetJacksonSerializer() { - super(ZoneOffset.class); - } - } - - final static class ZoneOffsetJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<ZoneOffset> { - public ZoneOffsetJacksonDeserializer() { - super(ZoneOffset.class); - } - - @Override - public ZoneOffset parse(final String val) { - return ZoneOffset.of(val); - } - } -}
