com.ivanceras.db.server.util.DAOGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of orm Show documentation
Show all versions of orm Show documentation
ORM - Core Library for Database
/*******************************************************************************
* Copyright by CMIL
******************************************************************************/
package com.ivanceras.db.server.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import com.ivanceras.commons.conf.Configuration;
import com.ivanceras.commons.strings.CStringUtils;
import com.ivanceras.db.api.EntityManager;
import com.ivanceras.db.api.IDatabaseDev;
import com.ivanceras.db.api.ModelDef;
import com.ivanceras.db.model.ModelMetaData;
import com.ivanceras.db.server.util.generators.BeanGenerator;
import com.ivanceras.db.server.util.generators.ColumnNameGenerator;
import com.ivanceras.db.server.util.generators.DAOClassGenerator;
import com.ivanceras.db.server.util.generators.DAOInstanceFactoryGenerator;
import com.ivanceras.db.server.util.generators.MapperGenerator;
import com.ivanceras.db.server.util.generators.ModelMetaDataGenerator;
import com.ivanceras.db.server.util.generators.ModelToDAOConversionGenerator;
import com.ivanceras.db.server.util.generators.SchemaTableGenerator;
import com.ivanceras.db.server.util.generators.TableColumnGenerator;
import com.ivanceras.db.server.util.generators.TableNameGenerator;
/**
* Creates a dao definition based on the database tables
* @author jcesar
*
*/
public class DAOGenerator{
private EntityManager em;
private Configuration conf;
private List tableGroups;
private boolean cleanupDirectory;
private ModelMetaData explicitMeta;
public static final String Array = "List"; //Use word "List" instead of "Array"
public DAOGenerator(EntityManager em, Configuration conf, List tableGroups, ModelMetaData explicitMeta, boolean cleanupDirectory){
this.em = em;
this.conf = conf;
this.tableGroups = tableGroups;
this.cleanupDirectory = cleanupDirectory;
this.explicitMeta = explicitMeta;
}
/**
* Curated will correct The ModelDef
* @param curated
* @throws Exception
*/
public void startUncurated(Configuration conf) throws Exception{
IDatabaseDev db = (IDatabaseDev) em.getDB();//TODO make sure DB platform can be used for development
ModelDefinitionProvider provider = new ModelDefinitionProvider(db, conf.dbUser, null, conf.includeSchema);
ModelDef[] origModelList = provider.getTableDefinitions();
//TODO: proper support for explicit ModelDefinitions
ModelDef[] withExplecitList = overrideModelDefFromExplicit(origModelList, explicitMeta);
ModelDef[] modelList = withExplecitList;
ModelDef[] modelListOwned = setModelOwners(modelList, tableGroups);
ModelDef[] modelListChilded = setDirectChildren(modelListOwned);
new ModelMetaDataGenerator().start(modelListChilded, conf);
}
/**
* Curated will correct The ModelDef
* @param curated
* @throws Exception
*/
public void start() throws Exception{
if(cleanupDirectory){
CleanUp.start(conf);
}
IDatabaseDev db = (IDatabaseDev) em.getDB();//TODO make sure DB platform can be used for development
ModelDefinitionProvider provider = new ModelDefinitionProvider(db, conf.dbUser, null, conf.includeSchema);
ModelDef[] origModelList = provider.getTableDefinitions();
new ModelMetaDataGenerator().start(origModelList, conf);
//TODO: proper support for explicit ModelDefinitions
ModelDef[] withExplecitList = overrideModelDefFromExplicit(origModelList, explicitMeta);
ModelDef[] modelList = correctModelList(withExplecitList);
new DAOClassGenerator().start(modelList, conf, true, false);
new BeanGenerator().start(modelList, conf);
new MapperGenerator().start(modelList, conf);
ModelDef[] modelListOwned = setModelOwners(modelList, tableGroups);
ModelDef[] modelListChilded = setDirectChildren(modelListOwned);
new ColumnNameGenerator().start(modelListChilded, conf);
new TableNameGenerator().start(modelListChilded, conf);
new SchemaTableGenerator().start(modelListChilded, conf);
new TableColumnGenerator().start(modelListChilded, conf);
//new ModelMetaDataGenerator().start(modelListChilded, conf);
new DAOInstanceFactoryGenerator().start(modelListChilded, conf);
new ModelToDAOConversionGenerator().start(modelListChilded, conf);
}
/**
* Support ExplecitModelDefinition
* @param modelList
* @param explicitMeta
* @return
*/
private ModelDef[] overrideModelDefFromExplicit(ModelDef[] modelList, ModelMetaData explicitMeta) {
List withExplecityMeta = new ArrayList();
for(ModelDef model : modelList){
ModelDef overrideModel = getOverrideModel(model, explicitMeta);
withExplecityMeta.add(overrideModel);
}
return withExplecityMeta.toArray(new ModelDef[withExplecityMeta.size()]);
}
/**
* When the mode is in the explecit model, use it instead, else use what's the in database
* @param model
* @param explicitMeta2
* @return
*/
private ModelDef getOverrideModel(ModelDef model,
ModelMetaData explicitMeta2) {
if(explicitMeta2 == null){
return model;
}
List explicitList = explicitMeta2.getModelDefinitionList();
for(ModelDef explicitModel : explicitList){
if(explicitModel.getModelName().equals(model.getModelName())){
return explicitModel;
}
}
return model;
}
/**
* Correctionals in model definition, such as
* when a primary column of a certain table is used as a foreign key of
* another table while at the same time it is the primary column of that table, then both table has 1:1 relationship only
*
* For each model that hasMany table
* If the hasmany table is using a primary key that is a foreign key refering to the primary key of this table
*
* @param tableDefinitions
* @return
*/
private ModelDef[] correctModelList(ModelDef[] modelList) {
return new ModelCurator(modelList).correct();
}
/**
*
* @param modelList
* @param tableGroups, gives a clue to the final/primary owner of this table, when grouping tables together
* @return
*/
private ModelDef[] setModelOwners(ModelDef[] modelList, List tableGroups) {
HashMap modelHash = new LinkedHashMap();//modelname, ModelDef
HashMap> model_owners = new LinkedHashMap>();//ModelName, owners
for(ModelDef model : modelList){
String modelName = model.getModelName().toLowerCase();
System.out.println("modelName: "+modelName);
modelHash.put(model.getModelName().toLowerCase(), model);
}
for(ModelDef owner : modelList){
String[] dependents = owner.getHasMany();
for(String ownedDependent : dependents){
if(model_owners.containsKey(ownedDependent)){
Set owners = model_owners.get(ownedDependent);
owners.add(owner.getModelName().toLowerCase());
}
else{
Set set = new HashSet();
set.add(owner.getModelName().toLowerCase());
model_owners.put(ownedDependent, set);
}
}
}
if(tableGroups != null){
Map> tableInvolvedment = transformGroup(tableGroups);
for(Entry> model_owner : model_owners.entrySet()){
String modelName = model_owner.getKey();
ModelDef model = modelHash.get(modelName);
if(model == null){
System.err.println("Warning: can not find model: "+modelName);
}
Set ownerSet = model_owner.getValue();
if(ownerSet != null && ownerSet.size() > 0){
String[] owners = ownerSet.toArray(new String[ownerSet.size()]);
if(model != null){
model.setOwners(owners);
if(owners.length == 1){
model.setPrimaryOwner(owners[0]);
}
else if(owners.length > 1){
String[] group = getTableInvolvement(model.getModelName().toLowerCase(), tableInvolvedment);
String primaryOwner = chooseFirstOccurence(owners, group, model.getTableName());
model.setPrimaryOwner(primaryOwner);
}
else{
}
}
}
}
}
List finalModelList = new ArrayList();
for(Entry modelEntry : modelHash.entrySet()){
finalModelList.add(modelEntry.getValue());
}
return finalModelList.toArray(new ModelDef[finalModelList.size()]);
}
private ModelDef[] setDirectChildren(ModelDef[] modelListOwned) {
Map modelSearchList = new LinkedHashMap();
for(ModelDef model : modelListOwned){
String modelName = model.getModelName().toLowerCase();
modelSearchList.put(modelName, model);
}
Map> owner_childrenSet = new LinkedHashMap>();
for(ModelDef model : modelListOwned){
String modelName = model.getModelName().toLowerCase();
String primaryOwner = model.getPrimaryOwner();
if(primaryOwner != null){
ModelDef owner = modelSearchList.get(primaryOwner);
if(!owner.getModelName().equalsIgnoreCase(modelName)){
if(owner_childrenSet.containsKey(owner)){
Set children = owner_childrenSet.get(owner);
children.add(modelName);
}
else{
Set children = new HashSet();
children.add(modelName);
owner_childrenSet.put(owner, children);
}
}
}
}
List childedModelList = new LinkedList();
for(ModelDef owner : modelListOwned){
Set children = owner_childrenSet.get(owner);
if(children != null){
owner.setDirectChildren(children.toArray(new String[children.size()]));
}
childedModelList.add(owner);
}
return childedModelList.toArray(new ModelDef[childedModelList.size()]);
}
/**
* Choose among the owners that are present within the list group that occurs before the tableName, and closest to it
* @param owners
* @param group
* @param tableName
*/
private String chooseFirstOccurence(String[] among_owners, String[] within_listgroup,
String prior_tableName) {
int index = CStringUtils.indexOf(within_listgroup, prior_tableName);
for(int i = index-1; i >= 0; i-- ){
String closest = within_listgroup[i];
if(CStringUtils.indexOf(among_owners, closest) >= 0){
return closest;
}
}
return null;
}
private String[] getTableInvolvement(String table, Map> involvements){
if(involvements == null){
return null;
}
if(involvements.size() == 0){
return null;
}
if(!involvements.containsKey(table)){
return null;
}
else{
Set involvedList = involvements.get(table);
String[] result = null;
if(involvedList!=null && involvedList.size() > 0){
result = involvedList.iterator().next();
}
else{
return null;
}
for(String[] inv : involvedList){
if(result.length < inv.length){
result = inv;
}
}
return result;
}
}
//transform the listing of table groups, according to table
private Map> transformGroup(List tableGroups) {
Map> model_tableGroup = new LinkedHashMap>();
for(String[] list : tableGroups){
for(String table : list){
if(model_tableGroup.containsKey(table)){
Set tableGroupSet = model_tableGroup.get(table);
tableGroupSet.add(list);
}
else{
Set tableGroupSet = new HashSet();
tableGroupSet.add(list);
model_tableGroup.put(table, tableGroupSet);
}
}
}
return model_tableGroup;
}
}