package joist.codegen.dtos; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import joist.codegen.Config; import joist.util.Copy; import joist.util.Inflector; import joist.util.MapToList; import org.apache.commons.lang.StringUtils; /** Represents a domain object we will generate code for. */ public class Entity { protected Config config; private String tableName; private Entity baseEntity; private List<Entity> subEntities = new ArrayList<Entity>(); private List<PrimitiveProperty> primitiveProperties = new ArrayList<PrimitiveProperty>(); private List<ManyToOneProperty> manyToOneProperties = new ArrayList<ManyToOneProperty>(); private List<OneToManyProperty> oneToManyProperties = new ArrayList<OneToManyProperty>(); private List<ManyToManyProperty> manyToManyProperties = new ArrayList<ManyToManyProperty>(); private List<String> uniquePropertyTypes; private List<String> uniqueCodeNames; public Entity(Config config, String tableName) { this.config = config; this.tableName = tableName; } public String getParentClassName() { if (this.isSubclass()) { return this.baseEntity.getClassName(); } else { return this.config.getDomainObjectBaseClass(); } } public boolean hasSubclasses() { return this.subEntities.size() > 0; } public Config getConfig() { return this.config; } public boolean isRoot() { return this.baseEntity == null && !this.isCodeEntity(); } public boolean isAbstract() { return this.hasSubclasses() && !this.config.isNotAbstractEvenThoughSubclassed(this.tableName); } public boolean isConcrete() { return !this.isAbstract(); } public boolean isSubclass() { return this.getBaseEntity() != null; } public boolean isCodeEntity() { return false; } public String getClassName() { return Inflector.camelize(this.getTableName()); } /** @return {@code st} for a table {@code some_table} */ public String getAliasAlias() { String a = ""; for (String part : this.getTableName().split("_")) { a += part.substring(0, 1); } // add trailing 0 to avoid using keywords (like AdStat == as) return a + "0"; } public String getAliasName() { return this.getClassName() + "Alias"; } public String getVariableName() { return StringUtils.uncapitalize(this.getClassName()); } public String getCodegenClassName() { return this.getClassName() + "Codegen"; } public String getBuilderClassName() { return this.getClassName() + "Builder"; } public String getBuilderCodegenClassName() { return this.getClassName() + "BuilderCodegen"; } public String getQueriesCodegenClassName() { return this.getClassName() + "QueriesCodegen"; } public String getFullCodegenClassName() { return this.config.getDomainObjectPackage() + "." + this.getCodegenClassName(); } public String getFullAliasClassName() { return this.config.getDomainObjectPackage() + "." + this.getClassName() + "Alias"; } public String getFullClassName() { return this.config.getDomainObjectPackage() + "." + this.getClassName(); } public String getFullQueriesClassName() { return this.config.getQueriesPackage() + "." + this.getClassName() + "Queries"; } public String getFullQueriesCodegenClassName() { return this.config.getQueriesPackage() + "." + this.getQueriesCodegenClassName(); } public String getFullBuilderCodegenClassName() { return this.config.getBuildersPackage() + "." + this.getBuilderCodegenClassName(); } public String getFullBuilderClassName() { return this.config.getBuildersPackage() + "." + this.getBuilderClassName(); } public List<PrimitiveProperty> getPrimitiveProperties() { return this.primitiveProperties; } public List<ManyToOneProperty> getManyToOneProperties() { return this.manyToOneProperties; } public List<OneToManyProperty> getOneToManyProperties() { return this.oneToManyProperties; } public List<ManyToManyProperty> getManyToManyProperties() { return this.manyToManyProperties; } public String getTableName() { return this.tableName; } public Entity getBaseEntity() { return this.baseEntity; } public Entity getRootEntity() { Entity current = this; while (current.getBaseEntity() != null) { current = current.getBaseEntity(); } return current; } public void setBaseEntity(Entity baseObject) { this.baseEntity = baseObject; // In Class Table Inheritance, the id column overlaps in each table, but we only want it in the root class for (Iterator<PrimitiveProperty> i = this.getPrimitiveProperties().iterator(); i.hasNext();) { if (i.next().getColumnName().equals("id")) { i.remove(); } } } public void addSubEntity(Entity subEntity) { this.subEntities.add(subEntity); } public List<Entity> getSubEntities() { return this.subEntities; } public List<Entity> getSubEntitiesRecursively() { List<Entity> ret = new ArrayList<Entity>(); List<Entity> walk = Copy.list(this.getSubEntities()); while (walk.size() != 0) { Entity sub = walk.remove(0); ret.add(sub); walk.addAll(sub.getSubEntities()); } return ret; } public List<Entity> getAllBaseAndSubEntities() { List<Entity> ret = new ArrayList<Entity>(); ret.addAll(this.getBaseEntities()); ret.add(this); ret.addAll(this.getSubEntitiesRecursively()); return ret; } public List<String> getUniqueCodeNames() { if (this.uniqueCodeNames == null) { MapToList<String, String> perCodeName = new MapToList<String, String>(); for (Entity entity : this.getAllBaseAndSubEntities()) { for (ManyToOneProperty mtop : entity.getManyToOneProperties()) { if (mtop.getOneSide().isCodeEntity()) { for (CodeValue code : ((CodeEntity) mtop.getOneSide()).getCodes()) { perCodeName.get(code.getEnumName()).add(mtop.getOneSide().getClassName()); } } } } this.uniqueCodeNames = listOfKeysWithOnlyOneValue(perCodeName); } return this.uniqueCodeNames; } public List<String> getUniquePropertyTypes() { if (this.uniquePropertyTypes == null) { MapToList<String, String> perType = new MapToList<String, String>(); for (Entity entity : this.getAllBaseAndSubEntities()) { for (PrimitiveProperty p : entity.getPrimitiveProperties()) { perType.get(p.getJavaType()).add(p.getVariableName()); } for (ManyToOneProperty mtop : entity.getManyToOneProperties()) { perType.get(mtop.getJavaType()).add(mtop.getVariableName()); } } this.uniquePropertyTypes = listOfKeysWithOnlyOneValue(perType); } return this.uniquePropertyTypes; } public List<Entity> getBaseEntities() { List<Entity> ret = new ArrayList<Entity>(); Entity base = this.getBaseEntity(); while (base != null) { ret.add(base); base = base.getBaseEntity(); } return ret; } public boolean isStableTable() { return this.config.isStableTable(this.getTableName()); } public String toString() { return this.getClassName(); } private static List<String> listOfKeysWithOnlyOneValue(MapToList<String, String> m) { List<String> ret = new ArrayList<String>(); for (Map.Entry<String, List<String>> e : m.entrySet()) { if (e.getValue().size() == 1) { ret.add(e.getKey()); } } return ret; } }