org.nuiton.topia.templates.EntityEnumTransformer Maven / Gradle / Ivy
The newest version!
package org.nuiton.topia.templates;
/*
* #%L
* ToPIA :: Templates
* $Id$
* $HeadURL$
* %%
* Copyright (C) 2004 - 2014 CodeLutin
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.plexus.component.annotations.Component;
import org.nuiton.eugene.Template;
import org.nuiton.eugene.java.ObjectModelTransformerToJava;
import org.nuiton.eugene.models.object.ObjectModel;
import org.nuiton.eugene.models.object.ObjectModelAttribute;
import org.nuiton.eugene.models.object.ObjectModelClass;
import org.nuiton.eugene.models.object.ObjectModelEnumeration;
import org.nuiton.eugene.models.object.ObjectModelJavaModifier;
import org.nuiton.eugene.models.object.ObjectModelOperation;
import org.nuiton.eugene.models.object.ObjectModelPackage;
import org.nuiton.eugene.models.object.xml.ObjectModelAttributeImpl;
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.TopiaEntityEnum;
import org.nuiton.topia.persistence.TopiaException;
import org.nuiton.topia.persistence.util.EntityOperator;
import org.nuiton.topia.persistence.util.EntityOperatorStore;
import org.nuiton.topia.persistence.util.TopiaEntityHelper;
import java.lang.reflect.Array;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/**
* Will generate XyzEntityEnum (where Xyz = Model name)
*
* @author Arnaud Thimel (Code Lutin)
* @since 3.0
*/
@Component( role = Template.class, hint="org.nuiton.topia.templates.EntityEnumTransformer")
public class EntityEnumTransformer extends ObjectModelTransformerToJava {
private static final Log log = LogFactory.getLog(EntityEnumTransformer.class);
protected TopiaTemplateHelper templateHelper;
protected final TopiaCoreTagValues topiaCoreTagValues;
protected final TopiaHibernateTagValues topiaHibernateTagValues;
public EntityEnumTransformer() {
this.topiaCoreTagValues = new TopiaCoreTagValues();
this.topiaHibernateTagValues = new TopiaHibernateTagValues();
}
@Override
public void transformFromModel(ObjectModel input) {
if (templateHelper == null) {
templateHelper = new TopiaTemplateHelper(model);
}
String packageName = templateHelper.getApplicationContextPackage(this, model);
String entityEnumName = templateHelper.getEntityEnumName(model);
boolean generateOperator = topiaCoreTagValues.getGenerateOperatorForDAOHelperTagValue(model);
generateEntityEnum(packageName, entityEnumName, generateOperator);
}
protected void generateEntityEnum(String packageName,
String entityEnumName,
boolean generateOperator) {
List classes =
templateHelper.getEntityClasses(model, true);
ObjectModelEnumeration entityEnum;
if (log.isDebugEnabled()) {
log.debug("Will generate standalone " + entityEnumName +
" in package " + packageName);
}
entityEnum = createEnumeration(entityEnumName, packageName);
addImport(entityEnum, TopiaEntity.class);
if (generateOperator) {
addImport(entityEnum, EntityOperatorStore.class);
}
addImport(entityEnum, Arrays.class);
addImport(entityEnum, ArrayUtils.class);
addImport(entityEnum, Modifier.class);
// generate TopiaEntityEnum
createEntityEnum(entityEnum,
entityEnumName,
generateOperator,
classes
);
}
protected void createEntityEnum(ObjectModelEnumeration entityEnum,
String entityEnumName,
boolean generateOperator,
List classes) {
ObjectModelAttributeImpl attr;
ObjectModelOperation op;
addInterface(entityEnum, TopiaEntityEnum.class);
addImport(entityEnum, Array.class);
if (generateOperator) {
addImport(entityEnum, EntityOperator.class);
}
for (ObjectModelClass clazz : classes) {
String clazzName = clazz.getName();
boolean withNatural = false;
boolean withNotNull = false;
StringBuilder naturalIdsParams = new StringBuilder();
StringBuilder notNullParams = new StringBuilder();
Set naturalIdsAttributes = templateHelper.getNaturalIdAttributes(clazz);
for (ObjectModelAttribute attribute: naturalIdsAttributes) {
withNatural = true;
// attribut metier
naturalIdsParams.append(", \"").append(attribute.getName()).append("\"");
}
Set notNullIdsAttributes = templateHelper.getNotNullAttributes(clazz);
for (ObjectModelAttribute attribute : notNullIdsAttributes) {
withNotNull = true;
// attribut not-null
notNullParams.append(", \"").append(attribute.getName()).append("\"");
}
StringBuilder params = new StringBuilder(clazzName + ".class");
ObjectModelPackage aPackage = model.getPackage(clazz);
String dbSchema = topiaHibernateTagValues.getDbSchemaNameTagValue(clazz, aPackage, model);
if (dbSchema == null) {
params.append(", null");
} else {
params.append(", \"").append(dbSchema.toLowerCase()).append("\"");
}
String dbTable = templateHelper.getDbName(clazz);
params.append(", \"").append(dbTable.toLowerCase()).append("\"");
if (withNotNull) {
params.append(", new String[]{" + notNullParams.substring(2) + "}");
} else {
params.append(", ArrayUtils.EMPTY_STRING_ARRAY");
}
if (withNatural) {
params.append(", ").append(naturalIdsParams.substring(2));
}
addLiteral(entityEnum, clazzName + '(' + params.toString() + ')');
addImport(entityEnum, clazz);
}
attr = (ObjectModelAttributeImpl) addAttribute(entityEnum, "contract", "Class extends TopiaEntity>", null, ObjectModelJavaModifier.PRIVATE, ObjectModelJavaModifier.FINAL);
attr.setDocumentation("The contract of the entity.");
attr = (ObjectModelAttributeImpl) addAttribute(entityEnum, "dbSchemaName", "String", null, ObjectModelJavaModifier.PRIVATE, ObjectModelJavaModifier.FINAL);
attr.setDocumentation("The optional name of database schema of the entity (if none was filled, will be {@code null}).");
attr = (ObjectModelAttributeImpl) addAttribute(entityEnum, "dbTableName", "String", null, ObjectModelJavaModifier.PRIVATE, ObjectModelJavaModifier.FINAL);
attr.setDocumentation("The name of the database table for the entity.");
attr = (ObjectModelAttributeImpl) addAttribute(entityEnum, "implementationFQN", "String", null, ObjectModelJavaModifier.PRIVATE);
attr.setDocumentation("The fully qualified name of the implementation of the entity.");
attr = (ObjectModelAttributeImpl) addAttribute(entityEnum, "implementation", "Class extends TopiaEntity>",null, ObjectModelJavaModifier.PRIVATE);
attr.setDocumentation("The implementation class of the entity (will be lazy computed at runtime).");
attr = (ObjectModelAttributeImpl) addAttribute(entityEnum, "naturalIds", "String[]", null, ObjectModelJavaModifier.PRIVATE, ObjectModelJavaModifier.FINAL);
attr.setDocumentation("The array of property involved in the natural key of the entity.");
attr = (ObjectModelAttributeImpl) addAttribute(entityEnum, "notNulls", "String[]", null, ObjectModelJavaModifier.PRIVATE, ObjectModelJavaModifier.FINAL);
attr.setDocumentation("The array of not null properties of the entity.");
// constructor
op = addConstructor(entityEnum, ObjectModelJavaModifier.PACKAGE);
addParameter(op,"Class extends TopiaEntity>","contract");
addParameter(op,"String","dbSchemaName");
addParameter(op,"String","dbTableName");
addParameter(op,"String[]","notNulls");
addParameter(op,"String ...","naturalIds");
setOperationBody(op, ""
+"\n"
+" this.contract = contract;\n"
+" this.dbSchemaName = dbSchemaName;\n"
+" this.dbTableName = dbTableName;\n"
+" this.notNulls = Arrays.copyOf(notNulls, notNulls.length);\n"
+" this.naturalIds = naturalIds;\n"
+" implementationFQN = contract.getName() + \"Impl\";\n"
+" "
);
// getContract method
op = addOperation(entityEnum, "getContract", "Class extends TopiaEntity>", ObjectModelJavaModifier.PUBLIC);
addAnnotation(entityEnum,op,Override.class);
setOperationBody(op, ""
+"\n"
+" return contract;\n"
+" "
);
// dbSchemaName method
op = addOperation(entityEnum, "dbSchemaName", String.class, ObjectModelJavaModifier.PUBLIC);
addAnnotation(entityEnum,op,Override.class.getSimpleName());
setOperationBody(op, ""
+"\n"
+" return dbSchemaName;\n"
+" "
);
// dbTableName method
op = addOperation(entityEnum, "dbTableName", String.class, ObjectModelJavaModifier.PUBLIC);
addAnnotation(entityEnum,op,Override.class.getSimpleName());
setOperationBody(op, ""
+"\n"
+" return dbTableName;\n"
+" "
);
// getNaturalIds method
op = addOperation(entityEnum, "getNaturalIds", "String[]", ObjectModelJavaModifier.PUBLIC);
addAnnotation(entityEnum,op,Override.class);
setOperationBody(op, ""
+"\n"
+" return naturalIds;\n"
+" "
);
// isUseNaturalIds method
op = addOperation(entityEnum, "isUseNaturalIds", "boolean", ObjectModelJavaModifier.PUBLIC);
addAnnotation(entityEnum,op,Override.class);
setOperationBody(op, ""
+"\n"
+" return naturalIds.length > 0;\n"
+" "
);
// getNotNulls method
op = addOperation(entityEnum, "getNotNulls", "String[]", ObjectModelJavaModifier.PUBLIC);
addAnnotation(entityEnum,op,Override.class);
setOperationBody(op, ""
+"\n"
+" return notNulls;\n"
+" "
);
// isUseNotNulls method
op = addOperation(entityEnum, "isUseNotNulls", "boolean", ObjectModelJavaModifier.PUBLIC);
addAnnotation(entityEnum,op,Override.class);
setOperationBody(op, ""
+"\n"
+" return notNulls.length > 0;\n"
+" "
);
// getImplementationFQN method
op = addOperation(entityEnum, "getImplementationFQN","String",ObjectModelJavaModifier.PUBLIC);
addAnnotation(entityEnum, op, Override.class);
setOperationBody(op, ""
+"\n"
+" return implementationFQN;\n"
+" "
);
// setImplementationFQN method
op = addOperation(entityEnum, "setImplementationFQN","void",ObjectModelJavaModifier.PUBLIC);
addAnnotation(entityEnum,op,Override.class);
addParameter(op,"String","implementationFQN");
if (generateOperator) {
setOperationBody(op, ""
+"\n"
+" this.implementationFQN = implementationFQN;\n"
+" implementation = null;\n"
+" // reinit the operators store\n"
+" EntityOperatorStore.clear();\n"
+" "
);
} else {
setOperationBody(op, ""
+"\n"
+" this.implementationFQN = implementationFQN;\n"
+" this.implementation = null;\n"
+" "
);
}
// accept method
op = addOperation(entityEnum, "accept","boolean",ObjectModelJavaModifier.PUBLIC);
addAnnotation(entityEnum,op,Override.class);
addParameter(op,"Class extends TopiaEntity>","klass");
setOperationBody(op, ""
+"\n"
+" "+entityEnumName+" constant = valueOf(klass);\n"
+" boolean result = constant.getContract() == contract;\n"
+" return result;\n"
+" "
);
// getImplementation method
op = addOperation(entityEnum, "getImplementation","Class extends TopiaEntity>",
ObjectModelJavaModifier.PUBLIC);
addAnnotation(entityEnum,op,Override.class);
addImport(entityEnum, TopiaException.class);
setOperationBody(op, ""
+"\n"
+" if (implementation == null) {\n"
+" try {\n"
+" implementation = (Class extends TopiaEntity>) Class.forName(implementationFQN);\n"
+" } catch (ClassNotFoundException e) {\n"
+" throw new TopiaException(\"could not find class \" + implementationFQN, e);\n"
+" }\n"
+" }\n"
+" return implementation;\n"
+" "
);
// valueOf method
op = addOperation(entityEnum, "valueOf", entityEnumName,
ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC);
addParameter(op,"TopiaEntity", "entity");
setOperationBody(op, ""
+"\n"
+" return valueOf(entity.getClass());\n"
+" "
);
// valueOf method
op = addOperation(entityEnum, "valueOf", entityEnumName,
ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC);
addParameter(op, "final Class>", "klass");
addImport(entityEnum, Sets.class);
addImport(entityEnum, Set.class);
addImport(entityEnum, List.class);
addImport(entityEnum, ArrayList.class);
addImport(entityEnum, Predicate.class);
addImport(entityEnum, Iterables.class);
addImport(entityEnum, Iterable.class);
addImport(entityEnum, TopiaEntityHelper.class);
setOperationBody(op, ""
+"\n"
+" if (klass.isInterface()) {\n"
+" return valueOf(klass.getSimpleName());\n"
+" }\n"
+"\n"
+" Class> contractClass = TopiaEntityHelper.getContractClass("+entityEnumName+".values(), (Class) klass);\n"
+"\n"
+" if (contractClass != null) {\n"
+"\n"
+" return valueOf(contractClass.getSimpleName());\n"
+" }\n"
+"\n"
+" throw new IllegalArgumentException(\"no entity defined for the class \" + klass + \" in : \" + Arrays.toString("+entityEnumName+".values()));\n"
+" "
);
// getContracts method
op = addOperation(entityEnum, "getContracts", entityEnumName + "[]",
ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC);
setOperationBody(op, ""
+"\n"
+" "+entityEnumName+"[] result = values();\n"
+" return result;\n"
+" "
);
// getContractClass method
op = addOperation(entityEnum, "getContractClass", " Class",
ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC);
addParameter(op,"Class", "klass");
setOperationBody(op, ""
+"\n"
+" "+entityEnumName+" constant = valueOf(klass);\n"
+" Class result = (Class) constant.getContract();\n"
+" return result;\n"
+" "
);
// getContractClasses method
op = addOperation(entityEnum, "getContractClasses", "Class extends TopiaEntity>[]",
ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC);
setOperationBody(op, ""
+"\n"
+" "+entityEnumName+"[] values = values();\n"
+" Class extends TopiaEntity>[] result = (Class extends TopiaEntity>[]) Array.newInstance(Class.class, values.length);\n"
+" for (int i = 0; i < values.length; i++) {\n"
+" result[i] = values[i].getContract();\n"
+" }\n"
+" return result;\n"
+" "
);
// getContractClasses method
op = addOperation(entityEnum, "getImplementationClass", " Class",
ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC);
addParameter(op,"Class", "klass");
setOperationBody(op, ""
+"\n"
+" "+entityEnumName+" constant = valueOf(klass);\n"
+" Class result = (Class) constant.getImplementation();\n"
+" return result;\n"
+" "
);
addImport(entityEnum, LinkedHashSet.class);
// getImplementationClasses method
op = addOperation(entityEnum, "getImplementationClasses", "Set>",
ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC);
setOperationBody(op, ""
+"\n"
+" "+entityEnumName+"[] values = values();\n"
+" Set> result = new LinkedHashSet>();\n"
+" for (int i = 0; i < values.length; i++) {\n"
+" result.add(values[i].getImplementation());\n"
+" }\n"
+" return result;\n"
+" "
);
// getImplementationClassesAsString method
op = addOperation(entityEnum, "getImplementationClassesAsString", "String",
ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC);
setOperationBody(op, ""
+"\n"
+" StringBuilder buffer = new StringBuilder();\n"
+" for (Class extends TopiaEntity> aClass : getImplementationClasses()) {\n"
+" buffer.append(',').append(aClass.getName());\n"
+" }\n"
+" String result = buffer.substring(1);\n"
+" return result;\n"
+" "
);
if (generateOperator) {
// getOperator method
op = addOperation(entityEnum, "getOperator", " EntityOperator",
ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC);
addParameter(op,"Class", "klass");
setOperationBody(op, ""
+"\n"
+" "+entityEnumName+" constant = valueOf(klass);\n"
+" EntityOperator result = EntityOperatorStore.getOperator(constant);\n"
+" return result;\n"
+" "
);
}
}
}