diff options
Diffstat (limited to 'container-compiler-plugin/src/main/java')
9 files changed, 195 insertions, 116 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 ba9f100..5eb404b 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 @@ -9,6 +9,7 @@ import io.trygvis.persistence.SqlEntity; import io.trygvis.persistence.SqlEntitySet; import io.trygvis.persistence.TypeHandler; import io.trygvis.persistence.generators.DaoGenerator; +import io.trygvis.persistence.sql.SqlConstructor; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.AnnotationMirror; @@ -22,6 +23,7 @@ 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.AccessType; import javax.persistence.Id; import javax.persistence.SequenceGenerator; import java.util.ArrayList; @@ -37,13 +39,12 @@ import static io.trygvis.container.compiler.Utils.toFieldName; import static io.trygvis.container.compiler.Utils.writeFile; import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE; import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE; -import static io.trygvis.persistence.FieldMirror.GetterType; -import static io.trygvis.persistence.FieldMirror.SetterType; import static io.trygvis.persistence.TypeHandler.StringEnumTypeHandler; import static java.lang.Character.isUpperCase; import static java.lang.String.format; -import static javax.lang.model.util.ElementFilter.fieldsIn; -import static javax.lang.model.util.ElementFilter.methodsIn; +import static javax.lang.model.util.ElementFilter.*; +import static javax.persistence.AccessType.FIELD; +import static javax.persistence.AccessType.PROPERTY; import static org.apache.commons.lang.StringUtils.join; public class EntityHandler extends AbstractHandler { @@ -116,6 +117,10 @@ public class EntityHandler extends AbstractHandler { } public EntityMirror buildMirror(TypeElement element, boolean concrete) throws Exception { + // ----------------------------------------------------------------------- + // Figure out inheritage and ancestry + // ----------------------------------------------------------------------- + EntityMirror superEntity = null; Set<TypeMirror> ancestry = new TreeSet<>(new TypeMirrorComparator()); @@ -135,11 +140,48 @@ public class EntityHandler extends AbstractHandler { superType = superTypeMirror.getSuperclass(); } + // ----------------------------------------------------------------------- + // Find constructor + // ----------------------------------------------------------------------- + + ExecutableElement constructor = null; + List<ExecutableElement> constructors = constructorsIn(elements.getAllMembers(element)); + if (constructors.size() == 1) { + constructor = constructors.get(0); + } else { + for (ExecutableElement c : constructors) { + AnnotationMirror sqlConstructor = findAnnotation(SqlConstructor.class, c); + if (sqlConstructor == null) { + continue; + } + + if (constructor != null) { + throw new CompilerException(c, "There can only be one @SqlConstructor annotated constructor."); + } + + constructor = c; + } + } + + System.out.println("element = " + element); + System.out.println("constructor = " + constructor); + + List<String> constructorParameters = new ArrayList<>(); + for (VariableElement p : constructor.getParameters()) { + String name = p.getSimpleName().toString(); + constructorParameters.add(name); + } + + // ----------------------------------------------------------------------- + // + // ----------------------------------------------------------------------- + EntityMirror entity = new EntityMirror( generatorConfiguration, new TypeRef(types.getDeclaredType(element)), concrete, superEntity, + constructor, constructorParameters, concrete ? Utils.sqlName(element.getSimpleName().toString()) : null); Map<String, ExecutableElement> getters = new TreeMap<>(); @@ -166,7 +208,6 @@ 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; } @@ -174,7 +215,7 @@ public class EntityHandler extends AbstractHandler { String name = f.getSimpleName().toString(); ExecutableElement getter = getters.remove(name); ExecutableElement setter = setters.remove(name); - FieldMirror field = fromElement(generatorConfiguration, f, getter, setter); + FieldMirror field = fromElement(generatorConfiguration, entity, f, getter, setter); if (field == null) { continue; } @@ -191,7 +232,7 @@ public class EntityHandler extends AbstractHandler { continue; } - FieldMirror field = fromElement(generatorConfiguration, null, getter, setter); + FieldMirror field = fromElement(generatorConfiguration, entity, null, getter, setter); if (field == null) { continue; } @@ -221,25 +262,40 @@ public class EntityHandler extends AbstractHandler { } public void validate(Element element, EntityMirror entity) { - if (!entity.concrete) { - return; - } + if (entity.concrete) { + List<FieldMirror> idFields = new ArrayList<>(); + List<FieldMirror> constructorFields = new ArrayList<>(); + for (FieldMirror field : entity.getFields()) { + if (field.id) { + idFields.add(field); + } + if (field.constructorParam) { + constructorFields.add(field); + } + } - List<FieldMirror> idFields = new ArrayList<>(); - for (FieldMirror field : entity.getFields()) { - if (field.id) { - idFields.add(field); + if (idFields.size() == 0) { + throw new CompilerException(element, "An @Entity is required to have at least one @Id field."); + } + if (idFields.size() != 1) { + throw new CompilerException(element, "This implementation only support a single @Id annotated field."); } - } - if (idFields.size() == 0) { - throw new CompilerException(element, "An @Entity is required to have at least one @Id field."); - } - if (idFields.size() != 1) { - throw new CompilerException(element, "This implementation only support a single @Id annotated field."); - } + entity.setIdType(idFields.get(0).type); - entity.setIdType(idFields.get(0).type); + System.out.println("constructorFields = " + constructorFields); + System.out.println("entity.getConstructorParameters() = " + entity.getConstructorParameters()); + List<String> constructorParameters = new ArrayList<>(entity.getConstructorParameters()); + for (FieldMirror f : constructorFields) { + if (!constructorParameters.remove(f.javaName)) { + throw new CompilerException(entity.constructor, "Unknown field used in constructor: " + f.javaName); + } + } + + if (!constructorParameters.isEmpty()) { + throw new CompilerException(entity.constructor, "Unknown field used in constructor: " + join(constructorParameters, ", ")); + } + } } private void processSequenceGenerators(Element element) { @@ -278,12 +334,13 @@ public class EntityHandler extends AbstractHandler { } } - public FieldMirror fromElement(GeneratorConfiguration generatorConfiguration, VariableElement var, - ExecutableElement getter, ExecutableElement setter) { + public FieldMirror fromElement(GeneratorConfiguration generatorConfiguration, EntityMirror entity, + VariableElement var, ExecutableElement getter, ExecutableElement setter) { // TODO: check the setter for annotations too // TODO: check for transient and @Transient - final SetterType setterType; - final GetterType getterType; + boolean isConstructorParameter; + final AccessType setterType; + final AccessType getterType; TypeRef type; Element element; String javaName; @@ -294,16 +351,19 @@ public class EntityHandler extends AbstractHandler { if (var.getModifiers().contains(Modifier.STATIC)) { return null; } + javaName = var.getSimpleName().toString(); + isConstructorParameter = entity.hasConstructorParameter(javaName); + boolean isFinal = var.getModifiers().contains(Modifier.FINAL); if (isFinal) { - setterType = SetterType.CONSTRUCTOR; - } else { - setterType = setter != null ? SetterType.METHOD : SetterType.FIELD; + if (!isConstructorParameter) { + throw new CompilerException(var, "The field " + javaName + " is final, but not a constructor parameter. Constructor parameters: " + join(entity.getConstructorParameters(), ", ")); + } } - getterType = getter != null ? GetterType.METHOD : GetterType.FIELD; + setterType = setter != null ? PROPERTY : FIELD; + getterType = getter != null ? PROPERTY : FIELD; type = new TypeRef(var.asType()); element = types.asElement(var.asType()); - javaName = var.getSimpleName().toString(); id = isId(var); processSequenceGenerators(var); } else { @@ -314,8 +374,9 @@ public class EntityHandler extends AbstractHandler { // Skipping fields is closer to what hibernate does. return null; } - setterType = SetterType.METHOD; - getterType = GetterType.METHOD; + isConstructorParameter = false; + setterType = PROPERTY; + getterType = PROPERTY; type = new TypeRef(getter.getReturnType()); element = types.asElement(getter.getReturnType()); id = isId(getter); @@ -348,11 +409,11 @@ public class EntityHandler extends AbstractHandler { TypeHandler typeHandler = generatorConfiguration.typeHandler(type); // TODO: check for configuration conflict notNull = !typeHandler.nullable; - field = new FieldMirror(PRIMITIVE, setterType, getterType, type, javaName, sqlName, id, notNull, unique); + field = new FieldMirror(PRIMITIVE, isConstructorParameter, setterType, getterType, 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(REFERENCE, setterType, getterType, type, javaName, sqlName, id, notNull, unique); + field = new FieldMirror(REFERENCE, isConstructorParameter, setterType, getterType, type, javaName, sqlName, id, notNull, unique); } return field; } @@ -378,7 +439,6 @@ public class EntityHandler extends AbstractHandler { 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)); @@ -392,6 +452,9 @@ public class EntityHandler extends AbstractHandler { } } + /** + * @return Returns null if the annotation could not be found. + */ private AnnotationMirror findAnnotation(Class<?> c, Element type) { TypeMirror annotationType = elements.getTypeElement(c.getCanonicalName()).asType(); for (AnnotationMirror a : type.getAnnotationMirrors()) { 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 80b7283..e9029c7 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 @@ -27,7 +27,6 @@ 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.SqlSessionFactoryGenerator.generateSqlSessionFactory; import static io.trygvis.persistence.generators.SqlSessionGenerator.generateSqlSession; import static java.util.Arrays.asList; @@ -145,7 +144,6 @@ public class MyProcessor implements Processor { } entityHandler.phase3(hadErrors); - writeFile(processingEnv, generateSequences(unit), null); // writeFile(processingEnv, generateEntityManagerFactory(unit), null); // writeFile(processingEnv, generateEntityManager(unit), null); writeFile(processingEnv, generateSqlSession(unit), null); 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 3f6816d..e3d0ec8 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 @@ -3,10 +3,12 @@ package io.trygvis.persistence; import io.trygvis.container.compiler.CompilerException; import io.trygvis.container.compiler.model.TypeRef; +import javax.lang.model.element.ExecutableElement; import java.util.ArrayList; import java.util.List; import static java.util.Collections.addAll; +import static java.util.Collections.unmodifiableList; public class EntityMirror implements Comparable<EntityMirror> { public final GeneratorConfiguration generatorConfiguration; @@ -21,14 +23,19 @@ public class EntityMirror implements Comparable<EntityMirror> { /** * The nearest @MappedSuperclass */ - public EntityMirror superEntity; + public final EntityMirror superEntity; + private final List<String> constructorParameters; + public ExecutableElement constructor; public EntityMirror(GeneratorConfiguration generatorConfiguration, TypeRef type, boolean concrete, - EntityMirror superEntity, String tableName) { + EntityMirror superEntity, ExecutableElement constructor, List<String> constructorParameters, + String tableName) { this.generatorConfiguration = generatorConfiguration; this.type = type; this.concrete = concrete; this.superEntity = superEntity; + this.constructor = constructor; + this.constructorParameters = unmodifiableList(constructorParameters); if (concrete) { this.tableName = tableName; @@ -67,6 +74,14 @@ public class EntityMirror implements Comparable<EntityMirror> { return fields; } + public List<String> getConstructorParameters() { + return constructorParameters; + } + + public boolean hasConstructorParameter(String parameter) { + return constructorParameters.contains(parameter); + } + // ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- 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 dd759ef..c235c77 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,16 +2,20 @@ package io.trygvis.persistence; import io.trygvis.container.compiler.model.TypeRef; +import javax.persistence.AccessType; + import static io.trygvis.container.compiler.Utils.toGetterName; import static io.trygvis.container.compiler.model.Parameters.ParameterRef; +import static javax.persistence.AccessType.FIELD; /** * TODO: a single field might have to be mapped to multiple sql columns. */ public class FieldMirror { public final FieldType fieldType; - public final SetterType setterType; - public final GetterType getterType; + public final boolean constructorParam; + public final AccessType setterType; + public final AccessType getterType; public final TypeRef type; public final String javaName; public final String sqlName; @@ -24,20 +28,10 @@ public class FieldMirror { REFERENCE, } - public enum SetterType { - CONSTRUCTOR, - FIELD, - METHOD, - } - - public enum GetterType { - FIELD, - METHOD, - } - - public FieldMirror(FieldType fieldType, SetterType setterType, GetterType getterType, TypeRef type, String javaName, - String sqlName, boolean id, boolean notNull, boolean unique) { + public FieldMirror(FieldType fieldType, boolean constructorParam, AccessType setterType, AccessType getterType, + TypeRef type, String javaName, String sqlName, boolean id, boolean notNull, boolean unique) { this.fieldType = fieldType; + this.constructorParam = constructorParam; this.setterType = setterType; this.getterType = getterType; this.type = type; @@ -57,7 +51,7 @@ public class FieldMirror { } private String fieldAccessor(String o) { - if (getterType == GetterType.FIELD) { + if (getterType == FIELD) { return o + "." + javaName; } return o + "." + toGetterName(javaName) + "()"; @@ -67,6 +61,7 @@ public class FieldMirror { public String toString() { return "FieldMirror{" + "fieldType=" + fieldType + + ", constructorParam=" + constructorParam + ", setterType=" + setterType + ", getterType=" + getterType + ", type=" + type + 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 7cd3f59..b9b65a5 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 @@ -26,9 +26,10 @@ import static io.trygvis.container.compiler.Utils.*; import static io.trygvis.container.compiler.model.TypeRef.VOID; import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE; import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE; -import static io.trygvis.persistence.FieldMirror.SetterType; import static java.lang.String.format; import static java.lang.reflect.Modifier.PUBLIC; +import static javax.persistence.AccessType.FIELD; +import static javax.persistence.AccessType.PROPERTY; import static org.apache.commons.lang.StringUtils.join; public class DaoGenerator { @@ -51,16 +52,17 @@ public class DaoGenerator { g.add(new Constructor(p, "super(" + session.name + ");")); TypeRef stringType = g.imports.add(String.class); + TypeRef stringArrayType = g.imports.add(String[].class); TypeRef sqlEntityDescType = g.imports.add(SqlEntityMeta.class); TypeRef sqlException = g.imports.add(SQLException.class); // TypeRef listOfEntityType = new TypeRef(List.class).args(entity.type); FieldRef createTableSql = g.addPublicStaticFinalField(stringType, "createTableSql"). value(toJavaString(createTableSql())); - g.add(new MethodRef(PUBLIC, stringType, "createTableSql", "return createTableSql;")); + g.add(new MethodRef(PUBLIC, stringArrayType, "createTableSql", "return new String[]{createTableSql};")); FieldRef dropTableSql = g.addPublicStaticFinalField(stringType, "dropTableSql"). value(toJavaString(dropTableSql())); - g.add(new MethodRef(PUBLIC, stringType, "dropTableSql", "return dropTableSql;")); + g.add(new MethodRef(PUBLIC, stringArrayType, "dropTableSql", "return new String[]{dropTableSql};")); g.addPublicStaticFinalField(stringType, "insertIntoSql"). value(toJavaString(insertIntoSql())); g.addPublicStaticFinalField(stringType, "deleteFromSql"). @@ -277,7 +279,7 @@ public class DaoGenerator { Parameters.ParameterRef row = p.addParameter(this.entity.rowType, "row"); List<String> body = new ArrayList<>(); - List<String> cArgs = new ArrayList<>(); + String[] cArgs = new String[entity.getConstructorParameters().size()]; List<String> method = new ArrayList<>(); for (int i = 0; i < entity.getFields().size(); i++) { FieldMirror field = this.entity.getFields().get(i); @@ -292,11 +294,13 @@ public class DaoGenerator { // body.add(x); } - if (field.setterType == SetterType.CONSTRUCTOR) { - cArgs.add(value); - } else if (field.setterType == SetterType.METHOD) { + if (field.constructorParam) { + System.out.println("entity.getConstructorParameters() = " + entity.getConstructorParameters()); + System.out.println("field.javaName = " + field.javaName); + cArgs[entity.getConstructorParameters().indexOf(field.javaName)] = value; + } else if (field.setterType == PROPERTY) { method.add("_entity." + toSetterName(field.javaName) + "(" + value + ");"); - } else if (field.setterType == SetterType.FIELD) { + } else if (field.setterType == FIELD) { method.add("_entity." + field.javaName + " = " + value + ";"); } } 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 08a7f45..3ca191f 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 @@ -22,10 +22,10 @@ import java.util.List; import static io.trygvis.container.compiler.Utils.toGetterName; import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE; -import static io.trygvis.persistence.FieldMirror.GetterType; import static java.lang.reflect.Modifier.PUBLIC; import static java.lang.reflect.Modifier.STATIC; import static java.util.Collections.singletonList; +import static javax.persistence.AccessType.FIELD; import static org.apache.commons.lang.StringUtils.join; public class DaoUtilsGenerator { @@ -134,7 +134,7 @@ public class DaoUtilsGenerator { List<String> arguments = new ArrayList<>(); arguments.add(con.name); FieldMirror field = entity.getIdField(); - if (field.getterType == GetterType.FIELD) { + if (field.getterType == FIELD) { arguments.add(o.name + "." + field.javaName); } else { arguments.add(o.name + "." + toGetterName(field.javaName) + "()"); diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SequencesGenerator.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SequencesGenerator.java deleted file mode 100644 index 07823af..0000000 --- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SequencesGenerator.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.trygvis.persistence.generators; - -import io.trygvis.container.compiler.SqlUnitModel; -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.SequenceMirror; - -import java.util.ArrayList; -import java.util.List; - -import static io.trygvis.container.compiler.Utils.toJavaString; -import static java.lang.reflect.Modifier.PUBLIC; -import static org.apache.commons.lang.StringUtils.capitalize; -import static org.apache.commons.lang.StringUtils.join; - -public class SequencesGenerator { - public static ClassG generateSequences(SqlUnitModel unit) { - TypeRef sequences = new TypeRef(unit.getPackageName() + ".Sequences"); - ClassG g = new ClassG(PUBLIC, sequences); - List<String> creates = new ArrayList<>(); - List<String> drops = new ArrayList<>(); - for (SequenceMirror sequence : unit.getSequences().values()) { - TypeRef stringType = g.imports.add(String.class); - String value = "CREATE SEQUENCE " + sequence.sequenceName + ";"; - FieldRef f = g.addPublicStaticFinalField(stringType, "create" + capitalize(sequence.name)). - value(toJavaString(value)); - creates.add(f.name); - - f = g.addPublicStaticFinalField(stringType, "drop" + capitalize(sequence.name)). - value(toJavaString("DROP SEQUENCE " + sequence.sequenceName) + ";"); - drops.add(f.name); - - } - g.addPublicStaticFinalField(new TypeRef(String[].class), "createSequences"). - value("new String[]{" + join(creates, ", ") + "}"); - g.addPublicStaticFinalField(new TypeRef(String[].class), "dropSequences"). - value("new String[]{" + join(drops, ", ") + "}"); - return g; - } -} 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 7b6f667..697b262 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 @@ -9,7 +9,9 @@ import io.trygvis.container.compiler.model.MethodRef; import io.trygvis.container.compiler.model.Parameters; import io.trygvis.container.compiler.model.TypeRef; import io.trygvis.persistence.EntityMirror; +import io.trygvis.persistence.SequenceMirror; import io.trygvis.persistence.sql.SqlEntityMeta; +import io.trygvis.persistence.sql.SqlSequenceMeta; import io.trygvis.persistence.sql.SqlSessionFactory; import io.trygvis.persistence.sql.SqlUnit; @@ -20,6 +22,8 @@ import java.util.ArrayList; import java.util.List; import static io.trygvis.container.compiler.Utils.toClassName; +import static io.trygvis.container.compiler.Utils.toJavaString; +import static java.lang.String.format; import static java.lang.reflect.Modifier.*; import static org.apache.commons.lang.StringUtils.join; @@ -32,30 +36,50 @@ public class SqlSessionFactoryGenerator { ClassG g = new ClassG(PUBLIC, ssfType). extendsType(new TypeRef(SqlSessionFactory.class).args(ssType)); - List<String> s = new ArrayList<>(); + List<String> es = new ArrayList<>(); for (EntityMirror entity : unit.getEntities().values()) { if (!entity.concrete) { continue; } - s.add(entity.daoType.plainName + ".desc"); + es.add(entity.daoType.plainName + ".desc"); } TypeRef sqlEntityMetaArrayType = new TypeRef(SqlEntityMeta[].class); - FieldRef entities = g.addField(PUBLIC | STATIC, sqlEntityMetaArrayType, "entities"). - value("new " + sqlEntityMetaArrayType + "{" + join(s, ", ") + "}"); + FieldRef entities = g.addField(PRIVATE | STATIC, sqlEntityMetaArrayType, "entities"). + value(format("new " + sqlEntityMetaArrayType + "{%n" + join(es, ", %n") + "%n}")); - g.add(constructor(entities, g.imports)); + TypeRef sqlSequenceMetaArrayType = new TypeRef(SqlSequenceMeta[].class); + List<String> ss = generateSequences(unit, g.imports); + FieldRef sequences = g.addField(PRIVATE | STATIC, sqlSequenceMetaArrayType, "sequences"). + value(format("new " + sqlSequenceMetaArrayType + "{%n" + join(ss, ", %n") + "%n}")); + + g.add(constructor(entities, sequences, g.imports)); g.add(newSession(unit, ssType, g.imports)); return g; } - private static Constructor constructor(FieldRef entities, Imports imports) { + public static List<String> generateSequences(SqlUnitModel unit, Imports imports) { + TypeRef sqlSequenceMetaType = imports.add(SqlSequenceMeta.class); + List<String> fields = new ArrayList<>(); + for (SequenceMirror sequence : unit.getSequences().values()) { + String create = "CREATE SEQUENCE " + sequence.sequenceName; + String drop = "DROP SEQUENCE " + sequence.sequenceName; + + fields.add(format("new " + sqlSequenceMetaType.plainName + "(" + toJavaString(sequence.sequenceName) + ",%n" + + toJavaString(create) + ",%n" + + toJavaString(drop) + ")")); + } + + return fields; + } + + private static Constructor constructor(FieldRef entities, FieldRef sequences, Imports imports) { TypeRef dataSourceType = imports.add(DataSource.class); TypeRef sqlUnitType = imports.add(SqlUnit.class); Parameters p = new Parameters(); Parameters.ParameterRef ds = p.addParameter(dataSourceType, "ds"); ArrayList<String> body = new ArrayList<>(); - body.add("super(new " + sqlUnitType.plainName + "(" + entities.name + "), " + ds.name + ");"); + body.add("super(new " + sqlUnitType.plainName + "(" + entities.name + "," + sequences.name + "), " + ds.name + ");"); return new Constructor(p, body); } 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 8e32cfe..90309e4 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 @@ -16,13 +16,17 @@ import io.trygvis.persistence.sql.SqlSession; import java.io.IOException; import java.sql.Connection; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import static io.trygvis.container.compiler.Utils.toFieldName; import static io.trygvis.container.compiler.model.Parameters.ParameterRef; +import static java.lang.String.format; +import static java.lang.reflect.Modifier.FINAL; import static java.lang.reflect.Modifier.PUBLIC; +import static org.apache.commons.lang.StringUtils.join; public class SqlSessionGenerator { public static ClassG generateSqlSession(SqlUnitModel unit) throws IOException { @@ -41,18 +45,33 @@ public class SqlSessionGenerator { daoFields.put(entity, f); } - g.add(constructor(unit, g.imports, daoFields)); + TypeRef sqlDaoType = new TypeRef(SqlDao.class); + TypeRef listOfDaos = g.imports.add(new TypeRef(List.class).args(sqlDaoType)); + FieldRef daos = new FieldRef(PUBLIC | FINAL, listOfDaos, "daos"); + + g.add(daos); + g.add(constructor(unit, g.imports, daoFields, daos)); g.add(getSqlDao(unit, g.imports, daoFields)); + g.add(getDaos(g.imports, daos)); return g; } - private static Constructor constructor(SqlUnitModel unit, Imports imports, Map<EntityMirror, FieldRef> daoFields) { + private static MethodRef getDaos(Imports imports, FieldRef daos) { + TypeRef sqlDaoType = new TypeRef(SqlDao.class); + TypeRef listOfDaos = imports.add(new TypeRef(List.class).args(sqlDaoType)); + return new MethodRef(PUBLIC, listOfDaos, "getDaos", "return " + daos.name + ";"); + } + + private static Constructor constructor(SqlUnitModel unit, Imports imports, Map<EntityMirror, FieldRef> daoFields, FieldRef daos) { + TypeRef arraysType = imports.add(Arrays.class); + Parameters p = new Parameters(); ParameterRef c = p.addParameter(imports.add(Connection.class), "c"); List<String> body = new ArrayList<>(); body.add("super(" + c.name + ");"); + List<String> daoNames = new ArrayList<>(); for (EntityMirror entity : unit.getEntities().values()) { if (!entity.concrete) { continue; @@ -60,7 +79,9 @@ public class SqlSessionGenerator { FieldRef f = daoFields.get(entity); body.add("this." + f.name + " = new " + entity.daoType.plainName + "(this);"); + daoNames.add(f.name); } + body.add(format("this." + daos.name + " = " + arraysType.plainName + ".asList(new SqlDao[]{%n" + join(daoNames, ", %n") + "%n});")); return new Constructor(p, body); } |