r661 - in branches/1.1.0-Javabuilder: eugene/src/main/java/org/nuiton/eugene eugene-test eugene-test/src/main eugene-test/src/main/java/org/nuiton/eugene/test/generator eugene-test/src/main/models eugene-test/src/test eugene-test/src/test/resources maven-eugene-plugin/src/main/java/org/nuiton/eugene/plugin
Author: fdesbois Date: 2009-10-27 11:32:23 +0100 (Tue, 27 Oct 2009) New Revision: 661 Added: branches/1.1.0-Javabuilder/eugene-test/src/main/java/org/nuiton/eugene/test/generator/BeanGenerator.java branches/1.1.0-Javabuilder/eugene-test/src/main/java/org/nuiton/eugene/test/generator/TopiaGeneratorUtil.java branches/1.1.0-Javabuilder/eugene-test/src/main/models/ branches/1.1.0-Javabuilder/eugene-test/src/main/models/dtotest.objectmodel branches/1.1.0-Javabuilder/eugene-test/src/test/resources/ branches/1.1.0-Javabuilder/eugene-test/src/test/resources/log4j.properties branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/ModelReader.java Removed: branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/FileReader.java Modified: branches/1.1.0-Javabuilder/eugene-test/pom.xml branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/Generator.java branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/ObjectModelGenerator.java branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/ObjectModelReader.java branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/StateModelGenerator.java branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/StateModelReader.java branches/1.1.0-Javabuilder/maven-eugene-plugin/src/main/java/org/nuiton/eugene/plugin/EugenePlugin.java Log: - Integrate Reader in maven-plugin - Add template from ToPIA to test for regression (must be deleted after finished JavaGenerator) Deleted: branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/FileReader.java =================================================================== --- branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/FileReader.java 2009-10-26 18:35:44 UTC (rev 660) +++ branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/FileReader.java 2009-10-27 10:32:23 UTC (rev 661) @@ -1,65 +0,0 @@ - -package org.nuiton.eugene; - -import java.io.File; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.nuiton.eugene.models.Model; - -/** - * FileReader - * - * Created: 26 oct. 2009 - * - * @author fdesbois - * @version $Revision$ - * - * Mise a jour: $Date$ - * par : $Author$ - */ -public abstract class FileReader<M extends Model> { - - private static final Log log = LogFactory.getLog(FileReader.class); - - /** date de derniere modification de la source la plus recente */ - protected long lastModifiedSource = 0; - - protected void setLastModifiedSource(File[] files) { - for (File file : files) { - if (isNewerThanSource(file)) { - lastModifiedSource = file.lastModified(); - log.debug("source date: " + lastModifiedSource - + " files[i] date: " + file.lastModified() + "(" + file - + ")"); - } - } - } - - protected long getLastModifiedSource() { - return lastModifiedSource; - } - - /** - * @param file fichier a tester - * @return vrai si le fichier passé en parametre est plus recent que - * les sources sur generateur. - */ - protected boolean isNewerThanSource(File file) { - if (log.isDebugEnabled()) { - log.debug("source date: " + getLastModifiedSource() - + " file date: " + file.lastModified() + "(" + file + ")"); - } - return file.lastModified() > getLastModifiedSource(); - } - - public M read(File file, File destDir) { - return read(new File[] { file }, destDir); - } - - public M read(File file) { - return read(new File[] { file }, new File(".")); - } - - public abstract M read(File[] file, File destDir); - -} Modified: branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/Generator.java =================================================================== --- branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/Generator.java 2009-10-26 18:35:44 UTC (rev 660) +++ branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/Generator.java 2009-10-27 10:32:23 UTC (rev 661) @@ -28,6 +28,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.nuiton.eugene.models.Model; /** * Generator. @@ -40,7 +41,7 @@ * Mise a jour: $Date$ * par : $Author$ */ -public abstract class Generator { +public abstract class Generator<M extends Model> { protected static Log log = LogFactory.getLog(Generator.class); @@ -58,7 +59,10 @@ protected String encoding; + /** date de derniere modification de la source la plus recente */ + protected long lastModifiedSource = 0; + protected Generator parent = null; public Generator() { @@ -119,32 +123,23 @@ } return properties.getProperty(name); } -/* - protected void setLastModifiedSource(File[] files) { - for (File file : files) { - if (isNewerThanSource(file)) { - lastModifiedSource = file.lastModified(); - log.debug("source date: " + lastModifiedSource - + " files[i] date: " + file.lastModified() + "(" + file - + ")"); - } - } - } - protected long getLastModifiedSource() { - if (parent != null) { - return parent.getLastModifiedSource(); - } - return lastModifiedSource; + public void setLastModifiedSource(long lastModifiedSource) { + this.lastModifiedSource = lastModifiedSource; } + /** + * @param file fichier a tester + * @return vrai si le fichier passé en parametre est plus recent que + * les sources sur generateur. + */ protected boolean isNewerThanSource(File file) { if (log.isDebugEnabled()) { - log.debug("source date: " + getLastModifiedSource() + log.debug("source date: " + lastModifiedSource + " file date: " + file.lastModified() + "(" + file + ")"); } - return file.lastModified() > getLastModifiedSource(); - }*/ + return file.lastModified() > lastModifiedSource; + } protected File getDestinationFile(File destDir, String filename) { return new File(destDir, filename); @@ -191,8 +186,11 @@ this.excludeTemplates = excludeTemplates; } + @Deprecated public abstract void generate(File[] file, File destDir); + public abstract void generate(M model, File destDir); + /** * Test if given package is allowed for generation. * Copied: branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/ModelReader.java (from rev 659, branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/FileReader.java) =================================================================== --- branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/ModelReader.java (rev 0) +++ branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/ModelReader.java 2009-10-27 10:32:23 UTC (rev 661) @@ -0,0 +1,48 @@ + +package org.nuiton.eugene; + +import java.io.File; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.eugene.models.Model; + +/** + * FileReader + * + * Created: 26 oct. 2009 + * + * @author fdesbois + * @version $Revision$ + * + * Mise a jour: $Date$ + * par : $Author$ + */ +public abstract class ModelReader<M extends Model> { + + private static final Log log = LogFactory.getLog(ModelReader.class); + + /** date de derniere modification de la source la plus recente */ + protected long lastModifiedSource = 0; + + protected void setLastModifiedSource(File[] files) { + for (File file : files) { + if (file.lastModified() > getLastModifiedSource()) { + lastModifiedSource = file.lastModified(); + log.debug("source date: " + lastModifiedSource + + " files[i] date: " + file.lastModified() + "(" + file + + ")"); + } + } + } + + public long getLastModifiedSource() { + return lastModifiedSource; + } + + public M read(File file) { + return read(new File[] { file }); + } + + public abstract M read(File[] file); + +} Property changes on: branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/ModelReader.java ___________________________________________________________________ Added: svn:mergeinfo + Modified: branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/ObjectModelGenerator.java =================================================================== --- branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/ObjectModelGenerator.java 2009-10-26 18:35:44 UTC (rev 660) +++ branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/ObjectModelGenerator.java 2009-10-27 10:32:23 UTC (rev 661) @@ -18,36 +18,20 @@ package org.nuiton.eugene; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; -import java.util.ArrayList; import java.util.Collection; -import java.util.Enumeration; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.apache.commons.digester.Digester; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.nuiton.eugene.models.Model; import org.nuiton.eugene.models.object.ObjectModel; import org.nuiton.eugene.models.object.ObjectModelClass; import org.nuiton.eugene.models.object.ObjectModelClassifier; import org.nuiton.eugene.models.object.ObjectModelElement; import org.nuiton.eugene.models.object.ObjectModelEnumeration; import org.nuiton.eugene.models.object.ObjectModelInterface; -import org.nuiton.eugene.models.object.xml.DigesterObjectModelRuleSet; -import org.nuiton.eugene.models.object.xml.ObjectModelClassifierImpl; -import org.nuiton.eugene.models.object.xml.ObjectModelElementImpl; -import org.nuiton.eugene.models.object.xml.ObjectModelImpl; -import org.nuiton.eugene.models.object.xml.ObjectModelImplRef; -import org.nuiton.eugene.models.object.xml.ObjectModelImplTagValue; -import org.nuiton.util.FileUtil; -import org.nuiton.util.RecursiveProperties; -import org.nuiton.util.StringUtil; -import org.xml.sax.SAXException; /** * Pour utiliser ce type de générateur il faut implanter au moins une des trois @@ -84,15 +68,13 @@ * * Mise a jour: $Date$ par : $Author$ */ -public class ObjectModelGenerator extends Generator { +public class ObjectModelGenerator extends Generator<ObjectModel> { /** Logger for this class. */ private static Log log = LogFactory.getLog(ObjectModelGenerator.class); protected ObjectModel model = null; - protected ObjectModelReader reader; - public ObjectModelGenerator() { super(); } @@ -105,25 +87,14 @@ return model; } - /** - * @param files les noms des fichiers existant contenant du XML représentant - * des ObjectModel. Il est automatiquement recherche un fichier de - * propriété associé a ce fichier pour pouvoir ajouter des - * stereotype ou des tag value sur les class, attribute ou operation - * @param destDir le répertoire dans lequel il faudra mettre les fichiers - * générés - */ + @Override + @Deprecated public void generate(File[] files, File destDir) { - reader = new ObjectModelReader(); - ObjectModel objectModel = reader.read(files, destDir); - try { - generate(objectModel, destDir); - } catch (IOException eee) { - if (log.isWarnEnabled()) { - log.warn("Unable to generate for file", eee); - } - } + ObjectModelReader reader = new ObjectModelReader(); + ObjectModel objectModel = reader.read(files); + setLastModifiedSource(reader.getLastModifiedSource()); + generate(objectModel, destDir); } /** @@ -142,31 +113,44 @@ * @param model * @param destDir * @throws IOException - */ - public void generate(ObjectModel model, File destDir) throws IOException { + */@Override + public void generate(ObjectModel model, File destDir) { // generateFromModel this.model = model; - String filename = getFilenameForModel(model); - generateFromElement(model, destDir, filename, - ObjectModelType.OBJECT_MODEL); + if (log.isDebugEnabled()) { + log.debug("name : " + model.getName()); + log.debug("interfaces : " + model.getInterfaces().size()); + log.debug("classes : " + model.getClasses().size()); + } - // generateFromClassifier - generateFromElements(model.getClassifiers(), destDir, - ObjectModelType.OBJECT_MODEL_CLASSIFIER); + //try { + String filename = getFilenameForModel(model); + generateFromElement(model, destDir, filename, + ObjectModelType.OBJECT_MODEL); - // generateFromInterface - generateFromElements(model.getInterfaces(), destDir, - ObjectModelType.OBJECT_MODEL_INTERFACE); + // generateFromClassifier + generateFromElements(model.getClassifiers(), destDir, + ObjectModelType.OBJECT_MODEL_CLASSIFIER); - // generateFromClass - generateFromElements(model.getClasses(), destDir, - ObjectModelType.OBJECT_MODEL_CLASS); + // generateFromInterface + generateFromElements(model.getInterfaces(), destDir, + ObjectModelType.OBJECT_MODEL_INTERFACE); - // generateFromEnumeration - generateFromElements(model.getEnumerations(), destDir, - ObjectModelType.OBJECT_MODEL_ENUMERATION); + // generateFromClass + generateFromElements(model.getClasses(), destDir, + ObjectModelType.OBJECT_MODEL_CLASS); + + // generateFromEnumeration + generateFromElements(model.getEnumerations(), destDir, + ObjectModelType.OBJECT_MODEL_ENUMERATION); + + /*} catch (IOException eee) { + if (log.isWarnEnabled()) { + log.warn("Unable to generate for file", eee); + } + }*/ } /** @@ -226,7 +210,7 @@ if (canGenerateElement(element)) { File outputFile = getDestinationFile(destDir, filename); - if (!getOverwrite() && reader.isNewerThanSource(outputFile)) { + if (!getOverwrite() && isNewerThanSource(outputFile)) { if (log.isDebugEnabled()) { log.debug("file " + outputFile + " is up-to-date"); } Modified: branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/ObjectModelReader.java =================================================================== --- branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/ObjectModelReader.java 2009-10-26 18:35:44 UTC (rev 660) +++ branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/ObjectModelReader.java 2009-10-27 10:32:23 UTC (rev 661) @@ -39,7 +39,7 @@ * Mise a jour: $Date$ * par : $Author$ */ -public class ObjectModelReader extends FileReader<ObjectModel> { +public class ObjectModelReader extends ModelReader<ObjectModel> { private static final Log log = LogFactory.getLog(ObjectModelReader.class); @@ -62,11 +62,9 @@ * des ObjectModel. Il est automatiquement recherche un fichier de * propriété associé a ce fichier pour pouvoir ajouter des * stereotype ou des tag value sur les class, attribute ou operation - * @param destDir le répertoire dans lequel il faudra mettre les fichiers - * générés */ @Override - public ObjectModel read(File[] files, File destDir) { + public ObjectModel read(File[] files) { setLastModifiedSource(files); ObjectModel objectModel = new ObjectModelImpl(); Modified: branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/StateModelGenerator.java =================================================================== --- branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/StateModelGenerator.java 2009-10-26 18:35:44 UTC (rev 660) +++ branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/StateModelGenerator.java 2009-10-27 10:32:23 UTC (rev 661) @@ -18,24 +18,15 @@ package org.nuiton.eugene; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; -import java.util.Enumeration; -import org.apache.commons.digester.Digester; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.nuiton.eugene.models.object.ObjectModelClassifier; import org.nuiton.eugene.models.state.StateModel; import org.nuiton.eugene.models.state.StateModelState; import org.nuiton.eugene.models.state.StateModelStateChart; -import org.nuiton.eugene.models.state.xml.DigesterStateModelRuleSet; -import org.nuiton.eugene.models.state.xml.StateModelImpl; -import org.nuiton.util.FileUtil; -import org.nuiton.util.RecursiveProperties; -import org.xml.sax.SAXException; /** * StateModelGenerator. @@ -55,7 +46,7 @@ * * Last update : $Date$ By : $Author$ */ -public class StateModelGenerator extends Generator { +public class StateModelGenerator extends Generator<StateModel> { /** Logger for this class */ private static Log log = LogFactory.getLog(StateModelGenerator.class); @@ -63,8 +54,6 @@ /** Model */ protected StateModel model; - protected StateModelReader reader; - /** * Empty constructor */ @@ -91,17 +80,19 @@ * @see org.nuiton.eugene.Generator#generate(java.io.File[], java.io.File) */ @Override + @Deprecated public void generate(File[] files, File destDir) { - reader = new StateModelReader(); - StateModel stateModel = reader.read(files, destDir); + StateModelReader reader = new StateModelReader(); + StateModel stateModel = reader.read(files); + setLastModifiedSource(reader.getLastModifiedSource()); // generate code - try { + //try { generate(stateModel, destDir); - } catch (IOException e) { + /*} catch (IOException e) { log.warn("Can't generate code for files", e); - } + }*/ } @@ -114,14 +105,14 @@ * @param destDir le dossier de destination * @throws IOException */ - public void generate(StateModel stateModel, File destDir) - throws IOException { + @Override + public void generate(StateModel stateModel, File destDir) { model = stateModel; String filename = getFilenameFromModel(stateModel); File outputFile = getDestinationFile(destDir, filename); - if (getOverwrite() || !reader.isNewerThanSource(outputFile)) { + if (getOverwrite() || !isNewerThanSource(outputFile)) { try { StringWriter out = new StringWriter(); MonitorWriter monitorOut = new MonitorWriter(out); @@ -148,7 +139,7 @@ String filenameState = getFilenameFromState(state, chart .getName()); File outputFiletate = getDestinationFile(destDir, filenameState); - if (getOverwrite() || !reader.isNewerThanSource(outputFiletate)) { + if (getOverwrite() || !isNewerThanSource(outputFiletate)) { try { StringWriter out = new StringWriter(); MonitorWriter monitorOut = new MonitorWriter(out); Modified: branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/StateModelReader.java =================================================================== --- branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/StateModelReader.java 2009-10-26 18:35:44 UTC (rev 660) +++ branches/1.1.0-Javabuilder/eugene/src/main/java/org/nuiton/eugene/StateModelReader.java 2009-10-27 10:32:23 UTC (rev 661) @@ -26,12 +26,12 @@ * Mise a jour: $Date$ * par : $Author$ */ -public class StateModelReader extends FileReader<StateModel> { +public class StateModelReader extends ModelReader<StateModel> { private static final Log log = LogFactory.getLog(StateModelReader.class); @Override - public StateModel read(File[] files, File destDir) { + public StateModel read(File[] files) { Digester digester = new Digester(); digester.addRuleSet(new DigesterStateModelRuleSet()); Modified: branches/1.1.0-Javabuilder/eugene-test/pom.xml =================================================================== --- branches/1.1.0-Javabuilder/eugene-test/pom.xml 2009-10-26 18:35:44 UTC (rev 660) +++ branches/1.1.0-Javabuilder/eugene-test/pom.xml 2009-10-27 10:32:23 UTC (rev 661) @@ -92,13 +92,14 @@ <groupId>org.nuiton.eugene</groupId> <artifactId>maven-eugene-plugin</artifactId> <version>${project.version}</version> - <!--executions> + <executions> <execution> - <id>Test Java Generator</id> + <id>Test Generator</id> <phase>generate-test-sources</phase> <configuration> + <reader>org.nuiton.eugene.ObjectModelReader</reader> <includes>**/*.objectmodel</includes> - <templates>org.nuiton.eugene.test.generator.JavaGenerator</templates> + <templates>org.nuiton.eugene.test.generator.BeanGenerator</templates> <defaultPackage>org.nuiton.eugene.test</defaultPackage> <extraClassPathDirectory>target/classes</extraClassPathDirectory> <generateResources> @@ -109,7 +110,7 @@ <goal>generate</goal> </goals> </execution> - </executions--> + </executions> </plugin> <!--plugin> Added: branches/1.1.0-Javabuilder/eugene-test/src/main/java/org/nuiton/eugene/test/generator/BeanGenerator.java =================================================================== --- branches/1.1.0-Javabuilder/eugene-test/src/main/java/org/nuiton/eugene/test/generator/BeanGenerator.java (rev 0) +++ branches/1.1.0-Javabuilder/eugene-test/src/main/java/org/nuiton/eugene/test/generator/BeanGenerator.java 2009-10-27 10:32:23 UTC (rev 661) @@ -0,0 +1,618 @@ +/* *##% ToPIA - Persistence + * Copyright (C) 2004 - 2009 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. ##%*/ + +/* * +* BeanGenerator.java +* +* Created: 17 avril 2009 +* +* @author tony Chemit <chemit@codelutin.com> +* @version $Revision: 1334 $ +* +* Mise a jour: $Date: 2009-01-29 16:47:42 +0100 (jeu 29 jan 2009) $ +* par : $Author: chemit $ +*/ + +package org.nuiton.eugene.test.generator; + +import static org.nuiton.eugene.test.generator.TopiaGeneratorUtil.TAG_ANNOTATION; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; + +import java.util.List; +import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.eugene.ObjectModelGenerator; +import org.nuiton.eugene.GeneratorUtil; +import org.nuiton.eugene.ImportsManager; +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.ObjectModelDependency; +import org.nuiton.eugene.models.object.ObjectModelInterface; +import org.nuiton.eugene.models.object.ObjectModelOperation; +import org.nuiton.eugene.models.object.ObjectModelParameter; +//import org.nuiton.topia.persistence.TopiaEntity; +import static org.nuiton.eugene.test.generator.TopiaGeneratorUtil.isPrimitiveType; +import static org.nuiton.eugene.test.generator.TopiaGeneratorUtil.isDateType; + +/** + * DTO generator + */ +public class BeanGenerator extends ObjectModelGenerator { + + /** + * Logger for this class + */ + private static final Log log = LogFactory.getLog(BeanGenerator.class); + + public BeanGenerator() { + super(); + } + + @Override + public String getFilenameForClass(ObjectModelClass clazz) { + return clazz.getQualifiedName().replace('.', File.separatorChar) + ".java"; + } + + @Override + public void generateFromClass(Writer output, ObjectModelClass clazz) throws IOException { + if (!clazz.hasStereotype(TopiaGeneratorUtil.STEREOTYPE_BEAN) && + !clazz.hasStereotype(TopiaGeneratorUtil.STEREOTYPE_DTO)) { + return; + } + // + // première phase : calcul des variables + // + String copyright = TopiaGeneratorUtil.getCopyright(model); + String clazzName = clazz.getName(); + String abstractStr = isAbstract(clazz) ? " abstract " : " "; + boolean needGetEntityMethod = false; + boolean generateToString = TopiaGeneratorUtil.generateToString(clazz, model); + + ImportsManager imports = new ImportsManager(); + + String extendClass = ""; + Iterator<ObjectModelClass> j = clazz.getSuperclasses().iterator(); + if (j.hasNext()) { + ObjectModelClassifier p = j.next(); + imports.addImport(p.getQualifiedName()); + extendClass += p.getName(); + } + String implInterface = ""; + for (Iterator<ObjectModelInterface> i=clazz.getInterfaces().iterator(); i.hasNext();) { + ObjectModelClassifier parentInterface = i.next(); + imports.addImport(parentInterface.getQualifiedName()); + implInterface += parentInterface.getName(); + if (i.hasNext()) { + implInterface += ", "; + } + } + // Add Serializable implements for DTO generation + if (clazz.hasStereotype(TopiaGeneratorUtil.STEREOTYPE_DTO)) { + imports.addImport(Serializable.class); + if (!implInterface.isEmpty()) { + implInterface += ", "; + } + implInterface += Serializable.class.getName(); + } + String svUID = TopiaGeneratorUtil.findTagValue("dto-serialVersionUID", clazz, model); + + List<ObjectModelAttribute> attributes = new ArrayList<ObjectModelAttribute>(); + List<ObjectModelAttribute> multipleAttr = new ArrayList<ObjectModelAttribute>(); + + setAttributesForDTO(clazz, attributes,imports); + + boolean needListInImport=false; + + for (ObjectModelAttribute attr : clazz.getAttributes()) { + if (attr.isNavigable()) { + attributes.add(attr); + imports.addImport(attr.getType()); + if (GeneratorUtil.isNMultiplicity(attr)) { + multipleAttr.add(attr); + ObjectModelClass attrEntity = null; + if (model.hasClass(attr.getType())) { + attrEntity = model.getClass(attr.getType()); + } + boolean isEntity = (attrEntity != null && attrEntity.hasStereotype(TopiaGeneratorUtil.STEREOTYPE_ENTITY)); + needGetEntityMethod |= isEntity; + if (attr.isOrdered()) { + needListInImport = true; + } + } + } + } + + imports.addImport(java.beans.PropertyChangeListener.class.getName()); + imports.addImport(java.beans.PropertyChangeSupport.class.getName()); + + for (ObjectModelOperation operation : clazz.getOperations()) { + imports.addImport(operation.getReturnType()); + for (ObjectModelParameter parameter : operation.getParameters()) { + imports.addImport(parameter.getType()); + } + } + + if (needGetEntityMethod) { + imports.addImport("org.nuiton.topia.persistence.TopiaEntity"); + } + if (!multipleAttr.isEmpty()) { + imports.addImport(Collection.class); + } + if (needListInImport) { + imports.addImport(List.class); + } + if (generateToString) { + imports.addImport(org.apache.commons.lang.builder.ToStringBuilder.class); + } + + boolean sortAttribute = TopiaGeneratorUtil.sortAttribute(clazz, model); + if (sortAttribute) { + Comparator<ObjectModelAttribute> comp = new Comparator<ObjectModelAttribute>(){ + + @Override + public int compare(ObjectModelAttribute o1, ObjectModelAttribute o2) { + return o1.getName().compareTo(o2.getName()); + } + }; + java.util.Collections.sort(attributes,comp); + java.util.Collections.sort(multipleAttr,comp); + } + // + // seconde phase : génération + // + + if (TopiaGeneratorUtil.notEmpty(copyright)) { +/*{<%=copyright%> +}*/ + } + +/*{package <%=clazz.getPackageName()%>; + + }*/ + + if (log.isDebugEnabled()) { + log.debug("imports for class <" + clazzName + ">"); + } + //for (String anImport : imports) { + for (String anImport : imports.getImports(clazz.getPackageName())) { + if (log.isDebugEnabled()) { + log.debug("import " + anImport); + } +/*{import <%=anImport%>; +}*/ + } +/*{ +public<%=abstractStr%>class <%=clazzName%>}*/ + +/* + * Définition de la super classe : il ne doit y avoir qu'une + */ + if (extendClass.length() > 0) { +/*{ extends <%=extendClass%>}*/ + } + + if (implInterface.length() > 0) { +/*{ implements <%=implInterface%> { + +}*/ + } else { + /*{ { + +}*/ + } + + + // TODO Calculer un serialVersionUID si il n'y en a pas + if (svUID != null) { +/*{ public static final long serialVersionUID = <%=svUID%>; + +}*/ + } + generateInterfaceOperations(output, clazz); + generateAttributes(output, attributes); +/*{ protected final PropertyChangeSupport pcs; + + /** + * Default constructor of <%=clazzName%>. + *) + public <%=clazzName%>() { + pcs = new PropertyChangeSupport(this); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + pcs.addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { + pcs.addPropertyChangeListener(propertyName, listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + pcs.removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { + pcs.removePropertyChangeListener(propertyName, listener); + } + +}*/ + generateGetters(output, attributes); + generateSetters(output, attributes); + generateGetChild(output, multipleAttr); + generateAddChild(output, multipleAttr); + generateRemoveChild(output, multipleAttr); + if (generateToString) { + generateToString(output, clazz); + } + if (!multipleAttr.isEmpty()) { +/*{ + + protected <T> T getChild(Collection<T> childs, int index) { + if (childs != null) { + int i = 0; + for (T o : childs) { + if (index == i) { + return o; + } + i++; + } + } + return null; + } + + }*/ + if (needGetEntityMethod) { +/*{ protected <T extends TopiaEntity> T getEntity(Collection<T> childs, String topiaId) { + if (childs != null) { + for (T o : childs) { + if (topiaId.equals(o.getTopiaId())) { + return o; + } + } + } + return null; + } + }*/ + } + } + +/*{ + protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { + pcs.firePropertyChange(propertyName, oldValue, newValue); + } + +} //<%=clazz.getName()%> +}*/ + } + + protected void generateAttributes(Writer output, List<ObjectModelAttribute> attributes) throws IOException { + + for (ObjectModelAttribute attr : attributes) { + + if (!(attr.isNavigable() + || attr.hasAssociationClass())) { + continue; + } + + if (TopiaGeneratorUtil.hasDocumentation(attr)) { +/*{ /** + * <%=attr.getDocumentation()%> + *) +}*/ + } + String annotation = attr.getTagValue(TAG_ANNOTATION); + if (annotation != null && annotation.length() > 0) { +/*{ <%=annotation%> +}*/ + } + String attrName = attr.getName(); + String attrVisibility = attr.getVisibility(); + String attrType = attr.getType(); + if (attr.hasAssociationClass()) { + String assocAttrName = TopiaGeneratorUtil.getAssocAttrName(attr); + attrName = GeneratorUtil.toLowerCaseFirstLetter(assocAttrName); + attrType = attr.getAssociationClass().getName(); + } + int dot = attrType.lastIndexOf("."); + if (dot>-1) { + attrType = attrType.substring(dot + 1); + } + if (GeneratorUtil.isNMultiplicity(attr)) { + attrType = getCollection(attr, attrType); + } + +/*{ <%=attrVisibility%> <%=attrType%> <%=attrName%>; +}*/ + } + } + + protected void generateGetters(Writer output, List<ObjectModelAttribute> attributes) throws IOException { + /* + * Définition des getteurs et setteurs + */ + for (ObjectModelAttribute attr : attributes) { + + if (!attr.isNavigable()) { + continue; + } + + String attrName = attr.getName(); + String attrType = attr.getType(); + if (attr.hasAssociationClass()) { + String assocAttrName = TopiaGeneratorUtil.getAssocAttrName(attr); + attrName = GeneratorUtil.toLowerCaseFirstLetter(assocAttrName); + attrType = attr.getAssociationClass().getName(); + } + String attrNameCapitalized = GeneratorUtil.capitalize(attrName); + int dot = attrType.lastIndexOf("."); + if (dot>-1) { + attrType = attrType.substring(dot + 1); + } + if (GeneratorUtil.isNMultiplicity(attr)) { + attrType = getCollection(attr, attrType); + } +/*{ public <%=attrType%> get<%=attrNameCapitalized%>() { + return <%=attrName%>; + } + +}*/ + } + } + + protected void generateSetters(Writer output, List<ObjectModelAttribute> attributes) throws IOException { + /* + * Définition des getteurs et setteurs + */ + for (ObjectModelAttribute attr : attributes) { + + if (!attr.isNavigable()) { + continue; + } + + String attrName = attr.getName(); + String attrType = attr.getType(); + + if (attr.hasAssociationClass()) { + String assocAttrName = TopiaGeneratorUtil.getAssocAttrName(attr); + attrName = GeneratorUtil.toLowerCaseFirstLetter(assocAttrName); + attrType = attr.getAssociationClass().getName(); + } + String attrNameCapitalized = GeneratorUtil.capitalize(attrName); + int dot = attrType.lastIndexOf("."); + if (dot>-1) { + attrType = attrType.substring(dot + 1); + } + if (GeneratorUtil.isNMultiplicity(attr)) { + attrType = getCollection(attr, attrType); + } +/*{ public void set<%=attrNameCapitalized%>(<%=attrType%> newValue) { + <%=attrType%> oldValue = get<%=attrNameCapitalized%>(); + this.<%=attrName%> = newValue; + firePropertyChange("<%=attrName%>", oldValue, newValue); + } + +}*/ + } + } + + protected void generateGetChild(Writer output, List<ObjectModelAttribute> multipleAttr) throws IOException { + + for (ObjectModelAttribute attr : multipleAttr) { + + String attrName = attr.getName(); + String attrNameCapitalized = GeneratorUtil.capitalize(attrName); + String attrType = attr.getType(); + int dot = attrType.lastIndexOf("."); + if (dot>-1) { + attrType = attrType.substring(dot + 1); + } + ObjectModelClass attrEntity=null; + if (model.hasClass(attr.getType())) { + attrEntity = model.getClass(attr.getType()); + } + boolean isEntity = (attrEntity != null && attrEntity.hasStereotype(TopiaGeneratorUtil.STEREOTYPE_ENTITY)); +/*{ public <%=attrType%> get<%=attrNameCapitalized%>(int index) { + <%=attrType%> o = getChild(<%=attrName%>, index); + return o; + } + +}*/ + if (isEntity) { +/*{ public <%=attrType%> get<%=attrNameCapitalized%>(String topiaId) { + <%=attrType%> o = getEntity(<%=attrName%>, topiaId); + return o; + } + +}*/ + } + } + } + protected void generateAddChild(Writer output, List<ObjectModelAttribute> multipleAttr) throws IOException { + for (ObjectModelAttribute attr : multipleAttr) { + + String attrName = attr.getName(); + String attrNameCapitalized = GeneratorUtil.capitalize(attrName); + String attrType = attr.getType(); + int dot = attrType.lastIndexOf("."); + if (dot>-1) { + attrType = attrType.substring(dot + 1); + } +/*{ public <%=attrType%> add<%=attrNameCapitalized%>(<%=attrType%> <%=attrName%>) { + get<%=attrNameCapitalized%>().add(<%=attrName%>); + firePropertyChange("<%=attrName%>", null, <%=attrName%>); + return <%=attrName%>; + } + +}*/ + } + } + + protected void generateRemoveChild(Writer output, List<ObjectModelAttribute> multipleAttr) throws IOException { + for (ObjectModelAttribute attr : multipleAttr) { + String attrName = attr.getName(); + String attrNameCapitalized = GeneratorUtil.capitalize(attrName); + String attrType = attr.getType(); + int dot = attrType.lastIndexOf("."); + if (dot>-1) { + attrType = attrType.substring(dot + 1); + } +/*{ public boolean remove<%=attrNameCapitalized%>(<%=attrType%> <%=attrName%>) { + boolean removed = get<%=attrNameCapitalized%>().remove(<%=attrName%>); + if (removed) { + firePropertyChange("<%=attrName%>", <%=attrName%>, null); + } + return removed; + } + +}*/ + } + } + + protected void generateInterfaceOperations(Writer output, ObjectModelClassifier classifier) throws IOException { + for (ObjectModelOperation op : classifier.getOperations()) { + String opName = op.getName(); +/*{ /** +}*/ + if (TopiaGeneratorUtil.hasDocumentation(op)) { + String opDocumentation = op.getDocumentation(); +/*{ * <%=opName%> : <%=opDocumentation%> +}*/ + } + Collection<ObjectModelParameter> params = op.getParameters(); + for (ObjectModelParameter param : params) { + String paramName = param.getName(); + String paramDocumentation = param.getDocumentation(); +/*{ * @param <%=paramName%> <%=paramDocumentation%> + }*/ + } + String opVisibility = op.getVisibility(); + String opType = op.getReturnType(); +/*{ *) + <%=opVisibility%> abstract <%=opType%> <%=opName%>(}*/ + String comma = ""; + for (ObjectModelParameter param : params) { + String paramName = param.getName(); + String paramType = param.getType(); +/*{<%=comma%><%=paramType%> <%=paramName%>}*/ + comma = ", "; + } +/*{)}*/ + Set<String> exceptions = op.getExceptions(); + comma = " throws "; + for (String exception : exceptions) { +/*{<%=comma%><%=exception%>}*/ + comma = ", "; + } +/*{; + +}*/ + } + } + protected void generateToString(Writer output, ObjectModelClass clazz) throws IOException { +/*{ + @Override + public String toString() { + String result = new ToStringBuilder(this). +}*/ + for (ObjectModelAttribute attr : clazz.getAttributes()) { + if (!(attr.isNavigable() || attr.hasAssociationClass())) { + continue; + } + //FIXME possibilité de boucles (non directes) + String attrName = attr.getName(); +/*{ append("<%=attrName%>", this.<%=attrName%>). +}*/ + } +/*{ toString(); + return result; + } + }*/ + } + + protected String getCollection(ObjectModelAttribute attr, String attrType) { + String nMultType; + if (attr.isOrdered()) { + nMultType = "List<"; + } else { + nMultType = "Collection<"; + } + nMultType += attrType; + nMultType += ">"; + return nMultType; + } + + protected boolean isAbstract(ObjectModelClass clazz) { + if (clazz.isAbstract()) { + return true; + } + return !clazz.getOperations().isEmpty(); + } + + /** + * Dependecy gestion for DTO generation. + * All primitives attributes (and dates) of dependencies entities of the DTO are + * copied in the DTO. This method only prepare a list of attributes to be generated. + * @param clazz DTO ObjectModelClass + * @param attributes list of attributes for the generation (may be not empty) + * @param imports the ImportsManager used to generate the header imports of the DTO + * @return the same list of attributes in parameter with attributes from entities dependencies + * @see org.nuiton.eugene.ImportsManager + * @see org.nuiton.eugene.models.object.ObjectModelDependency + */ + private List<ObjectModelAttribute> setAttributesForDTO(ObjectModelClass clazz, + List<ObjectModelAttribute> attributes, ImportsManager imports) { + + if (clazz.hasStereotype(TopiaGeneratorUtil.STEREOTYPE_DTO)) { + if (log.isInfoEnabled()) { + log.info("DTO dependency gestion"); + } + for (ObjectModelDependency dependency : clazz.getDependencies()) { + ObjectModelClass supplier = (ObjectModelClass)dependency.getSupplier(); + + // ENTITY dependency + // Copy all primitives attributes from the Entity (supplier) to the DTO + // Prepare a list to future generation of all object generated attributes + if (supplier.hasStereotype(TopiaGeneratorUtil.STEREOTYPE_ENTITY)) { + if (log.isInfoEnabled()) { + log.info("Create primitive and date fields in DTO from Entity : " + + supplier.getQualifiedName()); + } + for (ObjectModelAttribute attr : supplier.getAttributes()) { + if (isPrimitiveType(attr) || isDateType(attr)) { + attributes.add(attr); + imports.addImport(attr.getType()); + } + if (GeneratorUtil.isNMultiplicity(attr)) { + imports.addImport("java.util.Collection"); + } + } + } + } + } + return attributes; + } +} //BeanGenerator Added: branches/1.1.0-Javabuilder/eugene-test/src/main/java/org/nuiton/eugene/test/generator/TopiaGeneratorUtil.java =================================================================== --- branches/1.1.0-Javabuilder/eugene-test/src/main/java/org/nuiton/eugene/test/generator/TopiaGeneratorUtil.java (rev 0) +++ branches/1.1.0-Javabuilder/eugene-test/src/main/java/org/nuiton/eugene/test/generator/TopiaGeneratorUtil.java 2009-10-27 10:32:23 UTC (rev 661) @@ -0,0 +1,946 @@ +/* *##% ToPIA - Persistence + * Copyright (C) 2004 - 2009 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. ##%*/ +/******************************************************************************* + * GeneratorUtil.java + * + * Created: 13 déc. 2005 + * + * @author Arnaud Thimel <thimel@codelutin.com> + * + * @version $Revision: 1298 $ + * + * Mise a jour: $Date: 2009-01-15 00:01:45 +0100 (jeu 15 jan 2009) $ par : $Author: tchemit $ + */ +package org.nuiton.eugene.test.generator; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.nuiton.eugene.Generator; +import org.nuiton.eugene.GeneratorUtil; +import org.nuiton.eugene.models.Model; +import org.nuiton.eugene.models.object.ObjectModel; +import org.nuiton.eugene.models.object.ObjectModelAssociationClass; +import org.nuiton.eugene.models.object.ObjectModelAttribute; +import org.nuiton.eugene.models.object.ObjectModelClass; +import org.nuiton.eugene.models.object.ObjectModelElement; +import org.nuiton.eugene.models.object.ObjectModelInterface; +import org.nuiton.eugene.models.object.ObjectModelOperation; +import org.nuiton.eugene.models.object.ObjectModelParameter; + +/** Classe regroupant divers méthodes utiles pour la génération des entités */ +public class TopiaGeneratorUtil extends GeneratorUtil { + + /** Stéréotype pour les interfaces devant être générées sous forme de facades */ + public final static String STEREOTYPE_FACADE = "facade"; + /** Stéréotype pour les objets devant être générées sous forme d'entités */ + public static final String STEREOTYPE_ENTITY = "entity"; + /** Stéréotype pour les objets devant être générées sous forme de DTO */ + public static final String STEREOTYPE_DTO = "dto"; + /** Stéréotype pour les objets devant être générées sous forme de bean */ + public static final String STEREOTYPE_BEAN = "bean"; + /** + * Stéréotype pour les interfaces devant être générées sous forme de + * services + */ + public static final String STEREOTYPE_SERVICE = "service"; + /** Stéréotype pour les interfaces devant être générées sous forme de DAO */ + public static final String STEREOTYPE_DAO = "dao"; + /** Stéréotype pour les attributs à indexer en base */ + public static final String STEREOTYPE_INDEXED = "indexed"; + /** Stéréotype pour les collections avec unicité */ + public static final String STEREOTYPE_UNIQUE = "unique"; + /** Stéréotype pour les attributs étant des clés primaires */ + public static final String STEREOTYPE_PRIMARYKAY = "primaryKey"; + /** Tag pour le type de persistence */ + public static final String TAG_PERSISTENCE_TYPE = "persistenceType"; + /** Tag pour le nom du champ / entité en BD */ + public static final String TAG_DB_NAME = "dbName"; + /** Tag pour le nom du schema en BD */ + public static final String TAG_SCHEMA_NAME = "dbSchema"; + /** Tag pour la taille du champ en BD */ + public static final String TAG_LENGTH = "length"; + /** Tag pour ajouter une annotation à un champ */ + public static final String TAG_ANNOTATION = "annotation"; + /** Tag pour ajouter specifier le copyright d'un fichier */ + public static final String TAG_COPYRIGHT = "copyright"; + /** Tag pour specfier le type d'acces a un champ */ + public static final String TAG_ACCESS = "access"; + /** Tag pour specfier si on doit générer i18n */ + public static final String TAG_I18N_PREFIX = "i18n"; + /** Tag pour ajouter un attribut dans une clef métier */ + public static final String TAG_NATURAL_ID = "naturalId"; + /** Tag pour specifier si une clef metier est mutable */ + public static final String TAG_NATURAL_ID_MUTABLE = "naturalIdMutable"; + /** Tag pour spécifier la caractèrelazy d'une association multiple */ + public static final String TAG_LAZY = "lazy"; + /** Tag pour spécifier la caractère fetch d'une association multiple */ + public static final String TAG_FETCH = "fetch"; + /** Tag pour spécifier la caractère order-by d'une association multiple */ + public static final String TAG_ORDER_BY = "orderBy"; + /** Tag pour spécifier la caractère not-null d'un attribut */ + public static final String TAG_NOT_NULL = "notNull"; + /** Tag pour spécifier la caractère embed-xml d'une association */ + public static final String TAG_EMBED_XML = "embedXml"; + /** + * Tag pour configurer l'interface du proxy sur autre chose que l'implementation par defaut. + * + * Par defaut : + * null > generere le proxy sur l'interface de l'implementation + * Autre valeur : + * "none" > laisse la configuration par defaut d'hibernate + */ + public static final String TAG_PROXY_INTERFACE = "hibernateProxyInterface"; + /** Tag pour spécifier le permissions à la création */ + public static final String TAG_SECURITY_CREATE = "securityCreate"; + /** Tag pour spécifier le permissions au chargement */ + public static final String TAG_SECURITY_LOAD = "securityLoad"; + /** Tag pour spécifier le permissions à la mise à jour */ + public static final String TAG_SECURITY_UPDATE = "securityUpdate"; + /** Tag pour spécifier le permissions à la suppression */ + public static final String TAG_SECURITY_DELETE = "securityDelete"; + /** Tag pour specifier de ne pas generer la methode toString */ + public static final String TAG_NOT_GENERATE_TO_STRING = "notGenerateToString"; + /** Tag pour specifier de trier les attributs par nom lors de la generation */ + public static final String TAG_SORT_ATTRIBUTE = "sortAttribute"; + /** Tag pour specfier si on doit générer la methode getOperator dans les daohelpers )*/ + public static final String TAG_GENERATE_OPERATOR_FOR_DAO_HELPER = "generateOperatorForDAOHelper"; + /** Type de persistence Hibernate */ + public static final String PERSISTENCE_TYPE_HIBERNATE = "hibernate"; + /** Type de persistence LDAP */ + public static final String PERSISTENCE_TYPE_LDAP = "ldap"; + /** Type de persistence par défaut (si aucun précisé) */ + public static final String PERSISTENCE_TYPE_DEFAULT = PERSISTENCE_TYPE_HIBERNATE; + /** Propriété des générateurs indiquant le package par défaut */ + public static final String PROPERTY_DEFAULT_PACKAGE = "defaultPackage"; + /** Le package par défaut si aucun n'est spécifié */ + public static final String DEFAULT_PACKAGE = "org.codelutin.malo"; + + /** + * Renvoie le package par défaut pour le générateur donné + * + * @param generator le générateur donné + * @return le package par défaut du générator donné + */ + public static String getDefaultPackage(Generator generator) { + String packageName = generator.getProperty(PROPERTY_DEFAULT_PACKAGE); + if (packageName == null || "".equals(packageName)) { + packageName = DEFAULT_PACKAGE; + } + return packageName; + } + + /** + * @see GeneratorUtil#hasDocumentation + * @deprecated + */ + @Deprecated + public static boolean hasDocumentation(ObjectModelElement element) { + return notEmpty(element.getDocumentation()); + } + + /** + * @see GeneratorUtil#notEmpty + * @deprecated + */ + @Deprecated + public static boolean notEmpty(String s) { + return (s != null && !"".equals(s)); + } + + /** + * Renvoie l'interface DAO associée à la classe passée en paramètre + * + * @param clazz la classe à tester + * @param model le modele utilisé + * @return l'interface trouvée ou null sinon + */ + public static ObjectModelInterface getDAOInterface(ObjectModelClass clazz, + ObjectModel model) { + for (Object o : model.getInterfaces()) { + ObjectModelInterface daoInterface = (ObjectModelInterface) o; + if (daoInterface.getName().equals(clazz.getName() + "DAO")) { + if (daoInterface.hasStereotype(STEREOTYPE_DAO)) { + return daoInterface; + } + } + } + return null; + } + + /** + * Renvoie le type de persistence pour l'élément donné. Si aucun n'est + * trouvé, le type par défaut est utilisé + * + * @param element l'élément à tester + * @return le type de persitence pour l'élément donné. + */ + public static String getPersistenceType(ObjectModelElement element) { + String tag = element.getTagValue(TAG_PERSISTENCE_TYPE); + if (tag == null) { + tag = PERSISTENCE_TYPE_DEFAULT; + } + return tag; + } + + public static String getReverseDBName(ObjectModelAttribute attr) { + if (attr.getReverseAttribute() != null) { + return getDBName(attr.getReverseAttribute()); + } else { + return getDBName(attr) + "_id"; + } + } + + /** + * Renvoie le nom BD de l'élement passé en paramètre. Elle se base sur le + * tag associé si il existe, sinon sur le nom de l'élément + * + * @param element l'élément à tester + * @return le nom de table + */ + public static String getDBName(ObjectModelElement element) { + if (element == null) { + return null; + } + if (notEmpty(element.getTagValue(TAG_DB_NAME))) { + return element.getTagValue(TAG_DB_NAME); + } + return toLowerCaseFirstLetter(element.getName()); + } + + /** + * Cherche et renvoie le schema a utiliser sur cet element, sinon sur le model. + * + * @param element l'élément à tester + * @param model le modele utilisé + * @return le nom du schema ou null + */ + public static String getSchemaName(ObjectModelElement element, + ObjectModel model) { + return findTagValue(TAG_SCHEMA_NAME, element, model); + } + + /** + * Cherche et renvoie le prefixe i18n à utiliser sur cet element, sinon sur le model. + * + * @param element l'élément à tester + * @param model le modele utilisé + * @return le prefix i18n ou <code>null</code> si non spécifié + */ + public static String getI18nPrefix(ObjectModelElement element, + ObjectModel model) { + return GeneratorUtil.findTagValue(TAG_I18N_PREFIX, element, model); + } + + /** + * Cherche et renvoie le prefixe i18n à utiliser sur cet element, sinon sur le model. + * + * @param element l'élément à tester + * @param model le modele utilisé + * @return le prefix i18n ou <code>null</code> si non spécifié + */ + public static boolean shouldgenerateOperatorForDAOHelper(ObjectModelElement element, + ObjectModel model) { + String tagValue = GeneratorUtil.findTagValue(TAG_GENERATE_OPERATOR_FOR_DAO_HELPER, element, model); + boolean generate = GeneratorUtil.notEmpty(tagValue) && Boolean.valueOf(tagValue); + return generate; + } + + /** + * Cherche et renvoie la liste des attributs constituant la clef metier d'une classe. + * + * @param clazz la classe à tester + * @return la liste des attributs de la clef métier ou null si pas de clef métier. + */ + public static List<String> getNaturalId(ObjectModelClass clazz) { + String value = clazz.getTagValue(TAG_NATURAL_ID); + if (value == null || value.trim().isEmpty()) { + return java.util.Collections.emptyList(); + } + List<String> result = new ArrayList<String>(); + for (String attribute : value.split(",")) { + result.add(attribute.trim()); + } + return result; + } + + /** + * Cherche et renvoie la liste des attributs constituant la clef metier d'une classe. + * + * @param clazz la classe à tester + * @param model le modele + * @return la liste des attributs de la clef métier ou null si pas de clef métier. + */ + public static boolean generateToString(ObjectModelClass clazz, + ObjectModel model) { + String value; + value = model.getTagValue(TAG_NOT_GENERATE_TO_STRING); + if (value != null && !value.trim().isEmpty()) { + return false; + } + value = clazz.getTagValue(TAG_NOT_GENERATE_TO_STRING); + if (value != null && !value.trim().isEmpty()) { + return false; + } + return true; + } + + /** + * Cherche et renvoie la liste des attributs constituant la clef metier d'une classe. + * + * @param clazz la classe à tester + * @param model le modele + * @return la liste des attributs de la clef métier ou null si pas de clef métier. + */ + public static boolean sortAttribute(ObjectModelClass clazz, + ObjectModel model) { + String value; + value = clazz.getTagValue(TAG_SORT_ATTRIBUTE); + if (value == null || value.trim().isEmpty() || "false".equals(value.trim())) { + return false; + } + if (value != null && "true".equals(value.trim())) { + return true; + } + + value = model.getTagValue(TAG_SORT_ATTRIBUTE); + if (value == null || value.trim().isEmpty() || "false".equals(value.trim())) { + return false; + } + if (value != null && "true".equals(value.trim())) { + return true; + } + return true; + } + + /** + * Detecte si un attribut fait partie d'une clef metier. + * + * @param attribute l'attribut à tester + * @return <code>true</code> si l'attribut fait partie d'une clef metier, <code>false</cdoe> sinon. + */ + public static boolean isNaturalId(ObjectModelAttribute attribute) { + String value = attribute.getTagValue(TAG_NATURAL_ID); + if (!GeneratorUtil.notEmpty(value)) { + // valeur null, donc pas positionnee + return false; + } + try { + return Boolean.valueOf(value.trim()); + } catch (Exception e) { + // on a pas reussi a convertir en boolean. + //todo peut-être declancher une exception ? + return false; + } + } + + /** + * Cherches et renvoie le copyright a utiliser sur le model. + * + * @param model le modele utilisé + * @return le texte du copyright ou null + */ + public static String getCopyright(Model model) { + return findTagValue(TAG_COPYRIGHT, null, model); + } + + /** + * @see GeneratorUtil#findTagValue + * @deprecated + */ + @Deprecated + public static String findTagValue(String tagName, + ObjectModelElement element, Model model) { + if (element == null) { + if (model != null) { + if (notEmpty(model.getTagValue(tagName))) { + return model.getTagValue(tagName); + } + } + return null; + } + if (notEmpty(element.getTagValue(tagName))) { + return element.getTagValue(tagName); + } + //On va chercher sur l'element declarant + return findTagValue(tagName, element.getDeclaringElement(), model); + } + + public static <Type extends ObjectModelElement> Collection<Type> getElementsWithStereotype( + Collection<Type> elements, String... stereotypes) { + Collection<Type> result = new ArrayList<Type>(); + for (Type element : elements) { + if (hasStereotypes(element, stereotypes)) { + result.add(element); + } + } + return result; + } + + public static boolean hasStereotypes(ObjectModelElement element, + String... stereotypes) { + for (String stereotype : stereotypes) { + if (!element.hasStereotype(stereotype)) { + return false; + } + } + return true; + } + + public static String getPrimaryKeyAttributesListDeclaration( + ObjectModelClass clazz, boolean includeName) { + String attributes = ""; + for (ObjectModelAttribute attr : getElementsWithStereotype(clazz.getAttributes(), STEREOTYPE_PRIMARYKAY)) { + attributes += attr.getType(); + if (includeName) { + attributes += " " + attr.getName(); + } + attributes += ", "; + } + if (attributes.length() > 0) { + attributes = attributes.substring(0, attributes.length() - 2); + } + return attributes; + } + + public static String capitalize(String s) { + return StringUtils.capitalize(s); + } + + public static boolean isAssociationClassDoublon(ObjectModelAttribute attr) { + return (attr.getReverseAttribute() != null) && (attr.getDeclaringElement().equals(attr.getReverseAttribute().getDeclaringElement())) && (!GeneratorUtil.isFirstAttribute(attr)); + } + + /** + * Renvoie le nom de l'attribut de classe d'association en fonction des cas: + * Si l'attribut porte le même nom que le type (extrémité inverse de + * l'association), on lui ajoute le nom de la classe d'association + * + * @param attr l'attribut a traiter + * @return le nom de l'attribut de classe d'association + */ + public static String getAssocAttrName(ObjectModelAttribute attr) { + String typeName = attr.getType().substring( + attr.getType().lastIndexOf(".") + 1); + String result = attr.getName(); + if (attr.getName().equalsIgnoreCase(typeName)) { + result += capitalize(attr.getAssociationClass().getName()); + } + return result; + } + + public static String getDOType(ObjectModelElement elem, ObjectModel model) { + String type = elem.getName(); + if (elem instanceof ObjectModelAttribute) { + type = ((ObjectModelAttribute) elem).getType(); + } + if (elem instanceof ObjectModelClass) { + type = ((ObjectModelClass) elem).getQualifiedName(); + } + return getDOType(type, model); + } + + public static String getDOType(String type, ObjectModel model) { + if (!model.hasClass(type)) { + return type; + } + ObjectModelClass clazz = model.getClass(type); + if (clazz.hasStereotype(STEREOTYPE_ENTITY)) { + if (shouldBeAbstract(clazz)) { + type += "Abstract"; + } else { + type += "Impl"; + } + } + return type; + } + private static final Set<String> numberTypes = new HashSet<String>(); + private static final Set<String> textTypes = new HashSet<String>(); + private static final Set<String> booleanTypes = new HashSet<String>(); + private static final Set<String> primitiveTypes = new HashSet<String>(); + private static final String VOID_TYPE = "void"; + + static { + numberTypes.add("byte"); + numberTypes.add("java.lang.Byte"); + numberTypes.add("Byte"); + numberTypes.add("short"); + numberTypes.add("java.lang.Short"); + numberTypes.add("Short"); + numberTypes.add("int"); + numberTypes.add("java.lang.Integer"); + numberTypes.add("Integer"); + numberTypes.add("long"); + numberTypes.add("java.lang.Long"); + numberTypes.add("Long"); + numberTypes.add("float"); + numberTypes.add("java.lang.Float"); + numberTypes.add("Float"); + numberTypes.add("double"); + numberTypes.add("java.lang.Double"); + numberTypes.add("Double"); + + textTypes.add("char"); + textTypes.add("java.lang.Char"); + textTypes.add("Char"); + textTypes.add("java.lang.String"); + textTypes.add("String"); + + booleanTypes.add("boolean"); + booleanTypes.add("java.lang.Boolean"); + booleanTypes.add("Boolean"); + + primitiveTypes.addAll(numberTypes); + primitiveTypes.addAll(textTypes); + primitiveTypes.addAll(booleanTypes); + } + + public static boolean isNumericType(ObjectModelAttribute attr) { + return numberTypes.contains(attr.getType()); + } + + public static boolean isTextType(ObjectModelAttribute attr) { + return textTypes.contains(attr.getType()); + } + + public static boolean isDateType(ObjectModelAttribute attr) { + return "java.util.Date".equals(attr.getType()); + } + + public static boolean isBooleanType(ObjectModelAttribute attr) { + return booleanTypes.contains(attr.getType()); + } + + public static boolean isPrimitiveType(ObjectModelAttribute attr) { + return primitiveTypes.contains(attr.getType()); + } + + /** + * Indique si la classe specifiee n'a aucune ou que des methodes abstraites + * + * @param clazz l'instance de ObjectModelClass + * @return true si la classe n'a que des operations abstraite ou aucune + * operation + */ + public static boolean hasNothingOrAbstractMethods(ObjectModelClass clazz) { + boolean result = true; + Iterator<?> operations = clazz.getOperations().iterator(); + while (result && operations.hasNext()) { + ObjectModelOperation op = (ObjectModelOperation) operations.next(); + result = op.isAbstract(); + } + return result; + } + + /** + * Indique si la classe specifiee devrait etre abstraite + * + * @param clazz l'instance de ObjectModelClass + * @return true dans ce cas, false sinon + */ + public static boolean shouldBeAbstract(ObjectModelClass clazz) { + return clazz != null && (clazz.isAbstract() && hasNothingOrAbstractMethods(clazz)); + } + + /** + * <p> + * Cette méthode permet de détecter si + * - l'attribut représente une relation 1-n + * - cette relation est unidirectionnelle + * - le type de l'attribut représente un entité + * - cette entité a des sous-classes dans le modèle + * <p/> + * Ce cas correspond à une incompatibilité d'Hibernate qui nous oblige a + * adopter un comportement particulier. + * </p> + * + * @param attr l'attribut a tester + * @param model le model + * @return true si et seulement si il s'agit bien de ce type de relation + */ + public static boolean hasUnidirectionalRelationOnAbstractType( + ObjectModelAttribute attr, ObjectModel model) { + ObjectModelAttribute reverse = attr.getReverseAttribute(); + //relation 1-n + if (reverse != null && isNMultiplicity(attr) && !isNMultiplicity(reverse)) { + //Pas de navigabilité + if (!reverse.isNavigable()) { + //Il s'agit d'une entity + ObjectModelClass clazz = model.getClass(attr.getType()); + if (clazz != null && clazz.hasStereotype(STEREOTYPE_ENTITY)) { + //Cette classe a des sous-classes dans le modèle + for (ObjectModelClass subClass : model.getClasses()) { + if (subClass.getSuperclasses().contains(clazz)) { + return true; + } + } + } + } + } + return false; + } + + /** + * Renvoie le nom unique de table pour une relation ManyToMany en fonction + * de l'attribut <code>attr</code> + * <p/> + * Plusieurs cas de figure: + * <li> + * + * @param attr l'attribut servant de base au calcul du nom + * @return le nom de la table + */ + public static String getManyToManyTableName(ObjectModelAttribute attr) { + String result; + + if (attr.hasAssociationClass()) { + result = TopiaGeneratorUtil.getDBName(attr.getAssociationClass()); + } else { + String name = attr.getName(); + String revers = attr.getReverseAttributeName(); + + if (name.compareToIgnoreCase(revers) < 0) { + result = name + "_" + revers; + } else { + result = revers + "_" + name; + } + } + // String result; + // if (!Util.isFirstAttribute(attr)) { + // result = attr.getDeclaringElement().getName() + "_" + attr.getReverseAttribute().getDeclaringElement().getName(); + // } else { + // result = attr.getReverseAttribute().getDeclaringElement().getName() + "_" + attr.getDeclaringElement().getName(); + // } + return result.toLowerCase(); + } + + /** + * Renvoie le type d'interface à utiliser en fonction de l'attribut + * + * @param attr l'attribut a traiter + * @return String + */ + public static String getNMultiplicityInterfaceType(ObjectModelAttribute attr) { + if (attr.hasStereotype(STEREOTYPE_UNIQUE)) { + return Set.class.getName(); + } else if (attr.isIndexed() || attr.isOrdered()) { + return List.class.getName(); + } + return Collection.class.getName(); + } + + /** + * Renvoie le type d'objet (instance) à utiliser en fonction de l'attribut + * + * @param attr l'attribut a traiter + * @return String + */ + public static String getNMultiplicityObjectType(ObjectModelAttribute attr) { + if (attr.hasStereotype(STEREOTYPE_UNIQUE)) { + return HashSet.class.getName(); + } else if (attr.isIndexed() || attr.isOrdered()) { + //On considère qu'on ne sait pas traiter vraiment l'attribut "ordered" + // puisqu'on va conserver l'ordre d'insertion, et non un ordre en + // fonction d'un élément donné. Donc on renvoi une ArrayList + return ArrayList.class.getName(); + } + LinkedList.class.getName(); + return ArrayList.class.getName(); + } + + /** + * Renvoie le type d'interface à utiliser en fonction de l'attribut + * + * @param attr l'attribut a traiter + * @return String + */ + public static String getNMultiplicityHibernateType(ObjectModelAttribute attr) { + if (attr.hasStereotype(STEREOTYPE_UNIQUE)) { + return "set"; + } else if (attr.isIndexed()) { + return "list"; + } + //attr.isOrdered() - On génère le ordered en bag + return "bag"; + } + + /** + * Obtain the list of entities classes with the possibility to sort the result. + * + * @param model the current model to scan + * @param sort flag to allow sort the result + * @return the list of filtred classes by their stereotype + */ + public static List<ObjectModelClass> getEntityClasses(ObjectModel model, + boolean sort) { + return getClassesByStereotype(STEREOTYPE_ENTITY, model, sort); + } + + /** + * Obtain the list of classes for a given stereotype with the possibility to sort the result. + * + * @param stereotype filter stereotype + * @param model the current model to scan + * @param sort flag to allow sort the result + * @return the list of filtred classes by their stereotype + */ + public static List<ObjectModelClass> getClassesByStereotype( + String stereotype, ObjectModel model, boolean sort) { + List<ObjectModelClass> classes = new ArrayList<ObjectModelClass>(); + for (ObjectModelClass clazz : model.getClasses()) { + if (clazz.hasStereotype(stereotype)) { + classes.add(clazz); + } + } + if (sort && !classes.isEmpty()) { + java.util.Collections.sort(classes, + new java.util.Comparator<ObjectModelClass>() { + + @Override + public int compare(ObjectModelClass o1, + ObjectModelClass o2) { + return o1.getQualifiedName().compareTo( + o2.getQualifiedName()); + } + }); + } + return classes; + } + + /** + * Detecte si la clef metier d'une classe est mutable ou pas. + * <p/> + * On respecte la valeur par defaut d'hibernate, à savoir que par default une clef metier est non mutable. + * + * @param clazz la classe a tester + * @return <code>true</code> si le tag value a ete positionne sur la classe via le tag + * {@link #TAG_NATURAL_ID_MUTABLE}, , <code>false</code> sinon. + */ + public static boolean isNaturalIdMutable(ObjectModelClass clazz) { + String value = clazz.getTagValue(TAG_NATURAL_ID_MUTABLE); + if (!notEmpty(value)) { + // valeur null, donc par default positionnee + return false; + } + try { + return Boolean.valueOf(value.trim()); + } catch (Exception e) { + // on a pas reussi a convertir en boolean. + //todo peut-être declancher une exception ? + return false; + } + } + + /** + * Obtain the list of fqn of object involed in the given class. + * + * @param aClass the clazz to inspect + * @param incomingFqns incoming fqns + * @return the list of fqn of attributes + */ + public static List<String> getImports(ObjectModelClass aClass, String... incomingFqns) { + Set<String> tmp = new HashSet<String>(); + tmp.addAll(Arrays.asList(incomingFqns)); + getImports(aClass, tmp); + List<String> result = cleanImports(aClass.getPackageName(), tmp); + return result; + } + + /** + * Obtain the list of fqn of object involed in the given interface. + * + * @param anInterface the interface to inspect + * @param incomingFqns incoming fqns + * @return the list of fqn of attributes + */ + public static List<String> getImports(ObjectModelInterface anInterface, String... incomingFqns) { + Set<String> tmp = new HashSet<String>(); + tmp.addAll(Arrays.asList(incomingFqns)); + getImports(anInterface, tmp); + List<String> result = cleanImports(anInterface.getPackageName(), tmp); + return result; + } + + public static String getSimpleName(String fqn) { + int lasIndex = fqn.lastIndexOf("."); + if (lasIndex == 1) { + // primitive type + return fqn; + } + return fqn.substring(lasIndex + 1); + /*if (lasIndex == aClass.getPackageName().length()) { + // same package + return fqn.substring(lasIndex + 1); + } + + return fqn;*/ + } + + /** + * Obtain the list of fqn of object involed in the given class. + * + * @param aClass the class to inspect + * @param fqns where to store found fqns + */ + protected static void getImports(ObjectModelClass aClass, Set<String> fqns) { + // scan attributes + for (ObjectModelAttribute attr : aClass.getAttributes()) { + fqns.add(attr.getType()); + if (isNMultiplicity(attr)) { + String collectionType = getNMultiplicityInterfaceType(attr); + fqns.add(collectionType); + String collectionObject = getNMultiplicityObjectType(attr); + fqns.add(collectionObject); + } + } + for (ObjectModelAttribute attribute : aClass.getAllOtherAttributes()) { + fqns.add(attribute.getType()); + } + // scan associations + if (aClass instanceof ObjectModelAssociationClass) { + ObjectModelAssociationClass assoc = (ObjectModelAssociationClass) aClass; + for (ObjectModelAttribute attr : assoc.getParticipantsAttributes()) { + if (attr == null) { + continue; + } + fqns.add(attr.getType()); + if (isNMultiplicity(attr)) { + String collectionType = getNMultiplicityInterfaceType(attr); + fqns.add(collectionType); + String collectionObject = getNMultiplicityObjectType(attr); + fqns.add(collectionObject); + } + } + } + // scan operations + for (ObjectModelOperation operation : aClass.getOperations()) { + getImports(operation, fqns); + } + // scan super interfaces + for (ObjectModelInterface modelInterface : aClass.getInterfaces()) { + fqns.add(modelInterface.getQualifiedName()); + getImports(modelInterface, fqns); + } + // scan super classes + for (ObjectModelClass modelClass : aClass.getSuperclasses()) { + fqns.add(modelClass.getQualifiedName()); + getImports(modelClass); + } + } + + /** + * Obtain the list of fqn of object involed in the given interface. + * + * @param anInterface the interface to inspect + * @param fqns where to store found fqns + */ + protected static void getImports(ObjectModelInterface anInterface, Set<String> fqns) { + // scan operations + for (ObjectModelOperation operation : anInterface.getOperations()) { + getImports(operation, fqns); + } + // scan super interfaces + for (ObjectModelInterface modelInterface : anInterface.getInterfaces()) { + fqns.add(modelInterface.getQualifiedName()); + getImports(modelInterface, fqns); + } + } + + /** + * Obtain the fqn's list of all involed type in a givne operation. + * + * @param operation operation to inspect + * @param fqns where to store found fqns + */ + protected static void getImports(ObjectModelOperation operation, Set<String> fqns) { + String fqn = operation.getReturnType(); + fqns.add(fqn); + for (ObjectModelParameter parameter : operation.getParameters()) { + fqns.add(parameter.getType()); + } + } + + /** + * Clean a set of fqns, transform it into a {@link List} and sort it. + * + * @param packageName the current package name + * @param fqns the dirty set of fqns + * @return the sorted cleaned list of fqns. + */ + protected static List<String> cleanImports(String packageName, Set<String> fqns) { + fqns.removeAll(primitiveTypes); + fqns.remove(VOID_TYPE); + int packageLength = packageName.length(); + List<String> genericType = new ArrayList<String>(); + for (Iterator<String> it = fqns.iterator(); it.hasNext();) { + String fqn = it.next(); + int lastIndex = fqn.lastIndexOf("."); + if (lastIndex == packageLength && fqn.startsWith(packageName)) { + // same package + it.remove(); + continue; + } + int genericIndex = fqn.indexOf('<'); + if (genericIndex != -1) { + genericType.add(fqn.substring(0, genericIndex)); + it.remove(); + } + } + fqns.addAll(genericType); + + ArrayList<String> result = new ArrayList<String>(fqns); + java.util.Collections.sort(result); + return result; + } + + /** + * Convertit un nom de variable en nom de constante. + * + * @param variableName le nom de variable a convertir + * @return le nom de la constante à partir du nom de la variable + */ + public static String convertVariableNameToConstantName(String variableName) { + //TODO Faire des tests pour savoir si variableName est non null et valide + //TODO Ameliorer l'algo pour tenir compte des caractères non alpha + //TODO pour le moment cela convient, donc... + StringBuilder buffer = new StringBuilder(); + boolean lastCarIsUp = false; + for (int i = 0, j = variableName.length(); i < j; i++) { + char c = variableName.charAt(i); + boolean carIsUp = Character.isUpperCase(c); + if (i > 0 && !lastCarIsUp && carIsUp) { + // ajout d'un _ + buffer.append('_'); + } + if (carIsUp) { + buffer.append(c); + } else { + buffer.append(Character.toUpperCase(c)); + } + lastCarIsUp = carIsUp; + } + return buffer.toString(); + } +} // GeneratorUtil + Added: branches/1.1.0-Javabuilder/eugene-test/src/main/models/dtotest.objectmodel =================================================================== --- branches/1.1.0-Javabuilder/eugene-test/src/main/models/dtotest.objectmodel (rev 0) +++ branches/1.1.0-Javabuilder/eugene-test/src/main/models/dtotest.objectmodel 2009-10-27 10:32:23 UTC (rev 661) @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="UTF-8"?> +<objectModel xmlns="http://www.codelutin.org/eugene/objectModel" name="TopiaTest" version="1"> + <class name="Personne" package="org.nuiton.eugene.test"> + <stereotype name="entity"/> + <superclass name="org.nuiton.eugene.test.Party2" discriminator=""/> + <attribute name="name" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute name="otherNames" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="0" maxMultiplicity="-1"/> + <attribute visibility="public" type="org.nuiton.eugene.test.Address" reverseAttributeName="" associationType="aggregate" reverseMaxMultiplicity="1" minMultiplicity="1" maxMultiplicity="1" navigable="true" ordering="unordered"/> + </class> + <class name="Employe" package="org.nuiton.eugene.test"> + <stereotype name="entity"/> + <superclass name="org.nuiton.eugene.test.Personne" discriminator=""/> + <attribute name="salary" associationType="composite" visibility="public" type="int" minMultiplicity="1" maxMultiplicity="1"/> + <attribute visibility="public" type="org.nuiton.eugene.test.Company" reverseAttributeName="" reverseMaxMultiplicity="-1" minMultiplicity="1" maxMultiplicity="1" navigable="false" ordering="unordered"/> + <attribute name="lead" visibility="public" type="org.nuiton.eugene.test.Department" reverseAttributeName="leader" reverseMaxMultiplicity="1" minMultiplicity="0" maxMultiplicity="1" navigable="false" ordering="unordered"/> + </class> + <class name="Company" package="org.nuiton.eugene.test"> + <stereotype name="entity"/> + <attribute name="name" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute visibility="public" type="org.nuiton.eugene.test.Employe" reverseAttributeName="" reverseMaxMultiplicity="1" minMultiplicity="0" maxMultiplicity="-1" navigable="true" ordering="unordered"/> + <attribute visibility="public" associationClassName="org.nuiton.eugene.test.Bill" type="org.nuiton.eugene.test.Store" reverseAttributeName="" reverseMaxMultiplicity="-1" minMultiplicity="0" maxMultiplicity="-1" navigable="true" ordering="unordered"/> + <attribute visibility="public" type="org.nuiton.eugene.test.Department" reverseAttributeName="" associationType="composite" reverseMaxMultiplicity="1" minMultiplicity="0" maxMultiplicity="-1" navigable="true" ordering="unordered"/> + </class> + <class name="Address" package="org.nuiton.eugene.test"> + <stereotype name="entity"/> + <attribute name="city" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute name="adress" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute visibility="public" type="org.nuiton.eugene.test.Personne" reverseAttributeName="" reverseMaxMultiplicity="1" minMultiplicity="1" maxMultiplicity="1" navigable="false" ordering="unordered"/> + </class> + <class name="Department" package="org.nuiton.eugene.test"> + <stereotype name="entity"/> + <attribute name="name" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute name="leader" visibility="public" type="org.nuiton.eugene.test.Employe" reverseAttributeName="lead" reverseMaxMultiplicity="1" minMultiplicity="1" maxMultiplicity="1" navigable="true" ordering="unordered"/> + <attribute visibility="public" type="org.nuiton.eugene.test.Company" reverseAttributeName="" reverseMaxMultiplicity="-1" minMultiplicity="1" maxMultiplicity="1" navigable="true" ordering="unordered"/> + <attribute visibility="public" type="org.nuiton.eugene.test.Product" reverseAttributeName="" reverseMaxMultiplicity="1" minMultiplicity="0" maxMultiplicity="-1" navigable="true" ordering="unordered"/> + </class> + <class name="Product" package="org.nuiton.eugene.test"> + <stereotype name="entity"/> + <attribute name="name" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute visibility="public" type="org.nuiton.eugene.test.Department" reverseAttributeName="" reverseMaxMultiplicity="-1" minMultiplicity="1" maxMultiplicity="1" navigable="false" ordering="unordered"/> + <attribute visibility="public" type="org.nuiton.eugene.test.Type" reverseAttributeName="" reverseMaxMultiplicity="-1" minMultiplicity="1" maxMultiplicity="1" navigable="true" ordering="unordered"/> + </class> + <class name="Store" package="org.nuiton.eugene.test"> + <stereotype name="entity"/> + <attribute name="name" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute name="DEFAULT_NUM" associationType="composite" visibility="public" static="true" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute name="numStore" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <operation name="getDefaultNum" visibility="public" static="true"> + <returnParameter type="java.lang.String"/> + </operation> + <class name="Row" package="org.nuiton.eugene.test"> + <attribute name="num" associationType="composite" visibility="public" type="int" minMultiplicity="1" maxMultiplicity="1"/> + <attribute name="position" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + </class> + <attribute visibility="public" associationClassName="org.nuiton.eugene.test.Bill" type="org.nuiton.eugene.test.Company" reverseAttributeName="" reverseMaxMultiplicity="-1" minMultiplicity="0" maxMultiplicity="-1" navigable="false" ordering="unordered"/> + </class> + <class name="Type" package="org.nuiton.eugene.test"> + <stereotype name="entity"/> + <attribute name="name" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute visibility="public" type="org.nuiton.eugene.test.Product" reverseAttributeName="" reverseMaxMultiplicity="1" minMultiplicity="0" maxMultiplicity="-1" navigable="false" ordering="unordered"/> + </class> + <associationClass name="Bill" package="org.nuiton.eugene.test"> + <stereotype name="entity"/> + <participant name="org.nuiton.eugene.test.Company" attribute=""/> + <participant name="org.nuiton.eugene.test.Store" attribute=""/> + <attribute name="cost" associationType="composite" visibility="public" type="int" minMultiplicity="1" maxMultiplicity="1"/> + <attribute name="date" associationType="composite" visibility="public" type="java.util.Date" minMultiplicity="1" maxMultiplicity="1"/> + </associationClass> + <class name="Voiture" abstract="true" package="org.nuiton.eugene.test.beangen"> + <stereotype name="bean"/> + <tagValue name="documentation" value="Doc for BeanA"/> + <interface name="org.nuiton.eugene.test.beangen.Vehicule"/> + <attribute name="immatriculation" associationType="composite" visibility="public" type="int" minMultiplicity="1" maxMultiplicity="1"> + <tagValue name="documentation" value="attrA of BeanA"/> + </attribute> + <attribute name="modele" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute name="proprietaire" associationType="composite" visibility="public" type="org.nuiton.eugene.test.Personne" minMultiplicity="1" maxMultiplicity="1"/> + <attribute visibility="public" type="org.nuiton.eugene.test.beangen.Roue" reverseAttributeName="" associationType="composite" reverseMaxMultiplicity="1" minMultiplicity="4" maxMultiplicity="4" navigable="true" ordering="unordered"/> + <attribute visibility="public" type="org.nuiton.eugene.test.beangen.Siege" reverseAttributeName="" associationType="composite" reverseMaxMultiplicity="1" minMultiplicity="1" maxMultiplicity="4" navigable="true" ordering="unordered"/> + </class> + <class name="Roue" package="org.nuiton.eugene.test.beangen"> + <stereotype name="bean"/> + <operation name="mount" visibility="public"> + <returnParameter type="void"/> + </operation> + <operation name="getModel" visibility="public"> + <returnParameter type="org.nuiton.eugene.test.Product"/> + <parameter name="id" type="java.lang.String"/> + </operation> + <attribute visibility="public" type="org.nuiton.eugene.test.beangen.Voiture" reverseAttributeName="" reverseMaxMultiplicity="4" minMultiplicity="1" maxMultiplicity="1" navigable="true" ordering="unordered"/> + </class> + <class name="RelationDTO" package="org.nuiton.eugene.test.beangen"> + <stereotype name="dto"/> + <attribute name="idCompany" associationType="composite" visibility="public" type="int" minMultiplicity="1" maxMultiplicity="1"/> + <attribute name="idDepartement" associationType="composite" visibility="public" type="int" minMultiplicity="1" maxMultiplicity="1"/> + <attribute name="dateDebut" associationType="composite" visibility="public" type="java.util.Date" minMultiplicity="1" maxMultiplicity="1"/> + <attribute name="person" visibility="public" type="org.nuiton.eugene.test.beangen.PersonneDTO" reverseAttributeName="" reverseMaxMultiplicity="-1" minMultiplicity="1" maxMultiplicity="1" navigable="true" ordering="unordered"/> + </class> + <class name="PersonneDTO" package="org.nuiton.eugene.test.beangen"> + <dependency name="" supplierName="org.nuiton.eugene.test.Personne"/> + <stereotype name="dto"/> + <attribute visibility="public" type="org.nuiton.eugene.test.beangen.RelationDTO" reverseAttributeName="person" reverseMaxMultiplicity="1" minMultiplicity="0" maxMultiplicity="-1" navigable="false" ordering="unordered"/> + </class> + <class name="Siege" package="org.nuiton.eugene.test.beangen"> + <stereotype name="bean"/> + <attribute name="noSerie" associationType="composite" visibility="public" type="int" minMultiplicity="1" maxMultiplicity="1"/> + <attribute visibility="public" type="org.nuiton.eugene.test.beangen.Voiture" reverseAttributeName="" reverseMaxMultiplicity="4" minMultiplicity="1" maxMultiplicity="1" navigable="true" ordering="unordered"/> + </class> + <interface name="Vehicule" package="org.nuiton.eugene.test.beangen"> + <operation name="start" visibility="public"> + <returnParameter type="void"/> + </operation> + </interface> + <class name="Contact2" package="org.nuiton.eugene.test.deletetest"> + <stereotype name="entity"/> + <attribute name="contactValue" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute name="type" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <operation name="findAllByCompany" visibility="public"> + <returnParameter type="java.util.Set<Contact2>"/> + <parameter name="company" type="org.nuiton.eugene.test.Company"/> + <stereotype name="dao"/> + </operation> + <attribute visibility="public" type="org.nuiton.eugene.test.Party2" reverseAttributeName="contacts" reverseMaxMultiplicity="-1" minMultiplicity="0" maxMultiplicity="-1" navigable="true" ordering="unordered"/> + </class> + <class name="Telephone2" package="org.nuiton.eugene.test.deletetest"> + <stereotype name="entity"/> + <superclass name="org.nuiton.eugene.test.Contact2" discriminator=""/> + <attribute name="prefix" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute name="country" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + </class> + <class name="Party2" package="org.nuiton.eugene.test.deletetest"> + <stereotype name="entity"/> + <attribute name="contacts" visibility="public" type="org.nuiton.eugene.test.Contact2" reverseAttributeName="" reverseMaxMultiplicity="-1" minMultiplicity="0" maxMultiplicity="-1" navigable="true" ordering="unordered"/> + </class> + <class name="Person" package="org.nuiton.topia.test.entities"> + <stereotype name="entity"/> + <attribute name="name" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute name="firstname" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute visibility="public" type="org.nuiton.topia.test.entities.Pet" reverseAttributeName="" reverseMaxMultiplicity="1" minMultiplicity="0" maxMultiplicity="-1" navigable="true" ordering="unordered"/> + </class> + <class name="Pet" package="org.nuiton.topia.test.entities"> + <stereotype name="entity"/> + <attribute name="name" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute name="type" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute visibility="public" type="org.nuiton.topia.test.entities.Person" reverseAttributeName="" reverseMaxMultiplicity="-1" minMultiplicity="1" maxMultiplicity="1" navigable="true" ordering="unordered"/> + <attribute visibility="public" type="org.nuiton.topia.test.entities.Race" reverseAttributeName="" associationType="composite" reverseMaxMultiplicity="1" minMultiplicity="1" maxMultiplicity="1" navigable="true" ordering="unordered"/> + </class> + <class name="Race" package="org.nuiton.topia.test.entities"> + <stereotype name="entity"/> + <attribute name="name" associationType="composite" visibility="public" type="java.lang.String" minMultiplicity="1" maxMultiplicity="1"/> + <attribute visibility="public" type="org.nuiton.topia.test.entities.Pet" reverseAttributeName="" reverseMaxMultiplicity="1" minMultiplicity="1" maxMultiplicity="1" navigable="false" ordering="unordered"/> + </class> + <class name="Set<Contact2>" package="java.util"/> +</objectModel> Added: branches/1.1.0-Javabuilder/eugene-test/src/test/resources/log4j.properties =================================================================== --- branches/1.1.0-Javabuilder/eugene-test/src/test/resources/log4j.properties (rev 0) +++ branches/1.1.0-Javabuilder/eugene-test/src/test/resources/log4j.properties 2009-10-27 10:32:23 UTC (rev 661) @@ -0,0 +1,12 @@ +# Global logging configuration +log4j.rootLogger=ERROR, stdout + +# Console output... +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) %M - %m%n + +# package level +log4j.logger.org.nuiton.eugene=INFO +log4j.logger.org.nuiton.eugene.test=DEBUG +log4j.logger.org.nuiton.processor=DEBUG Modified: branches/1.1.0-Javabuilder/maven-eugene-plugin/src/main/java/org/nuiton/eugene/plugin/EugenePlugin.java =================================================================== --- branches/1.1.0-Javabuilder/maven-eugene-plugin/src/main/java/org/nuiton/eugene/plugin/EugenePlugin.java 2009-10-26 18:35:44 UTC (rev 660) +++ branches/1.1.0-Javabuilder/maven-eugene-plugin/src/main/java/org/nuiton/eugene/plugin/EugenePlugin.java 2009-10-27 10:32:23 UTC (rev 661) @@ -33,7 +33,9 @@ import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; +import org.nuiton.eugene.ModelReader; import org.nuiton.eugene.Generator; +import org.nuiton.eugene.models.Model; import org.nuiton.plugin.PluginIOContext; import org.nuiton.plugin.PluginHelper; @@ -136,10 +138,20 @@ */ protected String generatedPackages; + /** + * Reader for transform input files in a Model to generate + * + * @parameter expression="${eugene.reader}" + * @since 1.1.0 + */ + protected String reader; + + @Override public void doAction() throws MojoExecutionException, MojoFailureException { getLog().info("Generating java sources from models"); + getLog().info(" reader : " + reader); getLog().info(" includes : " + includes); getLog().info(" using template : " + templates); getLog().info(" using defaultPackage : " + defaultPackage); @@ -156,6 +168,14 @@ } } + ModelReader modelReader = getReader(); + if (modelReader == null) { + // can skip + getLog().warn("no reader to use"); + return; + } + Model model = modelReader.read(modelFiles); + List<String> packages = getPackagesToGenerate(); if (packages == null) { @@ -164,13 +184,14 @@ getLog().info(" generating only for packages " + packages); } - List<Generator> generators = getGenerators(packages); + List<Generator> generators = getGenerators(packages, modelReader); for (Generator generator : generators) { getLog().info("Apply " + generator.getClass().getSimpleName() + " generator"); //TC-20090829 fix when loading more than one model together... - generator.generate(modelFiles, generateResources.getOutput()); + + generator.generate(model, generateResources.getOutput()); // for (File modelFile : modelFiles) { // getLog().debug(" on " + modelFile.getAbsolutePath()); // @@ -261,7 +282,24 @@ // return modelFiles.toArray(new File[modelFiles.size()]); // } - protected List<Generator> getGenerators(List<String> generatedPackagesAsList) throws MojoFailureException, MojoExecutionException { + protected ModelReader getReader() throws MojoFailureException, MojoExecutionException { + ModelReader modelReader = null; + try { + ClassLoader fixedClassLoader = fixClassLoader(); + modelReader = (ModelReader) Class.forName(reader, + true, fixedClassLoader).newInstance(); + } catch (InstantiationException eee) { + throw new MojoFailureException("Can't instantiate reader : " + reader, eee); + } catch (IllegalAccessException eee) { + throw new MojoFailureException("Can't access reader : " + reader, eee); + } catch (ClassNotFoundException eee) { + throw new MojoFailureException("Can't found reader : " + reader, eee); + } + return modelReader; + } + + protected List<Generator> getGenerators(List<String> generatedPackagesAsList, ModelReader modelReader) + throws MojoFailureException, MojoExecutionException { // init generators Properties generatorProperties = new Properties(); generatorProperties.setProperty("defaultPackage", defaultPackage); @@ -279,6 +317,7 @@ generator.setProperties(generatorProperties); generator.setOverwrite(overwrite); generator.setEncoding(encoding); + generator.setLastModifiedSource(modelReader.getLastModifiedSource()); generator.setGeneratedPackages(generatedPackagesAsList); generators.add(generator); } catch (InstantiationException e) {
participants (1)
-
fdesbois@users.nuiton.org