All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.ird.observe.toolkit.eugene.templates.dto.DtoTransformer Maven / Gradle / Ivy

The newest version!
package fr.ird.observe.toolkit.eugene.templates.dto;

/*-
 * #%L
 * ObServe Toolkit :: Eugene Templates
 * %%
 * Copyright (C) 2008 - 2017 IRD, Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU 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 Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * .
 * #L%
 */




import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import fr.ird.observe.binder.DtoReferenceBinder;
import fr.ird.observe.dto.IdHelper;
import fr.ird.observe.dto.form.FormDefinition;
import fr.ird.observe.dto.reference.DataDtoReferenceDefinition;
import fr.ird.observe.dto.reference.ReferentialDtoReferenceDefinition;
import fr.ird.observe.spi.dto.DtoModuleHelper;
import fr.ird.observe.toolkit.eugene.templates.DtoHelper;
import fr.ird.observe.toolkit.eugene.templates.DtoModel;
import fr.ird.observe.toolkit.eugene.templates.DtoTransformerContext;
import fr.ird.observe.toolkit.eugene.templates.ToolkitTagValues;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.nuiton.eugene.EugeneCoreTagValues;
import org.nuiton.eugene.GeneratorUtil;
import org.nuiton.eugene.java.BeanTransformerTagValues;
import org.nuiton.eugene.java.EugeneJavaTagValues;
import org.nuiton.eugene.java.JavaGeneratorUtil;
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.ObjectModelClassifier;
import org.nuiton.eugene.models.object.ObjectModelInterface;
import org.nuiton.eugene.models.object.ObjectModelJavaModifier;
import org.nuiton.eugene.models.object.ObjectModelOperation;
import org.nuiton.eugene.models.object.ObjectModelPackage;
import org.nuiton.util.beans.Binder;
import org.nuiton.util.beans.BinderFactory;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Generates a bean and a helper class around it.
 * 

* Generates also a model initializer contract which permits you to interact with all selectedClasses of your model. *

* For example: *

 *     GeneratedBoat
 *     Boat (extends GeneratedBoat)
 *     GeneratedBoatHelper
 *     BoatHelper (extends AbstractBoats)
 * 
