package io.trygvis.persistence.generators; import io.trygvis.container.compiler.SqlUnitModel; import io.trygvis.container.compiler.model.AnnotationG; import io.trygvis.container.compiler.model.ClassG; import io.trygvis.container.compiler.model.Constructor; import io.trygvis.container.compiler.model.FieldRef; import io.trygvis.container.compiler.model.Imports; 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.sql.SqlDao; import io.trygvis.persistence.sql.SqlEntityManager; import io.trygvis.persistence.sql.SqlEntityManagerFactory; import java.io.IOException; import java.sql.Connection; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static io.trygvis.container.compiler.Utils.toClassName; import static io.trygvis.container.compiler.Utils.toFieldName; import static io.trygvis.container.compiler.model.Parameters.ParameterRef; import static java.lang.reflect.Modifier.PUBLIC; public class EntityManagerGenerator { public static ClassG generateEntityManager(SqlUnitModel unit) throws IOException { String prefix = unit.getPackageName() + "." + toClassName(unit.getName()); TypeRef emType = new TypeRef(prefix + "EntityManager"); ClassG g = new ClassG(PUBLIC, emType). extendsType(SqlEntityManager.class); Map daoFields = new HashMap<>(); for (EntityMirror entity : unit.getEntities().values()) { daoFields.put(entity, g.addField(entity.daoType, toFieldName(entity.type.className))); } g.add(constructor(unit, g.imports, daoFields)); g.add(getSqlDao(unit, g.imports, daoFields)); return g; } private static Constructor constructor(SqlUnitModel unit, Imports imports, Map daoFields) { Parameters p = new Parameters(); ParameterRef semf = p.addParameter(imports.add(SqlEntityManagerFactory.class), "emf"); ParameterRef c = p.addParameter(imports.add(Connection.class), "c"); List body = new ArrayList<>(); body.add("super(" + semf.name + ", " + c.name + ");"); for (EntityMirror entity : unit.getEntities().values()) { FieldRef f = daoFields.get(entity); body.add("this." + f.name + " = new " + entity.daoType.plainName + "(" + c.name + ");"); } return new Constructor(p, body); } public static MethodRef getSqlDao(SqlUnitModel unit, Imports imports, Map daoFields) { TypeRef sqlDatoType = imports.add(new TypeRef(SqlDao.class)).args("Id", "T"); Parameters p = new Parameters(); TypeRef klassType = new TypeRef(Class.class).args("T"); ParameterRef klass = p.addParameter(klassType, "klass"); List body = new ArrayList<>(); for (EntityMirror entity : unit.getEntities().values()) { body.add("if (klass == " + entity.type.plainName + ".class) {"); body.add(" return (SqlDao) " + daoFields.get(entity).name + ";"); body.add("}"); } body.add("throw new RuntimeException(\"Type is not a part of this persistence unit: \" + klass);"); return new MethodRef(PUBLIC, sqlDatoType, "getDao", p, body).typeArgs("Id", "T"). annotation(new AnnotationG(new TypeRef(SuppressWarnings.class), "\"unchecked\"")); } /* public static ClassG sem(EntityMirror entity) { ClassG g = new ClassG(PUBLIC, new TypeRef(entity.type.className + "SEM")); g.implementsType(g.imports.add(new TypeRef(SqlDao.class)).args(entity.idType, entity.type)); return g. add(semFind(entity, g.imports)). add(semPersist(entity, g.imports)). add(semMerge(entity, g.imports)). add(semRemove(entity, g.imports)); } public static MethodRef semFind(EntityMirror entity, Imports imports) { TypeRef type = imports.add(entity.type); TypeRef sqlException = imports.add(SQLException.class); Parameters p = new Parameters(); ParameterRef primaryKey = p.addParameter(new TypeRef(Object.class), "primaryKey"); List body = new ArrayList<>(); body.add("throw new " + sqlException.plainName + "(\"Not implemented\");"); return new MethodRef(PUBLIC, type, "find", p, tryCatchSqlException(imports, body)); } public static MethodRef semPersist(EntityMirror entity, Imports imports) { TypeRef type = imports.add(entity.type); TypeRef dao = imports.add(entity.daoType); Parameters p = new Parameters(); ParameterRef e = p.addParameter(type, "entity"); List body = new ArrayList<>(); body.add(dao.plainName + ".insertInto(currentConnection(), " + e.name + ");"); return new MethodRef(PUBLIC, VOID, "persist", p, tryCatchSqlException(imports, body)); } public static MethodRef semMerge(EntityMirror entity, Imports imports) { TypeRef type = imports.add(entity.type); TypeRef sqlException = imports.add(SQLException.class); Parameters p = new Parameters(); ParameterRef e = p.addParameter(type, "entity"); List body = new ArrayList<>(); body.add("throw new " + sqlException.plainName + "(\"Not implemented\");"); return new MethodRef(PUBLIC, type, "merge", p, tryCatchSqlException(imports, body)); } public static MethodRef semRemove(EntityMirror entity, Imports imports) { TypeRef type = imports.add(entity.type); TypeRef sqlException = imports.add(SQLException.class); Parameters p = new Parameters(); ParameterRef e = p.addParameter(type, "entity"); List body = new ArrayList<>(); body.add("throw new " + sqlException.plainName + "(\"Not implemented\");"); return new MethodRef(PUBLIC, VOID, "remove", p, tryCatchSqlException(imports, body)); } */ }