summaryrefslogtreecommitdiff
path: root/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java
diff options
context:
space:
mode:
Diffstat (limited to 'container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java')
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java140
1 files changed, 102 insertions, 38 deletions
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java
index d9e13ac..a25c766 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java
@@ -1,10 +1,12 @@
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.TypeRef;
import io.trygvis.persistence.EntityMirror;
import io.trygvis.persistence.FieldMirror;
import io.trygvis.persistence.GeneratorConfiguration;
+import io.trygvis.persistence.SequenceMirror;
import io.trygvis.persistence.SqlEntity;
import io.trygvis.persistence.TypeHandler;
import io.trygvis.persistence.sql.SqlEntityDesc;
@@ -12,16 +14,17 @@ import io.trygvis.persistence.sql.SqlEntityDesc;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
import javax.tools.JavaFileObject;
import java.io.IOException;
import java.io.PrintWriter;
-import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -32,6 +35,7 @@ import static io.trygvis.persistence.FieldMirror.PrimitiveFieldMirror;
import static java.lang.Character.isUpperCase;
import static java.lang.reflect.Modifier.PUBLIC;
import static javax.lang.model.util.ElementFilter.fieldsIn;
+import static org.apache.commons.lang.StringUtils.join;
import static org.apache.commons.lang.StringUtils.stripEnd;
public class EntityHandler extends AbstractHandler {
@@ -45,9 +49,10 @@ public class EntityHandler extends AbstractHandler {
public void phase1(Set<TypeElement> sqlEntities, Set<PackageElement> packages) throws Exception {
for (TypeElement entity : sqlEntities) {
- AnnotationMirror sqlEntity = findAnnotation(SqlEntity.class, entity);
+ AnnotationMirror sqlEntity = getAnnotation(SqlEntity.class, entity);
for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> v : sqlEntity.getElementValues().entrySet()) {
- switch (v.getKey().getSimpleName().toString()) {
+ String field = v.getKey().getSimpleName().toString();
+ switch (field) {
case "value":
Class<?> typeHandlerClass = getClass().getClassLoader().loadClass(v.getValue().getValue().toString());
@@ -56,12 +61,13 @@ public class EntityHandler extends AbstractHandler {
generatorConfiguration.addTypeHandler(new TypeRef(type), typeHandler);
System.out.println("Loaded TypeHandler for " + type + " through " + typeHandlerClass.getCanonicalName());
break;
+ default:
+ throw new InternalErrorException("Unknown @SqlEntity field: " + field);
}
}
// System.out.println("sqlEntity.getElementValues() = " + sqlEntity.getElementValues());
}
- System.out.println("packages = " + packages);
if (packages.size() == 0) {
throw new CompilerException("There has to be exactly one @SqlEntitySet annotated package.");
}
@@ -70,27 +76,48 @@ public class EntityHandler extends AbstractHandler {
if (packages.size() != 1) {
throw new CompilerException(packageElement, "There can only be one @SqlEntitySet annotated package.");
}
- }
-
- private AnnotationMirror findAnnotation(Class<?> c, TypeElement type) {
- TypeMirror annotationType = elements.getTypeElement(c.getCanonicalName()).asType();
- for (AnnotationMirror a : type.getAnnotationMirrors()) {
- if (types.isSameType(a.getAnnotationType(), annotationType)) {
- return a;
- }
- }
-
- throw new CompilerException(type, "Could not find annotation " + c.getSimpleName());
+ sqlUnit.setPackageName(packageElement.getQualifiedName().toString());
}
public void recordEntity(TypeElement element) throws Exception {
- EntityMirror entityMirror = new EntityMirror(generatorConfiguration, new TypeRef(types.getDeclaredType(element)),
+ EntityMirror entityMirror = new EntityMirror(
+ generatorConfiguration,
+ new TypeRef(types.getDeclaredType(element)),
sqlName(element.getSimpleName().toString()));
for (VariableElement f : fieldsIn(elements.getAllMembers(element))) {
- entityMirror.add(fromElement(generatorConfiguration, f));
+ FieldMirror field = fromElement(generatorConfiguration, f);
+ entityMirror.add(field);
}
+ // -----------------------------------------------------------------------
+ // Process any extra annotations
+ // -----------------------------------------------------------------------
+
+ AnnotationMirror sequenceGenerator = findAnnotation(SequenceGenerator.class, element);
+
+ if (sequenceGenerator != null) {
+ String name = null;
+ for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> v : sequenceGenerator.getElementValues().entrySet()) {
+ String field = v.getKey().getSimpleName().toString();
+ switch (field) {
+ case "name":
+ name = v.getValue().getValue().toString();
+
+ break;
+ default:
+ throw new InternalErrorException("Unsupported field on @SequenceGenerator: " + field);
+ }
+ }
+ if (name != null) {
+ sqlUnit.add(new SequenceMirror(name));
+ }
+ }
+
+ // -----------------------------------------------------------------------
+ // Validation
+ // -----------------------------------------------------------------------
+
List<FieldMirror> idFields = new ArrayList<>();
for (FieldMirror field : entityMirror.fields) {
if (field.id) {
@@ -105,22 +132,21 @@ public class EntityHandler extends AbstractHandler {
throw new CompilerException(element, "This implementation only support a single @Id annotated field.");
}
- sqlUnit.add(entityMirror);
+ sqlUnit.add(entityMirror, element);
}
- public void generate(EntityMirror entityMirror) throws IOException {
+ public ClassG phase3(EntityMirror entityMirror) throws IOException {
ClassG g = new ClassG(PUBLIC, entityMirror.daoType);
TypeRef stringType = g.imports.add(String.class);
TypeRef sqlEntityDescType = g.imports.add(SqlEntityDesc.class);
- TypeRef sqlExceptionType = g.imports.add(SQLException.class);
g.addPublicStaticFinalField(stringType, "createTableSql").
value(toJavaString(entityMirror.createTableSql(sqlUnit)));
g.addPublicStaticFinalField(stringType, "dropTableSql").
value(toJavaString(entityMirror.dropTableSql()));
g.addPublicStaticFinalField(stringType, "insertIntoSql").
- value(toJavaString(entityMirror.insertIntoSql()));
+ value(toJavaString(entityMirror.insertIntoSql(sqlUnit)));
g.addPublicStaticFinalField(stringType, "deleteFromSql").
value(toJavaString(entityMirror.deleteFromSql()));
String desc = "new " + sqlEntityDescType + "(" +
@@ -129,18 +155,13 @@ public class EntityHandler extends AbstractHandler {
")";
g.addPublicStaticFinalField(sqlEntityDescType, "desc").value(desc);
ClassG.InnerClassG typedQuery = g.addInnerClass(entityMirror.queryType(g.imports));
- typedQuery.inner.addMethod(entityMirror.fromResultSet(sqlUnit, g.imports));
+ typedQuery.inner.addMethod(entityMirror.fromResultSet(g.imports));
g.addMethod(entityMirror.insertInto(sqlUnit, g.imports));
g.addMethod(entityMirror.delete(g.imports));
g.addMethod(entityMirror.deleteById(g.imports));
- g.addMethod(entityMirror.query(sqlUnit, g.imports));
+ g.addMethod(entityMirror.query(g.imports));
- JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(entityMirror.daoType.fqName, sqlUnit.elementForEntity(entityMirror));
- try (PrintWriter w = new PrintWriter(sourceFile.openWriter())) {
- for (String s : g.generate()) {
- w.println(stripEnd(s, " "));
- }
- }
+ return g;
}
public FieldMirror fromElement(GeneratorConfiguration generatorConfiguration, VariableElement var) {
@@ -174,12 +195,39 @@ public class EntityHandler extends AbstractHandler {
public void phase3() throws Exception {
for (EntityMirror entity : sqlUnit.getEntities().values()) {
- generate(entity);
+ writeFile(phase3(entity), sqlUnit.element(entity));
+ }
+ writeFile(generateSequences(sqlUnit), null);
+ writeFile(generateSession(), null);
+ }
+
+ private ClassG generateSequences(SqlUnitModel unit) {
+ TypeRef sequences = new TypeRef(unit.getPackageName() + ".Sequences");
+ ClassG g = new ClassG(PUBLIC, sequences);
+ List<String> fields = new ArrayList<>();
+ for (SequenceMirror sequence : unit.getSequences().values()) {
+ TypeRef stringType = g.imports.add(String.class);
+ String value = "CREATE SEQUENCE " + sequence.name + ";";
+ FieldRef f = g.addPublicStaticFinalField(stringType, sequence.name).value(toJavaString(value));
+ fields.add(f.name);
}
- generateSession();
+ TypeRef stringArrayType = new TypeRef(String[].class);
+ System.out.println("stringArrayType = " + stringArrayType);
+ g.addPublicStaticFinalField(stringArrayType, "sequences").
+ value("new String[]{" + join(fields, ", ") + "}");
+ return g;
}
- private void generateSession() throws IOException {
+ private void writeFile(ClassG g, Element element) throws IOException {
+ JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(g.type.fqName, element);
+ try (PrintWriter w = new PrintWriter(sourceFile.openWriter())) {
+ for (String s : g.generate()) {
+ w.println(stripEnd(s, " "));
+ }
+ }
+ }
+
+ private ClassG generateSession() throws IOException {
String p = packageElement.getQualifiedName().toString();
// TODO: Support a name prefix from @SqlEntitySet
@@ -201,12 +249,7 @@ public class EntityHandler extends AbstractHandler {
g.addConstructor(parameters, body);
*/
- JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(type.fqName, packageElement);
- try (PrintWriter w = new PrintWriter(sourceFile.openWriter())) {
- for (String s : g.generate()) {
- w.println(stripEnd(s, " "));
- }
- }
+ return g;
}
public static String sqlName(String javaName) {
@@ -220,4 +263,25 @@ public class EntityHandler extends AbstractHandler {
}
return builder.toString();
}
+
+ private AnnotationMirror findAnnotation(Class<?> c, TypeElement type) {
+ TypeMirror annotationType = elements.getTypeElement(c.getCanonicalName()).asType();
+ for (AnnotationMirror a : type.getAnnotationMirrors()) {
+ if (types.isSameType(a.getAnnotationType(), annotationType)) {
+ return a;
+ }
+ }
+
+ return null;
+ }
+
+ public AnnotationMirror getAnnotation(Class<?> c, TypeElement type) {
+ AnnotationMirror annotation = findAnnotation(c, type);
+
+ if (annotation != null) {
+ return annotation;
+ }
+
+ throw new CompilerException(type, "Could not find annotation " + c.getSimpleName());
+ }
}