* * @author Tony Chemit - [email protected] * @plexus.component role="org.nuiton.eugene.Template" role-hint="fr.ird.observe.toolkit.eugene.templates.dto.DtoTransformer" * @since 3.0 */ public class DtoTransformer extends ObjectModelTransformerToJava { private DtoModel dtoModel; @Override public void transformFromModel(ObjectModel model) { super.transformFromModel(model); dtoModel = new DtoModel( new EugeneCoreTagValues(), new EugeneJavaTagValues(), new BeanTransformerTagValues(), new ToolkitTagValues(), getLog(), model, getDefaultPackageName()); DtoTransformerContext context = dtoModel.context; context.report(); String defaultPackageName = getDefaultPackageName(); String modelBeanInitializeClassName = model.getName() + "ModelInitializer"; boolean generateModelInitializer = !getResourcesHelper().isJavaFileInClassPath(defaultPackageName + "." + modelBeanInitializeClassName); if (generateModelInitializer) { ObjectModelInterface anInterface = createInterface(modelBeanInitializeClassName, defaultPackageName); addOperation(anInterface, "start", "void"); addOperation(anInterface, "end", "void"); for (String fqn : context.selectedClassesFqn) { ObjectModelClass beanClass = context.selectedClassesByFqn.get(fqn); if (skipForInitializer(getModel().getPackage(beanClass), beanClass)) { continue; } String beanName = context.classesNameTranslation.get(beanClass); addImport(anInterface, beanName); addOperation(anInterface, "init" + beanName, "void"); } } String modelInitializerRunnerClassName = model.getName() + "ModelInitializerRunner"; boolean generateInitializerRunnerClassName = !getResourcesHelper().isJavaFileInClassPath(defaultPackageName + "." + modelInitializerRunnerClassName); if (generateInitializerRunnerClassName) { ObjectModelClass aClass = createClass(modelInitializerRunnerClassName, defaultPackageName); StringBuilder bodyBuilder = new StringBuilder(); bodyBuilder.append("" +"\n" +" initializer.start();" ); for (String fqn : context.selectedClassesFqn) { ObjectModelClass beanClass = context.selectedClassesByFqn.get(fqn); if (skipForInitializer(getModel().getPackage(beanClass), beanClass)) { continue; } String beanName = context.classesNameTranslation.get(beanClass); addImport(aClass, beanName); bodyBuilder.append("" +"\n" +" initializer.init"+beanName+"();" ); } bodyBuilder.append("" +"\n" +" initializer.end();" ); ObjectModelOperation operation = addOperation(aClass, "init", "void", ObjectModelJavaModifier.STATIC); addParameter(operation, modelBeanInitializeClassName, "initializer"); setOperationBody(operation, bodyBuilder.toString()); } } private static boolean skipForInitializer(ObjectModelPackage aPackage, ObjectModelClass beanClass) { return beanClass.isAbstract() || EugeneCoreTagValues.isSkip(beanClass, aPackage); } @Override public void transformFromClass(ObjectModelClass input) { ObjectModelPackage aPackage = getPackage(input); DtoTransformerContext context = dtoModel.context; if (context.selectedClasses.contains(input)) { if (EugeneCoreTagValues.isSkip(input, aPackage)) { return; } String prefix = getConstantPrefix(input); setConstantPrefix(prefix); String className = context.classesNameTranslation.get(input); String generatedClassName = "Generated" + className; boolean generateClass = notFoundInClassPath(input, className); if (generateClass) { generateClass(input, className, generatedClassName); } boolean generateGeneratedClass = canGenerateAbstractClass(input, generatedClassName); if (generateGeneratedClass) { generateGeneratedClass(aPackage, input, generatedClassName, className); } boolean generateHelper = dtoModel.helpers.contains(input); if (generateHelper) { String helperClassName = dtoModel.helpersNameTranslation.get(input); String generatedHelperClassName = "Generated" + helperClassName; if (notFoundInClassPath(input, helperClassName)) { generateHelper(input, generatedHelperClassName, helperClassName); } if (canGenerateAbstractClass(input, generatedHelperClassName)) { generateGeneratedHelper(aPackage, input, className, generatedHelperClassName); } } } } private void generateClass(ObjectModelClass input, String className, String abstractClassName) { ObjectModelClass output; if (input.isAbstract()) { output = createAbstractClass(className, input.getPackageName()); } else { output = createClass(className, input.getPackageName()); } setSuperClass(output, abstractClassName); getLog().debug("will generate " + output.getQualifiedName()); addSerializable(input, output, true); } private void generateGeneratedClass(ObjectModelPackage aPackage, ObjectModelClass input, String generatedClassName, String dtoType) { String superClass = null; // test if a super class has bean stereotype boolean superClassIsBean = false; Collection superclasses = input.getSuperclasses(); if (CollectionUtils.isNotEmpty(superclasses)) { for (ObjectModelClass superclass : superclasses) { superClassIsBean = dtoModel.context.selectedClasses.contains(superclass); if (superClassIsBean) { superClass = superclass.getPackageName() + "." + dtoModel.context.classesNameTranslation.get(superclass); break; } superClass = superclass.getQualifiedName(); } } if (!superClassIsBean) { // try to find a super class by tag-value superClass = dtoModel.beanTagValues.getSuperClassTagValue(input, aPackage, model); if (superClass != null) { // will act as if super class is a bean superClassIsBean = true; } } ObjectModelClass output; output = createAbstractClass(generatedClassName, input.getPackageName()); if (superClass != null) { setSuperClass(output, superClass); } getLog().debug("will generate " + output.getQualifiedName()); addInterfaces(input, output, null); generateI18nBlockAndConstants(aPackage, input, output); if (!input.isAbstract()) { addGetterProducerInterface(output, dtoType, true); addSetterProducerInterface(output, dtoType, true); addGetterProducerMethods(output, dtoType, true, "definition().getDtoGetters()"); addSetterProducerMethods(output, dtoType, true, "definition().getDtoSetters()"); String dtoDefinitionType = input.getName() + "DtoDefinition"; addAttribute(output, "DEFINITION", dtoDefinitionType, null, ObjectModelJavaModifier.PRIVATE, ObjectModelJavaModifier.STATIC); addImport(output, DtoModuleHelper.class); String dtoTypeSimpleName = GeneratorUtil.getSimpleName(dtoType); ObjectModelOperation definitionMethod = addOperation(output, "definition", dtoDefinitionType, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC, ObjectModelJavaModifier.FINAL); setOperationBody(definitionMethod, ""+"\n" +" if (DEFINITION == null) {\n" +" DEFINITION = ("+dtoDefinitionType+") DtoModuleHelper.get().getDefinition("+dtoTypeSimpleName+".class);\n" +" }\n" +" return DEFINITION;\n" +" "); boolean withReference = dtoModel.referenceContext.selectedClasses.contains(input); if (withReference) { addReferenceMethods(input, output); } boolean withForm = dtoModel.formContext.selectedClasses.contains(input); if (withForm) { addFormDefinitionMethod(output, dtoType); } } // Get available properties List properties = getProperties(input); boolean usePCS = dtoModel.beanTagValues.isGeneratePropertyChangeSupport(input, aPackage, model); boolean generateBooleanGetMethods = dtoModel.eugeneTagValues.isGenerateBooleanGetMethods(input, aPackage, model); boolean generateNotEmptyCollections = dtoModel.beanTagValues.isGenerateNotEmptyCollections(input, aPackage, model); // Add properties field + javabean methods for (ObjectModelAttribute attr : properties) { createProperty(output, attr, usePCS, generateBooleanGetMethods, generateNotEmptyCollections); } if (!superClassIsBean) { addDefaultMethodForNoneBeanSuperClass(output, usePCS, properties); } } private void addReferenceMethods(ObjectModelClass input, ObjectModelClass output) { ObjectModelPackage aPackage = getPackage(input); boolean referential = IdHelper.isReferentialFromPackageName(aPackage.getName()); String dtoType = dtoModel.context.classesNameTranslation.get(input); String fqn = input.getPackageName() + "." + dtoType; String referenceType = dtoType.replace("Dto", "Reference"); Class builderMethodName = referential ? ReferentialDtoReferenceDefinition.class : DataDtoReferenceDefinition.class; addImport(output, builderMethodName); String definitionType = String.format("%s<%s, %s>", builderMethodName.getName(), dtoType, referenceType); ObjectModelOperation referenceDefinition = addOperation(output, "referenceDefinition", definitionType, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC, ObjectModelJavaModifier.FINAL); setOperationBody(referenceDefinition, ""+"\n" +" return definition().toReferenceDefinition();\n" +" "); String binderPackageName = DtoReferenceBinder.class.getPackage().getName(); String binderFieldType = DtoHelper.generateBinderName(dtoModel.context.defaultPackage.getName().length(), binderPackageName, fqn, dtoType + "Reference", referential); addImport(output, binderFieldType); binderFieldType = JavaGeneratorUtil.getSimpleName(binderFieldType); ObjectModelOperation referenceBinder = addOperation(output, "referenceBinder", binderFieldType, ObjectModelJavaModifier.PUBLIC, ObjectModelJavaModifier.STATIC, ObjectModelJavaModifier.FINAL); setOperationBody(referenceBinder, ""+"\n" +" return definition().toReferenceBinder();\n" +" "); } private void addFormDefinitionMethod(ObjectModelClass output, String dtoType) { addImport(output, FormDefinition.class); String formDefinitionFieldType = String.format("FormDefinition<%s>", dtoType); ObjectModelOperation formDefinition = addOperation(output, "formDefinition", formDefinitionFieldType, ObjectModelJavaModifier.STATIC, ObjectModelJavaModifier.FINAL, ObjectModelJavaModifier.PUBLIC); setOperationBody(formDefinition, ""+"\n" +" return definition().formDefinition();\n" +" "); } private void generateHelper(ObjectModelClass aClass, String abstractClassName, String defaultClassName) { String packageName = aClass.getPackageName(); ObjectModelClass output = createClass(defaultClassName, packageName); setSuperClass(output, packageName + "." + abstractClassName); getLog().debug("will generate " + output.getQualifiedName()); } private void generateGeneratedHelper(ObjectModelPackage aPackage, ObjectModelClass aClass, String typeName, String abstractClassName) { ObjectModelClass output = createAbstractClass(abstractClassName, aPackage.getName()); String superClassName = getGeneratedHelperSuperClassName(aPackage, aClass); if (StringUtils.isNotBlank(superClassName)) { setSuperClass(output, superClassName); } getLog().debug("will generate " + output.getQualifiedName()); addImport(output, Binder.class); addImport(output, BinderFactory.class); ObjectModelOperation operation = addOperation( output, "typeOf" + typeName, " Class", ObjectModelJavaModifier.STATIC, ObjectModelJavaModifier.PUBLIC ); setOperationBody(operation, "" +"\n" +" return (Class) "+typeName+".class;\n" +" " ); boolean generateConstructors = dtoModel.beanTagValues.isGenerateHelperConstructors(aClass, aPackage, model) && !aClass.isAbstract(); if (generateConstructors) { generateGeneratedHelperConstructors(output, typeName); } generateGeneratedHelperCopyMethods(output, typeName); boolean generatePredicates = dtoModel.beanTagValues.isGenerateHelperPredicates(aClass, aPackage, model); if (generatePredicates) { generateGeneratedHelperPredicates(aClass, output, typeName); } boolean generateFunctions = dtoModel.beanTagValues.isGenerateHelperFunctions(aClass, aPackage, model); if (generateFunctions) { generateGeneratedHelperFunctions(aClass, output, typeName); } } private void generateGeneratedHelperConstructors(ObjectModelClass output, String typeName) { ObjectModelOperation operation = addOperation( output, "new" + typeName, typeName, ObjectModelJavaModifier.STATIC, ObjectModelJavaModifier.PUBLIC ); setOperationBody(operation, "" +"\n" +" return new "+typeName+"();\n" +" " ); operation = addOperation( output, "new" + typeName, " BeanType", ObjectModelJavaModifier.STATIC, ObjectModelJavaModifier.PUBLIC ); addParameter(operation, "BeanType", "source"); setOperationBody(operation, "" +"\n" +" Class sourceType = typeOf"+typeName+"();\n" +" Binder binder = BinderFactory.newBinder(sourceType);\n" +" BeanType result = new"+typeName+"(source, binder);\n" +" return result;\n" +" " ); operation = addOperation( output, "new" + typeName, " BeanType", ObjectModelJavaModifier.STATIC, ObjectModelJavaModifier.PUBLIC ); addParameter(operation, "BeanType", "source"); addParameter(operation, "Binder", "binder"); setOperationBody(operation, "" +"\n" +" BeanType result = (BeanType) new"+typeName+"();\n" +" binder.copy(source, result);\n" +" return result;\n" +" " ); } private void generateGeneratedHelperCopyMethods(ObjectModelClass output, String typeName) { ObjectModelOperation operation = addOperation( output, "copy" + typeName, " void", ObjectModelJavaModifier.STATIC, ObjectModelJavaModifier.PUBLIC ); addParameter(operation, "BeanType", "source"); addParameter(operation, "BeanType", "target"); setOperationBody(operation, "" +"\n" +" Class sourceType = typeOf"+typeName+"();\n" +" Binder binder = BinderFactory.newBinder(sourceType);\n" +" binder.copy(source, target);\n" +" " ); operation = addOperation( output, "copy" + typeName, " void", ObjectModelJavaModifier.STATIC, ObjectModelJavaModifier.PUBLIC ); addParameter(operation, "BeanType", "source"); addParameter(operation, "BeanType", "target"); addParameter(operation, "Binder", "binder"); setOperationBody(operation, "" +"\n" +" binder.copy(source, target);\n" +" " ); } private void generateGeneratedHelperPredicates(ObjectModelClass input, ObjectModelClass output, String typeName) { boolean atLeastOnePropertyFound = false; for (ObjectModelAttribute attribute : getProperties(input)) { boolean multiple = JavaGeneratorUtil.isNMultiplicity(attribute); if (multiple) { continue; } atLeastOnePropertyFound = true; String attrName = getAttributeName(attribute); String attrType = getAttributeTypeWithGeneric(attribute); addImport(output, attrType); String simpleType = JavaGeneratorUtil.getSimpleName(attrType); String capitalizeAttrName = JavaGeneratorUtil.capitalizeJavaBeanPropertyName(attrName); String newPreficateMethodName = "new" + capitalizeAttrName + "Predicate"; ObjectModelOperation operation; operation = addOperation( output, newPreficateMethodName, " Predicate", ObjectModelJavaModifier.STATIC, ObjectModelJavaModifier.PUBLIC ); addParameter(operation, simpleType, attrName); String getterName = getGetterName(attribute, attrName); if (dtoModel.context.useJava8) { setOperationBody(operation, "" +"\n" +" return o -> Objects.equals("+attrName+", o."+getterName+"());\n" +"\n" +" " ); } else { setOperationBody(operation, "" +"\n" +" final "+simpleType+" $tmp = "+attrName+";\n" +" return new Predicate() {\n" +"\n" +" @Override\n" +" public boolean apply(BeanType input) {\n" +" return Objects.equal($tmp, input."+getterName+"());\n" +" }\n" +" };\n" +"\n" +" " ); } operation = addOperation( output, "filterBy" + capitalizeAttrName, " List", ObjectModelJavaModifier.STATIC, ObjectModelJavaModifier.PUBLIC ); addParameter(operation, "Collection", "$source"); addParameter(operation, simpleType, attrName); if (dtoModel.context.useJava8) { setOperationBody(operation, "" +"\n" +" return $source.stream().filter("+newPreficateMethodName+"("+attrName+")).collect(Collectors.toList());\n" +" " ); } else { addImport(output, Collection.class); addImport(output, List.class); addImport(output, Lists.class); setOperationBody(operation, "" +"\n" +" return Lists.newArrayList(Iterables.filter($source, "+newPreficateMethodName+"("+attrName+")));\n" +" " ); } } if (atLeastOnePropertyFound) { if (dtoModel.context.useJava8) { addImport(output, Collection.class); addImport(output, List.class); addImport(output, "java.util.Objects"); addImport(output, "java.util.function.Predicate"); addImport(output, "java.util.stream.Collectors"); } else { addImport(output, com.google.common.base.Objects.class); addImport(output, com.google.common.base.Predicate.class); addImport(output, com.google.common.collect.Iterables.class); } addImport(output, Iterable.class); } } private void generateGeneratedHelperFunctions(ObjectModelClass input, ObjectModelClass output, String typeName) { boolean atLeastOnePropertyFound = false; boolean useJava8 = dtoModel.context.useJava8; for (ObjectModelAttribute attribute : getProperties(input)) { boolean multiple = JavaGeneratorUtil.isNMultiplicity(attribute); if (multiple) { continue; } atLeastOnePropertyFound = true; String attrName = getAttributeName(attribute); String attrType = getAttributeTypeWithGeneric(attribute); addImport(output, attrType); String simpleType = JavaGeneratorUtil.getSimpleName(attrType); simpleType = wrapPrimitiveType(simpleType); String capitalizeAttrName = JavaGeneratorUtil.capitalizeJavaBeanPropertyName(attrName); String getterName = getGetterName(attribute, attrName); String newFunctionMethodName = "new" + capitalizeAttrName + "Function"; String getFunctionMethodName = "get" + capitalizeAttrName + "Function"; String functionTypeName = "Function"; String functionFieldName = JavaGeneratorUtil.convertVariableNameToConstantName(capitalizeAttrName + "Function"); addAttribute( output, functionFieldName, "Function<" + typeName + ", " + simpleType + ">", useJava8 ? typeName + "::" + getterName : newFunctionMethodName + "()", ObjectModelJavaModifier.FINAL, ObjectModelJavaModifier.STATIC, useJava8 ? ObjectModelJavaModifier.PUBLIC : ObjectModelJavaModifier.PROTECTED ); if (!useJava8) { ObjectModelOperation operation = addOperation( output, getFunctionMethodName, " " + functionTypeName, ObjectModelJavaModifier.STATIC, ObjectModelJavaModifier.PUBLIC ); setOperationBody(operation, "" +"\n" +" return ("+functionTypeName+") "+functionFieldName+";\n" +"\n" +" " ); operation = addOperation( output, newFunctionMethodName, " " + functionTypeName, ObjectModelJavaModifier.STATIC, ObjectModelJavaModifier.PUBLIC ); setOperationBody(operation, "" +"\n" +" return new "+functionTypeName+"() {\n" +"\n" +" @Override\n" +" public "+simpleType+" apply(BeanType input) {\n" +" return input."+getterName+"();\n" +" }\n" +" };\n" +"\n" +"" ); } ObjectModelOperation operation = addOperation( output, "uniqueIndexBy" + capitalizeAttrName, " ImmutableMap<" + simpleType + ", BeanType>", ObjectModelJavaModifier.STATIC, ObjectModelJavaModifier.PUBLIC ); addParameter(operation, "Iterable", "$source"); if (useJava8) { setOperationBody(operation, "" +"\n" +" return Maps.uniqueIndex($source, "+functionFieldName+"::apply);\n" +" " ); } else { setOperationBody(operation, "" +"\n" +" return Maps.uniqueIndex($source, "+functionFieldName+");\n" +" " ); } } if (atLeastOnePropertyFound) { if (useJava8) { addImport(output, "java.util.function.Function"); addImport(output, "java.util.Objects"); } else { addImport(output, Function.class); addImport(output, com.google.common.collect.Iterables.class); addImport(output, com.google.common.base.Objects.class); } addImport(output, ImmutableMap.class); addImport(output, Iterable.class); addImport(output, Maps.class); } } private String getGeneratedHelperSuperClassName(ObjectModelPackage aPackage, ObjectModelClass aClass) { String superClassName = null; // test if a super class has bean stereotype boolean superClassIsBean = false; Collection superclasses = aClass.getSuperclasses(); if (CollectionUtils.isNotEmpty(superclasses)) { for (ObjectModelClass superclass : superclasses) { superClassIsBean = dtoModel.helpers.contains(superclass); if (superClassIsBean) { superClassName = superclass.getPackageName() + "." + dtoModel.helpersNameTranslation.get(superclass); break; } superClassName = superclass.getQualifiedName(); } } if (!superClassIsBean) { // try to find a super class by tag-value superClassName = dtoModel.beanTagValues.getHelperSuperClassTagValue(aClass, aPackage, model); } return superClassName; } private boolean notFoundInClassPath(ObjectModelClass input, String className) { String fqn = input.getPackageName() + "." + className; boolean inClassPath = getResourcesHelper().isJavaFileInClassPath(fqn); return !inClassPath; } protected String getPropertyType(ObjectModelClass output, ObjectModelAttribute attr) { boolean multiple = JavaGeneratorUtil.isNMultiplicity(attr); String attrType = getAttributeTypeWithGeneric(attr); if (multiple) { attrType = JavaGeneratorUtil.getAttributeInterfaceType(attr, getAttributeTypeWithGeneric(attr), true); } addImport(output, attrType); return JavaGeneratorUtil.getSimpleName(attrType); } private void createProperty(ObjectModelClass output, ObjectModelAttribute attr, boolean usePCS, boolean generateBooleanGetMethods, boolean generateNotEmptyCollections) { String attrName = getAttributeName(attr); String attrType = getAttributeTypeWithGeneric(attr); boolean multiple = JavaGeneratorUtil.isNMultiplicity(attr); String constantName = getConstantName(attrName); String simpleType = JavaGeneratorUtil.getSimpleName(attrType); if (multiple) { createGetChildMethod(output, attrName, attrType, simpleType); createIsEmptyMethod(output, attrName); createSizeMethod(output, attrName); createAddChildMethod(output, attrName, attrType, constantName, usePCS); createAddAllChildrenMethod(output, attrName, attrType, constantName, usePCS); createRemoveChildMethod(output, attrName, attrType, constantName, usePCS); createRemoveAllChildrenMethod(output, attrName, attrType, constantName, usePCS); createContainsChildMethod(output, attrName, attrType, constantName, usePCS); createContainsAllChildrenMethod(output, attrName, attrType, constantName); // Change type for Multiple attribute attrType = JavaGeneratorUtil.getAttributeInterfaceType(attr, getAttributeTypeWithGeneric(attr), true); simpleType = JavaGeneratorUtil.getSimpleName(attrType); } boolean booleanProperty = JavaGeneratorUtil.isBooleanPrimitive(attr); if (multiple) { String collectionImplementationType = JavaGeneratorUtil.getAttributeImplementationType(attr, getAttributeTypeWithGeneric(attr), true); // creates a getXXX (multiple) method createGetMethod(output, attrName, attrType, JavaGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX, generateNotEmptyCollections, collectionImplementationType ); } else { if (booleanProperty) { // creates a isXXX method createGetMethod(output, attrName, attrType, JavaGeneratorUtil.OPERATION_GETTER_BOOLEAN_PREFIX); } if (!booleanProperty || generateBooleanGetMethods) { // creates a getXXX method createGetMethod(output, attrName, attrType, JavaGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX); } } createSetMethod(output, attrName, attrType, simpleType, constantName, usePCS); // Add attribute to the class addAttribute(output, attrName, attrType, "", ObjectModelJavaModifier.PROTECTED); } private List getProperties(ObjectModelClass input) { List attributes = (List) input.getAttributes(); List attrs = new ArrayList<>(); for (ObjectModelAttribute attr : attributes) { if (attr.isNavigable()) { // only keep navigable attributes attrs.add(attr); } } return attrs; } private List getAllProperties(ObjectModelClass input) { List attributes = (List) input.getAllOtherAttributes(); List result = new ArrayList<>(); for (ObjectModelAttribute attr : attributes) { if (attr.isNavigable()) { // only keep navigable attributes result.add(attr); } } result.addAll(getProperties(input)); return result; } private void createGetMethod(ObjectModelClass output, String attrName, String attrType, String methodPrefix, boolean generateLayzCode, String collectionImplementationType) { ObjectModelOperation operation = addOperation( output, getJavaBeanMethodName(methodPrefix, attrName), attrType, ObjectModelJavaModifier.PUBLIC ); if (generateLayzCode) { addImport(output, collectionImplementationType); String implementationSimpleType = JavaGeneratorUtil.getSimpleName(collectionImplementationType); setOperationBody(operation, "" +"\n" +" if ("+attrName+" == null) {\n" +" "+attrName+" = new "+implementationSimpleType+"();\n" +" }\n" +" return "+attrName+";\n" +"" ); } else { setOperationBody(operation, "" +"\n" +" return "+attrName+";\n" +"" ); } } private void createGetMethod(ObjectModelClass output, String attrName, String attrType, String methodPrefix) { ObjectModelOperation operation = addOperation( output, getJavaBeanMethodName(methodPrefix, attrName), attrType, ObjectModelJavaModifier.PUBLIC ); setOperationBody(operation, "" +"\n" +" return "+attrName+";\n" +" " ); } private void createGetChildMethod(ObjectModelClass output, String attrName, String attrType, String simpleType) { ObjectModelOperation operation = addOperation( output, getJavaBeanMethodName("get", attrName), attrType, ObjectModelJavaModifier.PUBLIC ); addParameter(operation, "int", "index"); setOperationBody(operation, "" +"\n" +" "+simpleType+" o = getChild("+attrName+", index);\n" +" return o;\n" +" " ); } private void createIsEmptyMethod(ObjectModelClass output, String attrName) { ObjectModelOperation operation = addOperation( output, getJavaBeanMethodName("is", attrName) + "Empty", boolean.class, ObjectModelJavaModifier.PUBLIC ); setOperationBody(operation, "" +"\n" +" return "+attrName+" == null || "+attrName+".isEmpty();\n" +" " ); } private void createSizeMethod(ObjectModelClass output, String attrName) { ObjectModelOperation operation = addOperation( output, getJavaBeanMethodName("size", attrName), int.class, ObjectModelJavaModifier.PUBLIC ); setOperationBody(operation, "" +"\n" +" return "+attrName+" == null ? 0 : "+attrName+".size();\n" +" " ); } private void createAddChildMethod(ObjectModelClass output, String attrName, String attrType, String constantName, boolean usePCS) { ObjectModelOperation operation = addOperation( output, getJavaBeanMethodName("add", attrName), "void", ObjectModelJavaModifier.PUBLIC ); addParameter(operation, attrType, attrName); String methodName = getJavaBeanMethodName("get", attrName); StringBuilder buffer = new StringBuilder("" +"\n" +" "+methodName+"().add("+attrName+");\n" +" " ); if (usePCS) { buffer.append("" +" firePropertyChange("+constantName+", null, "+attrName+");\n" +" " ); } setOperationBody(operation, buffer.toString()); } private void createAddAllChildrenMethod(ObjectModelClass output, String attrName, String attrType, String constantName, boolean usePCS) { ObjectModelOperation operation = addOperation( output, getJavaBeanMethodName("addAll", attrName), "void", ObjectModelJavaModifier.PUBLIC ); addParameter(operation, "java.util.Collection<" + attrType + ">", attrName); String methodName = getJavaBeanMethodName("get", attrName); StringBuilder buffer = new StringBuilder("" +"\n" +" "+methodName+"().addAll("+attrName+");\n" +" " ); if (usePCS) { buffer.append("" +" firePropertyChange("+constantName+", null, "+attrName+");\n" +" " ); } setOperationBody(operation, buffer.toString()); } private void createRemoveChildMethod(ObjectModelClass output, String attrName, String attrType, String constantName, boolean usePCS) { ObjectModelOperation operation = addOperation( output, getJavaBeanMethodName("remove", attrName), "boolean", ObjectModelJavaModifier.PUBLIC ); addParameter(operation, attrType, attrName); String methodName = getJavaBeanMethodName("get", attrName); StringBuilder buffer = new StringBuilder(); buffer.append("" +"\n" +" boolean removed = "+methodName+"().remove("+attrName+");" ); if (usePCS) { buffer.append("" +"\n" +" if (removed) {\n" +" firePropertyChange("+constantName+", "+attrName+", null);\n" +" }" ); } buffer.append("" +"\n" +" return removed;\n" +" " ); setOperationBody(operation, buffer.toString()); } private void createRemoveAllChildrenMethod(ObjectModelClass output, String attrName, String attrType, String constantName, boolean usePCS) { ObjectModelOperation operation = addOperation( output, getJavaBeanMethodName("removeAll", attrName), "boolean", ObjectModelJavaModifier.PUBLIC ); addParameter(operation, "java.util.Collection<" + attrType + ">", attrName); StringBuilder buffer = new StringBuilder(); String methodName = getJavaBeanMethodName("get", attrName); buffer.append("" +"\n" +" boolean removed = "+methodName+"().removeAll("+attrName+");" ); if (usePCS) { buffer.append("" +"\n" +" if (removed) {\n" +" firePropertyChange("+constantName+", "+attrName+", null);\n" +" }" ); } buffer.append("" +"\n" +" return removed;\n" +" " ); setOperationBody(operation, buffer.toString()); } private void createContainsChildMethod(ObjectModelClass output, String attrName, String attrType, String constantName, boolean usePCS) { ObjectModelOperation operation = addOperation( output, getJavaBeanMethodName("contains", attrName), "boolean", ObjectModelJavaModifier.PUBLIC ); addParameter(operation, attrType, attrName); StringBuilder buffer = new StringBuilder(); String methodName = getJavaBeanMethodName("get", attrName); buffer.append("" +"\n" +" boolean contains = "+methodName+"().contains("+attrName+");\n" +" return contains;\n" +" " ); setOperationBody(operation, buffer.toString()); } private void createContainsAllChildrenMethod(ObjectModelClass output, String attrName, String attrType, String constantName) { ObjectModelOperation operation = addOperation( output, getJavaBeanMethodName("containsAll", attrName), "boolean", ObjectModelJavaModifier.PUBLIC ); addParameter(operation, "java.util.Collection<" + attrType + ">", attrName); StringBuilder buffer = new StringBuilder(); String methodName = getJavaBeanMethodName("get", attrName); buffer.append("" +"\n" +" boolean contains = "+methodName+"().containsAll("+attrName+");\n" +" return contains;\n" +" " ); setOperationBody(operation, buffer.toString()); } private void createSetMethod(ObjectModelClass output, String attrName, String attrType, String simpleType, String constantName, boolean usePCS) { boolean booleanProperty = GeneratorUtil.isBooleanPrimitive(simpleType); ObjectModelOperation operation = addOperation( output, getJavaBeanMethodName("set", attrName), "void", ObjectModelJavaModifier.PUBLIC ); addParameter(operation, attrType, attrName); if (usePCS) { String methodPrefix = JavaGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX; if (booleanProperty) { methodPrefix = JavaGeneratorUtil.OPERATION_GETTER_BOOLEAN_PREFIX; } String methodName = getJavaBeanMethodName(methodPrefix, attrName); setOperationBody(operation, "" +"\n" +" "+simpleType+" oldValue = "+methodName+"();\n" +" this."+attrName+" = "+attrName+";\n" +" firePropertyChange("+constantName+", oldValue, "+attrName+");\n" +" " ); } else { setOperationBody(operation, "" +"\n" +" this."+attrName+" = "+attrName+";\n" +" " ); } } private void addSerializable(ObjectModelClass input, ObjectModelClass output, boolean interfaceFound) { if (!interfaceFound) { addInterface(output, Serializable.class); } // Generate the serialVersionUID long serialVersionUID = JavaGeneratorUtil.generateSerialVersionUID(input); addConstant(output, JavaGeneratorUtil.SERIAL_VERSION_UID, "long", serialVersionUID + "L", ObjectModelJavaModifier.PRIVATE); } /** * Add all interfaces defines in input class and returns if * {@link Serializable} interface was found. * * @param input the input model class to process * @param output the output generated class * @return {@code true} if {@link Serializable} was found from input, * {@code false} otherwise */ private boolean addInterfaces(ObjectModelClass input, ObjectModelClassifier output, String extraInterfaceName) { boolean foundSerializable = false; Set added = new HashSet<>(); for (ObjectModelInterface parentInterface : input.getInterfaces()) { String fqn = parentInterface.getQualifiedName(); added.add(fqn); addInterface(output, fqn); if (Serializable.class.getName().equals(fqn)) { foundSerializable = true; } } if (extraInterfaceName != null && !added.contains(extraInterfaceName)) { addInterface(output, extraInterfaceName); } return foundSerializable; } private void createPropertyChangeSupport(ObjectModelClass output) { addAttribute(output, "pcs", PropertyChangeSupport.class, "new PropertyChangeSupport(this)", ObjectModelJavaModifier.PROTECTED, ObjectModelJavaModifier.FINAL, ObjectModelJavaModifier.TRANSIENT ); // Add PropertyListener ObjectModelOperation operation; operation = addOperation(output, "addPropertyChangeListener", "void", ObjectModelJavaModifier.PUBLIC ); addParameter(operation, PropertyChangeListener.class, "listener"); setOperationBody(operation, "" +"\n" +" pcs.addPropertyChangeListener(listener);\n" +" " ); operation = addOperation(output, "addPropertyChangeListener", "void", ObjectModelJavaModifier.PUBLIC ); addParameter(operation, String.class, "propertyName"); addParameter(operation, PropertyChangeListener.class, "listener"); setOperationBody(operation, "" +"\n" +" pcs.addPropertyChangeListener(propertyName, listener);\n" +" " ); operation = addOperation(output, "removePropertyChangeListener", "void", ObjectModelJavaModifier.PUBLIC ); addParameter(operation, PropertyChangeListener.class, "listener"); setOperationBody(operation, "" +"\n" +" pcs.removePropertyChangeListener(listener);\n" +" " ); operation = addOperation(output, "removePropertyChangeListener", "void", ObjectModelJavaModifier.PUBLIC ); addParameter(operation, String.class, "propertyName"); addParameter(operation, PropertyChangeListener.class, "listener"); setOperationBody(operation, "" +"\n" +" pcs.removePropertyChangeListener(propertyName, listener);\n" +" " ); operation = addOperation(output, "firePropertyChange", "void", ObjectModelJavaModifier.PROTECTED ); addParameter(operation, String.class, "propertyName"); addParameter(operation, Object.class, "oldValue"); addParameter(operation, Object.class, "newValue"); setOperationBody(operation, "" +"\n" +" pcs.firePropertyChange(propertyName, oldValue, newValue);\n" +" " ); operation = addOperation(output, "firePropertyChange", "void", ObjectModelJavaModifier.PROTECTED ); addParameter(operation, String.class, "propertyName"); addParameter(operation, Object.class, "newValue"); setOperationBody(operation, "" +"\n" +" firePropertyChange(propertyName, null, newValue);\n" +" " ); } private void createGetChildMethod(ObjectModelClass output) { ObjectModelOperation getChild = addOperation( output, "getChild", " T", ObjectModelJavaModifier.PROTECTED ); addImport(output, List.class); addParameter(getChild, "java.util.Collection", "childs"); addParameter(getChild, "int", "index"); setOperationBody(getChild, "" +"\n" +" T result = null;\n" +" if (childs != null) {\n" +" if (childs instanceof List) {\n" +" if (index < childs.size()) {\n" +" result = ((List) childs).get(index);\n" +" }\n" +" } else {\n" +" int i = 0;\n" +" for (T o : childs) {\n" +" if (index == i) {\n" +" result = o;\n" +" break;\n" +" }\n" +" i++;\n" +" }\n" +" }\n" +" }\n" +" return result;\n" +"" ); } private void generateI18nBlockAndConstants(ObjectModelPackage aPackage, ObjectModelClass input, ObjectModelClassifier output) { String i18nPrefix = eugeneTagValues.getI18nPrefixTagValue(input, aPackage, model); if (!StringUtils.isEmpty(i18nPrefix)) { generateI18nBlock(input, output, i18nPrefix); } String prefix = getConstantPrefix(input); setConstantPrefix(prefix); Set constantNames = addConstantsFromDependency(input, output); // Add properties constant for (ObjectModelAttribute attr : getProperties(input)) { createPropertyConstant(output, attr, prefix, constantNames); } } private void addDefaultMethodForNoneBeanSuperClass(ObjectModelClass output, boolean usePCS, List properties) { if (usePCS) { // Add property change support createPropertyChangeSupport(output); } boolean hasAMultipleProperty = containsMultiple(properties); // Add helper operations if (hasAMultipleProperty) { // add getChild methods createGetChildMethod(output); } } private String wrapPrimitiveType(String attrType) { if (JavaGeneratorUtil.isPrimitiveType(attrType)) { attrType = JavaGeneratorUtil.getPrimitiveWrapType(attrType); } return attrType; } private String getGetterName(ObjectModelAttribute attribute, String attrName) { boolean booleanProperty = JavaGeneratorUtil.isBooleanPrimitive(attribute); String methodPrefix = JavaGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX; if (booleanProperty) { methodPrefix = JavaGeneratorUtil.OPERATION_GETTER_BOOLEAN_PREFIX; } return getJavaBeanMethodName(methodPrefix, attrName); } private boolean canGenerateAbstractClass(ObjectModelClass aClass, String abstractClassName) { boolean inClassPath = !notFoundInClassPath(aClass, abstractClassName); if (inClassPath) { throw new IllegalStateException(String.format("Can't generate %s, already found in class-path, this is a generated class, you should not ovveride it.\n\nPlease remove it from class path and use the %s class instead.", aClass.getPackageName() + "." + abstractClassName, aClass)); } return true; } private void createPropertyConstant(ObjectModelClassifier output, ObjectModelAttribute attr, String prefix, Set constantNames) { String attrName = getAttributeName(attr); String constantName = prefix + builder.getConstantName(attrName); if (!constantNames.contains(constantName)) { addConstant(output, constantName, String.class, "\"" + attrName + "\"", ObjectModelJavaModifier.PUBLIC ); } } private String getAttributeName(ObjectModelAttribute attr) { String attrName = attr.getName(); if (attr.hasAssociationClass()) { String assocAttrName = JavaGeneratorUtil.getAssocAttrName(attr); attrName = JavaGeneratorUtil.toLowerCaseFirstLetter(assocAttrName); } return attrName; } private String getAttributeTypeWithGeneric(ObjectModelAttribute attr) { String attrType = dtoModel.context.getAttributeType(attr); String generic = eugeneTagValues.getAttributeGenericTagValue(attr); if (generic != null) { attrType += String.format("<%s>", dtoModel.context.getAttributeType(generic)); } return attrType; } private boolean containsMultiple(List attributes) { boolean result = false; for (ObjectModelAttribute attr : attributes) { if (JavaGeneratorUtil.isNMultiplicity(attr)) { result = true; break; } } return result; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy