Repository: tinkerpop Updated Branches: refs/heads/TINKERPOP-1278 9158431c0 -> 0319b3d95
Bytecode now has a simple List.toString(). GraphSONTraversalSerializers has Bytecode, P, and Enum serializers and deserializers. I registered these new serializers with GraphSONModule. Thus, now Bytecode to GraphSON is all done via GraphSON ... Added an toy example to TinkerGraphPlayTest. No formal testing yet. Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/0319b3d9 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/0319b3d9 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/0319b3d9 Branch: refs/heads/TINKERPOP-1278 Commit: 0319b3d951251ad47176ade3f19fbccccfdda250 Parents: 9158431 Author: Marko A. Rodriguez <okramma...@gmail.com> Authored: Wed Jul 13 15:38:27 2016 -0600 Committer: Marko A. Rodriguez <okramma...@gmail.com> Committed: Wed Jul 13 15:38:43 2016 -0600 ---------------------------------------------------------------------- .../gremlin/process/traversal/Bytecode.java | 16 +- .../process/traversal/util/JavaTranslator.java | 2 +- .../structure/io/graphson/GraphSONModule.java | 36 ++- .../graphson/GraphSONTraversalSerializers.java | 275 +++++++++++++++++++ .../structure/TinkerGraphPlayTest.java | 31 ++- 5 files changed, 333 insertions(+), 27 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0319b3d9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java index 7c41c32..ee49b85 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java @@ -59,24 +59,14 @@ public final class Bytecode implements Cloneable, Serializable { @Override public String toString() { - final StringBuilder builder = new StringBuilder("["); - for (final Instruction instruction : this.sourceInstructions) { - builder.append(instruction).append(",\n"); - } - for (final Instruction instruction : this.stepInstructions) { - builder.append(instruction).append(",\n"); - } - if (builder.length() > 2) - builder.delete(builder.length() - 2, builder.length()); - builder.append("]"); - return builder.toString(); + return this.sourceInstructions + " " + this.stepInstructions; } @Override public boolean equals(final Object object) { return object instanceof Bytecode && this.sourceInstructions.equals(((Bytecode) object).sourceInstructions) && - this.stepInstructions.equals(((Bytecode) object).sourceInstructions); + this.stepInstructions.equals(((Bytecode) object).stepInstructions); } @Override @@ -116,7 +106,7 @@ public final class Bytecode implements Cloneable, Serializable { @Override public String toString() { - return "[\"" + this.operator + stringifyArguments() + "]"; + return this.operator + "(" + Arrays.toString(arguments) + ")"; } @Override http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0319b3d9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/JavaTranslator.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/JavaTranslator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/JavaTranslator.java index a4e112f..fc271e0 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/JavaTranslator.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/JavaTranslator.java @@ -164,7 +164,7 @@ public final class JavaTranslator<S extends TraversalSource, T extends Traversal } } } catch (final Throwable e) { - throw new IllegalStateException(e.getMessage(), e); + throw new IllegalStateException(e.getMessage() + ":" + methodName + "(" + Arrays.toString(arguments) + ")", e); } throw new IllegalStateException("Could not locate method: " + delegate.getClass().getSimpleName() + "." + methodName + "(" + Arrays.toString(arguments) + ")"); } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0319b3d9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java index 7cc6c91..09bf169 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java @@ -18,11 +18,22 @@ */ package org.apache.tinkerpop.gremlin.structure.io.graphson; +import org.apache.tinkerpop.gremlin.process.traversal.Bytecode; +import org.apache.tinkerpop.gremlin.process.traversal.Operator; +import org.apache.tinkerpop.gremlin.process.traversal.Order; +import org.apache.tinkerpop.gremlin.process.traversal.P; import org.apache.tinkerpop.gremlin.process.traversal.Path; +import org.apache.tinkerpop.gremlin.process.traversal.Pop; +import org.apache.tinkerpop.gremlin.process.traversal.Scope; +import org.apache.tinkerpop.gremlin.process.traversal.Traversal; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation; import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalMetrics; +import org.apache.tinkerpop.gremlin.structure.Column; +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.Vertex; import org.apache.tinkerpop.gremlin.structure.VertexProperty; import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGraphSONSerializer; @@ -42,7 +53,6 @@ import java.time.YearMonth; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.Map; -import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; /** * The set of serializers that handle the core graph interfaces. These serializers support normalization which @@ -80,7 +90,7 @@ abstract class GraphSONModule extends SimpleModule { addSerializer(Path.class, new GraphSONSerializers.PathJacksonSerializer()); addSerializer(StarGraphGraphSONSerializer.DirectionalStarGraph.class, new StarGraphGraphSONSerializer(normalize)); addSerializer(Tree.class, new GraphSONSerializers.TreeJacksonSerializer()); - + // java.util addSerializer(Map.Entry.class, new JavaUtilSerializers.MapEntryJacksonSerializer()); @@ -112,6 +122,25 @@ abstract class GraphSONModule extends SimpleModule { addDeserializer(YearMonth.class, new JavaTimeSerializers.YearMonthJacksonDeserializer()); addDeserializer(ZonedDateTime.class, new JavaTimeSerializers.ZonedDateTimeJacksonDeserializer()); addDeserializer(ZoneOffset.class, new JavaTimeSerializers.ZoneOffsetJacksonDeserializer()); + + // traversal + // TODO: review (added for integration with new GraphSON model for GLV bytecode) + addSerializer(Traversal.class, new GraphSONTraversalSerializers.TraversalJacksonSerializer()); + addSerializer(Bytecode.class, new GraphSONTraversalSerializers.BytecodeJacksonSerializer()); + addSerializer(VertexProperty.Cardinality.class, new GraphSONTraversalSerializers.EnumJacksonSerializer()); + addSerializer(Column.class, new GraphSONTraversalSerializers.EnumJacksonSerializer()); + addSerializer(Direction.class, new GraphSONTraversalSerializers.EnumJacksonSerializer()); + addSerializer(Operator.class, new GraphSONTraversalSerializers.EnumJacksonSerializer()); + addSerializer(Order.class, new GraphSONTraversalSerializers.EnumJacksonSerializer()); + addSerializer(Pop.class, new GraphSONTraversalSerializers.EnumJacksonSerializer()); + addSerializer(Scope.class, new GraphSONTraversalSerializers.EnumJacksonSerializer()); + addSerializer(T.class, new GraphSONTraversalSerializers.EnumJacksonSerializer()); + addSerializer(P.class, new GraphSONTraversalSerializers.PJacksonSerializer()); + // -- deserializers for traversal + addDeserializer(Bytecode.class, new GraphSONTraversalSerializers.BytecodeJacksonDeserializer()); + addDeserializer(Enum.class, new GraphSONTraversalSerializers.EnumJacksonDeserializer()); + addDeserializer(P.class, new GraphSONTraversalSerializers.PJacksonDeserializer()); + } public static Builder build() { @@ -120,7 +149,8 @@ abstract class GraphSONModule extends SimpleModule { static final class Builder implements GraphSONModuleBuilder { - private Builder() {} + private Builder() { + } @Override public GraphSONModule create(final boolean normalize) { http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0319b3d9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java new file mode 100644 index 0000000..ab7aee0 --- /dev/null +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java @@ -0,0 +1,275 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tinkerpop.gremlin.structure.io.graphson; + +import org.apache.tinkerpop.gremlin.process.traversal.Bytecode; +import org.apache.tinkerpop.gremlin.process.traversal.Operator; +import org.apache.tinkerpop.gremlin.process.traversal.Order; +import org.apache.tinkerpop.gremlin.process.traversal.P; +import org.apache.tinkerpop.gremlin.process.traversal.Pop; +import org.apache.tinkerpop.gremlin.process.traversal.Scope; +import org.apache.tinkerpop.gremlin.process.traversal.Traversal; +import org.apache.tinkerpop.gremlin.process.traversal.util.AndP; +import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP; +import org.apache.tinkerpop.gremlin.process.traversal.util.OrP; +import org.apache.tinkerpop.gremlin.structure.Column; +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.T; +import org.apache.tinkerpop.gremlin.structure.VertexProperty; +import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator; +import org.apache.tinkerpop.shaded.jackson.core.JsonParser; +import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException; +import org.apache.tinkerpop.shaded.jackson.core.ObjectCodec; +import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext; +import org.apache.tinkerpop.shaded.jackson.databind.JsonNode; +import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider; +import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer; +import org.apache.tinkerpop.shaded.jackson.databind.node.JsonNodeType; +import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public final class GraphSONTraversalSerializers { + + private GraphSONTraversalSerializers() { + } + + ///////////////// + // SERIALIZERS // + //////////////// + + final static class TraversalJacksonSerializer extends StdSerializer<Traversal> { + + public TraversalJacksonSerializer() { + super(Traversal.class); + } + + @Override + public void serialize(final Traversal traversal, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) + throws IOException { + jsonGenerator.writeObject(traversal.asAdmin().getBytecode()); + } + + } + + final static class BytecodeJacksonSerializer extends StdSerializer<Bytecode> { + + public BytecodeJacksonSerializer() { + super(Bytecode.class); + } + + @Override + public void serialize(final Bytecode bytecode, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) + throws IOException { + jsonGenerator.writeStartObject(); + jsonGenerator.writeStringField("@type", "Bytecode"); + jsonGenerator.writeArrayFieldStart("source"); + for (final Bytecode.Instruction instruction : bytecode.getSourceInstructions()) { + jsonGenerator.writeStartArray(); + jsonGenerator.writeString(instruction.getOperator()); + for (final Object argument : instruction.getArguments()) { + jsonGenerator.writeObject(argument); + } + jsonGenerator.writeEndArray(); + } + jsonGenerator.writeEndArray(); + jsonGenerator.writeArrayFieldStart("step"); + for (final Bytecode.Instruction instruction : bytecode.getStepInstructions()) { + jsonGenerator.writeStartArray(); + jsonGenerator.writeString(instruction.getOperator()); + for (final Object argument : instruction.getArguments()) { + jsonGenerator.writeObject(argument); + } + jsonGenerator.writeEndArray(); + } + jsonGenerator.writeEndArray(); + + jsonGenerator.writeEndObject(); + } + } + + final static class EnumJacksonSerializer extends StdSerializer<Enum> { + + public EnumJacksonSerializer() { + super(Enum.class); + } + + @Override + public void serialize(final Enum enumInstance, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) + throws IOException { + jsonGenerator.writeStartObject(); + jsonGenerator.writeObjectField("@type", enumInstance.getDeclaringClass().getSimpleName()); + jsonGenerator.writeObjectField("value", enumInstance.name()); + jsonGenerator.writeEndObject(); + } + + } + + final static class PJacksonSerializer extends StdSerializer<P> { + + public PJacksonSerializer() { + super(P.class); + } + + @Override + public void serialize(final P p, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) + throws IOException { + jsonGenerator.writeStartObject(); + jsonGenerator.writeStringField("@type", "P"); + jsonGenerator.writeStringField("predicate", p instanceof ConnectiveP ? p instanceof AndP ? "and" : "or" : p.getBiPredicate().toString()); + jsonGenerator.writeObjectField("value", p instanceof ConnectiveP ? ((ConnectiveP) p).getPredicates() : p.getValue()); + jsonGenerator.writeEndObject(); + } + + } + + /////////////////// + // DESERIALIZERS // + ////////////////// + + final static class BytecodeJacksonDeserializer extends StdDeserializer<Bytecode> { + + public BytecodeJacksonDeserializer() { + super(Bytecode.class); + } + + private static void processInstruction(final JsonNode instruction, final ObjectCodec oc, final Bytecode bytecode, final boolean source) throws IOException { + final String operator = instruction.get(0).textValue(); + final List<Object> arguments = new ArrayList<>(); + for (int j = 1; j < instruction.size(); j++) { + final JsonNode argument = instruction.get(j); + if (argument.getNodeType().equals(JsonNodeType.OBJECT)) { + final String type = argument.get("@type").textValue(); + if (type.equals("Bytecode")) + arguments.add(oc.readValue(argument.traverse(oc), Bytecode.class)); + else if (type.equals("P")) + arguments.add(oc.readValue(argument.traverse(oc), P.class)); + else + arguments.add(oc.readValue(argument.traverse(oc), Enum.class)); + } else if (argument.getNodeType().equals(JsonNodeType.NUMBER)) { + arguments.add(argument.asInt()); // TODO + } else if (argument.getNodeType().equals(JsonNodeType.STRING)) { + arguments.add(argument.textValue()); + } else if (argument.getNodeType().equals(JsonNodeType.BOOLEAN)) { + arguments.add(argument.booleanValue()); + } else { + throw new IOException("Unknown argument: " + argument); + } + } + if (source) + bytecode.addSource(operator, arguments.toArray()); + else + bytecode.addStep(operator, arguments.toArray()); + } + + @Override + public Bytecode deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + final Bytecode bytecode = new Bytecode(); + final ObjectCodec oc = jsonParser.getCodec(); + final JsonNode node = oc.readTree(jsonParser); + assert node.get("@type").textValue().equals("Bytecode"); + if (node.has("source")) { + final JsonNode source = node.get("source"); + for (int i = 0; i < source.size(); i++) { + processInstruction(source.get(i), oc, bytecode, true); + } + } + if (node.has("step")) { + final JsonNode step = node.get("step"); + for (int i = 0; i < step.size(); i++) { + processInstruction(step.get(i), oc, bytecode, false); + + } + } + return bytecode; + } + } + + final static class PJacksonDeserializer extends StdDeserializer<P> { + + public PJacksonDeserializer() { + super(P.class); + } + + @Override + public P deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + + final ObjectCodec oc = jsonParser.getCodec(); + final JsonNode node = oc.readTree(jsonParser); + assert node.get("@type").textValue().equals("P"); + final JsonNode predicate = node.get("predicate"); + if (predicate.textValue().equals("and") || predicate.textValue().equals("or")) { + final List<P<?>> arguments = new ArrayList<>(); + for (int i = 0; i < node.get("value").size(); i++) { + arguments.add(oc.readValue(node.get("value").get(i).traverse(oc), P.class)); + } + return predicate.textValue().equals("and") ? new AndP(arguments) : new OrP(arguments); + } else { + try { + return (P) P.class.getMethod(predicate.textValue(), Object.class).invoke(null, oc.readValue(node.get("value").traverse(oc), Object.class)); + } catch (Exception e) { + throw new IOException(); + } + } + + } + } + + final static class EnumJacksonDeserializer extends StdDeserializer<Enum> { + + public EnumJacksonDeserializer() { + super(Enum.class); + } + + @Override + public Enum deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + + final ObjectCodec oc = jsonParser.getCodec(); + final JsonNode node = oc.readTree(jsonParser); + final String type = node.get("@type").textValue(); + if (type.equals("Cardinality")) + return VertexProperty.Cardinality.valueOf(node.get("value").textValue()); + else if (type.equals("Column")) + return Column.valueOf(node.get("value").textValue()); + else if (type.equals("Direction")) + return Direction.valueOf(node.get("value").textValue()); + else if (type.equals("Operator")) + return Operator.valueOf(node.get("value").textValue()); + else if (type.equals("Order")) + return Order.valueOf(node.get("value").textValue()); + else if (type.equals("Pop")) + return Pop.valueOf(node.get("value").textValue()); + else if (type.equals("Scope")) + return Scope.valueOf(node.get("value").textValue()); + else if (type.equals("T")) + return T.valueOf(node.get("value").textValue()); + else + throw new IOException("Unknown enum type: " + type); + + } + } + + +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0319b3d9/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java ---------------------------------------------------------------------- diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java index 3711b3d..86a091c 100644 --- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java +++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java @@ -21,6 +21,7 @@ package org.apache.tinkerpop.gremlin.tinkergraph.structure; import org.apache.tinkerpop.gremlin.process.computer.Computer; import org.apache.tinkerpop.gremlin.process.traversal.Bytecode; import org.apache.tinkerpop.gremlin.process.traversal.Operator; +import org.apache.tinkerpop.gremlin.process.traversal.P; import org.apache.tinkerpop.gremlin.process.traversal.Scope; import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; @@ -32,12 +33,16 @@ import org.apache.tinkerpop.gremlin.structure.Graph; import org.apache.tinkerpop.gremlin.structure.T; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.apache.tinkerpop.gremlin.structure.io.graphml.GraphMLIo; +import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONReader; +import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONWriter; import org.apache.tinkerpop.gremlin.util.TimeUtil; import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.util.Arrays; import java.util.List; import java.util.function.Supplier; @@ -66,17 +71,23 @@ public class TinkerGraphPlayTest { @Test @Ignore public void testPlay8() throws Exception { - Graph graph = TinkerFactory.createModern(); - GraphTraversalSource g = graph.traversal();//GraphTraversalSource.computer()); - System.out.println(g.V().as("a").repeat(out("created", "knows")).times(2).as("b").dedup().select("a", "b").toList()); - final Bytecode bytecode = g.withComputer().V().as("a").repeat(out("created", "knows")).times(2).as("b").dedup().select("a", "b").asAdmin().getBytecode(); - JavaTranslator translator = new JavaTranslator(g, __.class); - Traversal.Admin<?, ?> traversal = translator.translate(bytecode); - System.out.println(traversal); - System.out.println(traversal.toList()); - System.out.println(traversal); - System.out.println(bytecode); + GraphTraversalSource g = graph.traversal().withComputer(); + + Traversal<?, ?> traversal1 = g.V().has("age", P.gt(10).and(P.lt(30))).out("knows", "created").repeat(__.as("a").out().as("b").hasLabel("software")).times(1).select("b").by(T.label).groupCount(); + Bytecode bytecode1 = traversal1.asAdmin().getBytecode(); + System.out.println("BYTECODE 1: \n " + bytecode1 + "\n"); + final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + GraphSONWriter.build().create().writeObject(outputStream, bytecode1); + // + System.out.println("GRAPHSON BYTECODE: \n " + new String(outputStream.toByteArray()) + "\n"); + // + Traversal<?, ?> traversal2 = new JavaTranslator(graph.traversal(), __.class).translate(GraphSONReader.build().create().readObject(new ByteArrayInputStream(outputStream.toByteArray()), Bytecode.class)); + Bytecode bytecode2 = traversal2.asAdmin().getBytecode(); + System.out.println("BYTECODE 2: \n " + bytecode2 + "\n"); + assert traversal1.equals(traversal2); + assert bytecode1.equals(bytecode2); + System.out.println("RESULT: \n " + traversal2.toList()); }