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.java110
1 files changed, 91 insertions, 19 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) {