summaryrefslogtreecommitdiff
path: root/container-compiler-plugin/src/main/java/io/trygvis/container/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'container-compiler-plugin/src/main/java/io/trygvis/container/compiler')
-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
6 files changed, 152 insertions, 52 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();
+ }
}