From 35330309221b7c39adf71f508190628459ad7138 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Fri, 2 Aug 2013 02:48:11 +0200 Subject: wip --- .../io/trygvis/container/compiler/MyProcessor.java | 162 +----------------- .../container/compiler/TransactionalHandler.java | 182 +++++++++++++++++++++ .../trygvis/container/compiler/model/ClassG.java | 56 +++---- .../container/compiler/model/Constructor.java | 38 +++++ .../container/compiler/model/MethodRef.java | 6 +- .../container/compiler/model/Parameters.java | 33 +++- 6 files changed, 279 insertions(+), 198 deletions(-) create mode 100644 container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TransactionalHandler.java create mode 100644 container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Constructor.java diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java index 0ec7001..4873e9b 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java @@ -1,11 +1,6 @@ package io.trygvis.container.compiler; -import io.trygvis.container.compiler.model.ClassG; -import io.trygvis.container.compiler.model.FieldRef; -import io.trygvis.container.compiler.model.ParameterRef; -import io.trygvis.container.compiler.model.TypeRef; import io.trygvis.container.log.Log; -import io.trygvis.container.tx.PlatformTransactionManager; import org.springframework.transaction.annotation.Transactional; import javax.annotation.processing.Completion; @@ -16,28 +11,15 @@ import javax.lang.model.SourceVersion; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.Name; import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; -import javax.tools.JavaFileObject; -import java.io.CharArrayWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; import java.util.HashSet; -import java.util.List; import java.util.Set; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.emptySet; -import static javax.lang.model.util.ElementFilter.constructorsIn; -import static org.springframework.util.StringUtils.collectionToDelimitedString; public class MyProcessor implements Processor { @@ -87,7 +69,7 @@ public class MyProcessor implements Processor { System.out.println("annotationMirror.getAnnotationType().asElement().getSimpleName() = " + annotationMirror.getAnnotationType().asElement().getSimpleName()); if (types.isSameType(tx.asType(), annotationMirror.getAnnotationType())) { - processTransactional((TypeElement) element); + new TransactionalHandler(processingEnv).processTransactional((TypeElement) element); } // if (types.isSameType(log.asType(), annotationMirror.getAnnotationType())) { // processLog((TypeElement) element); @@ -101,146 +83,4 @@ public class MyProcessor implements Processor { } return true; } - - private void processTransactional(TypeElement element) throws IOException { - Name targetClassName = element.getSimpleName(); - System.out.println("Processing @Transactional " + targetClassName); - - Transactional transactional = element.getAnnotation(Transactional.class); - - String p = elements.getPackageOf(element).getQualifiedName().toString(); - - String className = targetClassName + "_Transactional"; - - JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(p + "." + className, element); - - try (PrintWriter w = new PrintWriter(sourceFile.openWriter())) { - ClassG g = new ClassG(p, className, targetClassName.toString()); -// writer.println("package " + p + ";"); -// writer.println(); -// writer.println("import io.trygvis.container.tx.PlatformTransactionManager;"); -// writer.println(); -// writer.println("public class " + className + " extends " + targetClassName + " {"); -// writer.println(" private final PlatformTransactionManager transactionManager;"); -// writer.println(); - - TypeRef platformTransactionManager = g.addImport(PlatformTransactionManager.class); - FieldRef transactionManager = g.addField(PlatformTransactionManager.class, "transactionManager"); - - for (ExecutableElement constructor : constructorsIn(elements.getAllMembers(element))) { - if (!constructor.getModifiers().contains(Modifier.PUBLIC)) { - continue; - } - - constructor(g, constructor); - } - -// System.out.println("elements.getTypeElement(\"Object\") = " + elements.getTypeElement("java.lang.Object")); - Name javaLangObjectName = elements.getTypeElement("java.lang.Object").getQualifiedName(); - - for (Element e : elements.getAllMembers(element)) { - if (!(e instanceof ExecutableElement)) { - continue; - } - - ExecutableElement ee = (ExecutableElement) e; - - TypeElement enclosingElement = (TypeElement) ee.getEnclosingElement(); - - if (enclosingElement.getQualifiedName().equals(javaLangObjectName)) { - continue; - } - - if (ee.getSimpleName().toString().equals("")) { - continue; - } - -// System.out.println("ee.getSimpleName() = " + ee.getSimpleName()); -// System.out.println("ee.getEnclosingElement() = " + enclosingElement); -// System.out.println("ee.getEnclosingElement().getQualifiedName() = " + enclosingElement.getQualifiedName()); -// System.out.println("ee.getEnclosingElement().asType().getKind().getDeclaringClass() = " + enclosingElement.asType().getKind().getDeclaringClass()); - - TypeMirror returnTypeMirror = ee.getReturnType(); - - TypeKind kind = returnTypeMirror.getKind(); - - boolean isVoid = kind == TypeKind.VOID; - TypeRef returnType = isVoid ? TypeRef.VOID : g.addImport(returnTypeMirror); -// String returnString; -// if (isVoid) { -// returnString = "void"; -// } else { -// returnString = returnTypeMirror.toString(); -// } - - List parameters = new ArrayList<>(); - List arguments = new ArrayList<>(); - for (VariableElement ve : ee.getParameters()) { -// parameters.add("final " + ve.asType().toString() + " " + ve.getSimpleName().toString()); - TypeRef k = g.addImport(ve.asType()); - parameters.add(new ParameterRef(k, ve.getSimpleName().toString())); - arguments.add(ve.getSimpleName().toString()); - } - - CharArrayWriter buffer = new CharArrayWriter(); - PrintWriter m = new PrintWriter(buffer); - g.addMethod(buffer.toString(), returnType, ee.getSimpleName().toString(), parameters.toArray(new ParameterRef[arguments.size()])); - -// writer.println(); -// writer.println(" public " + returnString + " " + ee.getSimpleName() + "(" + collectionToDelimitedString(parameters, ", ") + ") {"); - -/* - writer.println(" " + (isVoid ? "" : "return ") + "transactionManager.doInTransaction("); - writer.println(" PlatformTransactionManager.TransactionIsolation.ISOLATION_" + transactional.isolation() + ","); - writer.println(" PlatformTransactionManager.TransactionPropagation.PROPAGATION_" + transactional.propagation() + ","); - writer.println(" new PlatformTransactionManager.TransactionTemplate<" + (isVoid ? "Object" : returnTypeMirror) + ">() {"); - writer.println(" @Override"); - writer.println(" public " + (isVoid ? "Object" : returnTypeMirror) + " doInTransaction() {"); - String targetInvocation = className + ".super." + ee.getSimpleName() + "(" + collectionToDelimitedString(arguments, ", ") + ");"; - - if (isVoid) { - writer.println(" " + targetInvocation); - writer.println(" return null;"); - } else { - writer.print(" return "); - writer.println(targetInvocation); - } - - writer.println(" }"); - writer.println(" });"); - writer.println(" }"); -*/ - - elements.printElements(new PrintWriter(System.out), ee); - } -// writer.println("}"); - g.write(w); - } - } - - private void constructor(ClassG g, ExecutableElement constructor) { - List parameters = new ArrayList<>(); - List goesToSuper = new ArrayList<>(); - - TypeRef k = g.addImport(PlatformTransactionManager.class); - parameters.add(new ParameterRef(k, "_transactionManager_")); - - for (VariableElement p : constructor.getParameters()) { -// parameters.add(p.asType().toString() + " " + p.getSimpleName().toString()); -// arguments.add(p.getSimpleName().toString()); - k = g.addImport(p.asType()); - String name = p.getSimpleName().toString(); - parameters.add(new ParameterRef(k, name)); - goesToSuper.add(name); - } - -// String params = parameters.size() == 0 ? "" : ", " + collectionToDelimitedString(parameters, ", "); - - g.simpleConstructor(parameters, goesToSuper); - -// writer.println(" public " + className + "(PlatformTransactionManager _transactionManager_" + params + ") {"); -// writer.println(" super(" + collectionToDelimitedString(arguments, ", ") + ");"); -// writer.println(" this.transactionManager = _transactionManager_;"); -// writer.println(" }"); - } } diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TransactionalHandler.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TransactionalHandler.java new file mode 100644 index 0000000..f1f3bc5 --- /dev/null +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TransactionalHandler.java @@ -0,0 +1,182 @@ +package io.trygvis.container.compiler; + +import io.trygvis.container.compiler.model.ClassG; +import io.trygvis.container.compiler.model.FieldRef; +import io.trygvis.container.compiler.model.ParameterRef; +import io.trygvis.container.compiler.model.Parameters; +import io.trygvis.container.compiler.model.TypeRef; +import io.trygvis.container.tx.PlatformTransactionManager; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.Name; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; +import javax.tools.JavaFileObject; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; + +import static javax.lang.model.util.ElementFilter.constructorsIn; +import static org.springframework.util.StringUtils.collectionToDelimitedString; + +public class TransactionalHandler { + + private final ProcessingEnvironment processingEnv; + private final Elements elements; + private final Types types; + + public TransactionalHandler(ProcessingEnvironment processingEnv) { + this.processingEnv = processingEnv; + this.elements = processingEnv.getElementUtils(); + this.types = processingEnv.getTypeUtils(); + } + + public void processTransactional(TypeElement element) throws IOException { + Name targetClassName = element.getSimpleName(); + System.out.println("Processing @Transactional " + targetClassName); + + Transactional transactional = element.getAnnotation(Transactional.class); + + String p = elements.getPackageOf(element).getQualifiedName().toString(); + + String className = targetClassName + "_Transactional"; + + JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(p + "." + className, element); + + try (PrintWriter w = new PrintWriter(sourceFile.openWriter())) { + ClassG g = new ClassG(p, className, targetClassName.toString()); +// writer.println("package " + p + ";"); +// writer.println(); +// writer.println("import io.trygvis.container.tx.PlatformTransactionManager;"); +// writer.println(); +// writer.println("public class " + className + " extends " + targetClassName + " {"); +// writer.println(" private final PlatformTransactionManager transactionManager;"); +// writer.println(); + +// TypeRef platformTransactionManager = g.addImport(PlatformTransactionManager.class); + FieldRef transactionManager = g.addField(PlatformTransactionManager.class, "transactionManager"); + + for (ExecutableElement constructor : constructorsIn(elements.getAllMembers(element))) { + if (!constructor.getModifiers().contains(Modifier.PUBLIC)) { + continue; + } + + constructor(g, constructor, transactionManager); + } + +// System.out.println("elements.getTypeElement(\"Object\") = " + elements.getTypeElement("java.lang.Object")); + Name javaLangObjectName = elements.getTypeElement("java.lang.Object").getQualifiedName(); + + for (Element e : elements.getAllMembers(element)) { + if (!(e instanceof ExecutableElement)) { + continue; + } + + ExecutableElement ee = (ExecutableElement) e; + + TypeElement enclosingElement = (TypeElement) ee.getEnclosingElement(); + + if (enclosingElement.getQualifiedName().equals(javaLangObjectName)) { + continue; + } + + if (ee.getSimpleName().toString().equals("")) { + continue; + } + +// System.out.println("ee.getSimpleName() = " + ee.getSimpleName()); +// System.out.println("ee.getEnclosingElement() = " + enclosingElement); +// System.out.println("ee.getEnclosingElement().getQualifiedName() = " + enclosingElement.getQualifiedName()); +// System.out.println("ee.getEnclosingElement().asType().getKind().getDeclaringClass() = " + enclosingElement.asType().getKind().getDeclaringClass()); + + TypeMirror returnTypeMirror = ee.getReturnType(); + + TypeKind kind = returnTypeMirror.getKind(); + + boolean isVoid = kind == TypeKind.VOID; + TypeRef returnType = isVoid ? TypeRef.VOID : g.addImport(returnTypeMirror); +// String returnString; +// if (isVoid) { +// returnString = "void"; +// } else { +// returnString = returnTypeMirror.toString(); +// } + + List parameters = new ArrayList<>(); + List arguments = new ArrayList<>(); + for (VariableElement ve : ee.getParameters()) { +// parameters.add("final " + ve.asType().toString() + " " + ve.getSimpleName().toString()); + TypeRef k = g.addImport(ve.asType()); + parameters.add(new ParameterRef(k, ve.getSimpleName().toString())); + arguments.add(ve.getSimpleName().toString()); + } + + List body = new ArrayList<>(); + +// writer.println(); +// writer.println(" public " + returnString + " " + ee.getSimpleName() + "(" + collectionToDelimitedString(parameters, ", ") + ") {"); + + body.add((isVoid ? "" : "return ") + "transactionManager.doInTransaction("); + body.add(" PlatformTransactionManager.TransactionIsolation.ISOLATION_" + transactional.isolation() + ","); + body.add(" PlatformTransactionManager.TransactionPropagation.PROPAGATION_" + transactional.propagation() + ","); + body.add(" new PlatformTransactionManager.TransactionTemplate<" + (isVoid ? "Object" : returnTypeMirror) + ">() {"); + body.add(" @Override"); + body.add(" public " + (isVoid ? "Object" : returnTypeMirror) + " doInTransaction() {"); + String targetInvocation = className + ".super." + ee.getSimpleName() + "(" + collectionToDelimitedString(arguments, ", ") + ");"; + + if (isVoid) { + body.add(" " + targetInvocation); + body.add(" return null;"); + } else { + body.add(" return " + targetInvocation); + } + + body.add(" }"); + body.add(" });"); + + g.addMethod(body, returnType, ee.getSimpleName().toString(), parameters.toArray(new ParameterRef[arguments.size()])); +// elements.printElements(new PrintWriter(System.out), ee); + } +// writer.println("}"); + g.write(w); + } + } + + private void constructor(ClassG g, ExecutableElement constructor, FieldRef platformTransactionManager) { + Parameters parameters = new Parameters(); + List goesToSuper = new ArrayList<>(); + + TypeRef k = g.addImport(PlatformTransactionManager.class); + ParameterRef transactionManager = parameters.addParameter(k, "transactionManager"); + + for (VariableElement p : constructor.getParameters()) { +// parameters.add(p.asType().toString() + " " + p.getSimpleName().toString()); +// arguments.add(p.getSimpleName().toString()); + k = g.addImport(p.asType()); + String name = p.getSimpleName().toString(); + parameters.addParameter(k, name); + goesToSuper.add(name); + } + +// String params = parameters.size() == 0 ? "" : ", " + collectionToDelimitedString(parameters, ", "); + + List body = new ArrayList<>(); + body.add("super(" + collectionToDelimitedString(goesToSuper, ", ") + ");"); + body.add("this." + platformTransactionManager.name + " = " + transactionManager.name + ";"); + g.addConstructor(parameters, body); + +// writer.println(" public " + className + "(PlatformTransactionManager _transactionManager_" + params + ") {"); +// writer.println(" super(" + collectionToDelimitedString(arguments, ", ") + ");"); +// writer.println(" this.transactionManager = _transactionManager_;"); +// writer.println(" }"); + } +} diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ClassG.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ClassG.java index 6c0e246..13e1b03 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ClassG.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ClassG.java @@ -1,7 +1,6 @@ package io.trygvis.container.compiler.model; import javax.lang.model.type.TypeMirror; -import java.io.CharArrayWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; @@ -12,11 +11,12 @@ import static org.springframework.util.StringUtils.collectionToDelimitedString; public class ClassG { private final String packageName; - private final String className; + public final String className; private final String extendsClass; private final Set imports = new TreeSet<>(); private final Set fields = new TreeSet<>(); private final List methods = new ArrayList<>(); + private final List constructors = new ArrayList<>(); // public ClassG(String packageName, String className) { // this(packageName, className, null); @@ -79,7 +79,13 @@ public class ClassG { return ref; } - public MethodRef addMethod(String body, TypeRef returnType, String name, ParameterRef... parameters) { + public Constructor addConstructor(Parameters parameters, List body) { + Constructor constructor = new Constructor(this, parameters, body); + constructors.add(constructor); + return constructor; + } + + public MethodRef addMethod(List body, TypeRef returnType, String name, ParameterRef... parameters) { MethodRef ref = new MethodRef(returnType, name, parameters, body); methods.add(ref); return ref; @@ -97,10 +103,19 @@ public class ClassG { writer.println(); writer.println("public class " + className + " extends " + extendsClass + " {"); for (FieldRef field : fields) { + writer.println(); writer.println(" private final " + field.klass.name + " " + field.name + ";"); } + for (Constructor constructor : constructors) { + writer.println(); + for (String s : constructor.write()) { + writer.println(s); + } + } + for (MethodRef method : methods) { + writer.println(); write(writer, method); } @@ -117,40 +132,13 @@ public class ClassG { List parameters = new ArrayList<>(); for (ParameterRef p : method.parameters) { - parameters.add(p.klass.name + " " + p.name); + parameters.add("final " + p.klass.name + " " + p.name); } writer.println(" public " + returnString + " " + method.name + "(" + collectionToDelimitedString(parameters, ", ") + ") {"); - writer.println(method.body); - writer.println(" }"); - } - - public void simpleConstructor(List parameters, List goesToSuper) { - List ps = new ArrayList<>(); - for (ParameterRef p : parameters) { - ps.add(p.klass.name + " " + p.name); - } - List ss = new ArrayList<>(); - List local = new ArrayList<>(); - for (String s : goesToSuper) { - for (ParameterRef parameter : parameters) { - if (parameter.name.equals(s)) { - ss.add(parameter.name); - continue; - } - } - local.add(s); - } - String params = ps.size() == 0 ? "" : ", " + collectionToDelimitedString(ps, ", "); - - CharArrayWriter buffer = new CharArrayWriter(); - PrintWriter writer = new PrintWriter(buffer); - - writer.println(" public " + className + "(" + params + ") {"); - writer.println(" super(" + collectionToDelimitedString(ss, ", ") + ");"); -// writer.println(" this.transactionManager = _transactionManager_;"); - for (String s : local) { - writer.println(" this." + s + " = " + s); + for (String s : method.body) { + writer.print(" "); + writer.println(s); } writer.println(" }"); } diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Constructor.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Constructor.java new file mode 100644 index 0000000..43800ce --- /dev/null +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Constructor.java @@ -0,0 +1,38 @@ +package io.trygvis.container.compiler.model; + +import java.util.ArrayList; +import java.util.List; + +import static org.springframework.util.StringUtils.collectionToDelimitedString; + +public class Constructor { + + private final ClassG g; + private final Parameters parameters; + private final List body; + + public Constructor(ClassG g, Parameters parameters, List body) { + this.g = g; + this.parameters = parameters; + this.body = body; + } + + public List write() { + List body = new ArrayList<>(); + + List ps = new ArrayList<>(); + for (ParameterRef p : parameters) { + ps.add(p.klass.name + " " + p.name); + } + + String params = collectionToDelimitedString(ps, ", "); + + body.add(" public " + g.className + "(" + params + ") {"); + for (String s : this.body) { + body.add(" " + s); + } + body.add(" }"); + + return body; + } +} diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/MethodRef.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/MethodRef.java index 0b2cf89..36f61e8 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/MethodRef.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/MethodRef.java @@ -1,13 +1,15 @@ package io.trygvis.container.compiler.model; +import java.util.List; + public class MethodRef { public final TypeRef returnType; public final String name; public final ParameterRef[] parameters; - public final String body; + public final List body; public - MethodRef(TypeRef returnType, String name, ParameterRef[] parameters, String body) { + MethodRef(TypeRef returnType, String name, ParameterRef[] parameters, List body) { this.returnType = returnType; this.name = name; this.parameters = parameters; diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Parameters.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Parameters.java index bfb32b6..7c1ab5b 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Parameters.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Parameters.java @@ -1,4 +1,35 @@ package io.trygvis.container.compiler.model; -public class Parameters { +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; + +public class Parameters implements Iterable { + private final List parameters = new ArrayList<>(); + + public ParameterRef addParameter(TypeRef klass, String name) { + + while (taken(name)) { + name = name + "_"; + } + + ParameterRef ref = new ParameterRef(klass, name); + parameters.add(ref); + return ref; + } + + private boolean taken(String name) { + for (ParameterRef parameter : parameters) { + if (parameter.name.equals(name)) { + return true; + } + } + + return false; + } + + @Override + public ListIterator iterator() { + return parameters.listIterator(); + } } -- cgit v1.2.3