package io.trygvis.persistence.generators; import io.trygvis.container.compiler.SqlUnitModel; 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.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; import javax.sql.DataSource; import java.io.IOException; import java.sql.Connection; 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; public class SqlSessionFactoryGenerator { public static ClassG generateSqlSessionFactory(SqlUnitModel unit) throws IOException { String prefix = unit.getPackageName() + "." + toClassName(unit.getName()); TypeRef ssfType = new TypeRef(prefix + "SqlSessionFactory"); TypeRef ssType = new TypeRef(prefix + "SqlSession"); ClassG g = new ClassG(PUBLIC, ssfType). extendsType(new TypeRef(SqlSessionFactory.class).args(ssType)); List es = new ArrayList<>(); for (EntityMirror entity : unit.getEntities().values()) { if (!entity.concrete) { continue; } es.add(entity.daoType.plainName + ".desc"); } TypeRef sqlEntityMetaArrayType = new TypeRef(SqlEntityMeta[].class); FieldRef entities = g.addField(PRIVATE | STATIC, sqlEntityMetaArrayType, "entities"). value(format("new " + sqlEntityMetaArrayType + "{%n" + join(es, ", %n") + "%n}")); TypeRef sqlSequenceMetaArrayType = new TypeRef(SqlSequenceMeta[].class); List 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; } public static List generateSequences(SqlUnitModel unit, Imports imports) { TypeRef sqlSequenceMetaType = imports.add(SqlSequenceMeta.class); List 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 body = new ArrayList<>(); body.add("super(new " + sqlUnitType.plainName + "(" + entities.name + "," + sequences.name + "), " + ds.name + ");"); return new Constructor(p, body); } private static MethodRef newSession(SqlUnitModel unit, TypeRef sessionType, Imports imports) { String prefix = unit.getPackageName() + "." + toClassName(unit.getName()); TypeRef connectionType = imports.add(Connection.class); Parameters p = new Parameters(); Parameters.ParameterRef c = p.addParameter(connectionType, "c"); return new MethodRef(PROTECTED, sessionType, "newSession", p, "return new " + sessionType + "(" + c.name + ");"); } }