first draft of new updates to GraphSON 2.0. The object models are concise, all the elements/properties are attachable. Really wasn't that much of a headache to change -- a few test cases in Gremlin-Python needed updating and in GraphSONMessageSerializerV2d0Test. The corresponding ticket in JIRA has a comment with the pretty print JSON of the various elements/properties.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/58097006 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/58097006 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/58097006 Branch: refs/heads/TINKERPOP-1565 Commit: 580970064c5dad70aa6635960f288862e07ac5d0 Parents: bfe432e Author: Marko A. Rodriguez <okramma...@gmail.com> Authored: Tue Nov 29 11:32:21 2016 -0700 Committer: Stephen Mallette <sp...@genoprime.com> Committed: Thu Jan 19 15:15:32 2017 -0500 ---------------------------------------------------------------------- .../io/graphson/GraphSONSerializersV2d0.java | 50 ++++++++++++------- .../structure/io/graphson/GraphSONTokens.java | 2 +- .../ser/GraphSONMessageSerializerV2d0Test.java | 18 +++---- .../gremlin_python/structure/io/graphson.py | 52 ++++++++++++++------ .../jython/tests/structure/io/test_graphson.py | 12 ++--- 5 files changed, 84 insertions(+), 50 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/58097006/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 e4cc755..824fc7f 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 @@ -100,22 +100,34 @@ class GraphSONSerializersV2d0 { } private void writeProperties(final Vertex vertex, final JsonGenerator jsonGenerator) throws IOException { - if (vertex.keys().size() == 0) + if (vertex.keys().isEmpty()) return; jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES); jsonGenerator.writeStartObject(); final List<String> keys = normalize ? IteratorUtils.list(vertex.keys().iterator(), Comparator.naturalOrder()) : new ArrayList<>(vertex.keys()); - for (String key : keys) { + for (final String key : keys) { final Iterator<VertexProperty<Object>> vertexProperties = normalize ? IteratorUtils.list(vertex.properties(key), Comparators.PROPERTY_COMPARATOR).iterator() : vertex.properties(key); if (vertexProperties.hasNext()) { jsonGenerator.writeFieldName(key); - jsonGenerator.writeStartArray(); while (vertexProperties.hasNext()) { - jsonGenerator.writeObject(vertexProperties.next()); + final VertexProperty<?> vertexProperty = vertexProperties.next(); + jsonGenerator.writeStartObject(); + jsonGenerator.writeObjectField(GraphSONTokens.ID, vertexProperty.id()); + jsonGenerator.writeObjectField(GraphSONTokens.VALUE, vertexProperty.value()); + if (!vertexProperty.keys().isEmpty()) { + jsonGenerator.writeObjectFieldStart(GraphSONTokens.PROPERTIES); + final Iterator<Property<?>> properties = (Iterator) vertexProperty.properties(); + while (properties.hasNext()) { + final Property<?> property = properties.next(); + jsonGenerator.writeObjectField(property.key(), property.value()); + } + jsonGenerator.writeEndObject(); + } + jsonGenerator.writeEndObject(); } jsonGenerator.writeEndArray(); } @@ -156,7 +168,6 @@ class GraphSONSerializersV2d0 { IteratorUtils.list(edge.properties(), Comparators.PROPERTY_COMPARATOR).iterator() : edge.properties(); if (edgeProperties.hasNext()) { jsonGenerator.writeFieldName(GraphSONTokens.PROPERTIES); - jsonGenerator.writeStartObject(); while (edgeProperties.hasNext()) { final Property<?> property = edgeProperties.next(); @@ -181,24 +192,19 @@ class GraphSONSerializersV2d0 { jsonGenerator.writeObjectField(GraphSONTokens.VALUE, property.value()); if (property.element() instanceof VertexProperty) { VertexProperty vertexProperty = (VertexProperty) property.element(); - jsonGenerator.writeObjectFieldStart(GraphSONTokens.ELEMENT); - jsonGenerator.writeStringField(GraphSONTokens.VALUETYPE, "g:VertexProperty"); - jsonGenerator.writeObjectFieldStart(GraphSONTokens.VALUEPROP); + jsonGenerator.writeObjectFieldStart(GraphSONTokens.VERTEX_PROPERTY); jsonGenerator.writeObjectField(GraphSONTokens.ID, vertexProperty.id()); jsonGenerator.writeStringField(GraphSONTokens.LABEL, vertexProperty.label()); + jsonGenerator.writeObjectField(GraphSONTokens.VALUE, vertexProperty.value()); jsonGenerator.writeObjectField(GraphSONTokens.VERTEX, vertexProperty.element().id()); jsonGenerator.writeEndObject(); - jsonGenerator.writeEndObject(); } else if (property.element() instanceof Edge) { Edge edge = (Edge) property.element(); - jsonGenerator.writeObjectFieldStart(GraphSONTokens.ELEMENT); - jsonGenerator.writeStringField(GraphSONTokens.VALUETYPE, "g:Edge"); - jsonGenerator.writeObjectFieldStart(GraphSONTokens.VALUEPROP); + jsonGenerator.writeObjectFieldStart(GraphSONTokens.EDGE); jsonGenerator.writeObjectField(GraphSONTokens.ID, edge.id()); jsonGenerator.writeStringField(GraphSONTokens.LABEL, edge.label()); - jsonGenerator.writeObjectField(GraphSONTokens.OUT, edge.outVertex().id()); jsonGenerator.writeObjectField(GraphSONTokens.IN, edge.inVertex().id()); - jsonGenerator.writeEndObject(); + jsonGenerator.writeObjectField(GraphSONTokens.OUT, edge.outVertex().id()); jsonGenerator.writeEndObject(); } jsonGenerator.writeEndObject(); @@ -485,9 +491,16 @@ class GraphSONSerializersV2d0 { @Override public Property createObject(final Map<String, Object> propData) { - final Object element = propData.get(GraphSONTokens.ELEMENT); - return element instanceof Element ? // graphson-non-embedded is treated differently, but since this is a hard coded embedding... - new DetachedProperty<>((String) propData.get(GraphSONTokens.KEY), propData.get(GraphSONTokens.VALUE), (Element) element) : + Element element = null; + if (propData.containsKey(GraphSONTokens.VERTEX_PROPERTY)) { + final Map<String, Object> elementData = (Map<String, Object>) propData.get(GraphSONTokens.VERTEX_PROPERTY); + element = new VertexPropertyJacksonDeserializer().createObject(elementData); + } else if (propData.containsKey(GraphSONTokens.EDGE)) { + final Map<String, Object> elementData = (Map<String, Object>) propData.get(GraphSONTokens.EDGE); + element = new EdgeJacksonDeserializer().createObject(elementData); + } + return null != element ? // graphson-non-embedded is treated differently, but since this is a hard coded embedding... + new DetachedProperty<>((String) propData.get(GraphSONTokens.KEY), propData.get(GraphSONTokens.VALUE), element) : new DetachedProperty<>((String) propData.get(GraphSONTokens.KEY), propData.get(GraphSONTokens.VALUE)); } } @@ -504,7 +517,8 @@ class GraphSONSerializersV2d0 { new DetachedVertexProperty<>( propData.get(GraphSONTokens.ID), (String) propData.get(GraphSONTokens.LABEL), - propData.get(GraphSONTokens.VALUE), (Map<String, Object>) propData.get(GraphSONTokens.PROPERTIES), + propData.get(GraphSONTokens.VALUE), + (Map<String, Object>) propData.get(GraphSONTokens.PROPERTIES), new DetachedVertex(propData.get(GraphSONTokens.VERTEX), Vertex.DEFAULT_LABEL, null)) : new DetachedVertexProperty<>( propData.get(GraphSONTokens.ID), http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/58097006/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java index 4f804ad..d804f0b 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTokens.java @@ -37,8 +37,8 @@ public final class GraphSONTokens { public static final String EDGE = "edge"; public static final String EDGES = "edges"; public static final String VERTEX = "vertex"; + public static final String VERTEX_PROPERTY = "vertexProperty"; public static final String VERTICES = "vertices"; - public static final String ELEMENT = "element"; public static final String IN = "inV"; public static final String OUT = "outV"; public static final String IN_E = "inE"; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/58097006/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 13e2e69..4125946 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 @@ -315,17 +315,17 @@ public class GraphSONMessageSerializerV2d0Test { final JsonNode friendProperties = properties.get("friends"); assertEquals(1, friendProperties.size()); - final JsonNode friendsProperty = friendProperties.get(0).get(GraphSONTokens.VALUEPROP); + final JsonNode friendsProperty = friendProperties.get(0).get(GraphSONTokens.VALUE); assertNotNull(friendsProperty); - assertEquals(4, friendsProperty.size()); + assertEquals(3, friendsProperty.size()); - final String object1 = friendsProperty.get(GraphSONTokens.VALUE).get(0).asText(); + final String object1 = friendsProperty.get(0).asText(); assertEquals("x", object1); - final int object2 = friendsProperty.get(GraphSONTokens.VALUE).get(1).get(GraphSONTokens.VALUEPROP).asInt(); + final int object2 = friendsProperty.get(1).get(GraphSONTokens.VALUEPROP).asInt(); assertEquals(5, object2); - final JsonNode object3 = friendsProperty.get(GraphSONTokens.VALUE).get(2); + final JsonNode object3 = friendsProperty.get(2); assertEquals(500, object3.get("x").get(GraphSONTokens.VALUEPROP).asInt()); assertEquals("some", object3.get("y").asText()); } @@ -439,7 +439,7 @@ public class GraphSONMessageSerializerV2d0Test { .get(GraphSONTokens.KEY).get(GraphSONTokens.VALUEPROP) .get(GraphSONTokens.PROPERTIES) .get("name") - .get(0).get(GraphSONTokens.VALUEPROP) + .get(0) .get(GraphSONTokens.VALUE).asText()); //check the leafs @@ -450,7 +450,7 @@ public class GraphSONMessageSerializerV2d0Test { .get(GraphSONTokens.KEY).get(GraphSONTokens.VALUEPROP) .get(GraphSONTokens.PROPERTIES) .get("name") - .get(0).get(GraphSONTokens.VALUEPROP) + .get(0) .get(GraphSONTokens.VALUE).asText()); assertEquals("lop", converted.get(GraphSONTokens.VALUEPROP) @@ -460,7 +460,7 @@ public class GraphSONMessageSerializerV2d0Test { .get(GraphSONTokens.KEY).get(GraphSONTokens.VALUEPROP) .get(GraphSONTokens.PROPERTIES) .get("name") - .get(0).get(GraphSONTokens.VALUEPROP) + .get(0) .get(GraphSONTokens.VALUE).asText()); assertEquals("josh", converted.get(GraphSONTokens.VALUEPROP) @@ -470,7 +470,7 @@ public class GraphSONMessageSerializerV2d0Test { .get(GraphSONTokens.KEY).get(GraphSONTokens.VALUEPROP) .get(GraphSONTokens.PROPERTIES) .get("name") - .get(0).get(GraphSONTokens.VALUEPROP) + .get(0) .get(GraphSONTokens.VALUE).asText()); } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/58097006/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 a3276e2..8795ff1 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 @@ -208,20 +208,26 @@ class PropertySerializer(_GraphSONTypeIO): @classmethod def dictify(cls, property, writer): - elementDict = writer.toDict(property.element) - if elementDict is not None: - valueDict = elementDict["@value"] - if "outVLabel" in valueDict: - del valueDict["outVLabel"] - if "inVLabel" in valueDict: - 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)}) + element = property.element + elementDict = {} + if element is not None: + elementDict["id"] = element.id + elementDict["label"] = element.label + if isinstance(element, VertexProperty): + elementDict["value"] = element.value + elementDict["vertex"] = element.vertex.id + return GraphSONUtil.typedValue("Property", {"key": writer.toDict(property.key), + "value": writer.toDict(property.value), + "vertexProperty": writer.toDict(elementDict)}) + elif isinstance(element, Edge): + elementDict["outV"] = element.outV.id + elementDict["inV"] = element.inV.id + return GraphSONUtil.typedValue("Property", {"key": writer.toDict(property.key), + "value": writer.toDict(property.value), + "edge": writer.toDict(elementDict)}) + else: + return GraphSONUtil.typedValue("Property", {"key": writer.toDict(property.key), + "value": writer.toDict(property.value)}) class TraversalStrategySerializer(_GraphSONTypeIO): @@ -386,8 +392,22 @@ class PropertyDeserializer(_GraphSONTypeIO): @classmethod def objectify(cls, d, reader): - element = reader.toObject(d["element"]) if "element" in d else None - return Property(d["key"], reader.toObject(d["value"]), element) + if "edge" in d: + edge = reader.toObject(d["edge"]) + return Property(d["key"], reader.toObject(d["value"]), + Edge(edge["id"], + Vertex(edge["outV"]), + edge["label"], + Vertex(edge["inV"]))) + elif "vertexProperty" in d: + vertex_property = reader.toObject(d["vertexProperty"]) + return Property(d["key"], reader.toObject(d["value"]), + VertexProperty(vertex_property["id"], + vertex_property["label"], + vertex_property["value"], + Vertex(vertex_property["vertex"]))) + else: + return Property(d["key"], reader.toObject(d["value"]), None) class PathDeserializer(_GraphSONTypeIO): http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/58097006/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 f01100d..7e034c9 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 @@ -111,7 +111,7 @@ class TestGraphSONReader(TestCase): 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"}}}}""") + {"@type":"g:Property", "@value":{"key":"aKey","value":{"@type":"g:Int64","@value":17},"edge":{"id":{"@type":"g:Int64","@value":122},"label":"knows","inV":"x","outV":"y"}}}""") # print property assert isinstance(property, Property) assert "aKey" == property.key @@ -208,11 +208,11 @@ class TestGraphSONWriter(TestCase): self.graphson_writer.writeObject(VertexProperty("blah", "keyA", True, Vertex("stephen")))) assert {"@type": "g:Property", - "@value": {"key": "name", "value": "marko", "element": {"@type": "g:VertexProperty", - "@value": { - "vertex": "vertexId", - "id": "anId", - "label": "aKey"}}}} == json.loads( + "@value": {"key": "name", "value": "marko", "vertexProperty": { + "vertex": "vertexId", + "id": "anId", + "label": "aKey", + "value": {"@type": "g:Int32", "@value": 21345}}}} == json.loads( self.graphson_writer.writeObject( Property("name", "marko", VertexProperty("anId", "aKey", 21345, Vertex("vertexId")))))