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.SqlSession; 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.toFieldName; import static io.trygvis.container.compiler.model.Parameters.ParameterRef; import static java.lang.reflect.Modifier.PUBLIC; public class SqlSessionGenerator { public static ClassG generateSqlSession(SqlUnitModel unit) throws IOException { TypeRef sqlSession = new TypeRef(SqlSession.class); ClassG g = new ClassG(PUBLIC, unit.sessionType). extendsType(sqlSession); Map daoFields = new HashMap<>(); for (EntityMirror entity : unit.getEntities().values()) { FieldRef f = g.addPublicFinalField(entity.daoType, toFieldName(entity.type.className)); daoFields.put(entity, f); } 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 c = p.addParameter(imports.add(Connection.class), "c"); List body = new ArrayList<>(); body.add("super(" + c.name + ");"); for (EntityMirror entity : unit.getEntities().values()) { FieldRef f = daoFields.get(entity); body.add("this." + f.name + " = new " + entity.daoType.plainName + "(this);"); } 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", unit.sessionType.className, "?"); Parameters p = new Parameters(); p.addParameter(new TypeRef(Class.class).args("T"), "klass"); List body = new ArrayList<>(); for (EntityMirror entity : unit.getEntities().values()) { String sqlDao = "SqlDao"; 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)); } */ }