summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2013-08-11 22:35:02 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2013-08-11 22:35:02 +0200
commite78c0a1e4a4ebc71502dceccc9ae640862b7ce9e (patch)
tree38517a79011ee280d08da06ce20dba1ac7aebd62
parent41704c6a57d53b90b4e764ea4fb9c8ff81ced500 (diff)
downloadcontainer-playground-e78c0a1e4a4ebc71502dceccc9ae640862b7ce9e.tar.gz
container-playground-e78c0a1e4a4ebc71502dceccc9ae640862b7ce9e.tar.bz2
container-playground-e78c0a1e4a4ebc71502dceccc9ae640862b7ce9e.tar.xz
container-playground-e78c0a1e4a4ebc71502dceccc9ae640862b7ce9e.zip
o Overhauling inheritance, adding a decent start of support for @MappedSuperclass.
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/ElementComparator.java11
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java129
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java24
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/SqlUnitModel.java13
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TypeMirrorComparator.java11
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/container/compiler/Utils.java16
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java57
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java49
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java23
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionFactoryGenerator.java4
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionGenerator.java11
-rw-r--r--container-compiler-plugin/src/test/java/io/trygvis/container/compiler/EntityHandlerTest.java2
-rw-r--r--container-compiler-plugin/src/test/java/io/trygvis/container/compiler/ProcessorTest.java71
-rw-r--r--container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java8
-rw-r--r--container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/Car.java (renamed from container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/Car.java)2
-rw-r--r--container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/ChildEntity.java (renamed from container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/ChildEntity.java)2
-rw-r--r--container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/ParentEntity.java (renamed from container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/ParentEntity.java)4
-rw-r--r--container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/Person.java (renamed from container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/Person.java)2
-rw-r--r--container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/package-info.java4
-rw-r--r--container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/inheritance/A.java40
-rw-r--r--container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/inheritance/package-info.java4
-rw-r--r--container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/package-info.java4
22 files changed, 349 insertions, 142 deletions
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/ElementComparator.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/ElementComparator.java
new file mode 100644
index 0000000..d1ed776
--- /dev/null
+++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/ElementComparator.java
@@ -0,0 +1,11 @@
+package io.trygvis.container.compiler;
+
+import javax.lang.model.element.Element;
+import java.util.Comparator;
+
+class ElementComparator implements Comparator<Element> {
+ @Override
+ public int compare(Element o1, Element o2) {
+ return o1.asType().toString().compareTo(o2.asType().toString());
+ }
+}
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 9cb85e9..ba9f100 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
@@ -25,11 +25,13 @@ import javax.lang.model.type.TypeMirror;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
+import java.util.TreeSet;
import static io.trygvis.container.compiler.Utils.toFieldName;
import static io.trygvis.container.compiler.Utils.writeFile;
@@ -95,22 +97,60 @@ public class EntityHandler extends AbstractHandler {
sqlUnit.setName(name);
}
- public void recordEntity(TypeElement element) throws Exception {
+ Set<TypeElement> mappedSuperclasses = new HashSet<>();
+ Set<TypeElement> entities = new HashSet<>();
+
+ public void record(TypeElement element, boolean superclass) throws Exception {
+ (superclass ? mappedSuperclasses : entities).add(element);
+ }
+
+ private EntityMirror getEntity(TypeElement element, boolean superclass) throws Exception {
+ EntityMirror entity = sqlUnit.entity(element);
+ if (entity != null) {
+ return entity;
+ }
+
+ entity = buildMirror(element, superclass);
+ sqlUnit.add(entity, element);
+ return entity;
+ }
+
+ public EntityMirror buildMirror(TypeElement element, boolean concrete) throws Exception {
+ EntityMirror superEntity = null;
+
+ Set<TypeMirror> ancestry = new TreeSet<>(new TypeMirrorComparator());
+ ancestry.add(element.asType());
+ TypeMirror superType = element.getSuperclass();
+ while (!superType.toString().equals("java.lang.Object")) {
+ TypeElement superTypeMirror = elements.getTypeElement(superType.toString());
+ if (superTypeMirror == null) {
+ throw new CompilerException(element, "Couldn't find element for super class: " + element.getSuperclass());
+ }
+
+ if (mappedSuperclasses.contains(superTypeMirror)) {
+ superEntity = getEntity(superTypeMirror, false);
+ break;
+ }
+ ancestry.add(superType);
+ superType = superTypeMirror.getSuperclass();
+ }
+
EntityMirror entity = new EntityMirror(
generatorConfiguration,
new TypeRef(types.getDeclaredType(element)),
- sqlName(element.getSimpleName().toString()));
+ concrete,
+ superEntity,
+ concrete ? Utils.sqlName(element.getSimpleName().toString()) : null);
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))) {
+ if (!ancestry.contains(m.getEnclosingElement().asType())) {
continue;
}
- String declaringType = ((TypeElement) m.getEnclosingElement()).getQualifiedName().toString();
- if (declaringType.equals("java.lang.Object")) {
+ String name = m.getSimpleName().toString();
+ if (name.length() < 4 || !isUpperCase(name.charAt(3))) {
continue;
}
@@ -126,6 +166,11 @@ public class EntityHandler extends AbstractHandler {
}
for (VariableElement f : fieldsIn(elements.getAllMembers(element))) {
+ System.out.println("f.getEnclosingElement() = " + f.getEnclosingElement());
+ if (!ancestry.contains(f.getEnclosingElement().asType())) {
+ continue;
+ }
+
String name = f.getSimpleName().toString();
ExecutableElement getter = getters.remove(name);
ExecutableElement setter = setters.remove(name);
@@ -141,6 +186,11 @@ public class EntityHandler extends AbstractHandler {
String name = e.getKey();
ExecutableElement getter = e.getValue();
ExecutableElement setter = setters.remove(name);
+
+ if (!ancestry.contains(getter.getEnclosingElement().asType())) {
+ continue;
+ }
+
FieldMirror field = fromElement(generatorConfiguration, null, getter, setter);
if (field == null) {
continue;
@@ -167,12 +217,16 @@ public class EntityHandler extends AbstractHandler {
processSequenceGenerators(element);
- // -----------------------------------------------------------------------
- // Validation
- // -----------------------------------------------------------------------
+ return entity;
+ }
+
+ public void validate(Element element, EntityMirror entity) {
+ if (!entity.concrete) {
+ return;
+ }
List<FieldMirror> idFields = new ArrayList<>();
- for (FieldMirror field : entity.fields) {
+ for (FieldMirror field : entity.getFields()) {
if (field.id) {
idFields.add(field);
}
@@ -184,9 +238,8 @@ public class EntityHandler extends AbstractHandler {
if (idFields.size() != 1) {
throw new CompilerException(element, "This implementation only support a single @Id annotated field.");
}
- entity.setIdType(idFields.get(0).type);
- sqlUnit.add(entity, element);
+ entity.setIdType(idFields.get(0).type);
}
private void processSequenceGenerators(Element element) {
@@ -219,7 +272,7 @@ public class EntityHandler extends AbstractHandler {
}
}
if (name != null) {
- sequenceName = sequenceName == null ? sqlName(name) : sequenceName;
+ sequenceName = sequenceName == null ? Utils.sqlName(name) : sequenceName;
sqlUnit.add(new SequenceMirror(name, sequenceName, initialValue, allocationSize), element);
}
}
@@ -247,7 +300,7 @@ public class EntityHandler extends AbstractHandler {
} else {
setterType = setter != null ? SetterType.METHOD : SetterType.FIELD;
}
- getterType = GetterType.FIELD;
+ getterType = getter != null ? GetterType.METHOD : GetterType.FIELD;
type = new TypeRef(var.asType());
element = types.asElement(var.asType());
javaName = var.getSimpleName().toString();
@@ -274,7 +327,7 @@ public class EntityHandler extends AbstractHandler {
}
javaName = toFieldName(getter.getSimpleName().toString());
}
- sqlName = sqlName(javaName);
+ sqlName = Utils.sqlName(javaName);
// Register type handler if this is an enum
if (element != null && element.getKind() == ElementKind.ENUM) {
@@ -292,10 +345,7 @@ public class EntityHandler extends AbstractHandler {
FieldMirror field;
if (primitive) {
- System.out.println("type = " + type);
TypeHandler typeHandler = generatorConfiguration.typeHandler(type);
- System.out.println("typeHandler = " + typeHandler);
- System.out.println("typeHandler.typeName() = " + typeHandler.typeName());
// TODO: check for configuration conflict
notNull = !typeHandler.nullable;
field = new FieldMirror(PRIMITIVE, setterType, getterType, type, javaName, sqlName, id, notNull, unique);
@@ -312,31 +362,34 @@ public class EntityHandler extends AbstractHandler {
}
public void phase3(boolean errorRaised) throws Exception {
- try {
- for (EntityMirror entity : sqlUnit.getEntities().values()) {
+ for (TypeElement mappedSuperclass : mappedSuperclasses) {
+ getEntity(mappedSuperclass, false);
+ }
+
+ for (TypeElement entity : entities) {
+ getEntity(entity, true);
+ }
+
+ for (EntityMirror entity : sqlUnit.getEntities().values()) {
+ try {
+ validate(sqlUnit.element(entity), entity);
+
+ if (!entity.concrete) {
+ continue;
+ }
+
+ System.out.println("entity.type = " + entity.type);
DaoGenerator daoGenerator = new DaoGenerator(generatorConfiguration, sqlUnit, entity);
writeFile(processingEnv, daoGenerator.generate(), sqlUnit.element(entity));
writeFile(processingEnv, daoGenerator.generateRow(), sqlUnit.element(entity));
+ } catch (CompilerException | InternalErrorException e) {
+ // Ignore any exceptions if we had an error from before
+ if (errorRaised) {
+ continue;
+ }
+ throw e;
}
- } catch (CompilerException | InternalErrorException e) {
- // Ignore any exceptions if we had an error from before
- if (errorRaised) {
- return;
- }
- throw e;
- }
- }
-
- public static String sqlName(String javaName) {
- StringBuilder builder = new StringBuilder();
- for (char c : javaName.toCharArray()) {
- char lower = Character.toLowerCase(c);
- if (isUpperCase(c) && builder.length() > 0) {
- builder.append("_");
- }
- builder.append(lower);
}
- return builder.toString();
}
private AnnotationMirror findAnnotation(Class<?> c, Element type) {
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 24cacf4..80b7283 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,10 +1,8 @@
package io.trygvis.container.compiler;
import io.trygvis.container.log.Log;
-import io.trygvis.persistence.EntityMirror;
import io.trygvis.persistence.SqlEntity;
import io.trygvis.persistence.SqlEntitySet;
-import io.trygvis.persistence.generators.DaoGenerator;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.processing.Completion;
@@ -23,14 +21,15 @@ import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.persistence.Entity;
+import javax.persistence.MappedSuperclass;
import javax.tools.Diagnostic;
import java.util.HashSet;
import java.util.Set;
import static io.trygvis.container.compiler.Utils.writeFile;
import static io.trygvis.persistence.generators.SequencesGenerator.generateSequences;
-import static io.trygvis.persistence.generators.SqlSessionGenerator.generateSqlSession;
import static io.trygvis.persistence.generators.SqlSessionFactoryGenerator.generateSqlSessionFactory;
+import static io.trygvis.persistence.generators.SqlSessionGenerator.generateSqlSession;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptySet;
@@ -100,6 +99,7 @@ public class MyProcessor implements Processor {
}
boolean first = true;
+
public boolean work(RoundEnvironment roundEnv) throws Exception {
if (!first) {
return false;
@@ -109,6 +109,7 @@ public class MyProcessor implements Processor {
TypeElement tx = elements.getTypeElement(Transactional.class.getCanonicalName());
TypeElement log = elements.getTypeElement(Log.class.getCanonicalName());
TypeElement entity = elements.getTypeElement(Entity.class.getCanonicalName());
+ TypeElement mappedSuperclass = elements.getTypeElement(MappedSuperclass.class.getCanonicalName());
SqlUnitModel unit = new SqlUnitModel();
EntityHandler entityHandler = new EntityHandler(processingEnv, unit);
@@ -129,15 +130,16 @@ public class MyProcessor implements Processor {
if (types.isSameType(log.asType(), annotationType)) {
new LogHandler(processingEnv).processLog((TypeElement) element);
}
- if (types.isSameType(entity.asType(), annotationType)) {
- 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);
- hadErrors = true;
+ try {
+ if (types.isSameType(entity.asType(), annotationType)) {
+ entityHandler.record((TypeElement) element, false);
+ } else if (types.isSameType(mappedSuperclass.asType(), annotationType)) {
+ entityHandler.record((TypeElement) element, true);
}
+ } catch (CompilerException e) {
+ Messager messager = processingEnv.getMessager();
+ messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage(), e.element);
+ hadErrors = true;
}
}
}
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/SqlUnitModel.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/SqlUnitModel.java
index 717715e..1c0f538 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/SqlUnitModel.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/SqlUnitModel.java
@@ -10,7 +10,8 @@ import java.util.TreeMap;
public class SqlUnitModel {
private Map<TypeRef, EntityMirror> entities = new TreeMap<>();
- private Map<EntityMirror, Element> entityElements = new TreeMap<>();
+ private Map<Element, EntityMirror> elementToEntity = new TreeMap<>(new ElementComparator());
+ private Map<EntityMirror, Element> entityToElement = new TreeMap<>();
private Map<String, SequenceMirror> sequences = new TreeMap<>();
private Map<SequenceMirror, Element> sequenceElements = new TreeMap<>();
private String packageName;
@@ -44,7 +45,8 @@ public class SqlUnitModel {
public SqlUnitModel add(EntityMirror entity, Element element) {
entities.put(entity.type, entity);
- entityElements.put(entity, element);
+ entityToElement.put(entity, element);
+ elementToEntity.put(element, entity);
return this;
}
@@ -70,7 +72,11 @@ public class SqlUnitModel {
}
public Element element(EntityMirror entity) {
- return entityElements.get(entity);
+ return entityToElement.get(entity);
+ }
+
+ public EntityMirror entity(Element element) {
+ return elementToEntity.get(element);
}
// -----------------------------------------------------------------------
@@ -120,4 +126,5 @@ public class SqlUnitModel {
public Element element(SequenceMirror sequence) {
return sequenceElements.get(sequence);
}
+
}
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TypeMirrorComparator.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TypeMirrorComparator.java
new file mode 100644
index 0000000..325eeaf
--- /dev/null
+++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TypeMirrorComparator.java
@@ -0,0 +1,11 @@
+package io.trygvis.container.compiler;
+
+import javax.lang.model.type.TypeMirror;
+import java.util.Comparator;
+
+class TypeMirrorComparator implements Comparator<TypeMirror> {
+ @Override
+ public int compare(TypeMirror o1, TypeMirror o2) {
+ return o1.toString().compareTo(o2.toString());
+ }
+}
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 3478581..0cac828 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
@@ -17,6 +17,7 @@ import java.util.ArrayList;
import java.util.List;
import static io.trygvis.container.compiler.model.ClassG.addAll;
+import static java.lang.Character.isUpperCase;
import static java.lang.Character.toLowerCase;
import static java.lang.Character.toUpperCase;
import static org.apache.commons.lang.StringUtils.stripEnd;
@@ -116,4 +117,19 @@ public class Utils {
newBody.add("}");
return newBody;
}
+
+ public static String sqlName(String javaName) {
+ StringBuilder builder = new StringBuilder();
+ for (char c : javaName.toCharArray()) {
+ if (isUpperCase(c) && builder.length() > 0) {
+ builder.append("_");
+ }
+ if (Character.isLetterOrDigit(c)) {
+ builder.append(toLowerCase(c));
+ } else {
+ builder.append('_');
+ }
+ }
+ return builder.toString();
+ }
}
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 85523dc..3f6816d 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
@@ -1,39 +1,50 @@
package io.trygvis.persistence;
+import io.trygvis.container.compiler.CompilerException;
import io.trygvis.container.compiler.model.TypeRef;
import java.util.ArrayList;
import java.util.List;
+import static java.util.Collections.addAll;
+
public class EntityMirror implements Comparable<EntityMirror> {
public final GeneratorConfiguration generatorConfiguration;
- public final List<FieldMirror> fields = new ArrayList<>();
- public final List<FieldMirror> idFields = new ArrayList<>();
+ private final List<FieldMirror> fields = new ArrayList<>();
public final TypeRef type;
+ public final boolean concrete;
public final String tableName;
public final TypeRef rowType;
public final TypeRef daoType;
public final TypeRef utilsType;
public TypeRef idType;
+ /**
+ * The nearest @MappedSuperclass
+ */
+ public EntityMirror superEntity;
- public EntityMirror(GeneratorConfiguration generatorConfiguration, TypeRef type, String tableName) {
+ public EntityMirror(GeneratorConfiguration generatorConfiguration, TypeRef type, boolean concrete,
+ EntityMirror superEntity, String tableName) {
this.generatorConfiguration = generatorConfiguration;
this.type = type;
- this.tableName = tableName;
+ this.concrete = concrete;
+ this.superEntity = superEntity;
- this.rowType = new TypeRef(type.plainName + "Row");
- this.daoType = new TypeRef(type.plainName + "Dao").args(type.args);
- this.utilsType = new TypeRef(type.plainName + "Dao.Utils").args(type.args);
+ if (concrete) {
+ this.tableName = tableName;
+ this.rowType = new TypeRef(type.plainName + "Row");
+ this.daoType = new TypeRef(type.plainName + "Dao").args(type.args);
+ this.utilsType = new TypeRef(type.plainName + "Dao.Utils").args(type.args);
+ } else {
+ this.tableName = null;
+ this.rowType = null;
+ this.daoType = null;
+ this.utilsType = null;
+ }
}
public void add(FieldMirror... fields) {
- for (FieldMirror field : fields) {
- this.fields.add(field);
- if (field.id) {
- this.idFields.add(field);
- }
-
- }
+ addAll(this.fields, fields);
}
public void setIdType(TypeRef idType) {
@@ -41,9 +52,25 @@ public class EntityMirror implements Comparable<EntityMirror> {
}
public FieldMirror getIdField() {
- return idFields.get(0);
+ for (FieldMirror f : getFields()) {
+ if (f.id) {
+ return f;
+ }
+ }
+
+ throw new CompilerException("Internal error: no @Id field defined on " + type);
}
+ public List<FieldMirror> getFields() {
+ List<FieldMirror> fields = superEntity != null ? superEntity.getFields() : new ArrayList<FieldMirror>();
+ fields.addAll(this.fields);
+ return fields;
+ }
+
+ // -----------------------------------------------------------------------
+ //
+ // -----------------------------------------------------------------------
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java
index c260a48..7cd3f59 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java
@@ -1,6 +1,5 @@
package io.trygvis.persistence.generators;
-import io.trygvis.container.compiler.NotImplementedException;
import io.trygvis.container.compiler.SqlUnitModel;
import io.trygvis.container.compiler.model.ClassG;
import io.trygvis.container.compiler.model.Constructor;
@@ -123,7 +122,7 @@ public class DaoGenerator {
Parameters parameters = new Parameters();
List<String> body = new ArrayList<>();
- for (FieldMirror field : entity.fields) {
+ for (FieldMirror field : entity.getFields()) {
TypeRef type;
if (field.fieldType == PRIMITIVE) {
type = field.type;
@@ -142,7 +141,7 @@ public class DaoGenerator {
public String createTableSql() {
List<String> columns = new ArrayList<>();
- for (FieldMirror field : entity.fields) {
+ for (FieldMirror field : entity.getFields()) {
String s;
if (field.fieldType == PRIMITIVE) {
TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type);
@@ -156,18 +155,14 @@ public class DaoGenerator {
}
} 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);
- s = " " + field.sqlName + " " + typeHandler.sqlType(field);
- s += " REFERENCES " + referenced.tableName + "(" + idField.sqlName + ")";
- if (field.notNull) {
- s += " NOT NULL";
- } else if (field.unique) {
- s += " UNIQUE";
- }
- } else {
- throw new NotImplementedException();
+ FieldMirror idField = referenced.getIdField();
+ TypeHandler typeHandler = generatorConfiguration.typeHandler(idField.type);
+ s = " " + field.sqlName + " " + typeHandler.sqlType(field);
+ s += " REFERENCES " + referenced.tableName + "(" + idField.sqlName + ")";
+ if (field.notNull) {
+ s += " NOT NULL";
+ } else if (field.unique) {
+ s += " UNIQUE";
}
} else {
throw new RuntimeException("Unknown field type: " + field.getClass());
@@ -187,7 +182,7 @@ public class DaoGenerator {
public String insertIntoSql() {
List<String> columns = new ArrayList<>();
List<String> values = new ArrayList<>();
- for (FieldMirror field : entity.fields) {
+ for (FieldMirror field : entity.getFields()) {
columns.add(field.sqlName);
if (field.id) {
values.add("nextval('" + unit.getDefaultSequence().sequenceName + "')");
@@ -202,9 +197,7 @@ public class DaoGenerator {
public String deleteFromSql() {
List<String> ss = new ArrayList<>();
- for (FieldMirror field : entity.idFields) {
- ss.add(field.sqlName + "=?");
- }
+ ss.add(entity.getIdField().sqlName + "=?");
return "DELETE FROM " + entity.tableName + " WHERE " + join(ss, " AND ") + ";";
}
@@ -221,12 +214,8 @@ public class DaoGenerator {
body.add(entityListType + " list = runQuery(new Preparator() {");
body.add(" @Override");
body.add(" public void prepare(" + preparedStatementType.plainName + " stmt) throws " + sqlExceptionType + " {");
- List<FieldMirror> idFields = entity.idFields;
- for (int i = 0; i < idFields.size(); i++) {
- FieldMirror field = idFields.get(i);
- TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type);
- body.add(" stmt." + typeHandler.setter(i + 1, idP.name) + ";");
- }
+ TypeHandler typeHandler = generatorConfiguration.typeHandler(entity.getIdField().type);
+ body.add(" stmt." + typeHandler.setter(1, idP.name) + ";");
body.add(" }");
body.add("}, sql);");
body.add("if (list.isEmpty()) {");
@@ -257,8 +246,8 @@ public class DaoGenerator {
List<String> body = new ArrayList<>();
List<String> fields = new ArrayList<>();
- for (int i = 0; i < entity.fields.size(); i++) {
- FieldMirror field = entity.fields.get(i);
+ for (int i = 0; i < entity.getFields().size(); i++) {
+ FieldMirror field = entity.getFields().get(i);
String getter;
TypeRef type;
@@ -290,8 +279,8 @@ public class DaoGenerator {
List<String> body = new ArrayList<>();
List<String> cArgs = new ArrayList<>();
List<String> method = new ArrayList<>();
- for (int i = 0; i < this.entity.fields.size(); i++) {
- FieldMirror field = this.entity.fields.get(i);
+ for (int i = 0; i < entity.getFields().size(); i++) {
+ FieldMirror field = this.entity.getFields().get(i);
String value;
if (field.fieldType == PRIMITIVE) {
@@ -330,7 +319,7 @@ public class DaoGenerator {
public String defaultFields() {
List<String> names = new ArrayList<>();
- for (FieldMirror field : entity.fields) {
+ for (FieldMirror field : entity.getFields()) {
names.add(field.sqlName);
}
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java
index e4f69b5..08a7f45 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java
@@ -68,7 +68,7 @@ public class DaoUtilsGenerator {
body.add("try (" + psType + " stmt = " + con.name + ".prepareStatement(insertIntoSql)) {");
int i = 0;
- for (FieldMirror field : entity.fields) {
+ for (FieldMirror field : entity.getFields()) {
// Assume all ID fields are generated for now.
if (field.id) {
continue;
@@ -133,12 +133,11 @@ public class DaoUtilsGenerator {
List<String> arguments = new ArrayList<>();
arguments.add(con.name);
- for (FieldMirror field : entity.idFields) {
- if (field.getterType == GetterType.FIELD) {
- arguments.add(o.name + "." + field.javaName);
- } else {
- arguments.add(o.name + "." + toGetterName(field.javaName) + "()");
- }
+ FieldMirror field = entity.getIdField();
+ if (field.getterType == GetterType.FIELD) {
+ arguments.add(o.name + "." + field.javaName);
+ } else {
+ arguments.add(o.name + "." + toGetterName(field.javaName) + "()");
}
return new MethodRef(PUBLIC | STATIC, TypeRef.VOID, "delete" + entity.type.className, p,
@@ -154,12 +153,10 @@ public class DaoUtilsGenerator {
List<String> body = new ArrayList<>();
body.add("try (" + psType + " stmt = " + con.name + ".prepareStatement(deleteFromSql)) {");
- for (int i = 0; i < entity.idFields.size(); i++) {
- FieldMirror field = entity.idFields.get(i);
- p.addParameter(field.type, field.javaName);
- TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type);
- body.add(" stmt." + typeHandler.setter(i + 1, field.javaName) + ";");
- }
+ FieldMirror field = entity.getIdField();
+ p.addParameter(field.type, field.javaName);
+ TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type);
+ body.add(" stmt." + typeHandler.setter(1, field.javaName) + ";");
body.add(" stmt.executeUpdate();");
body.add("}");
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionFactoryGenerator.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionFactoryGenerator.java
index 3f0da2b..7b6f667 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionFactoryGenerator.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionFactoryGenerator.java
@@ -34,6 +34,10 @@ public class SqlSessionFactoryGenerator {
List<String> s = new ArrayList<>();
for (EntityMirror entity : unit.getEntities().values()) {
+ if (!entity.concrete) {
+ continue;
+ }
+
s.add(entity.daoType.plainName + ".desc");
}
TypeRef sqlEntityMetaArrayType = new TypeRef(SqlEntityMeta[].class);
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionGenerator.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionGenerator.java
index ddb4d99..8e32cfe 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionGenerator.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionGenerator.java
@@ -33,6 +33,10 @@ public class SqlSessionGenerator {
Map<EntityMirror, FieldRef> daoFields = new HashMap<>();
for (EntityMirror entity : unit.getEntities().values()) {
+ if (!entity.concrete) {
+ continue;
+ }
+
FieldRef f = g.addPublicFinalField(entity.daoType, toFieldName(entity.type.className));
daoFields.put(entity, f);
}
@@ -50,6 +54,10 @@ public class SqlSessionGenerator {
body.add("super(" + c.name + ");");
for (EntityMirror entity : unit.getEntities().values()) {
+ if (!entity.concrete) {
+ continue;
+ }
+
FieldRef f = daoFields.get(entity);
body.add("this." + f.name + " = new " + entity.daoType.plainName + "(this);");
}
@@ -63,6 +71,9 @@ public class SqlSessionGenerator {
p.addParameter(new TypeRef(Class.class).args("T"), "klass");
List<String> body = new ArrayList<>();
for (EntityMirror entity : unit.getEntities().values()) {
+ if(!entity.concrete) {
+ continue;
+ }
String sqlDao = "SqlDao<Id, T, " + unit.sessionType.className + ", " + entity.rowType.className + ">";
body.add("if (klass == " + entity.type.plainName + ".class) {");
body.add(" return (" + sqlDao + ") " + daoFields.get(entity).name + ";");
diff --git a/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/EntityHandlerTest.java b/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/EntityHandlerTest.java
index e24a362..bfe2d89 100644
--- a/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/EntityHandlerTest.java
+++ b/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/EntityHandlerTest.java
@@ -3,7 +3,7 @@ package io.trygvis.container.compiler;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
-import static io.trygvis.container.compiler.EntityHandler.sqlName;
+import static io.trygvis.container.compiler.Utils.sqlName;
import static org.fest.assertions.Assertions.assertThat;
@Test(singleThreaded = false)
diff --git a/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/ProcessorTest.java b/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/ProcessorTest.java
index f8cecac..4fa9e87 100644
--- a/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/ProcessorTest.java
+++ b/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/ProcessorTest.java
@@ -1,6 +1,8 @@
package io.trygvis.container.compiler;
import org.apache.commons.io.IOUtils;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import javax.tools.Diagnostic;
@@ -12,18 +14,58 @@ import javax.tools.ToolProvider;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.Charset;
+import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import static java.util.Arrays.asList;
+import static javax.tools.JavaCompiler.CompilationTask;
import static org.fest.assertions.Assertions.assertThat;
public class ProcessorTest {
Charset UTF_8 = Charset.forName("utf-8");
- @Test
- public void testBasic() throws Exception {
+ @BeforeMethod
+ private void before() {
+
+ }
+
+ @DataProvider(name = "data", parallel = true)
+ public static Object[][] data() {
+ return new Object[][]{new Object[]{
+ new String[]{
+ "io.trygvis.persistence.test.basic.package-info",
+ "io.trygvis.persistence.test.basic.Person",
+ "io.trygvis.persistence.test.basic.ParentEntity",
+ "io.trygvis.persistence.test.basic.ChildEntity",
+ },
+ new String[]{
+ "io.trygvis.persistence.test.basic.Sequences",
+ "io.trygvis.persistence.test.basic.BasicSqlSession",
+ "io.trygvis.persistence.test.basic.BasicSqlSessionFactory",
+ "io.trygvis.persistence.test.basic.PersonDao",
+ "io.trygvis.persistence.test.basic.PersonRow",
+ "io.trygvis.persistence.test.basic.ChildEntityDao",
+ "io.trygvis.persistence.test.basic.ChildEntityRow",
+ }
+ }, new Object[]{
+ new String[]{
+ "io.trygvis.persistence.test.inheritance.package-info",
+ "io.trygvis.persistence.test.inheritance.A",},
+ new String[]{
+ "io.trygvis.persistence.test.inheritance.Sequences",
+ "io.trygvis.persistence.test.inheritance.InheritanceSqlSession",
+ "io.trygvis.persistence.test.inheritance.InheritanceSqlSessionFactory",
+ "io.trygvis.persistence.test.inheritance.DDao",
+ "io.trygvis.persistence.test.inheritance.DRow",
+ }
+ },
+ };
+ }
+
+ @Test(dataProvider = "data")
+ public void testBasic(String[] files, String[] classes) throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> collector = new DiagnosticCollector<>();
@@ -31,14 +73,12 @@ public class ProcessorTest {
InMemoryJavaFileManager fileManager = new InMemoryJavaFileManager(standardFileManager);
- List<JavaSourceFromString> sources = asList((JavaSourceFromString[])new JavaSourceFromString[]{
- loadJava("io.trygvis.persistence.test.package-info"),
- loadJava("io.trygvis.persistence.test.Person"),
- loadJava("io.trygvis.persistence.test.ParentEntity"),
- loadJava("io.trygvis.persistence.test.ChildEntity"),
- });
+ List<JavaSourceFromString> sources = new ArrayList<>();
+ for (String file : files) {
+ sources.add(loadJava(file));
+ }
- JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, collector, null, null, sources);
+ CompilationTask task = compiler.getTask(null, fileManager, collector, null, null, sources);
task.setProcessors(asList(new MyProcessor()));
@@ -50,8 +90,8 @@ public class ProcessorTest {
if (source != null) {
error += source.toUri().getPath();
}
- error += ":" + diagnostic.getLineNumber() + ":" + diagnostic.getColumnNumber();
- System.out.println(error + ":" + diagnostic.getMessage(Locale.ENGLISH));
+ error += ":" + diagnostic.getLineNumber() + ":" + diagnostic.getColumnNumber();
+ System.out.println(error + ": " + diagnostic.getMessage(Locale.ENGLISH));
}
}
@@ -60,14 +100,7 @@ public class ProcessorTest {
System.out.println(entry.getValue());
}
- assertThat(fileManager.codes.keySet()).containsOnly(
- "io.trygvis.persistence.test.Sequences",
- "io.trygvis.persistence.test.TestSqlSession",
- "io.trygvis.persistence.test.TestSqlSessionFactory",
- "io.trygvis.persistence.test.PersonDao",
- "io.trygvis.persistence.test.PersonRow",
- "io.trygvis.persistence.test.ChildEntityDao",
- "io.trygvis.persistence.test.ChildEntityRow");
+ assertThat(fileManager.codes.keySet()).containsOnly((Object[]) classes);
assertThat(collector.getDiagnostics()).isEmpty();
assertThat(result).isTrue();
diff --git a/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java b/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java
index fc63a8a..c978ec9 100644
--- a/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java
+++ b/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java
@@ -78,7 +78,7 @@ public class EntityMirrorTest {
@Test(dataProvider = "insertIntoSql")
public void testInsertIntoSql(FieldMirror[] fields, String insert, String delete, String create) throws Exception {
- EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, "my_table");
+ EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, true, null, "my_table");
for (FieldMirror field : fields) {
myTable.add(field);
}
@@ -127,7 +127,7 @@ public class EntityMirrorTest {
}
private MethodRef insertInto(FieldMirror... fields) {
- EntityMirror myTable = new EntityMirror(generatorConfiguration, entityType, "my_table");
+ EntityMirror myTable = new EntityMirror(generatorConfiguration, entityType, true, null, "my_table");
myTable.add(fields);
SqlUnitModel unit = new SqlUnitModel().add(myTable);
return new DaoUtilsGenerator(unit, generatorConfiguration, myTable).insertInto(new Imports());
@@ -151,7 +151,7 @@ public class EntityMirrorTest {
}
private MethodRef delete(FieldMirror... fields) {
- EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, "my_table");
+ EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, true, null, "my_table");
myTable.add(fields);
SqlUnitModel unit = new SqlUnitModel().add(myTable);
return new DaoUtilsGenerator(unit, generatorConfiguration, myTable).delete(new Imports());
@@ -181,7 +181,7 @@ public class EntityMirrorTest {
}
private MethodRef deleteById(FieldMirror... fields) {
- EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, "my_table");
+ EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, true, null, "my_table");
myTable.add(fields);
SqlUnitModel unit = new SqlUnitModel().add(myTable);
return new DaoUtilsGenerator(unit, generatorConfiguration, myTable).deleteById(new Imports());
diff --git a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/Car.java b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/Car.java
index 4b80afc..2781712 100644
--- a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/Car.java
+++ b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/Car.java
@@ -1,4 +1,4 @@
-package io.trygvis.persistence.test;
+package io.trygvis.persistence.test.basic;
import javax.persistence.Entity;
diff --git a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/ChildEntity.java b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/ChildEntity.java
index ff91680..208ee9a 100644
--- a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/ChildEntity.java
+++ b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/ChildEntity.java
@@ -1,4 +1,4 @@
-package io.trygvis.persistence.test;
+package io.trygvis.persistence.test.basic;
import javax.persistence.Entity;
diff --git a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/ParentEntity.java b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/ParentEntity.java
index 9925f7e..3dd2375 100644
--- a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/ParentEntity.java
+++ b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/ParentEntity.java
@@ -1,7 +1,9 @@
-package io.trygvis.persistence.test;
+package io.trygvis.persistence.test.basic;
import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+@MappedSuperclass
public class ParentEntity {
@Id
public Long id;
diff --git a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/Person.java b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/Person.java
index 47a2fdd..3cbdb84 100644
--- a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/Person.java
+++ b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/Person.java
@@ -1,4 +1,4 @@
-package io.trygvis.persistence.test;
+package io.trygvis.persistence.test.basic;
import javax.persistence.Entity;
import javax.persistence.Id;
diff --git a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/package-info.java b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/package-info.java
new file mode 100644
index 0000000..780fae5
--- /dev/null
+++ b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/package-info.java
@@ -0,0 +1,4 @@
+@SqlEntitySet(name = "Basic")
+package io.trygvis.persistence.test.basic;
+
+import io.trygvis.persistence.SqlEntitySet;
diff --git a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/inheritance/A.java b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/inheritance/A.java
new file mode 100644
index 0000000..99770da
--- /dev/null
+++ b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/inheritance/A.java
@@ -0,0 +1,40 @@
+package io.trygvis.persistence.test.inheritance;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.SequenceGenerator;
+
+public class A {
+ public Integer a;
+}
+
+@SequenceGenerator(name = "id", sequenceName = "id_seq")
+@MappedSuperclass
+class B extends A {
+ public Integer b;
+}
+
+class C extends B {
+ public Integer c;
+}
+
+@Entity
+class D extends C {
+ @Id
+ public Integer d;
+
+ private int d2;
+
+ public Integer getD2() {
+ return d2;
+ }
+
+ public void setD2(Integer d2) {
+ this.d2 = d2;
+ }
+}
+
+class E extends D {
+ public int e;
+}
diff --git a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/inheritance/package-info.java b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/inheritance/package-info.java
new file mode 100644
index 0000000..7382c7a
--- /dev/null
+++ b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/inheritance/package-info.java
@@ -0,0 +1,4 @@
+@SqlEntitySet(name = "Inheritance")
+package io.trygvis.persistence.test.inheritance;
+
+import io.trygvis.persistence.SqlEntitySet;
diff --git a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/package-info.java b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/package-info.java
deleted file mode 100644
index 5a80282..0000000
--- a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-@SqlEntitySet(name = "Test")
-package io.trygvis.persistence.test;
-
-import io.trygvis.persistence.SqlEntitySet;