You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2016/08/22 18:30:45 UTC
[08/19] tinkerpop git commit: TINKERPOP-1274: GraphSON 2.0.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TinkerPopJacksonModule.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TinkerPopJacksonModule.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TinkerPopJacksonModule.java
new file mode 100644
index 0000000..847027c
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TinkerPopJacksonModule.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.structure.io.graphson;
+
+import org.apache.tinkerpop.shaded.jackson.databind.module.SimpleModule;
+
+import java.util.Map;
+
+/**
+ * A {@link SimpleModule} extension that does the necessary work to make the automatic typed deserialization
+ * without full canonical class names work.
+ *
+ * Users of custom modules with the GraphSONMapper that want their objects to be deserialized automatically by the
+ * mapper, must extend this class with their module. It is the only required step.
+ *
+ * Using this basis module allows the serialization and deserialization of typed objects without having the whole
+ * canonical name of the serialized classes included in the Json payload. This is also necessary because Java
+ * does not provide an agnostic way to search in a classpath a find a class by its simple name. Although that could
+ * be done with an external library, later if we deem it necessary.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ */
+public abstract class TinkerPopJacksonModule extends SimpleModule {
+
+ public TinkerPopJacksonModule(String name) {
+ super(name);
+ }
+
+ public abstract Map<Class, String> getTypeDefinitions();
+
+ public abstract String getTypeNamespace();
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/ToStringGraphSONSerializer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/ToStringGraphSONSerializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/ToStringGraphSONSerializer.java
new file mode 100644
index 0000000..fbd9e00
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/ToStringGraphSONSerializer.java
@@ -0,0 +1,41 @@
+/*
+ * 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.databind.SerializerProvider;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.ToStringSerializer;
+
+import java.io.IOException;
+
+/**
+ * A different implementation of the {@link ToStringSerializer} that does not serialize types by calling
+ * `typeSerializer.writeTypePrefixForScalar()` for unknown objects, because it doesn't make sense when there is a
+ * custom types mechanism in place.
+ *
+ * @author Kevin Gallardo (https://kgdo.me)
+ */
+public class ToStringGraphSONSerializer extends ToStringSerializer {
+ @Override
+ public void serializeWithType(Object value, JsonGenerator gen, SerializerProvider provider, TypeSerializer typeSer) throws IOException {
+ this.serialize(value, gen, provider);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TypeInfo.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TypeInfo.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TypeInfo.java
new file mode 100644
index 0000000..34e0d2b
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TypeInfo.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+/**
+ * Defines how data types are handled in GraphSON through the {@link GraphSONMapper}.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public enum TypeInfo {
+ NO_TYPES,
+ PARTIAL_TYPES
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
index 776d313..ba05cca 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
@@ -79,12 +79,17 @@ public class DetachedEdge extends DetachedElement<Edge> implements Edge {
super(id, label);
this.outVertex = new DetachedVertex(outV.getValue0(), outV.getValue1(), Collections.emptyMap());
this.inVertex = new DetachedVertex(inV.getValue0(), inV.getValue1(), Collections.emptyMap());
- if (!properties.isEmpty()) {
+ if (properties != null && !properties.isEmpty()) {
this.properties = new HashMap<>();
- properties.entrySet().stream().forEach(entry -> this.properties.put(entry.getKey(), Collections.singletonList(new DetachedProperty<>(entry.getKey(), entry.getValue(), this))));
+ properties.entrySet().stream().forEach(entry -> {
+ if (Property.class.isAssignableFrom(entry.getValue().getClass())) {
+ this.properties.put(entry.getKey(), Collections.singletonList((Property)entry.getValue()));
+ } else {
+ this.properties.put(entry.getKey(), Collections.singletonList(new DetachedProperty<>(entry.getKey(), entry.getValue(), this)));
+ }
+ });
}
}
-
@Override
public String toString() {
return StringFactory.edgeString(this);
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
index 371c091..70cce37 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
@@ -76,12 +76,14 @@ public class DetachedVertex extends DetachedElement<Vertex> implements Vertex {
public DetachedVertex(final Object id, final String label, final Map<String, Object> properties) {
super(id, label);
- if (!properties.isEmpty()) {
+ if (properties != null && !properties.isEmpty()) {
this.properties = new HashMap<>();
properties.entrySet().stream().forEach(
- entry -> this.properties.put(entry.getKey(), ((List<Map<String, Object>>) entry.getValue()).stream()
- .map(m -> new DetachedVertexProperty<>(m.get(ID), entry.getKey(), m.get(VALUE), (Map<String, Object>) m.getOrDefault(PROPERTIES, new HashMap<>()), this))
- .collect(Collectors.toList())));
+ entry -> this.properties.put(entry.getKey(), (List<VertexProperty>) ((List) entry.getValue()).stream()
+ .map(m -> VertexProperty.class.isAssignableFrom(m.getClass())
+ ? m
+ : new DetachedVertexProperty<>(((Map) m).get(ID), entry.getKey(), ((Map) m).get(VALUE), (Map<String, Object>) ((Map) m).getOrDefault(PROPERTIES, new HashMap<>()), this))
+ .collect(Collectors.toList())));
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/DirectionalStarGraph.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/DirectionalStarGraph.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/DirectionalStarGraph.java
new file mode 100644
index 0000000..ed7b58c
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/DirectionalStarGraph.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.structure.util.star;
+
+import org.apache.tinkerpop.gremlin.structure.Direction;
+
+public class DirectionalStarGraph {
+ private final Direction direction;
+ private final StarGraph starGraphToSerialize;
+
+ public DirectionalStarGraph(final StarGraph starGraphToSerialize, final Direction direction) {
+ this.direction = direction;
+ this.starGraphToSerialize = starGraphToSerialize;
+ }
+
+ public Direction getDirection() {
+ return direction;
+ }
+
+ public StarGraph getStarGraphToSerialize() {
+ return starGraphToSerialize;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONDeserializer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONDeserializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONDeserializer.java
new file mode 100644
index 0000000..84a3fd4
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONDeserializer.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.structure.util.star;
+
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
+import org.apache.tinkerpop.gremlin.structure.util.Attachable;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+/**
+ * Provides helper functions for reading vertex and edges from their serialized GraphSON forms.
+ */
+public class StarGraphGraphSONDeserializer {
+
+ /**
+ * A helper function for reading vertex edges from a serialized {@link org.apache.tinkerpop.gremlin.structure.util.star.StarGraph} (i.e. a {@link java.util.Map}) generated by
+ * {@link org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializerV1d0}.
+ */
+ public static void readStarGraphEdges(final Function<Attachable<Edge>, Edge> edgeMaker,
+ final StarGraph starGraph,
+ final Map<String, Object> vertexData,
+ final String direction) throws IOException {
+ final Map<String, List<Map<String,Object>>> edgeDatas = (Map<String, List<Map<String,Object>>>) vertexData.get(direction);
+ for (Map.Entry<String, List<Map<String,Object>>> edgeData : edgeDatas.entrySet()) {
+ for (Map<String,Object> inner : edgeData.getValue()) {
+ final StarGraph.StarEdge starEdge;
+ if (direction.equals(GraphSONTokens.OUT_E))
+ starEdge = (StarGraph.StarEdge) starGraph.getStarVertex().addOutEdge(edgeData.getKey(), starGraph.addVertex(T.id, inner.get(GraphSONTokens.IN)), T.id, inner.get(GraphSONTokens.ID));
+ else
+ starEdge = (StarGraph.StarEdge) starGraph.getStarVertex().addInEdge(edgeData.getKey(), starGraph.addVertex(T.id, inner.get(GraphSONTokens.OUT)), T.id, inner.get(GraphSONTokens.ID));
+
+ if (inner.containsKey(GraphSONTokens.PROPERTIES)) {
+ final Map<String, Object> edgePropertyData = (Map<String, Object>) inner.get(GraphSONTokens.PROPERTIES);
+ for (Map.Entry<String, Object> epd : edgePropertyData.entrySet()) {
+ starEdge.property(epd.getKey(), epd.getValue());
+ }
+ }
+
+ if (edgeMaker != null) edgeMaker.apply(starEdge);
+ }
+ }
+ }
+
+ /**
+ * A helper function for reading a serialized {@link org.apache.tinkerpop.gremlin.structure.util.star.StarGraph} from a {@link java.util.Map} generated by
+ * {@link org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializerV1d0}.
+ */
+ public static StarGraph readStarGraphVertex(final Map<String, Object> vertexData) throws IOException {
+ final StarGraph starGraph = StarGraph.open();
+ starGraph.addVertex(T.id, vertexData.get(GraphSONTokens.ID), T.label, vertexData.get(GraphSONTokens.LABEL));
+ if (vertexData.containsKey(GraphSONTokens.PROPERTIES)) {
+ final Map<String, List<Map<String, Object>>> properties = (Map<String, List<Map<String, Object>>>) vertexData.get(GraphSONTokens.PROPERTIES);
+ for (Map.Entry<String, List<Map<String, Object>>> property : properties.entrySet()) {
+ for (Map<String, Object> p : property.getValue()) {
+ final StarGraph.StarVertexProperty vp = (StarGraph.StarVertexProperty) starGraph.getStarVertex().property(VertexProperty.Cardinality.list, property.getKey(), p.get(GraphSONTokens.VALUE), T.id, p.get(GraphSONTokens.ID));
+ if (p.containsKey(GraphSONTokens.PROPERTIES)) {
+ final Map<String, Object> edgePropertyData = (Map<String, Object>) p.get(GraphSONTokens.PROPERTIES);
+ for (Map.Entry<String, Object> epd : edgePropertyData.entrySet()) {
+ vp.property(epd.getKey(), epd.getValue());
+ }
+ }
+ }
+ }
+ }
+
+ return starGraph;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializer.java
deleted file mode 100644
index 3d1a16a..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializer.java
+++ /dev/null
@@ -1,250 +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.util.star;
-
-import org.apache.tinkerpop.gremlin.structure.Direction;
-import org.apache.tinkerpop.gremlin.structure.Edge;
-import org.apache.tinkerpop.gremlin.structure.Property;
-import org.apache.tinkerpop.gremlin.structure.T;
-import org.apache.tinkerpop.gremlin.structure.VertexProperty;
-import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
-import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONUtil;
-import org.apache.tinkerpop.gremlin.structure.util.Attachable;
-import org.apache.tinkerpop.gremlin.structure.util.Comparators;
-import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
-import org.apache.tinkerpop.shaded.jackson.core.JsonGenerationException;
-import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
-import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
-import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
-import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
-import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-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.TreeSet;
-import java.util.function.Function;
-
-/**
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-public class StarGraphGraphSONSerializer extends StdSerializer<StarGraphGraphSONSerializer.DirectionalStarGraph> {
- private final boolean normalize;
- public StarGraphGraphSONSerializer(final boolean normalize) {
- super(DirectionalStarGraph.class);
- this.normalize = normalize;
- }
-
- @Override
- public void serialize(final DirectionalStarGraph starGraph, final JsonGenerator jsonGenerator,
- final SerializerProvider serializerProvider) throws IOException, JsonGenerationException {
- ser(starGraph, jsonGenerator, serializerProvider, null);
- }
-
- @Override
- public void serializeWithType(final DirectionalStarGraph starGraph, final JsonGenerator jsonGenerator,
- final SerializerProvider serializerProvider,
- final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
- ser(starGraph, jsonGenerator, serializerProvider, typeSerializer);
- }
-
- private void ser(final DirectionalStarGraph directionalStarGraph, final JsonGenerator jsonGenerator,
- final SerializerProvider serializerProvider,
- final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
- final StarGraph starGraph = directionalStarGraph.getStarGraphToSerialize();
- jsonGenerator.writeStartObject();
- if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
- GraphSONUtil.writeWithType(GraphSONTokens.ID, starGraph.starVertex.id, jsonGenerator, serializerProvider, typeSerializer);
- jsonGenerator.writeStringField(GraphSONTokens.LABEL, starGraph.starVertex.label);
- if (directionalStarGraph.direction != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.IN);
- if (directionalStarGraph.direction != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.OUT);
- if (starGraph.starVertex.vertexProperties != null && !starGraph.starVertex.vertexProperties.isEmpty()) {
- jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
- if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
- final Set<String> keys = normalize ? new TreeSet<>(starGraph.starVertex.vertexProperties.keySet()) : starGraph.starVertex.vertexProperties.keySet();
- for (final String k : keys) {
- final List<VertexProperty> vp = starGraph.starVertex.vertexProperties.get(k);
- jsonGenerator.writeArrayFieldStart(k);
- if (typeSerializer != null) {
- jsonGenerator.writeString(ArrayList.class.getName());
- jsonGenerator.writeStartArray();
- }
-
- final List<VertexProperty> vertexProperties = normalize ?sort(vp, Comparators.PROPERTY_COMPARATOR) : vp;
- for (final VertexProperty property : vertexProperties) {
- 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);
-
- final Iterator<Property> metaProperties = normalize ?
- IteratorUtils.list(property.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : property.properties();
- if (metaProperties.hasNext()) {
- jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
- if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
- while (metaProperties.hasNext()) {
- final Property<Object> meta = metaProperties.next();
- GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
- }
- jsonGenerator.writeEndObject();
- }
- jsonGenerator.writeEndObject();
- }
- jsonGenerator.writeEndArray();
- if (typeSerializer != null) jsonGenerator.writeEndArray();
- }
- jsonGenerator.writeEndObject();
- }
- }
-
- private void writeEdges(final DirectionalStarGraph directionalStarGraph, final JsonGenerator jsonGenerator,
- final SerializerProvider serializerProvider,
- final TypeSerializer typeSerializer,
- final Direction direction) throws IOException, JsonProcessingException {
- // only write edges if there are some AND if the user requested them to be serialized AND if they match
- // the direction being serialized by the format
- final StarGraph starGraph = directionalStarGraph.getStarGraphToSerialize();
- final Direction edgeDirectionToSerialize = directionalStarGraph.getDirection();
- final Map<String, List<Edge>> starEdges = direction.equals(Direction.OUT) ? starGraph.starVertex.outEdges : starGraph.starVertex.inEdges;
- final boolean writeEdges = null != starEdges && edgeDirectionToSerialize != null
- && (edgeDirectionToSerialize == direction || edgeDirectionToSerialize == Direction.BOTH);
- if (writeEdges) {
- jsonGenerator.writeObjectFieldStart(direction == Direction.IN ? GraphSONTokens.IN_E : GraphSONTokens.OUT_E);
- if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
- final Set<String> keys = normalize ? new TreeSet<>(starEdges.keySet()) : starEdges.keySet();
- for (final String k : keys) {
- final List<Edge> edges = starEdges.get(k);
- jsonGenerator.writeArrayFieldStart(k);
- if (typeSerializer != null) {
- jsonGenerator.writeString(ArrayList.class.getName());
- jsonGenerator.writeStartArray();
- }
-
- final List<Edge> edgesToWrite = normalize ? sort(edges, Comparators.EDGE_COMPARATOR) : edges;
- for (final Edge edge : edgesToWrite) {
- jsonGenerator.writeStartObject();
- if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
- GraphSONUtil.writeWithType(GraphSONTokens.ID, edge.id(), jsonGenerator, serializerProvider, typeSerializer);
- GraphSONUtil.writeWithType(direction.equals(Direction.OUT) ? GraphSONTokens.IN : GraphSONTokens.OUT,
- direction.equals(Direction.OUT) ? edge.inVertex().id() : edge.outVertex().id(),
- jsonGenerator, serializerProvider, typeSerializer);
-
- final Iterator<Property<Object>> edgeProperties = normalize ?
- IteratorUtils.list(edge.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : edge.properties();
- if (edgeProperties.hasNext()) {
- jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
- if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
- while (edgeProperties.hasNext()) {
- final Property<Object> meta = edgeProperties.next();
- GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
- }
- jsonGenerator.writeEndObject();
- }
- jsonGenerator.writeEndObject();
- }
- jsonGenerator.writeEndArray();
- if (typeSerializer != null) jsonGenerator.writeEndArray();
- }
- jsonGenerator.writeEndObject();
- }
- }
-
- /**
- * A helper function for reading vertex edges from a serialized {@link StarGraph} (i.e. a {@link Map}) generated by
- * {@link StarGraphGraphSONSerializer}.
- */
- public static void readStarGraphEdges(final Function<Attachable<Edge>, Edge> edgeMaker,
- final StarGraph starGraph,
- final Map<String, Object> vertexData,
- final String direction) throws IOException {
- final Map<String, List<Map<String,Object>>> edgeDatas = (Map<String, List<Map<String,Object>>>) vertexData.get(direction);
- for (Map.Entry<String, List<Map<String,Object>>> edgeData : edgeDatas.entrySet()) {
- for (Map<String,Object> inner : edgeData.getValue()) {
- final StarGraph.StarEdge starEdge;
- if (direction.equals(GraphSONTokens.OUT_E))
- starEdge = (StarGraph.StarEdge) starGraph.getStarVertex().addOutEdge(edgeData.getKey(), starGraph.addVertex(T.id, inner.get(GraphSONTokens.IN)), T.id, inner.get(GraphSONTokens.ID));
- else
- starEdge = (StarGraph.StarEdge) starGraph.getStarVertex().addInEdge(edgeData.getKey(), starGraph.addVertex(T.id, inner.get(GraphSONTokens.OUT)), T.id, inner.get(GraphSONTokens.ID));
-
- if (inner.containsKey(GraphSONTokens.PROPERTIES)) {
- final Map<String, Object> edgePropertyData = (Map<String, Object>) inner.get(GraphSONTokens.PROPERTIES);
- for (Map.Entry<String, Object> epd : edgePropertyData.entrySet()) {
- starEdge.property(epd.getKey(), epd.getValue());
- }
- }
-
- if (edgeMaker != null) edgeMaker.apply(starEdge);
- }
- }
- }
-
- /**
- * A helper function for reading a serialized {@link StarGraph} from a {@link Map} generated by
- * {@link StarGraphGraphSONSerializer}.
- */
- public static StarGraph readStarGraphVertex(final Map<String, Object> vertexData) throws IOException {
- final StarGraph starGraph = StarGraph.open();
- starGraph.addVertex(T.id, vertexData.get(GraphSONTokens.ID), T.label, vertexData.get(GraphSONTokens.LABEL));
- if (vertexData.containsKey(GraphSONTokens.PROPERTIES)) {
- final Map<String, List<Map<String, Object>>> properties = (Map<String, List<Map<String, Object>>>) vertexData.get(GraphSONTokens.PROPERTIES);
- for (Map.Entry<String, List<Map<String, Object>>> property : properties.entrySet()) {
- for (Map<String, Object> p : property.getValue()) {
- final StarGraph.StarVertexProperty vp = (StarGraph.StarVertexProperty) starGraph.getStarVertex().property(VertexProperty.Cardinality.list, property.getKey(), p.get(GraphSONTokens.VALUE), T.id, p.get(GraphSONTokens.ID));
- if (p.containsKey(GraphSONTokens.PROPERTIES)) {
- final Map<String, Object> edgePropertyData = (Map<String, Object>) p.get(GraphSONTokens.PROPERTIES);
- for (Map.Entry<String, Object> epd : edgePropertyData.entrySet()) {
- vp.property(epd.getKey(), epd.getValue());
- }
- }
- }
- }
- }
-
- return starGraph;
- }
-
- private static <S> List<S> sort(final List<S> listToSort, final Comparator comparator) {
- Collections.sort(listToSort, comparator);
- return listToSort;
- }
-
- public static class DirectionalStarGraph {
- private final Direction direction;
- private final StarGraph starGraphToSerialize;
-
- public DirectionalStarGraph(final StarGraph starGraphToSerialize, final Direction direction) {
- this.direction = direction;
- this.starGraphToSerialize = starGraphToSerialize;
- }
-
- public Direction getDirection() {
- return direction;
- }
-
- public StarGraph getStarGraphToSerialize() {
- return starGraphToSerialize;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV1d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV1d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV1d0.java
new file mode 100644
index 0000000..01cb6d6
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV1d0.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.structure.util.star;
+
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONUtil;
+import org.apache.tinkerpop.gremlin.structure.util.Comparators;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerationException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+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.TreeSet;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class StarGraphGraphSONSerializerV1d0 extends StdSerializer<DirectionalStarGraph> {
+ private final boolean normalize;
+ public StarGraphGraphSONSerializerV1d0(final boolean normalize) {
+ super(DirectionalStarGraph.class);
+ this.normalize = normalize;
+ }
+
+ @Override
+ public void serialize(final DirectionalStarGraph starGraph, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider) throws IOException, JsonGenerationException {
+ ser(starGraph, jsonGenerator, serializerProvider, null);
+ }
+
+ @Override
+ public void serializeWithType(final DirectionalStarGraph starGraph, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider,
+ final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
+ ser(starGraph, jsonGenerator, serializerProvider, typeSerializer);
+ }
+
+ private void ser(final DirectionalStarGraph directionalStarGraph, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider,
+ final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
+ final StarGraph starGraph = directionalStarGraph.getStarGraphToSerialize();
+ jsonGenerator.writeStartObject();
+ if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+ GraphSONUtil.writeWithType(GraphSONTokens.ID, starGraph.starVertex.id, jsonGenerator, serializerProvider, typeSerializer);
+ jsonGenerator.writeStringField(GraphSONTokens.LABEL, starGraph.starVertex.label);
+ if (directionalStarGraph.getDirection() != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.IN);
+ if (directionalStarGraph.getDirection() != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.OUT);
+ if (starGraph.starVertex.vertexProperties != null && !starGraph.starVertex.vertexProperties.isEmpty()) {
+ jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
+ if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+ final Set<String> keys = normalize ? new TreeSet<>(starGraph.starVertex.vertexProperties.keySet()) : starGraph.starVertex.vertexProperties.keySet();
+ for (final String k : keys) {
+ final List<VertexProperty> vp = starGraph.starVertex.vertexProperties.get(k);
+ jsonGenerator.writeArrayFieldStart(k);
+ if (typeSerializer != null) {
+ jsonGenerator.writeString(ArrayList.class.getName());
+ jsonGenerator.writeStartArray();
+ }
+
+ final List<VertexProperty> vertexProperties = normalize ? sort(vp, Comparators.PROPERTY_COMPARATOR) : vp;
+ for (final VertexProperty property : vertexProperties) {
+ 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);
+
+ final Iterator<Property> metaProperties = normalize ?
+ IteratorUtils.list(property.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : property.properties();
+ if (metaProperties.hasNext()) {
+ jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
+ if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+ while (metaProperties.hasNext()) {
+ final Property<Object> meta = metaProperties.next();
+ GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
+ }
+ jsonGenerator.writeEndObject();
+ }
+ jsonGenerator.writeEndObject();
+ }
+ jsonGenerator.writeEndArray();
+ if (typeSerializer != null) jsonGenerator.writeEndArray();
+ }
+ jsonGenerator.writeEndObject();
+ }
+ // For some reason, this wasn't closed.
+ jsonGenerator.writeEndObject();
+ }
+
+ private void writeEdges(final DirectionalStarGraph directionalStarGraph, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider,
+ final TypeSerializer typeSerializer,
+ final Direction direction) throws IOException, JsonProcessingException {
+ // only write edges if there are some AND if the user requested them to be serialized AND if they match
+ // the direction being serialized by the format
+ final StarGraph starGraph = directionalStarGraph.getStarGraphToSerialize();
+ final Direction edgeDirectionToSerialize = directionalStarGraph.getDirection();
+ final Map<String, List<Edge>> starEdges = direction.equals(Direction.OUT) ? starGraph.starVertex.outEdges : starGraph.starVertex.inEdges;
+ final boolean writeEdges = null != starEdges && edgeDirectionToSerialize != null
+ && (edgeDirectionToSerialize == direction || edgeDirectionToSerialize == Direction.BOTH);
+ if (writeEdges) {
+ jsonGenerator.writeObjectFieldStart(direction == Direction.IN ? GraphSONTokens.IN_E : GraphSONTokens.OUT_E);
+ if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+ final Set<String> keys = normalize ? new TreeSet<>(starEdges.keySet()) : starEdges.keySet();
+ for (final String k : keys) {
+ final List<Edge> edges = starEdges.get(k);
+ jsonGenerator.writeArrayFieldStart(k);
+ if (typeSerializer != null) {
+ jsonGenerator.writeString(ArrayList.class.getName());
+ jsonGenerator.writeStartArray();
+ }
+
+ final List<Edge> edgesToWrite = normalize ? sort(edges, Comparators.EDGE_COMPARATOR) : edges;
+ for (final Edge edge : edgesToWrite) {
+ jsonGenerator.writeStartObject();
+ if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+ GraphSONUtil.writeWithType(GraphSONTokens.ID, edge.id(), jsonGenerator, serializerProvider, typeSerializer);
+ GraphSONUtil.writeWithType(direction.equals(Direction.OUT) ? GraphSONTokens.IN : GraphSONTokens.OUT,
+ direction.equals(Direction.OUT) ? edge.inVertex().id() : edge.outVertex().id(),
+ jsonGenerator, serializerProvider, typeSerializer);
+
+ final Iterator<Property<Object>> edgeProperties = normalize ?
+ IteratorUtils.list(edge.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : edge.properties();
+ if (edgeProperties.hasNext()) {
+ jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES);
+ if (typeSerializer != null) jsonGenerator.writeStringField(GraphSONTokens.CLASS, HashMap.class.getName());
+ while (edgeProperties.hasNext()) {
+ final Property<Object> meta = edgeProperties.next();
+ GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
+ }
+ jsonGenerator.writeEndObject();
+ }
+ jsonGenerator.writeEndObject();
+ }
+ jsonGenerator.writeEndArray();
+ if (typeSerializer != null) jsonGenerator.writeEndArray();
+ }
+ jsonGenerator.writeEndObject();
+ }
+ }
+
+ static <S> List<S> sort(final List<S> listToSort, final Comparator comparator) {
+ Collections.sort(listToSort, comparator);
+ return listToSort;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV2d0.java
new file mode 100644
index 0000000..04d65c5
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraphGraphSONSerializerV2d0.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.structure.util.star;
+
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTokens;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONUtil;
+import org.apache.tinkerpop.gremlin.structure.util.Comparators;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerationException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class StarGraphGraphSONSerializerV2d0 extends StdSerializer<DirectionalStarGraph> {
+ private final boolean normalize;
+ public StarGraphGraphSONSerializerV2d0(final boolean normalize) {
+ super(DirectionalStarGraph.class);
+ this.normalize = normalize;
+ }
+
+ @Override
+ public void serialize(final DirectionalStarGraph starGraph, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider) throws IOException, JsonGenerationException {
+ ser(starGraph, jsonGenerator, serializerProvider, null);
+ }
+
+ @Override
+ public void serializeWithType(final DirectionalStarGraph starGraph, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider,
+ final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
+ ser(starGraph, jsonGenerator, serializerProvider, typeSerializer);
+ }
+
+ private void ser(final DirectionalStarGraph directionalStarGraph, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider,
+ final TypeSerializer typeSerializer) throws IOException, JsonProcessingException {
+ final StarGraph starGraph = directionalStarGraph.getStarGraphToSerialize();
+ GraphSONUtil.writeStartObject(starGraph, jsonGenerator, typeSerializer);
+ GraphSONUtil.writeWithType(GraphSONTokens.ID, starGraph.starVertex.id, jsonGenerator, serializerProvider, typeSerializer);
+ jsonGenerator.writeStringField(GraphSONTokens.LABEL, starGraph.starVertex.label);
+ if (directionalStarGraph.getDirection() != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.IN);
+ if (directionalStarGraph.getDirection() != null) writeEdges(directionalStarGraph, jsonGenerator, serializerProvider, typeSerializer, Direction.OUT);
+ if (starGraph.starVertex.vertexProperties != null && !starGraph.starVertex.vertexProperties.isEmpty()) {
+ jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+ GraphSONUtil.writeStartObject(starGraph, jsonGenerator, typeSerializer);
+ final Set<String> keys = normalize ? new TreeSet<>(starGraph.starVertex.vertexProperties.keySet()) : starGraph.starVertex.vertexProperties.keySet();
+ for (final String k : keys) {
+ final List<VertexProperty> vp = starGraph.starVertex.vertexProperties.get(k);
+ jsonGenerator.writeFieldName(k);
+ GraphSONUtil.writeStartArray(k, jsonGenerator, typeSerializer);
+
+ final List<VertexProperty> vertexProperties = normalize ?sort(vp, Comparators.PROPERTY_COMPARATOR) : vp;
+ for (final VertexProperty property : vertexProperties) {
+ GraphSONUtil.writeStartObject(property, jsonGenerator, typeSerializer);
+ GraphSONUtil.writeWithType(GraphSONTokens.ID, property.id(), jsonGenerator, serializerProvider, typeSerializer);
+ GraphSONUtil.writeWithType(GraphSONTokens.VALUE, property.value(), jsonGenerator, serializerProvider, typeSerializer);
+
+ final Iterator<Property> metaProperties = normalize ?
+ IteratorUtils.list(property.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : property.properties();
+ if (metaProperties.hasNext()) {
+ jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+ GraphSONUtil.writeStartObject(metaProperties, jsonGenerator, typeSerializer);
+
+ while (metaProperties.hasNext()) {
+ final Property<Object> meta = metaProperties.next();
+ GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
+ }
+ GraphSONUtil.writeEndObject(metaProperties, jsonGenerator, typeSerializer);
+ }
+ GraphSONUtil.writeEndObject(property, jsonGenerator, typeSerializer);
+ }
+ GraphSONUtil.writeEndArray(k, jsonGenerator, typeSerializer);
+ }
+ GraphSONUtil.writeEndObject(starGraph, jsonGenerator, typeSerializer);
+ }
+ GraphSONUtil.writeEndObject(starGraph, jsonGenerator, typeSerializer);
+ }
+
+ private void writeEdges(final DirectionalStarGraph directionalStarGraph, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider,
+ final TypeSerializer typeSerializer,
+ final Direction direction) throws IOException, JsonProcessingException {
+ // only write edges if there are some AND if the user requested them to be serialized AND if they match
+ // the direction being serialized by the format
+ final StarGraph starGraph = directionalStarGraph.getStarGraphToSerialize();
+ final Direction edgeDirectionToSerialize = directionalStarGraph.getDirection();
+ final Map<String, List<Edge>> starEdges = direction.equals(Direction.OUT) ? starGraph.starVertex.outEdges : starGraph.starVertex.inEdges;
+ final boolean writeEdges = null != starEdges && edgeDirectionToSerialize != null
+ && (edgeDirectionToSerialize == direction || edgeDirectionToSerialize == Direction.BOTH);
+ if (writeEdges) {
+ jsonGenerator.writeFieldName(direction == Direction.IN ? GraphSONTokens.IN_E : GraphSONTokens.OUT_E);
+ GraphSONUtil.writeStartObject(directionalStarGraph, jsonGenerator, typeSerializer);
+ final Set<String> keys = normalize ? new TreeSet<>(starEdges.keySet()) : starEdges.keySet();
+ for (final String k : keys) {
+ final List<Edge> edges = starEdges.get(k);
+ jsonGenerator.writeFieldName(k);
+ GraphSONUtil.writeStartArray(k, jsonGenerator, typeSerializer);
+
+ final List<Edge> edgesToWrite = normalize ? sort(edges, Comparators.EDGE_COMPARATOR) : edges;
+ for (final Edge edge : edgesToWrite) {
+ GraphSONUtil.writeStartObject(edge, jsonGenerator, typeSerializer);
+ GraphSONUtil.writeWithType(GraphSONTokens.ID, edge.id(), jsonGenerator, serializerProvider, typeSerializer);
+ GraphSONUtil.writeWithType(direction.equals(Direction.OUT) ? GraphSONTokens.IN : GraphSONTokens.OUT,
+ direction.equals(Direction.OUT) ? edge.inVertex().id() : edge.outVertex().id(),
+ jsonGenerator, serializerProvider, typeSerializer);
+
+ final Iterator<Property<Object>> edgeProperties = normalize ?
+ IteratorUtils.list(edge.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : edge.properties();
+ if (edgeProperties.hasNext()) {
+ jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES);
+ GraphSONUtil.writeStartObject(edge, jsonGenerator, typeSerializer);
+ while (edgeProperties.hasNext()) {
+ final Property<Object> meta = edgeProperties.next();
+ GraphSONUtil.writeWithType(meta.key(), meta.value(), jsonGenerator, serializerProvider, typeSerializer);
+ }
+ GraphSONUtil.writeEndObject(edge, jsonGenerator, typeSerializer);
+ }
+ GraphSONUtil.writeEndObject(edge, jsonGenerator, typeSerializer);
+ }
+ GraphSONUtil.writeEndArray(k, jsonGenerator, typeSerializer);
+ }
+ GraphSONUtil.writeEndObject(directionalStarGraph, jsonGenerator, typeSerializer);
+ }
+ }
+
+ private static <S> List<S> sort(final List<S> listToSort, final Comparator comparator) {
+ Collections.sort(listToSort, comparator);
+ return listToSort;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
index c7549f9..4980adf 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
@@ -19,9 +19,9 @@
package org.apache.tinkerpop.gremlin.structure.io.graphson;
import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
-import org.apache.tinkerpop.shaded.kryo.io.Input;
-import org.apache.tinkerpop.shaded.kryo.io.Output;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -39,11 +39,26 @@ import java.time.Year;
import java.time.YearMonth;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
import static org.junit.Assert.assertEquals;
+@RunWith(Parameterized.class)
public class GraphSONMapperEmbeddedTypeTest {
- private final ObjectMapper mapper = GraphSONMapper.build().embedTypes(true).create().createMapper();
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Iterable<Object[]> data() {
+ return Arrays.asList(new Object[][]{
+ {GraphSONMapper.build().version(GraphSONVersion.V1_0).embedTypes(true).create().createMapper()},
+ {GraphSONMapper.build().version(GraphSONVersion.V2_0).typeInfo(TypeInfo.PARTIAL_TYPES).create()
+ .createMapper()},
+ });
+ }
+
+ @Parameterized.Parameter
+ public ObjectMapper mapper;
@Test
public void shouldHandleDuration()throws Exception {
@@ -122,6 +137,40 @@ public class GraphSONMapperEmbeddedTypeTest {
assertEquals(o, serializeDeserialize(o, ZoneOffset.class));
}
+ @Test
+ public void shouldHandleMapWithTypesUsingEmbedTypeSetting() throws Exception {
+ final ObjectMapper mapper = GraphSONMapper.build()
+ .version(GraphSONVersion.V1_0)
+ .typeInfo(TypeInfo.PARTIAL_TYPES)
+ .create()
+ .createMapper();
+
+ final Map<String,Object> m = new HashMap<>();
+ m.put("test", 100L);
+
+ final String json = mapper.writeValueAsString(m);
+ final Map read = mapper.readValue(json, HashMap.class);
+
+ assertEquals(100L, read.get("test"));
+ }
+
+ @Test
+ public void shouldNotHandleMapWithTypesUsingEmbedTypeSetting() throws Exception {
+ final ObjectMapper mapper = GraphSONMapper.build()
+ .version(GraphSONVersion.V1_0)
+ .typeInfo(TypeInfo.NO_TYPES)
+ .create()
+ .createMapper();
+
+ final Map<String,Object> m = new HashMap<>();
+ m.put("test", 100L);
+
+ final String json = mapper.writeValueAsString(m);
+ final Map read = mapper.readValue(json, HashMap.class);
+
+ assertEquals(100, read.get("test"));
+ }
+
public <T> T serializeDeserialize(final Object o, final Class<T> clazz) throws Exception {
try (final ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
mapper.writeValue(stream, o);
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
index 41e24c6..4b2e98f 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperTest.java
@@ -21,6 +21,8 @@ package org.apache.tinkerpop.gremlin.structure.io.graphson;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation;
import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
import java.time.Duration;
import java.time.Instant;
@@ -35,12 +37,25 @@ import java.time.Year;
import java.time.YearMonth;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
+import java.util.Arrays;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.__;
import static org.junit.Assert.assertEquals;
+@RunWith(Parameterized.class)
public class GraphSONMapperTest {
- private final ObjectMapper mapper = GraphSONMapper.build().embedTypes(false).create().createMapper();
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Iterable<Object[]> data() {
+ return Arrays.asList(new Object[][]{
+ {GraphSONMapper.build().version(GraphSONVersion.V1_0).embedTypes(false).create().createMapper()},
+ {GraphSONMapper.build().version(GraphSONVersion.V2_0).typeInfo(TypeInfo.NO_TYPES).create().createMapper()},
+ });
+ }
+
+ @Parameterized.Parameter
+ public ObjectMapper mapper;
+
@Test
public void shouldHandleTraversalExplanation() throws Exception {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java
new file mode 100644
index 0000000..c2ad05e
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperV2d0PartialEmbeddedTypeTest.java
@@ -0,0 +1,344 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.structure.io.graphson;
+
+import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+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.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests automatic typed serialization/deserialization for GraphSON 2.0.
+ */
+public class GraphSONMapperV2d0PartialEmbeddedTypeTest {
+
+ private final ObjectMapper mapper = GraphSONMapper.build()
+ .version(GraphSONVersion.V2_0)
+ .typeInfo(TypeInfo.PARTIAL_TYPES)
+ .create()
+ .createMapper();
+
+ @Test
+ public void shouldHandleDurationAuto() throws Exception {
+ final Duration o = Duration.ZERO;
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleInstantAuto() throws Exception {
+ final Instant o = Instant.ofEpochMilli(System.currentTimeMillis());
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleLocalDateAuto() throws Exception {
+ final LocalDate o = LocalDate.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleLocalDateTimeAuto() throws Exception {
+ final LocalDateTime o = LocalDateTime.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleLocalTimeAuto() throws Exception {
+ final LocalTime o = LocalTime.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleMonthDayAuto() throws Exception {
+ final MonthDay o = MonthDay.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleOffsetDateTimeAuto() throws Exception {
+ final OffsetDateTime o = OffsetDateTime.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleOffsetTimeAuto() throws Exception {
+ final OffsetTime o = OffsetTime.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandlePeriodAuto() throws Exception {
+ final Period o = Period.ofDays(3);
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleYearAuto() throws Exception {
+ final Year o = Year.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleYearMonthAuto() throws Exception {
+ final YearMonth o = YearMonth.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleZonedDateTimeAuto() throws Exception {
+ final ZonedDateTime o = ZonedDateTime.now();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ public void shouldHandleZonedOffsetAuto() throws Exception {
+ final ZoneOffset o = ZonedDateTime.now().getOffset();
+ assertEquals(o, serializeDeserializeAuto(o));
+ }
+
+ @Test
+ // Trying to fail the TypeDeserializer type detection
+ public void shouldSerializeDeserializeNestedCollectionsAndMapAndTypedValuesCorrectly() throws Exception {
+ UUID uuid = UUID.randomUUID();
+ List myList = new ArrayList<>();
+
+ List myList2 = new ArrayList<>();
+ myList2.add(UUID.randomUUID());
+ myList2.add(33L);
+ myList2.add(84);
+ Map map2 = new HashMap<>();
+ map2.put("eheh", UUID.randomUUID());
+ map2.put("normal", "normal");
+ myList2.add(map2);
+
+ Map<String, Object> map1 = new HashMap<>();
+ map1.put("hello", "world");
+ map1.put("test", uuid);
+ map1.put("hehe", myList2);
+ myList.add(map1);
+
+ myList.add("kjkj");
+ myList.add(UUID.randomUUID());
+ assertEquals(myList, serializeDeserializeAuto(myList));
+
+ // no "@value" property
+ String s = "{\""+GraphSONTokens.VALUETYPE+"\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":uuid\", \"test\":2}";
+ Map map = new LinkedHashMap<>();
+ map.put(GraphSONTokens.VALUETYPE, "gremlin:uuid");
+ map.put("test", 2);
+ Object res = mapper.readValue(s, Object.class);
+ assertEquals(map, res);
+
+ // "@value" and "@type" property reversed
+ s = "{\""+GraphSONTokens.VALUEPROP+"\":2, \""+ GraphSONTokens.VALUETYPE+"\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":int64\"}";
+ res = mapper.readValue(s, Object.class);
+ assertEquals(res, 2L);
+ assertEquals(res.getClass(), Long.class);
+
+ // no "@type" property.
+ s = "{\""+GraphSONTokens.VALUEPROP+"\":2, \"id\":2}";
+ map = new LinkedHashMap<>();
+ map.put(GraphSONTokens.VALUEPROP, 2);
+ map.put("id", 2);
+ res = mapper.readValue(s, Object.class);
+ assertEquals(res, map);
+ }
+
+ @Test
+ public void shouldFailIfMoreThanTwoPropertiesInATypePattern() {
+ String s = "{\"" + GraphSONTokens.VALUEPROP + "\":2, \"" + GraphSONTokens.VALUETYPE + "\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":int64\", \"hello\": \"world\"}";
+ try {
+ mapper.readValue(s, Object.class);
+ fail("Should have failed deserializing because there's more than properties in the type.");
+ } catch (IOException e) {
+ assertThat(e.getMessage(), containsString("Detected the type pattern in the JSON payload but the map containing the types and values contains other fields. This is not allowed by the deserializer."));
+ }
+ s = "{\"" + GraphSONTokens.VALUETYPE + "\":\""+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":int64\",\"" + GraphSONTokens.VALUEPROP + "\":2, \"hello\": \"world\"}";
+ try {
+ mapper.readValue(s, Object.class);
+ fail("Should have failed deserializing because there's more than properties in the type.");
+ } catch (IOException e) {
+ assertThat(e.getMessage(), containsString("Detected the type pattern in the JSON payload but the map containing the types and values contains other fields. This is not allowed by the deserializer."));
+ }
+ }
+
+ @Test
+ public void shouldFailIfTypeSpecifiedIsNotSameTypeInPayload() {
+ final ZoneOffset o = ZonedDateTime.now().getOffset();
+ final ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ try {
+ mapper.writeValue(stream, o);
+ final InputStream inputStream = new ByteArrayInputStream(stream.toByteArray());
+ // What has been serialized is a ZoneOffset with the type, but the user explicitly requires another type.
+ mapper.readValue(inputStream, Instant.class);
+ fail("Should have failed decoding the value");
+ } catch (Exception e) {
+ assertThat(e.getMessage(), containsString("Could not deserialize the JSON value as required. Nested exception: java.lang.InstantiationException: Cannot deserialize the value with the detected type contained in the JSON ('"+GraphSONTokens.GREMLIN_TYPE_NAMESPACE +":zoneoffset') to the type specified in parameter to the object mapper (class java.time.Instant). Those types are incompatible."));
+ }
+ }
+
+ @Test
+ public void shouldHandleRawPOJOs() throws Exception {
+ final FunObject funObject = new FunObject();
+ funObject.setVal("test");
+ assertEquals(funObject.toString(), serializeDeserialize(funObject, FunObject.class).toString());
+ assertEquals(funObject.getClass(), serializeDeserialize(funObject, FunObject.class).getClass());
+ }
+
+ @Test
+ public void shouldHandleMapWithTypesUsingEmbedTypeSetting() throws Exception {
+ final ObjectMapper mapper = GraphSONMapper.build()
+ .version(GraphSONVersion.V2_0)
+ .embedTypes(true)
+ .create()
+ .createMapper();
+
+ final Map<String,Object> m = new HashMap<>();
+ m.put("test", 100L);
+
+ final String json = mapper.writeValueAsString(m);
+ final Map read = mapper.readValue(json, HashMap.class);
+
+ assertEquals(100L, read.get("test"));
+ }
+
+ @Test
+ public void shouldNotHandleMapWithTypesUsingEmbedTypeSetting() throws Exception {
+ final ObjectMapper mapper = GraphSONMapper.build()
+ .version(GraphSONVersion.V2_0)
+ .embedTypes(false)
+ .create()
+ .createMapper();
+
+ final Map<String,Object> m = new HashMap<>();
+ m.put("test", 100L);
+
+ final String json = mapper.writeValueAsString(m);
+ final Map read = mapper.readValue(json, HashMap.class);
+
+ assertEquals(100, read.get("test"));
+ }
+
+ @Test
+ public void shouldLooseTypesInfoWithGraphSONNoType() throws Exception {
+ ObjectMapper mapper = GraphSONMapper.build()
+ .version(GraphSONVersion.V2_0)
+ .typeInfo(TypeInfo.NO_TYPES)
+ .create()
+ .createMapper();
+
+ UUID uuid = UUID.randomUUID();
+ List myList = new ArrayList<>();
+
+ List myList2 = new ArrayList<>();
+ myList2.add(UUID.randomUUID());
+ myList2.add(33L);
+ myList2.add(84);
+ Map map2 = new HashMap<>();
+ map2.put("eheh", UUID.randomUUID());
+ map2.put("normal", "normal");
+ myList2.add(map2);
+
+ Map<String, Object> map1 = new HashMap<>();
+ map1.put("hello", "world");
+ map1.put("test", uuid);
+ map1.put("hehe", myList2);
+ myList.add(map1);
+
+ myList.add("kjkj");
+ myList.add(UUID.randomUUID());
+
+ String json = mapper.writeValueAsString(myList);
+ Object read = mapper.readValue(json, Object.class);
+
+ // Not equals because of type loss
+ assertNotEquals(myList, read);
+ }
+
+
+ // Class needs to be defined as statics as it's a nested class.
+ public static class FunObject {
+ private String val;
+
+ public FunObject() {
+ }
+
+ public String getVal() {
+ return this.val;
+ }
+
+ public void setVal(String s) {
+ this.val = s;
+ }
+
+ public String toString() {
+ return this.val;
+ }
+ }
+
+ public <T> T serializeDeserialize(final Object o, final Class<T> clazz) throws Exception {
+ try (final ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
+ mapper.writeValue(stream, o);
+
+ try (final InputStream inputStream = new ByteArrayInputStream(stream.toByteArray())) {
+ return mapper.readValue(inputStream, clazz);
+ }
+ }
+ }
+
+ public <T> T serializeDeserializeAuto(final Object o) throws Exception {
+ try (final ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
+ mapper.writeValue(stream, o);
+
+ try (final InputStream inputStream = new ByteArrayInputStream(stream.toByteArray())) {
+ // Object.class is the wildcard that triggers the auto discovery.
+ return (T)mapper.readValue(inputStream, Object.class);
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/115eb3c7/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractGraphSONMessageSerializerV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractGraphSONMessageSerializerV2d0.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractGraphSONMessageSerializerV2d0.java
new file mode 100644
index 0000000..d0303eb
--- /dev/null
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/AbstractGraphSONMessageSerializerV2d0.java
@@ -0,0 +1,248 @@
+/*
+ * 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.driver.ser;
+
+import groovy.json.JsonBuilder;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufAllocator;
+import io.netty.util.ReferenceCountUtil;
+import org.apache.tinkerpop.gremlin.driver.message.RequestMessage;
+import org.apache.tinkerpop.gremlin.driver.message.ResponseMessage;
+import org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONIo;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONMapper;
+import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONUtil;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerationException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
+import org.apache.tinkerpop.shaded.jackson.core.type.TypeReference;
+import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
+import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
+import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.module.SimpleModule;
+import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public abstract class AbstractGraphSONMessageSerializerV2d0 extends AbstractMessageSerializer {
+ private static final Logger logger = LoggerFactory.getLogger(AbstractGraphSONMessageSerializerV2d0.class);
+
+ protected ObjectMapper mapper;
+
+ protected static final String TOKEN_USE_MAPPER_FROM_GRAPH = "useMapperFromGraph";
+
+ protected final TypeReference<Map<String, Object>> mapTypeReference = new TypeReference<Map<String, Object>>() {
+ };
+
+ public AbstractGraphSONMessageSerializerV2d0() {
+ final GraphSONMapper.Builder builder = configureBuilder(GraphSONMapper.build());
+ mapper = builder.create().createMapper();
+ }
+
+ public AbstractGraphSONMessageSerializerV2d0(final GraphSONMapper mapper) {
+ this.mapper = mapper.createMapper();
+ }
+
+ abstract byte[] obtainHeader();
+
+ abstract GraphSONMapper.Builder configureBuilder(final GraphSONMapper.Builder builder);
+
+ @Override
+ public void configure(final Map<String, Object> config, final Map<String, Graph> graphs) {
+ final GraphSONMapper.Builder initialBuilder;
+ final Object graphToUseForMapper = config.get(TOKEN_USE_MAPPER_FROM_GRAPH);
+ if (graphToUseForMapper != null) {
+ if (null == graphs) throw new IllegalStateException(String.format(
+ "No graphs have been provided to the serializer and therefore %s is not a valid configuration", TOKEN_USE_MAPPER_FROM_GRAPH));
+
+ final Graph g = graphs.get(graphToUseForMapper.toString());
+ if (null == g) throw new IllegalStateException(String.format(
+ "There is no graph named [%s] configured to be used in the %s setting",
+ graphToUseForMapper, TOKEN_USE_MAPPER_FROM_GRAPH));
+
+ // a graph was found so use the mapper it constructs. this allows graphson to be auto-configured with any
+ // custom classes that the implementation allows for
+ initialBuilder = g.io(GraphSONIo.build()).mapper();
+ } else {
+ // no graph was supplied so just use the default - this will likely be the case when using a graph
+ // with no custom classes or a situation where the user needs complete control like when using two
+ // distinct implementations each with their own custom classes.
+ initialBuilder = GraphSONMapper.build();
+ }
+
+ addIoRegistries(config, initialBuilder);
+
+ mapper = configureBuilder(initialBuilder).create().createMapper();
+ }
+
+ @Override
+ public ByteBuf serializeResponseAsBinary(final ResponseMessage responseMessage, final ByteBufAllocator allocator) throws SerializationException {
+ ByteBuf encodedMessage = null;
+ try {
+ final byte[] payload = mapper.writeValueAsBytes(responseMessage);
+ encodedMessage = allocator.buffer(payload.length);
+ encodedMessage.writeBytes(payload);
+
+ return encodedMessage;
+ } catch (Exception ex) {
+ if (encodedMessage != null) ReferenceCountUtil.release(encodedMessage);
+
+ logger.warn("Response [{}] could not be serialized by {}.", responseMessage.toString(), AbstractGraphSONMessageSerializerV2d0.class.getName());
+ throw new SerializationException(ex);
+ }
+ }
+
+ @Override
+ public ByteBuf serializeRequestAsBinary(final RequestMessage requestMessage, final ByteBufAllocator allocator) throws SerializationException {
+ ByteBuf encodedMessage = null;
+ try {
+ final byte[] header = obtainHeader();
+ final byte[] payload = mapper.writeValueAsBytes(requestMessage);
+
+ encodedMessage = allocator.buffer(header.length + payload.length);
+ encodedMessage.writeBytes(header);
+ encodedMessage.writeBytes(payload);
+
+ return encodedMessage;
+ } catch (Exception ex) {
+ if (encodedMessage != null) ReferenceCountUtil.release(encodedMessage);
+
+ logger.warn("Request [{}] could not be serialized by {}.", requestMessage.toString(), AbstractGraphSONMessageSerializerV2d0.class.getName());
+ throw new SerializationException(ex);
+ }
+ }
+
+ @Override
+ public RequestMessage deserializeRequest(final ByteBuf msg) throws SerializationException {
+ try {
+ final byte[] payload = new byte[msg.readableBytes()];
+ msg.readBytes(payload);
+ return mapper.readValue(payload, RequestMessage.class);
+ } catch (Exception ex) {
+ logger.warn("Request [{}] could not be deserialized by {}.", msg, AbstractGraphSONMessageSerializerV2d0.class.getName());
+ throw new SerializationException(ex);
+ }
+ }
+
+ @Override
+ public ResponseMessage deserializeResponse(final ByteBuf msg) throws SerializationException {
+ try {
+ final byte[] payload = new byte[msg.readableBytes()];
+ msg.readBytes(payload);
+ final Map<String, Object> responseData = mapper.readValue(payload, mapTypeReference);
+ final Map<String, Object> status = (Map<String, Object>) responseData.get(SerTokens.TOKEN_STATUS);
+ final Map<String, Object> result = (Map<String, Object>) responseData.get(SerTokens.TOKEN_RESULT);
+ return ResponseMessage.build(UUID.fromString(responseData.get(SerTokens.TOKEN_REQUEST).toString()))
+ .code(ResponseStatusCode.getFromValue((Integer) status.get(SerTokens.TOKEN_CODE)))
+ .statusMessage(status.get(SerTokens.TOKEN_MESSAGE).toString())
+ .statusAttributes((Map<String, Object>) status.get(SerTokens.TOKEN_ATTRIBUTES))
+ .result(result.get(SerTokens.TOKEN_DATA))
+ .responseMetaData((Map<String, Object>) result.get(SerTokens.TOKEN_META))
+ .create();
+ } catch (Exception ex) {
+ logger.warn("Response [{}] could not be deserialized by {}.", msg, AbstractGraphSONMessageSerializerV2d0.class.getName());
+ throw new SerializationException(ex);
+ }
+ }
+
+ public final static class GremlinServerModule extends SimpleModule {
+ public GremlinServerModule() {
+ super("graphson-gremlin-server");
+ addSerializer(JsonBuilder.class, new JsonBuilderJacksonSerializer());
+ addSerializer(ResponseMessage.class, new ResponseMessageSerializer());
+ }
+ }
+
+ public final static class JsonBuilderJacksonSerializer extends StdSerializer<JsonBuilder> {
+ public JsonBuilderJacksonSerializer() {
+ super(JsonBuilder.class);
+ }
+
+ @Override
+ public void serialize(final JsonBuilder json, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
+ throws IOException, JsonGenerationException {
+ // the JSON from the builder will already be started/ended as array or object...just need to surround it
+ // with appropriate chars to fit into the serialization pattern.
+ jsonGenerator.writeRaw(":");
+ jsonGenerator.writeRaw(json.toString());
+ jsonGenerator.writeRaw(",");
+ }
+ }
+
+ public final static class ResponseMessageSerializer extends StdSerializer<ResponseMessage> {
+ public ResponseMessageSerializer() {
+ super(ResponseMessage.class);
+ }
+
+ @Override
+ public void serialize(final ResponseMessage responseMessage, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider) throws IOException {
+ ser(responseMessage, jsonGenerator, serializerProvider, null);
+ }
+
+ @Override
+ public void serializeWithType(final ResponseMessage responseMessage, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider,
+ final TypeSerializer typeSerializer) throws IOException {
+ ser(responseMessage, jsonGenerator, serializerProvider, typeSerializer);
+ }
+
+ public void ser(final ResponseMessage responseMessage, final JsonGenerator jsonGenerator,
+ final SerializerProvider serializerProvider,
+ final TypeSerializer typeSerializer) throws IOException {
+ GraphSONUtil.writeStartObject(responseMessage, jsonGenerator, typeSerializer);
+
+ jsonGenerator.writeStringField(SerTokens.TOKEN_REQUEST, responseMessage.getRequestId() != null ? responseMessage.getRequestId().toString() : null);
+ jsonGenerator.writeFieldName(SerTokens.TOKEN_STATUS);
+
+ GraphSONUtil.writeStartObject(responseMessage, jsonGenerator, typeSerializer);
+ jsonGenerator.writeStringField(SerTokens.TOKEN_MESSAGE, responseMessage.getStatus().getMessage());
+ jsonGenerator.writeNumberField(SerTokens.TOKEN_CODE, responseMessage.getStatus().getCode().getValue());
+ jsonGenerator.writeObjectField(SerTokens.TOKEN_ATTRIBUTES, responseMessage.getStatus().getAttributes());
+ GraphSONUtil.writeEndObject(responseMessage, jsonGenerator, typeSerializer);
+
+ jsonGenerator.writeFieldName(SerTokens.TOKEN_RESULT);
+
+ GraphSONUtil.writeStartObject(responseMessage, jsonGenerator, typeSerializer);
+
+ if (null == responseMessage.getResult().getData())
+ {
+ jsonGenerator.writeNullField(SerTokens.TOKEN_DATA);
+ }
+ else
+ {
+ jsonGenerator.writeFieldName(SerTokens.TOKEN_DATA);
+ Object result = responseMessage.getResult().getData();
+ serializerProvider.findTypedValueSerializer(result.getClass(), true, null).serialize(result, jsonGenerator, serializerProvider);
+ }
+
+ jsonGenerator.writeObjectField(SerTokens.TOKEN_META, responseMessage.getResult().getMeta());
+ GraphSONUtil.writeEndObject(responseMessage, jsonGenerator, typeSerializer);
+
+ GraphSONUtil.writeEndObject(responseMessage, jsonGenerator, typeSerializer);
+ }
+ }
+}