changed the Edge property GraphSON serialization to do key/value map like VertexProperty metaProperties. Talking with @spmallette -- we believe the Edge property serialization is a bug. Other random cleanups.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/eed6745e Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/eed6745e Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/eed6745e Branch: refs/heads/TINKERPOP-1520 Commit: eed6745e9b5755b42081082f3b0573d5eef10f95 Parents: 7725718 Author: Marko A. Rodriguez <okramma...@gmail.com> Authored: Thu Nov 17 13:47:02 2016 -0700 Committer: Marko A. Rodriguez <okramma...@gmail.com> Committed: Tue Nov 22 11:20:01 2016 -0700 ---------------------------------------------------------------------- .../io/graphson/GraphSONSerializersV2d0.java | 59 ++++++++------------ .../structure/io/graphson/GraphSONUtil.java | 10 +--- .../util/detached/DetachedVertexProperty.java | 4 +- .../ser/GraphSONMessageSerializerV2d0Test.java | 2 +- .../gremlin_python/structure/io/graphson.py | 2 + .../jython/tests/structure/io/test_graphson.py | 13 ++++- 6 files changed, 39 insertions(+), 51 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/eed6745e/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java index ad1fd0e..4d99f49 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java @@ -64,8 +64,6 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; -import static org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONUtil.safeWriteObjectField; - /** * 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. @@ -154,13 +152,16 @@ class GraphSONSerializersV2d0 { } private void writeProperties(final Edge edge, final JsonGenerator jsonGenerator) throws IOException { - final Iterator<Property<Object>> elementProperties = normalize ? + final Iterator<Property<Object>> edgeProperties = normalize ? IteratorUtils.list(edge.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : edge.properties(); - if (elementProperties.hasNext()) { + if (edgeProperties.hasNext()) { jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES); jsonGenerator.writeStartObject(); - elementProperties.forEachRemaining(prop -> safeWriteObjectField(jsonGenerator, prop.key(), prop)); + while (edgeProperties.hasNext()) { + final Property<?> property = edgeProperties.next(); + jsonGenerator.writeObjectField(property.key(), property.value()); + } jsonGenerator.writeEndObject(); } } @@ -231,31 +232,31 @@ class GraphSONSerializersV2d0 { jsonGenerator.writeEndObject(); } - private static void tryWriteMetaProperties(final VertexProperty property, final JsonGenerator jsonGenerator, + private static void tryWriteMetaProperties(final VertexProperty vertexProperty, final JsonGenerator jsonGenerator, 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) { + if (vertexProperty instanceof DetachedVertexProperty) { // only write meta properties key if they exist - if (property.properties().hasNext()) { - writeMetaProperties(property, jsonGenerator, normalize); + if (vertexProperty.properties().hasNext()) { + writeMetaProperties(vertexProperty, jsonGenerator, 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, normalize); + if (vertexProperty.graph().features().vertex().supportsMetaProperties() && vertexProperty.properties().hasNext()) { + writeMetaProperties(vertexProperty, jsonGenerator, normalize); } } } - private static void writeMetaProperties(final VertexProperty property, final JsonGenerator jsonGenerator, + private static void writeMetaProperties(final VertexProperty vertexProperty, final JsonGenerator jsonGenerator, final boolean normalize) throws IOException { jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES); jsonGenerator.writeStartObject(); final Iterator<Property<Object>> metaProperties = normalize ? - IteratorUtils.list((Iterator<Property<Object>>) property.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : property.properties(); + IteratorUtils.list((Iterator<Property<Object>>) vertexProperty.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : vertexProperty.properties(); while (metaProperties.hasNext()) { final Property<Object> metaProperty = metaProperties.next(); jsonGenerator.writeObjectField(metaProperty.key(), metaProperty.value()); @@ -454,7 +455,7 @@ class GraphSONSerializersV2d0 { return new DetachedVertex( vertexData.get(GraphSONTokens.ID), (String) vertexData.getOrDefault(GraphSONTokens.LABEL, Vertex.DEFAULT_LABEL), - (Map<String, Object>) vertexData.getOrDefault(GraphSONTokens.PROPERTIES, Collections.emptyMap()) + (Map<String, Object>) vertexData.get(GraphSONTokens.PROPERTIES) ); } } @@ -470,7 +471,7 @@ class GraphSONSerializersV2d0 { return new DetachedEdge( edgeData.get(GraphSONTokens.ID), (String) edgeData.getOrDefault(GraphSONTokens.LABEL, Edge.DEFAULT_LABEL), - (Map<String, Object>) edgeData.getOrDefault(GraphSONTokens.PROPERTIES, Collections.emptyMap()), + (Map<String, Object>) edgeData.get(GraphSONTokens.PROPERTIES), Pair.with(edgeData.get(GraphSONTokens.OUT), (String) edgeData.getOrDefault(GraphSONTokens.OUT_LABEL, Vertex.DEFAULT_LABEL)), Pair.with(edgeData.get(GraphSONTokens.IN), (String) edgeData.getOrDefault(GraphSONTokens.IN_LABEL, Vertex.DEFAULT_LABEL)) ); @@ -485,23 +486,7 @@ class GraphSONSerializersV2d0 { @Override public Property createObject(final Map<String, Object> propData) { - return propData.containsKey(GraphSONTokens.ELEMENT) ? - new DetachedProperty((String) propData.get(GraphSONTokens.KEY), propData.get(GraphSONTokens.VALUE), getElement(propData.get(GraphSONTokens.ELEMENT))) : - new DetachedProperty((String) propData.get(GraphSONTokens.KEY), propData.get(GraphSONTokens.VALUE)); - } - - private Element getElement(final Object element) { - if (element instanceof Edge) - return (Edge) element; - if (element instanceof Map) { - final String type = (String) ((Map<String, Object>) element).get(GraphSONTokens.VALUETYPE); - final Map<String, Object> elementMap = (Map<String, Object>) ((Map) element).get(GraphSONTokens.VALUEPROP); - if ("g:VertexProperty".equals(type)) - return new VertexPropertyJacksonDeserializer().createObject(elementMap); - else if ("g:Edge".equals(type)) - return new EdgeJacksonDeserializer().createObject(elementMap); - } - throw new IllegalArgumentException("Unknown element structure: " + element); + return new DetachedProperty((String) propData.get(GraphSONTokens.KEY), propData.get(GraphSONTokens.VALUE)); } } @@ -517,13 +502,13 @@ class GraphSONSerializersV2d0 { new DetachedVertexProperty<>( propData.get(GraphSONTokens.ID), (String) propData.get(GraphSONTokens.LABEL), - propData.get(GraphSONTokens.VALUE), (Map<String, Object>) propData.getOrDefault(GraphSONTokens.PROPERTIES, Collections.emptyMap()), + propData.get(GraphSONTokens.VALUE), (Map<String, Object>) propData.get(GraphSONTokens.PROPERTIES), new DetachedVertex(propData.get(GraphSONTokens.VERTEX), Vertex.DEFAULT_LABEL, Collections.emptyMap())) : new DetachedVertexProperty<>( propData.get(GraphSONTokens.ID), (String) propData.get(GraphSONTokens.LABEL), propData.get(GraphSONTokens.VALUE), - (Map<String, Object>) propData.getOrDefault(GraphSONTokens.PROPERTIES, Collections.emptyMap())); + (Map<String, Object>) propData.get(GraphSONTokens.PROPERTIES)); } } @@ -558,13 +543,13 @@ class GraphSONSerializersV2d0 { final MutableMetrics m = new MutableMetrics((String) metricsData.get(GraphSONTokens.ID), (String) metricsData.get(GraphSONTokens.NAME)); m.setDuration(Math.round((Double) metricsData.get(GraphSONTokens.DURATION) * 1000000), TimeUnit.NANOSECONDS); - for (Map.Entry<String, Long> count : ((Map<String, Long>) metricsData.getOrDefault(GraphSONTokens.COUNTS, new HashMap<>(0))).entrySet()) { + for (Map.Entry<String, Long> count : ((Map<String, Long>) metricsData.getOrDefault(GraphSONTokens.COUNTS, Collections.emptyMap())).entrySet()) { m.setCount(count.getKey(), count.getValue()); } - for (Map.Entry<String, Long> count : ((Map<String, Long>) metricsData.getOrDefault(GraphSONTokens.ANNOTATIONS, new HashMap<>(0))).entrySet()) { + for (Map.Entry<String, Long> count : ((Map<String, Long>) metricsData.getOrDefault(GraphSONTokens.ANNOTATIONS, Collections.emptyMap())).entrySet()) { m.setAnnotation(count.getKey(), count.getValue()); } - for (MutableMetrics nested : (List<MutableMetrics>) metricsData.getOrDefault(GraphSONTokens.METRICS, new ArrayList<>(0))) { + for (MutableMetrics nested : (List<MutableMetrics>) metricsData.getOrDefault(GraphSONTokens.METRICS, Collections.emptyList())) { m.addNested(nested); } return m; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/eed6745e/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java index 9b90c78..97292af 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONUtil.java @@ -32,7 +32,8 @@ import java.io.IOException; */ public final class GraphSONUtil { - private GraphSONUtil() {} + private GraphSONUtil() { + } public static void writeWithType(final Object object, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider, @@ -85,11 +86,4 @@ public final class GraphSONUtil { jsonGenerator.writeEndArray(); } - static void safeWriteObjectField(final JsonGenerator jsonGenerator, final String key, final Object value) { - try { - jsonGenerator.writeObjectField(key, value); - } catch (IOException e) { - throw new RuntimeException(e); - } - } } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/eed6745e/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java index 069c14c..b6b66fa 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java @@ -67,7 +67,7 @@ public class DetachedVertexProperty<V> extends DetachedElement<VertexProperty<V> this.value = value; this.vertex = DetachedFactory.detach(vertex, true); - if (!properties.isEmpty()) { + if (null != properties && !properties.isEmpty()) { this.properties = new HashMap<>(); properties.entrySet().iterator().forEachRemaining(entry -> this.properties.put(entry.getKey(), Collections.singletonList(new DetachedProperty<>(entry.getKey(), entry.getValue(), this)))); } @@ -81,7 +81,7 @@ public class DetachedVertexProperty<V> extends DetachedElement<VertexProperty<V> super(id, label); this.value = value; - if (properties != null && !properties.isEmpty()) { + if (null != properties && !properties.isEmpty()) { this.properties = new HashMap<>(); properties.entrySet().iterator().forEachRemaining(entry -> this.properties.put(entry.getKey(), Collections.singletonList(new DetachedProperty<>(entry.getKey(), entry.getValue(), this)))); } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/eed6745e/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV2d0Test.java ---------------------------------------------------------------------- diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV2d0Test.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV2d0Test.java index 2c824a5..a327537 100644 --- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV2d0Test.java +++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/GraphSONMessageSerializerV2d0Test.java @@ -250,7 +250,7 @@ public class GraphSONMessageSerializerV2d0Test { final JsonNode properties = edgeAsJson.get(GraphSONTokens.PROPERTIES); assertNotNull(properties); - assertEquals(123, properties.get("abc").get(GraphSONTokens.VALUEPROP).get("value").get(GraphSONTokens.VALUEPROP).asInt()); + assertEquals(123, properties.get("abc").get(GraphSONTokens.VALUEPROP).asInt()); } @Test http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/eed6745e/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py b/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py index 663ff5d..c4cda39 100644 --- a/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py +++ b/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py @@ -217,6 +217,8 @@ class PropertySerializer(_GraphSONTypeIO): del valueDict["inVLabel"] if "properties" in valueDict: del valueDict["properties"] + if "value" in valueDict: + del valueDict["value"] return GraphSONUtil.typedValue("Property", {"key": writer.toDict(property.key), "value": writer.toDict(property.value), "element": writer.toDict(elementDict)}) http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/eed6745e/gremlin-python/src/main/jython/tests/structure/io/test_graphson.py ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/jython/tests/structure/io/test_graphson.py b/gremlin-python/src/main/jython/tests/structure/io/test_graphson.py index 1e8c4cd..933dab6 100644 --- a/gremlin-python/src/main/jython/tests/structure/io/test_graphson.py +++ b/gremlin-python/src/main/jython/tests/structure/io/test_graphson.py @@ -102,13 +102,21 @@ class TestGraphSONReader(TestCase): assert vertex_property.vertex is None ## edge = self.graphson_reader.readObject(""" - {"@type":"g:Edge", "@value":{"id":{"@type":"g:Int64","@value":17},"label":"knows","inV":"x","outV":"y","inVLabel":"xLab"}}""") + {"@type":"g:Edge", "@value":{"id":{"@type":"g:Int64","@value":17},"label":"knows","inV":"x","outV":"y","inVLabel":"xLab","properties":{"aKey":"aValue","bKey":true}}}""") # print edge assert isinstance(edge, Edge) assert 17 == edge.id assert "knows" == edge.label assert edge.inV == Vertex("x", "xLabel") assert edge.outV == Vertex("y", "vertex") + ## + property = self.graphson_reader.readObject(""" + {"@type":"g:Property", "@value":{"key":"aKey","value":{"@type":"g:Int64","@value":17},"element":{"@type":"g:Edge","@value":{"id":{"@type":"g:Int64","@value":122},"label":"knows","inV":"x","outV":"y","inVLabel":"xLab"}}}}""") + # print property + assert isinstance(property, Property) + assert "aKey" == property.key + assert 17 == property.value + assert Edge(122, Vertex("x"), "knows", Vertex("y")) == property.element def test_path(self): path = self.graphson_reader.readObject( @@ -203,11 +211,10 @@ class TestGraphSONWriter(TestCase): "@value": {"key": "name", "value": "marko", "element": {"@type": "g:VertexProperty", "@value": { "vertex": "vertexId", - "value": True, "id": "anId", "label": "aKey"}}}} == json.loads( self.graphson_writer.writeObject( - Property("name", "marko", VertexProperty("anId", "aKey", True, Vertex("vertexId"))))) + Property("name", "marko", VertexProperty("anId", "aKey", 21345, Vertex("vertexId"))))) def test_custom_mapping(self): # extended mapping