TINKERPOP-786 Refactored code to extract TraversalSource generation in DSLs
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/81757e54 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/81757e54 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/81757e54 Branch: refs/heads/TINKERPOP-786 Commit: 81757e54bffd7444cf865e24754c17b726df97ba Parents: 08b54fe Author: Stephen Mallette <sp...@genoprime.com> Authored: Thu Apr 27 15:22:32 2017 -0400 Committer: Stephen Mallette <sp...@genoprime.com> Committed: Wed May 3 09:55:36 2017 -0400 ---------------------------------------------------------------------- .../traversal/dsl/GremlinDslProcessor.java | 156 ++++++++++--------- 1 file changed, 80 insertions(+), 76 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/81757e54/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/GremlinDslProcessor.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/GremlinDslProcessor.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/GremlinDslProcessor.java index f9d5a40..c2c4fc7 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/GremlinDslProcessor.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/GremlinDslProcessor.java @@ -96,84 +96,12 @@ public class GremlinDslProcessor extends AbstractProcessor { generateTraversalInterface(ctx); // create the "DefaultTraversal" class which implements the above generated "Traversal" and can then - // be used by the "TraversalSource" generated below to spawn new traversal instances + // be used by the "TraversalSource" generated below to spawn new traversal instances. generateDefaultTraversal(ctx); - // START write "TraversalSource" class - final TypeElement graphTraversalSourceElement = elementUtils.getTypeElement(GraphTraversalSource.class.getCanonicalName()); - final TypeSpec.Builder traversalSourceClass = TypeSpec.classBuilder(ctx.traversalSourceClazz) - .addModifiers(Modifier.PUBLIC) - .superclass(TypeName.get(graphTraversalSourceElement.asType())); - - // add the required constructors for instantiation - traversalSourceClass.addMethod(MethodSpec.constructorBuilder() - .addModifiers(Modifier.PUBLIC) - .addParameter(Graph.class, "graph") - .addStatement("super($N)", "graph") - .build()); - traversalSourceClass.addMethod(MethodSpec.constructorBuilder() - .addModifiers(Modifier.PUBLIC) - .addParameter(Graph.class, "graph") - .addParameter(TraversalStrategies.class, "strategies") - .addStatement("super($N, $N)", "graph", "strategies") - .build()); - - // override methods to return a the DSL TraversalSource - for (Element elementOfGraphTraversal : graphTraversalSourceElement.getEnclosedElements()) { - // first copy/override methods that return a GraphTraversalSource so that we can instead return - // the DSL TraversalSource class. - tryConstructMethod(elementOfGraphTraversal, ctx.traversalSourceClassName, "", - e -> !(e.getReturnType().getKind() == TypeKind.DECLARED && ((DeclaredType) e.getReturnType()).asElement().getSimpleName().contentEquals(GraphTraversalSource.class.getSimpleName())), - Modifier.PUBLIC) - .ifPresent(traversalSourceClass::addMethod); - } - - // override methods that return GraphTraversal - traversalSourceClass.addMethod(MethodSpec.methodBuilder("addV") - .addModifiers(Modifier.PUBLIC) - .addAnnotation(Override.class) - .addStatement("$N clone = this.clone()", ctx.traversalSourceClazz) - .addStatement("clone.bytecode.addStep($T.addV)", GraphTraversal.Symbols.class) - .addStatement("$N traversal = new $N(clone)", ctx.defaultTraversalClazz, ctx.defaultTraversalClazz) - .addStatement("return ($T) traversal.asAdmin().addStep(new $T(traversal, null))", ctx.traversalClassName, AddVertexStartStep.class) - .returns(ParameterizedTypeName.get(ctx.traversalClassName, ClassName.get(Vertex.class), ClassName.get(Vertex.class))) - .build()); - traversalSourceClass.addMethod(MethodSpec.methodBuilder("addV") - .addModifiers(Modifier.PUBLIC) - .addAnnotation(Override.class) - .addParameter(String.class, "label") - .addStatement("$N clone = this.clone()", ctx.traversalSourceClazz) - .addStatement("clone.bytecode.addStep($T.addV, label)", GraphTraversal.Symbols.class) - .addStatement("$N traversal = new $N(clone)", ctx.defaultTraversalClazz, ctx.defaultTraversalClazz) - .addStatement("return ($T) traversal.asAdmin().addStep(new $T(traversal, label))", ctx.traversalClassName, AddVertexStartStep.class) - .returns(ParameterizedTypeName.get(ctx.traversalClassName, ClassName.get(Vertex.class), ClassName.get(Vertex.class))) - .build()); - traversalSourceClass.addMethod(MethodSpec.methodBuilder("V") - .addModifiers(Modifier.PUBLIC) - .addAnnotation(Override.class) - .addParameter(Object[].class, "vertexIds") - .varargs(true) - .addStatement("$N clone = this.clone()", ctx.traversalSourceClazz) - .addStatement("clone.bytecode.addStep($T.V, vertexIds)", GraphTraversal.Symbols.class) - .addStatement("$N traversal = new $N(clone)", ctx.defaultTraversalClazz, ctx.defaultTraversalClazz) - .addStatement("return ($T) traversal.asAdmin().addStep(new $T(traversal, $T.class, true, vertexIds))", ctx.traversalClassName, GraphStep.class, Vertex.class) - .returns(ParameterizedTypeName.get(ctx.traversalClassName, ClassName.get(Vertex.class), ClassName.get(Vertex.class))) - .build()); - traversalSourceClass.addMethod(MethodSpec.methodBuilder("E") - .addModifiers(Modifier.PUBLIC) - .addAnnotation(Override.class) - .addParameter(Object[].class, "edgeIds") - .varargs(true) - .addStatement("$N clone = this.clone()", ctx.traversalSourceClazz) - .addStatement("clone.bytecode.addStep($T.E, edgeIds)", GraphTraversal.Symbols.class) - .addStatement("$N traversal = new $N(clone)", ctx.defaultTraversalClazz, ctx.defaultTraversalClazz) - .addStatement("return ($T) traversal.asAdmin().addStep(new $T(traversal, $T.class, true, edgeIds))", ctx.traversalClassName, GraphStep.class, Edge.class) - .returns(ParameterizedTypeName.get(ctx.traversalClassName, ClassName.get(Edge.class), ClassName.get(Edge.class))) - .build()); - - final JavaFile traversalSourceJavaFile = JavaFile.builder(ctx.packageName, traversalSourceClass.build()).build(); - traversalSourceJavaFile.writeTo(filer); - // END write "TraversalSource" class + // create the "TraversalSource" class which is used to spawn traversals from a Graph instance. It will + // spawn instances of the "DefaultTraversal" generated above. + generateTraversalSource(ctx); } } catch (Exception ex) { messager.printMessage(Diagnostic.Kind.ERROR, ex.getMessage()); @@ -182,6 +110,82 @@ public class GremlinDslProcessor extends AbstractProcessor { return true; } + private void generateTraversalSource(final Context ctx) throws IOException { + final TypeElement graphTraversalSourceElement = elementUtils.getTypeElement(GraphTraversalSource.class.getCanonicalName()); + final TypeSpec.Builder traversalSourceClass = TypeSpec.classBuilder(ctx.traversalSourceClazz) + .addModifiers(Modifier.PUBLIC) + .superclass(TypeName.get(graphTraversalSourceElement.asType())); + + // add the required constructors for instantiation + traversalSourceClass.addMethod(MethodSpec.constructorBuilder() + .addModifiers(Modifier.PUBLIC) + .addParameter(Graph.class, "graph") + .addStatement("super($N)", "graph") + .build()); + traversalSourceClass.addMethod(MethodSpec.constructorBuilder() + .addModifiers(Modifier.PUBLIC) + .addParameter(Graph.class, "graph") + .addParameter(TraversalStrategies.class, "strategies") + .addStatement("super($N, $N)", "graph", "strategies") + .build()); + + // override methods to return a the DSL TraversalSource + for (Element elementOfGraphTraversal : graphTraversalSourceElement.getEnclosedElements()) { + // first copy/override methods that return a GraphTraversalSource so that we can instead return + // the DSL TraversalSource class. + tryConstructMethod(elementOfGraphTraversal, ctx.traversalSourceClassName, "", + e -> !(e.getReturnType().getKind() == TypeKind.DECLARED && ((DeclaredType) e.getReturnType()).asElement().getSimpleName().contentEquals(GraphTraversalSource.class.getSimpleName())), + Modifier.PUBLIC) + .ifPresent(traversalSourceClass::addMethod); + } + + // override methods that return GraphTraversal + traversalSourceClass.addMethod(MethodSpec.methodBuilder("addV") + .addModifiers(Modifier.PUBLIC) + .addAnnotation(Override.class) + .addStatement("$N clone = this.clone()", ctx.traversalSourceClazz) + .addStatement("clone.bytecode.addStep($T.addV)", GraphTraversal.Symbols.class) + .addStatement("$N traversal = new $N(clone)", ctx.defaultTraversalClazz, ctx.defaultTraversalClazz) + .addStatement("return ($T) traversal.asAdmin().addStep(new $T(traversal, null))", ctx.traversalClassName, AddVertexStartStep.class) + .returns(ParameterizedTypeName.get(ctx.traversalClassName, ClassName.get(Vertex.class), ClassName.get(Vertex.class))) + .build()); + traversalSourceClass.addMethod(MethodSpec.methodBuilder("addV") + .addModifiers(Modifier.PUBLIC) + .addAnnotation(Override.class) + .addParameter(String.class, "label") + .addStatement("$N clone = this.clone()", ctx.traversalSourceClazz) + .addStatement("clone.bytecode.addStep($T.addV, label)", GraphTraversal.Symbols.class) + .addStatement("$N traversal = new $N(clone)", ctx.defaultTraversalClazz, ctx.defaultTraversalClazz) + .addStatement("return ($T) traversal.asAdmin().addStep(new $T(traversal, label))", ctx.traversalClassName, AddVertexStartStep.class) + .returns(ParameterizedTypeName.get(ctx.traversalClassName, ClassName.get(Vertex.class), ClassName.get(Vertex.class))) + .build()); + traversalSourceClass.addMethod(MethodSpec.methodBuilder("V") + .addModifiers(Modifier.PUBLIC) + .addAnnotation(Override.class) + .addParameter(Object[].class, "vertexIds") + .varargs(true) + .addStatement("$N clone = this.clone()", ctx.traversalSourceClazz) + .addStatement("clone.bytecode.addStep($T.V, vertexIds)", GraphTraversal.Symbols.class) + .addStatement("$N traversal = new $N(clone)", ctx.defaultTraversalClazz, ctx.defaultTraversalClazz) + .addStatement("return ($T) traversal.asAdmin().addStep(new $T(traversal, $T.class, true, vertexIds))", ctx.traversalClassName, GraphStep.class, Vertex.class) + .returns(ParameterizedTypeName.get(ctx.traversalClassName, ClassName.get(Vertex.class), ClassName.get(Vertex.class))) + .build()); + traversalSourceClass.addMethod(MethodSpec.methodBuilder("E") + .addModifiers(Modifier.PUBLIC) + .addAnnotation(Override.class) + .addParameter(Object[].class, "edgeIds") + .varargs(true) + .addStatement("$N clone = this.clone()", ctx.traversalSourceClazz) + .addStatement("clone.bytecode.addStep($T.E, edgeIds)", GraphTraversal.Symbols.class) + .addStatement("$N traversal = new $N(clone)", ctx.defaultTraversalClazz, ctx.defaultTraversalClazz) + .addStatement("return ($T) traversal.asAdmin().addStep(new $T(traversal, $T.class, true, edgeIds))", ctx.traversalClassName, GraphStep.class, Edge.class) + .returns(ParameterizedTypeName.get(ctx.traversalClassName, ClassName.get(Edge.class), ClassName.get(Edge.class))) + .build()); + + final JavaFile traversalSourceJavaFile = JavaFile.builder(ctx.packageName, traversalSourceClass.build()).build(); + traversalSourceJavaFile.writeTo(filer); + } + private void generateDefaultTraversal(final Context ctx) throws IOException { final TypeSpec.Builder defaultTraversalClass = TypeSpec.classBuilder(ctx.defaultTraversalClazz) .addModifiers(Modifier.PUBLIC)