summaryrefslogtreecommitdiff
path: root/container-compiler-plugin/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'container-compiler-plugin/src/main/java')
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java110
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java10
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/Utils.java17
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java60
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java62
5 files changed, 184 insertions, 75 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 a25c766..98090a4 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
@@ -19,6 +19,7 @@ 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.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
@@ -29,12 +30,19 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
+import static io.trygvis.container.compiler.Utils.toFieldName;
import static io.trygvis.container.compiler.Utils.toJavaString;
-import static io.trygvis.persistence.FieldMirror.PrimitiveFieldMirror;
+import static io.trygvis.persistence.FieldMirror.AccessorType.FIELD;
+import static io.trygvis.persistence.FieldMirror.AccessorType.METHOD;
+import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE;
+import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE;
import static java.lang.Character.isUpperCase;
+import static java.lang.String.format;
import static java.lang.reflect.Modifier.PUBLIC;
import static javax.lang.model.util.ElementFilter.fieldsIn;
+import static javax.lang.model.util.ElementFilter.methodsIn;
import static org.apache.commons.lang.StringUtils.join;
import static org.apache.commons.lang.StringUtils.stripEnd;
@@ -65,7 +73,6 @@ public class EntityHandler extends AbstractHandler {
throw new InternalErrorException("Unknown @SqlEntity field: " + field);
}
}
-// System.out.println("sqlEntity.getElementValues() = " + sqlEntity.getElementValues());
}
if (packages.size() == 0) {
@@ -85,9 +92,57 @@ public class EntityHandler extends AbstractHandler {
new TypeRef(types.getDeclaredType(element)),
sqlName(element.getSimpleName().toString()));
+ Map<String, ExecutableElement> getters = new TreeMap<>();
+ Map<String, ExecutableElement> setters = new TreeMap<>();
+ for (ExecutableElement m : methodsIn(elements.getAllMembers(element))) {
+ String name = m.getSimpleName().toString();
+ if (name.length() < 4 || !isUpperCase(name.charAt(3))) {
+ continue;
+ }
+
+ String declaringType = ((TypeElement) m.getEnclosingElement()).getQualifiedName().toString();
+ if (declaringType.equals("java.lang.Object")) {
+ continue;
+ }
+
+ boolean isVoid = m.getReturnType().getKind().equals(TypeKind.VOID);
+
+ if (name.startsWith("get") && m.getParameters().size() == 0 && !isVoid) {
+ getters.put(toFieldName(name), m);
+ }
+
+ if (name.startsWith("set") && m.getParameters().size() == 1 && isVoid) {
+ setters.put(toFieldName(name), m);
+ }
+ }
+
+ // Iterate over all fields. Consume relevant getters and setters.
for (VariableElement f : fieldsIn(elements.getAllMembers(element))) {
- FieldMirror field = fromElement(generatorConfiguration, f);
+ String name = f.getSimpleName().toString();
+ ExecutableElement getter = getters.remove(name);
+ ExecutableElement setter = setters.remove(name);
+ FieldMirror field = fromElement(generatorConfiguration, f, getter, setter);
+ if (field == null) {
+ continue;
+ }
entityMirror.add(field);
+ System.out.println("Field: " + field);
+ }
+
+ for (Map.Entry<String, ExecutableElement> e : getters.entrySet()) {
+ String name = e.getKey();
+ ExecutableElement getter = e.getValue();
+ ExecutableElement setter = setters.remove(name);
+ FieldMirror field = fromElement(generatorConfiguration, null, getter, setter);
+ if (field == null) {
+ continue;
+ }
+ entityMirror.add(field);
+ System.out.println("Field: " + field);
+ }
+
+ if (!setters.isEmpty()) {
+ throw new CompilerException(element, "Missing getters for setters: " + join(setters.keySet(), ", "));
}
// -----------------------------------------------------------------------
@@ -164,15 +219,36 @@ public class EntityHandler extends AbstractHandler {
return g;
}
- public FieldMirror fromElement(GeneratorConfiguration generatorConfiguration, VariableElement var) {
- TypeRef type = new TypeRef(var.asType());
-// System.out.print("element = ");
-// elements.printElements(new PrintWriter(System.out), var);
- String javaName = var.getSimpleName().toString();
- String sqlName = sqlName(javaName);
+ public FieldMirror fromElement(GeneratorConfiguration generatorConfiguration, VariableElement var,
+ ExecutableElement getter, ExecutableElement setter) {
+ // TODO: check the setter for annotations too
+ // TODO: check for transient and @Transient
+ FieldMirror.AccessorType accessorType;
+ TypeRef type;
+ String javaName;
+ String sqlName;
+ boolean id;
+
+ if (var != null) {
+ accessorType = FIELD;
+ type = new TypeRef(var.asType());
+ javaName = var.getSimpleName().toString();
+ id = isId(var);
+ } else {
+ accessorType = METHOD;
+ type = new TypeRef(getter.getReturnType());
+ id = isId(getter);
+ // TODO: this might be relaxed, just find the common type and use that.
+ if (!types.isSameType(getter.getReturnType(), setter.getParameters().get(0).asType())) {
+ throw new CompilerException(format("The setter and getter %s/%s must access the same types.",
+ setter.getSimpleName(), getter.getSimpleName()));
+ }
+ javaName = toFieldName(getter.getSimpleName().toString());
+ }
+ sqlName = sqlName(javaName);
+
boolean notNull = false;
boolean unique = false;
- boolean id = isId(var);
boolean primitive = generatorConfiguration.isPrimitive(type);
if (id && !primitive) {
throw new CompilerException(var, "A @Id field has to be a primitive or embedded.");
@@ -180,16 +256,16 @@ public class EntityHandler extends AbstractHandler {
FieldMirror field;
if (primitive) {
- field = new PrimitiveFieldMirror(type, javaName, sqlName, id, notNull, unique);
+ field = new FieldMirror(PRIMITIVE, accessorType, type, javaName, sqlName, id, notNull, unique);
} else if (generatorConfiguration.hasTypeHandler(type)) {
throw new CompilerException(var, "Missing type handler for type: " + type.fqName);
} else {
- field = new FieldMirror.ReferenceFieldMirror(type, javaName, sqlName, notNull, unique);
+ field = new FieldMirror(REFERENCE, accessorType, type, javaName, sqlName, id, notNull, unique);
}
return field;
}
- public static boolean isId(VariableElement var) {
+ public static boolean isId(Element var) {
return var.getAnnotation(Id.class) != null;
}
@@ -211,9 +287,7 @@ public class EntityHandler extends AbstractHandler {
FieldRef f = g.addPublicStaticFinalField(stringType, sequence.name).value(toJavaString(value));
fields.add(f.name);
}
- TypeRef stringArrayType = new TypeRef(String[].class);
- System.out.println("stringArrayType = " + stringArrayType);
- g.addPublicStaticFinalField(stringArrayType, "sequences").
+ g.addPublicStaticFinalField(new TypeRef(String[].class), "sequences").
value("new String[]{" + join(fields, ", ") + "}");
return g;
}
@@ -233,8 +307,6 @@ public class EntityHandler extends AbstractHandler {
// TODO: Support a name prefix from @SqlEntitySet
TypeRef type = new TypeRef(p + ".Session");
- ClassG g = new ClassG(PUBLIC, type);
-
/*
TypeRef conType = g.add(Connection.class);
Parameters parameters = new Parameters();
@@ -249,7 +321,7 @@ public class EntityHandler extends AbstractHandler {
g.addConstructor(parameters, body);
*/
- return g;
+ return new ClassG(PUBLIC, type);
}
public static String sqlName(String javaName) {
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 be0b446..89da439 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
@@ -77,7 +77,7 @@ public class MyProcessor implements Processor {
// System.out.println("claimed = " + claimed);
return claimed;
} catch (CompilerException e) {
- e.printStackTrace(System.err);
+// e.printStackTrace(System.out);
Messager messager = processingEnv.getMessager();
messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage(), e.element);
return true;
@@ -122,7 +122,13 @@ public class MyProcessor implements Processor {
new LogHandler(processingEnv).processLog((TypeElement) element);
}
if (types.isSameType(entity.asType(), annotationType)) {
- entityHandler.recordEntity((TypeElement) element);
+ try {
+ entityHandler.recordEntity((TypeElement) element);
+ } catch (CompilerException e) {
+// e.printStackTrace(System.out);
+ Messager messager = processingEnv.getMessager();
+ messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage(), e.element);
+ }
}
}
}
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/Utils.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/Utils.java
index 5057968..8bb1b33 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/Utils.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/Utils.java
@@ -12,6 +12,13 @@ public class Utils {
if (s.length() < 1) {
return s.toLowerCase();
}
+
+ if (s.startsWith("set")) {
+ s = s.substring(3, s.length());
+ } else if (s.startsWith("get")) {
+ s = s.substring(3, s.length());
+ }
+
char[] chars = s.toCharArray();
boolean toUpper = false;
@@ -33,6 +40,16 @@ public class Utils {
return new String(chars, 0, j);
}
+ public static String toSetterName(String s) {
+ s = toFieldName(s);
+ return "set" + toUpperCase(s.charAt(0)) + s.substring(1, s.length());
+ }
+
+ public static String toGetterName(String s) {
+ s = toFieldName(s);
+ return "get" + toUpperCase(s.charAt(0)) + s.substring(1, s.length());
+ }
+
public static String toJavaString(String s) {
try {
BufferedReader reader = new BufferedReader(new StringReader(s));
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java
index 48f8adc..f1970f7 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java
@@ -18,9 +18,13 @@ import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
+import static io.trygvis.container.compiler.Utils.toGetterName;
+import static io.trygvis.container.compiler.Utils.toSetterName;
import static io.trygvis.container.compiler.model.Parameters.ParameterRef;
-import static io.trygvis.persistence.FieldMirror.PrimitiveFieldMirror;
-import static io.trygvis.persistence.FieldMirror.ReferenceFieldMirror;
+import static io.trygvis.persistence.FieldMirror.AccessorType.FIELD;
+import static io.trygvis.persistence.FieldMirror.AccessorType.METHOD;
+import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE;
+import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE;
import static java.lang.String.format;
import static java.lang.reflect.Modifier.PUBLIC;
import static java.lang.reflect.Modifier.STATIC;
@@ -61,7 +65,7 @@ public class EntityMirror implements Comparable<EntityMirror> {
List<String> columns = new ArrayList<>();
for (FieldMirror field : fields) {
String s;
- if (field instanceof PrimitiveFieldMirror) {
+ if (field.fieldType == PRIMITIVE) {
TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type);
s = " " + field.sqlName + " " + typeHandler.sqlType(field);
if (field.id) {
@@ -71,9 +75,8 @@ public class EntityMirror implements Comparable<EntityMirror> {
} else if (field.unique) {
s += " UNIQUE";
}
- } else if (field instanceof ReferenceFieldMirror) {
- ReferenceFieldMirror ref = (ReferenceFieldMirror) field;
- EntityMirror referenced = unit.get(ref.type);
+ } else if (field.fieldType == REFERENCE) {
+ EntityMirror referenced = unit.get(field.type);
if (referenced.idFields.size() == 1) {
FieldMirror idField = referenced.idFields.get(0);
TypeHandler typeHandler = generatorConfiguration.typeHandler(idField.type);
@@ -157,7 +160,7 @@ public class EntityMirror implements Comparable<EntityMirror> {
i++;
- if (field instanceof PrimitiveFieldMirror) {
+ if (field.fieldType == PRIMITIVE) {
TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type);
String access = o.name + "." + field.javaName;
String setter = " stmt." + typeHandler.setter(i, access) + ";";
@@ -172,9 +175,8 @@ public class EntityMirror implements Comparable<EntityMirror> {
body.add(" " + setter);
body.add(" }");
}
- } else if (field instanceof ReferenceFieldMirror) {
- ReferenceFieldMirror ref = (ReferenceFieldMirror) field;
- EntityMirror referenced = unit.get(ref.type);
+ } else if (field.fieldType == REFERENCE) {
+ EntityMirror referenced = unit.get(field.type);
FieldMirror idField = referenced.getIdField();
TypeHandler typeHandler = generatorConfiguration.typeHandler(idField.type);
body.add(" stmt." + typeHandler.setter(i, o.name + "." + field.javaName + "." + idField.javaName) + ";");
@@ -195,7 +197,11 @@ public class EntityMirror implements Comparable<EntityMirror> {
List<String> arguments = new ArrayList<>();
arguments.add(con.name);
for (FieldMirror field : idFields) {
- arguments.add(o.name + "." + field.javaName);
+ if(field.accessorType == FIELD) {
+ arguments.add(o.name + "." + field.javaName);
+ } else {
+ arguments.add(o.name + "." + toGetterName(field.javaName) + "()");
+ }
}
List<String> body = new ArrayList<>();
body.add("deleteById(" + join(arguments, ", ") + ");");
@@ -262,10 +268,13 @@ public class EntityMirror implements Comparable<EntityMirror> {
List<String> names = new ArrayList<>();
for (int i = 0; i < fields.size(); i++) {
FieldMirror field = fields.get(i);
- if (field instanceof PrimitiveFieldMirror) {
+ if (field.accessorType != FIELD) {
+ continue;
+ }
+ if (field.fieldType == PRIMITIVE) {
TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type);
body.add(field.type + " " + field.javaName + " = " + typeHandler.getter(rs.name, i + 1) + ";");
- } else if (field instanceof ReferenceFieldMirror) {
+ } else if (field.fieldType == REFERENCE) {
// ReferenceFieldMirror ref = (ReferenceFieldMirror) field;
// EntityMirror referenced = unit.get(ref.type);
// FieldMirror idField = referenced.getIdField();
@@ -274,9 +283,32 @@ public class EntityMirror implements Comparable<EntityMirror> {
body.add(field.type + " " + field.javaName + " = null;");
}
names.add(field.javaName);
+ i++;
+ }
+
+ body.add(type + " returnValue = new " + type + "(" + join(names, ", ") + ");");
+
+ for (int i = 0; i < fields.size(); i++) {
+ FieldMirror field = fields.get(i);
+ if (field.accessorType != METHOD) {
+ continue;
+ }
+ if (field.fieldType == PRIMITIVE) {
+ TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type);
+ body.add("returnValue." + toSetterName(field.javaName) + "(" + typeHandler.getter(rs.name, i + 1) + ");");
+ } else if (field.fieldType == REFERENCE) {
+// ReferenceFieldMirror ref = (ReferenceFieldMirror) field;
+// EntityMirror referenced = unit.get(ref.type);
+// FieldMirror idField = referenced.getIdField();
+// TypeHandler typeHandler = generatorConfiguration.typeHandler(idField.type);
+// body.add(field.type + " " + field.javaName + " = " + typeHandler.getter(rs.name, i + 1) + ";");
+ body.add("returnValue." + toSetterName(field.javaName) + "(" + null + ");");
+ }
+ names.add(field.javaName);
+ i++;
}
- body.add("return new " + type + "(" + join(names, ", ") + ");");
+ body.add("return returnValue;");
return new MethodRef(PUBLIC, type, "fromResultSet", p, body).
exception(g.add(SQLException.class));
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java
index f92cc2c..07fa769 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java
@@ -2,14 +2,12 @@ package io.trygvis.persistence;
import io.trygvis.container.compiler.model.TypeRef;
-import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE;
-import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE;
-
/**
* TODO: a single field might have to be mapped to multiple sql columns.
*/
-public abstract class FieldMirror {
+public class FieldMirror {
public final FieldType fieldType;
+ public final AccessorType accessorType;
public final TypeRef type;
public final String javaName;
public final String sqlName;
@@ -22,8 +20,15 @@ public abstract class FieldMirror {
REFERENCE,
}
- protected FieldMirror(FieldType fieldType, TypeRef type, String javaName, String sqlName, boolean id, boolean notNull, boolean unique) {
+ public enum AccessorType {
+ FIELD,
+ METHOD,
+ }
+
+ public FieldMirror(FieldType fieldType, AccessorType accessorType, TypeRef type, String javaName, String sqlName,
+ boolean id, boolean notNull, boolean unique) {
this.fieldType = fieldType;
+ this.accessorType = accessorType;
this.type = type;
this.javaName = javaName;
this.sqlName = sqlName;
@@ -32,40 +37,17 @@ public abstract class FieldMirror {
this.unique = unique;
}
- public static class PrimitiveFieldMirror extends FieldMirror {
- public PrimitiveFieldMirror(TypeRef typeRef, String javaName, String sqlName, boolean id, boolean notNull, boolean unique) {
- super(PRIMITIVE, typeRef, javaName, sqlName, id, notNull, unique);
- }
-
- @Override
- public String toString() {
- return "PrimitiveFieldMirror{" +
- "type='" + type + '\'' +
- ", javaName='" + javaName + '\'' +
- ", sqlName='" + sqlName + '\'' +
- ", notNull=" + notNull +
- ", unique=" + unique +
- '}';
- }
- }
-
- public static class ReferenceFieldMirror extends FieldMirror {
- public ReferenceFieldMirror(TypeRef typeRef, String javaName, String sqlName, boolean notNull, boolean unique) {
- super(REFERENCE, typeRef, javaName, sqlName, false, notNull, unique);
- }
-
- @Override
- public String toString() {
- return "ReferenceFieldMirror{" +
- "type='" + type + '\'' +
- ", javaName='" + javaName + '\'' +
- ", sqlName='" + sqlName + '\'' +
- ", notNull=" + notNull +
- ", unique=" + unique +
- '}';
- }
- }
-
@Override
- public abstract String toString();
+ public String toString() {
+ return "FieldMirror{" +
+ "fieldType=" + fieldType +
+ ", accessorType=" + accessorType +
+ ", type=" + type +
+ ", javaName='" + javaName + '\'' +
+ ", sqlName='" + sqlName + '\'' +
+ ", id=" + id +
+ ", notNull=" + notNull +
+ ", unique=" + unique +
+ '}';
+ }
}