Re: [Eugene-devel] [Wikitty-commits] r1051 - trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator
J'ai modifier le transformer de wikitty qui transforme un modele en un autre. Il étendait ObjectModelTransformerToJava, mais comme il ne génère pas de java, il est mieux d'étendre seulement ObjectModelTransformer. Autre point, pour utiliser un simple ObjectModel au lieu d'un JavaGenerator, j'ai du copier/coller beaucoup beaucoup de code. Essentiellement toutes les méthodes cloneXXX() Je pense qu'il y aurait une factorisation possible sur un transformer qui fait de la copie, mais pas typé Java... Le 05/07/2011 16:13, echatellier@users.nuiton.org a écrit :
Author: echatellier Date: 2011-07-05 16:13:10 +0200 (Tue, 05 Jul 2011) New Revision: 1051
Url: http://nuiton.org/repositories/revision/wikitty/1051
Log: Fix model transformation (to generate new modele instead of java)
Modified: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyPurifierTransformer.java
Modified: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyPurifierTransformer.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyPurifierTransformer.java 2011-07-05 14:12:19 UTC (rev 1050) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyPurifierTransformer.java 2011-07-05 14:13:10 UTC (rev 1051) @@ -5,7 +5,7 @@ * $Id$ * $HeadURL$ * %% - * Copyright (C) 2009 - 2010 CodeLutin, Benjamin Poussin + * Copyright (C) 2009 - 2011 CodeLutin, Benjamin Poussin, Chatellier Eric * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as @@ -25,35 +25,53 @@ package org.nuiton.wikitty.generator;
import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map;
+import org.apache.commons.collections.CollectionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.nuiton.eugene.java.ObjectModelTransformerToJava; +import org.nuiton.eugene.GeneratorUtil; +import org.nuiton.eugene.Template; import org.nuiton.eugene.models.object.ObjectModel; import org.nuiton.eugene.models.object.ObjectModelAttribute; +import org.nuiton.eugene.models.object.ObjectModelBuilder; 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.ObjectModelGenerator; +import org.nuiton.eugene.models.object.ObjectModelInterface; +import org.nuiton.eugene.models.object.ObjectModelModifier; +import org.nuiton.eugene.models.object.ObjectModelOperation; +import org.nuiton.eugene.models.object.ObjectModelParameter; +import org.nuiton.eugene.models.object.ObjectModelTransformer; +import org.nuiton.eugene.models.object.ObjectModelType;
/** - * this transformer read the original user model and generate the intermediate - * model needed by generators. + * This transformer read the original user model and generate the intermediate + * model needed by generators. * - * - * + * Currently: + * - manage name collision for attributes or methods inherited from two + * different classes */ -public class WikittyPurifierTransformer extends ObjectModelTransformerToJava { +public class WikittyPurifierTransformer extends ObjectModelTransformer<ObjectModel> {
private static final Log log = LogFactory.getLog(WikittyPurifierTransformer.class);
/** for a given class, store all the names used by this class and subClasses */ - Map<ObjectModelClass, List<String>> namesUsedByClass = new HashMap<ObjectModelClass, List<String>>(); + protected Map<ObjectModelClass, List<String>> namesUsedByClass = new HashMap<ObjectModelClass, List<String>>();
/** class of the original model that are already processed */ - List<ObjectModelClass> processedClasses = new ArrayList<ObjectModelClass>(); + protected List<ObjectModelClass> processedClasses = new ArrayList<ObjectModelClass>();
+ /** Generated model builder. */ + protected ObjectModelBuilder builder; + /** * for a given, class read all attributes name and try to find conflicts * with parent classes attributes names. @@ -129,7 +147,7 @@ // using alternative name lead to a conflict attributeName = null; } else { - addTagValue(attribute, WikittyTransformerUtil.TAG_ALTERNATIVE_NAME, attributeName); + builder.addTagValue(attribute, WikittyTransformerUtil.TAG_ALTERNATIVE_NAME, attributeName); } }
@@ -142,8 +160,17 @@ WikittyTransformerUtil.TAG_ALTERNATIVE_NAME + "\" on this attribute"); } else { + + if (isVerbose()) { + if (!attributeName.equals(attribute.getName())) { + log.info("attribute " + attribute.getName() + " purified to " + attributeName); + } + } + allUsedNames.add(attributeName); } + + }
// saving all names we used in current class will permit to sub classes @@ -163,4 +190,304 @@ } } } + + @Override + protected Template<ObjectModel> initOutputTemplate() { + return new ObjectModelGenerator(); + } + + /* + * @see org.nuiton.eugene.models.object.ObjectModelTransformer#debugOutputModel() + */ + @Override + protected void debugOutputModel() { + + } + + /* + * @see org.nuiton.eugene.Transformer#initOutputModel() + */ + @Override + protected ObjectModel initOutputModel() { + builder = new ObjectModelBuilder(getModel().getName()); + ObjectModel model = builder.getModel(); + return model; + } + + /** + * creates a clone of the given {@code source} class in the output model + * and clones attributes, inheritance declarations and operations into the + * clone + * + * @param source the class to clone from the source model + * @param cloneDocumentation flag to add documentation if some found in model + * @return the clone of the given class + */ + public ObjectModelClass cloneClass(ObjectModelClass source, + boolean cloneDocumentation) { + ObjectModelClass outputClass = + builder.createClass(source.getName(), source.getPackageName()); + + cloneClassifier(source, outputClass, cloneDocumentation); + + for (ObjectModelClass superClass : source.getSuperclasses()) { + builder.addSuperclass(outputClass, superClass.getQualifiedName()); + } + + if (!CollectionUtils.isEmpty(source.getInnerClassifiers())) { + for (ObjectModelClassifier classifier : source.getInnerClassifiers()) { + ObjectModelClassifier innerClassifierClone = + cloneClassifier(classifier, cloneDocumentation); + builder.addInnerClassifier(outputClass, + ObjectModelType.OBJECT_MODEL_CLASSIFIER, + innerClassifierClone.getName()); + } + } + return outputClass; + } + + /** + * creates a clone of the given {@code source} classifier in the output + * model and clones attributes, inheritance declaration and operations + * + * class-specific, enumeration-specific and interface-specific features + * of the given classifier <strong>will</strong> be present in the clone + * + * @param source the classifier to clone from the source model + * @param cloneDocumentation flag to add documentation if some found in model + * @return the clone of the given classifier + */ + public ObjectModelClassifier cloneClassifier(ObjectModelClassifier source, + boolean cloneDocumentation) { + ObjectModelClassifier clone = null; + if (source.isInterface()) { + clone = cloneInterface((ObjectModelInterface) source, cloneDocumentation); + } else if (source.isClass()) { + clone = cloneClass((ObjectModelClass) source, cloneDocumentation); + } else if (source.isEnum()) { + clone = cloneEnumeration((ObjectModelEnumeration) source, cloneDocumentation); + } else { + // should never occur + log.error("strange classifier " + source); + } + return clone; + } + + /** + * creates a clone of the given {@code source} interface in the output model + * and clones attributes, inheritance declaration and operations into the + * clone + * + * @param source the interface to clone from the source model + * @param cloneDocumentation flag to add documentation if some found in model + * @return the clone of the given interface + */ + public ObjectModelInterface cloneInterface(ObjectModelInterface source, + boolean cloneDocumentation) { + ObjectModelInterface outputInterface = + builder.createInterface(source.getName(), source.getPackageName()); + + cloneClassifier(source, outputInterface, cloneDocumentation); + // nothing more to do. copyClassifier already done the job + + return outputInterface; + } + + /** + * creates a clone of the given {@code source} enumeration in the output + * model and clones attributes, inheritance declaration, operations and + * literals into the clone + * + * @param source the enumeration to clone from the source model + * @param cloneDocumentation flag to add documentation if some found in model + * @return the clone of the given enumeration + */ + public ObjectModelEnumeration cloneEnumeration(ObjectModelEnumeration source, + boolean cloneDocumentation) { + ObjectModelEnumeration outputEnumeration = + builder.createEnumeration(source.getName(), source.getPackageName()); + + cloneClassifier(source, outputEnumeration, cloneDocumentation); + + for (String literal : source.getLiterals()) { + builder.addLiteral(outputEnumeration, literal); + } + + return outputEnumeration; + } + + /** + * copy attributes, interfaces declaration and operation of a given classifier + * into another classifier. + * + * class-specific, enumeration-specific and interface-specific features + * of the given classifier <strong>will not</strong> be present in the clone. + * To copy those specific elements, use {@link #cloneClassifier(ObjectModelClassifier, boolean)} + * + * @param source the classifier to clone from the source model + * @param destination where to clone the given source one + * @param copyDocumentation flag to add documentation if some found in model + */ + protected void cloneClassifier(ObjectModelClassifier source, + ObjectModelClassifier destination, + boolean copyDocumentation) { + + cloneTagValues(source, destination); + + cloneStereotypes(source, destination); + + for (ObjectModelAttribute attribute : source.getAttributes()) { + cloneAttribute(attribute, destination, copyDocumentation); + } + + for (ObjectModelInterface interfacez : source.getInterfaces()) { + builder.addInterface(destination, interfacez.getQualifiedName()); + } + + for (ObjectModelOperation operation : source.getOperations()) { + cloneOperation(operation, destination, copyDocumentation); + } + } + + /** + * Clone the {@code source} operation into the {@code destination} classifier. + * whole signature, tagValues and body code will be cloned. You can specify + * {@code modifiers} for the result operation. + * + * @param source operation to clone + * @param destination classifier where result operation will be added + * @param cloneDocumentation flag to add documentation if some found in model + * @param modifiers extra modifiers + * @return the new operation created in destination classifier + */ + public ObjectModelOperation cloneOperation(ObjectModelOperation source, + ObjectModelClassifier destination, + boolean cloneDocumentation, + ObjectModelModifier... modifiers) { + ObjectModelOperation outputOperation = cloneOperationSignature( + source, + destination, + cloneDocumentation, + modifiers + ); + + // add body only if operation is not abstract + boolean opAbstract = false; + for (ObjectModelModifier modifier : modifiers) { + if (modifier == ObjectModelModifier.ABSTRACT) { + opAbstract = true; + break; + } + } + if (!opAbstract) { + builder.setOperationBody(outputOperation, source.getBodyCode()); + } + return outputOperation; + } + + /** + * Copy all tag values for the given {@code source} to the given + * {@code destination}. + * + * @param source the source element + * @param destination the destination element + */ + protected void cloneTagValues(ObjectModelElement source, + ObjectModelElement destination) { + Map<String, String> tags = source.getTagValues(); + for (Map.Entry<String, String> entry : tags.entrySet()) { + builder.addTagValue(destination,entry.getKey(),entry.getValue()); + } + } + + /** + * + * @param source + * @param destination + */ + protected void cloneStereotypes(ObjectModelClassifier source, + ObjectModelClassifier destination) { + + Collection<String> stereotypes = source.getStereotypes(); + for (String stereotype : stereotypes) { + builder.addStereotype(destination,stereotype); + } + } + + /** + * Clone the {@code source} operation into the {@code destination} classifier. + * name, returnType, parameters, exceptions and tagValues will be cloned. + * You can specify {@code modifiers} for the result operation. + * + * @param source operation to clone + * @param destination classifier where result operation will be added + * @param cloneDocumentation flag to add documentation if some found in model + * @param modifiers extra modifiers + * @return the new operation created in destination classifier + */ + public ObjectModelOperation cloneOperationSignature(ObjectModelOperation source, + ObjectModelClassifier destination, + boolean cloneDocumentation, + ObjectModelModifier... modifiers) { + + ObjectModelOperation outputOperation = + builder.addOperation(destination, source.getName(), source.getReturnType(), modifiers); + + if (cloneDocumentation && GeneratorUtil.hasDocumentation(source)) { + builder.setDocumentation(outputOperation, source.getDocumentation()); + } + + for (ObjectModelParameter parameter : source.getParameters()) { + + ObjectModelParameter outputParam = + builder.addParameter(outputOperation, parameter.getType(), parameter.getName()); + + if (cloneDocumentation && GeneratorUtil.hasDocumentation(parameter)) { + builder.setDocumentation(outputParam, parameter.getDocumentation()); + } + } + + for (String exception : source.getExceptions()) { + builder.addException(outputOperation, exception); + } + + cloneTagValues(source, outputOperation); + + return outputOperation; + } + + /** + * clone a given attribute into a classifier of the output model + * + * @param source the original attribute + * @param destination classifier where the clone will be added + * @param cloneDocumentation flag to add documentation if some found in model + * @param modifiers extra modifiers + * @return the clone attribute + */ + protected ObjectModelAttribute cloneAttribute(ObjectModelAttribute source, + ObjectModelClassifier destination, + boolean cloneDocumentation, + ObjectModelModifier... modifiers) { + + ObjectModelAttribute outputAttribute = builder.addAttribute(destination, + source.getName(), source.getType(), + source.getDefaultValue(), modifiers); + + cloneTagValues(source, outputAttribute); + + if (cloneDocumentation) { + builder.setDocumentation(outputAttribute, source.getDocumentation()); + } + + for (String comment : source.getComments()) { + builder.addComment(outputAttribute, comment); + } + + builder.setMinMultiplicity(outputAttribute, source.getMinMultiplicity()); + builder.setMaxMultiplicity(outputAttribute, source.getMaxMultiplicity()); + builder.setNavigable(outputAttribute,source.isNavigable()); + + return outputAttribute; + } }
-- Éric Chatellier <chatellier@codelutin.com> Tel: 02.40.50.29.28 http://www.codelutin.com
On Tue, 05 Jul 2011 16:17:50 +0200 Eric Chatellier <chatellier@codelutin.com> wrote:
J'ai modifier le transformer de wikitty qui transforme un modele en un autre.
Il étendait ObjectModelTransformerToJava, mais comme il ne génère pas de java, il est mieux d'étendre seulement ObjectModelTransformer.
Autre point, pour utiliser un simple ObjectModel au lieu d'un JavaGenerator, j'ai du copier/coller beaucoup beaucoup de code. Essentiellement toutes les méthodes cloneXXX()
Je pense qu'il y aurait une factorisation possible sur un transformer qui fait de la copie, mais pas typé Java...
Oui il faut absoluement revoir ça car il est vrai qu'il est peu normal qu'on clone à partir d'un javaBuilder... De toute façon, il faudrait un peut revoir tout ça car c'est complexe, confu et pas assez flexible :(
Le 05/07/2011 16:13, echatellier@users.nuiton.org a écrit :
Author: echatellier Date: 2011-07-05 16:13:10 +0200 (Tue, 05 Jul 2011) New Revision: 1051
Url: http://nuiton.org/repositories/revision/wikitty/1051
Log: Fix model transformation (to generate new modele instead of java)
Modified: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyPurifierTransformer.java
Modified: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyPurifierTransformer.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyPurifierTransformer.java 2011-07-05 14:12:19 UTC (rev 1050) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyPurifierTransformer.java 2011-07-05 14:13:10 UTC (rev 1051) @@ -5,7 +5,7 @@ * $Id$ * $HeadURL$ * %% - * Copyright (C) 2009 - 2010 CodeLutin, Benjamin Poussin + * Copyright (C) 2009 - 2011 CodeLutin, Benjamin Poussin, Chatellier Eric * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as @@ -25,35 +25,53 @@ package org.nuiton.wikitty.generator;
import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map;
+import org.apache.commons.collections.CollectionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.nuiton.eugene.java.ObjectModelTransformerToJava; +import org.nuiton.eugene.GeneratorUtil; +import org.nuiton.eugene.Template; import org.nuiton.eugene.models.object.ObjectModel; import org.nuiton.eugene.models.object.ObjectModelAttribute; +import org.nuiton.eugene.models.object.ObjectModelBuilder; 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.ObjectModelGenerator; +import org.nuiton.eugene.models.object.ObjectModelInterface; +import org.nuiton.eugene.models.object.ObjectModelModifier; +import org.nuiton.eugene.models.object.ObjectModelOperation; +import org.nuiton.eugene.models.object.ObjectModelParameter; +import org.nuiton.eugene.models.object.ObjectModelTransformer; +import org.nuiton.eugene.models.object.ObjectModelType;
/** - * this transformer read the original user model and generate the intermediate - * model needed by generators. + * This transformer read the original user model and generate the intermediate + * model needed by generators. * - * - * + * Currently: + * - manage name collision for attributes or methods inherited from two + * different classes */ -public class WikittyPurifierTransformer extends ObjectModelTransformerToJava { +public class WikittyPurifierTransformer extends ObjectModelTransformer<ObjectModel> { private static final Log log = LogFactory.getLog(WikittyPurifierTransformer.class);
/** for a given class, store all the names used by this class and subClasses */ - Map<ObjectModelClass, List<String>> namesUsedByClass = new HashMap<ObjectModelClass, List<String>>(); + protected Map<ObjectModelClass, List<String>> namesUsedByClass = new HashMap<ObjectModelClass, List<String>>(); /** class of the original model that are already processed */ - List<ObjectModelClass> processedClasses = new ArrayList<ObjectModelClass>(); + protected List<ObjectModelClass> processedClasses = new ArrayList<ObjectModelClass>(); + /** Generated model builder. */ + protected ObjectModelBuilder builder; + /** * for a given, class read all attributes name and try to find conflicts * with parent classes attributes names. @@ -129,7 +147,7 @@ // using alternative name lead to a conflict attributeName = null; } else { - addTagValue(attribute, WikittyTransformerUtil.TAG_ALTERNATIVE_NAME, attributeName); + builder.addTagValue(attribute, WikittyTransformerUtil.TAG_ALTERNATIVE_NAME, attributeName); } }
@@ -142,8 +160,17 @@ WikittyTransformerUtil.TAG_ALTERNATIVE_NAME + "\" on this attribute"); } else { + + if (isVerbose()) { + if (!attributeName.equals(attribute.getName())) { + log.info("attribute " + attribute.getName() + " purified to " + attributeName); + } + } + allUsedNames.add(attributeName); } + + }
// saving all names we used in current class will permit to sub classes @@ -163,4 +190,304 @@ } } } + + @Override + protected Template<ObjectModel> initOutputTemplate() { + return new ObjectModelGenerator(); + } + + /* + * @see org.nuiton.eugene.models.object.ObjectModelTransformer#debugOutputModel() + */ + @Override + protected void debugOutputModel() { + + } + + /* + * @see org.nuiton.eugene.Transformer#initOutputModel() + */ + @Override + protected ObjectModel initOutputModel() { + builder = new ObjectModelBuilder(getModel().getName()); + ObjectModel model = builder.getModel(); + return model; + } + + /** + * creates a clone of the given {@code source} class in the output model + * and clones attributes, inheritance declarations and operations into the + * clone + * + * @param source the class to clone from the source model + * @param cloneDocumentation flag to add documentation if some found in model + * @return the clone of the given class + */ + public ObjectModelClass cloneClass(ObjectModelClass source, + boolean cloneDocumentation) { + ObjectModelClass outputClass = + builder.createClass(source.getName(), source.getPackageName()); + + cloneClassifier(source, outputClass, cloneDocumentation); + + for (ObjectModelClass superClass : source.getSuperclasses()) { + builder.addSuperclass(outputClass, superClass.getQualifiedName()); + } + + if (!CollectionUtils.isEmpty(source.getInnerClassifiers())) { + for (ObjectModelClassifier classifier : source.getInnerClassifiers()) { + ObjectModelClassifier innerClassifierClone = + cloneClassifier(classifier, cloneDocumentation); + builder.addInnerClassifier(outputClass, + ObjectModelType.OBJECT_MODEL_CLASSIFIER, + innerClassifierClone.getName()); + } + } + return outputClass; + } + + /** + * creates a clone of the given {@code source} classifier in the output + * model and clones attributes, inheritance declaration and operations + * + * class-specific, enumeration-specific and interface-specific features + * of the given classifier <strong>will</strong> be present in the clone + * + * @param source the classifier to clone from the source model + * @param cloneDocumentation flag to add documentation if some found in model + * @return the clone of the given classifier + */ + public ObjectModelClassifier cloneClassifier(ObjectModelClassifier source, + boolean cloneDocumentation) { + ObjectModelClassifier clone = null; + if (source.isInterface()) { + clone = cloneInterface((ObjectModelInterface) source, cloneDocumentation); + } else if (source.isClass()) { + clone = cloneClass((ObjectModelClass) source, cloneDocumentation); + } else if (source.isEnum()) { + clone = cloneEnumeration((ObjectModelEnumeration) source, cloneDocumentation); + } else { + // should never occur + log.error("strange classifier " + source); + } + return clone; + } + + /** + * creates a clone of the given {@code source} interface in the output model + * and clones attributes, inheritance declaration and operations into the + * clone + * + * @param source the interface to clone from the source model + * @param cloneDocumentation flag to add documentation if some found in model + * @return the clone of the given interface + */ + public ObjectModelInterface cloneInterface(ObjectModelInterface source, + boolean cloneDocumentation) { + ObjectModelInterface outputInterface = + builder.createInterface(source.getName(), source.getPackageName()); + + cloneClassifier(source, outputInterface, cloneDocumentation); + // nothing more to do. copyClassifier already done the job + + return outputInterface; + } + + /** + * creates a clone of the given {@code source} enumeration in the output + * model and clones attributes, inheritance declaration, operations and + * literals into the clone + * + * @param source the enumeration to clone from the source model + * @param cloneDocumentation flag to add documentation if some found in model + * @return the clone of the given enumeration + */ + public ObjectModelEnumeration cloneEnumeration(ObjectModelEnumeration source, + boolean cloneDocumentation) { + ObjectModelEnumeration outputEnumeration = + builder.createEnumeration(source.getName(), source.getPackageName()); + + cloneClassifier(source, outputEnumeration, cloneDocumentation); + + for (String literal : source.getLiterals()) { + builder.addLiteral(outputEnumeration, literal); + } + + return outputEnumeration; + } + + /** + * copy attributes, interfaces declaration and operation of a given classifier + * into another classifier. + * + * class-specific, enumeration-specific and interface-specific features + * of the given classifier <strong>will not</strong> be present in the clone. + * To copy those specific elements, use {@link #cloneClassifier(ObjectModelClassifier, boolean)} + * + * @param source the classifier to clone from the source model + * @param destination where to clone the given source one + * @param copyDocumentation flag to add documentation if some found in model + */ + protected void cloneClassifier(ObjectModelClassifier source, + ObjectModelClassifier destination, + boolean copyDocumentation) { + + cloneTagValues(source, destination); + + cloneStereotypes(source, destination); + + for (ObjectModelAttribute attribute : source.getAttributes()) { + cloneAttribute(attribute, destination, copyDocumentation); + } + + for (ObjectModelInterface interfacez : source.getInterfaces()) { + builder.addInterface(destination, interfacez.getQualifiedName()); + } + + for (ObjectModelOperation operation : source.getOperations()) { + cloneOperation(operation, destination, copyDocumentation); + } + } + + /** + * Clone the {@code source} operation into the {@code destination} classifier. + * whole signature, tagValues and body code will be cloned. You can specify + * {@code modifiers} for the result operation. + * + * @param source operation to clone + * @param destination classifier where result operation will be added + * @param cloneDocumentation flag to add documentation if some found in model + * @param modifiers extra modifiers + * @return the new operation created in destination classifier + */ + public ObjectModelOperation cloneOperation(ObjectModelOperation source, + ObjectModelClassifier destination, + boolean cloneDocumentation, + ObjectModelModifier... modifiers) { + ObjectModelOperation outputOperation = cloneOperationSignature( + source, + destination, + cloneDocumentation, + modifiers + ); + + // add body only if operation is not abstract + boolean opAbstract = false; + for (ObjectModelModifier modifier : modifiers) { + if (modifier == ObjectModelModifier.ABSTRACT) { + opAbstract = true; + break; + } + } + if (!opAbstract) { + builder.setOperationBody(outputOperation, source.getBodyCode()); + } + return outputOperation; + } + + /** + * Copy all tag values for the given {@code source} to the given + * {@code destination}. + * + * @param source the source element + * @param destination the destination element + */ + protected void cloneTagValues(ObjectModelElement source, + ObjectModelElement destination) { + Map<String, String> tags = source.getTagValues(); + for (Map.Entry<String, String> entry : tags.entrySet()) { + builder.addTagValue(destination,entry.getKey(),entry.getValue()); + } + } + + /** + * + * @param source + * @param destination + */ + protected void cloneStereotypes(ObjectModelClassifier source, + ObjectModelClassifier destination) { + + Collection<String> stereotypes = source.getStereotypes(); + for (String stereotype : stereotypes) { + builder.addStereotype(destination,stereotype); + } + } + + /** + * Clone the {@code source} operation into the {@code destination} classifier. + * name, returnType, parameters, exceptions and tagValues will be cloned. + * You can specify {@code modifiers} for the result operation. + * + * @param source operation to clone + * @param destination classifier where result operation will be added + * @param cloneDocumentation flag to add documentation if some found in model + * @param modifiers extra modifiers + * @return the new operation created in destination classifier + */ + public ObjectModelOperation cloneOperationSignature(ObjectModelOperation source, + ObjectModelClassifier destination, + boolean cloneDocumentation, + ObjectModelModifier... modifiers) { + + ObjectModelOperation outputOperation = + builder.addOperation(destination, source.getName(), source.getReturnType(), modifiers); + + if (cloneDocumentation && GeneratorUtil.hasDocumentation(source)) { + builder.setDocumentation(outputOperation, source.getDocumentation()); + } + + for (ObjectModelParameter parameter : source.getParameters()) { + + ObjectModelParameter outputParam = + builder.addParameter(outputOperation, parameter.getType(), parameter.getName()); + + if (cloneDocumentation && GeneratorUtil.hasDocumentation(parameter)) { + builder.setDocumentation(outputParam, parameter.getDocumentation()); + } + } + + for (String exception : source.getExceptions()) { + builder.addException(outputOperation, exception); + } + + cloneTagValues(source, outputOperation); + + return outputOperation; + } + + /** + * clone a given attribute into a classifier of the output model + * + * @param source the original attribute + * @param destination classifier where the clone will be added + * @param cloneDocumentation flag to add documentation if some found in model + * @param modifiers extra modifiers + * @return the clone attribute + */ + protected ObjectModelAttribute cloneAttribute(ObjectModelAttribute source, + ObjectModelClassifier destination, + boolean cloneDocumentation, + ObjectModelModifier... modifiers) { + + ObjectModelAttribute outputAttribute = builder.addAttribute(destination, + source.getName(), source.getType(), + source.getDefaultValue(), modifiers); + + cloneTagValues(source, outputAttribute); + + if (cloneDocumentation) { + builder.setDocumentation(outputAttribute, source.getDocumentation()); + } + + for (String comment : source.getComments()) { + builder.addComment(outputAttribute, comment); + } + + builder.setMinMultiplicity(outputAttribute, source.getMinMultiplicity()); + builder.setMaxMultiplicity(outputAttribute, source.getMaxMultiplicity()); + builder.setNavigable(outputAttribute,source.isNavigable()); + + return outputAttribute; + } }
-- Tony Chemit -------------------- tél: +33 (0) 2 40 50 29 28 email: chemit@codelutin.com http://www.codelutin.com
On Tue, 05 Jul 2011 16:17:50 +0200 Eric Chatellier<chatellier@codelutin.com> wrote:
J'ai modifier le transformer de wikitty qui transforme un modele en un autre.
Il étendait ObjectModelTransformerToJava, mais comme il ne génère pas de java, il est mieux d'étendre seulement ObjectModelTransformer.
Autre point, pour utiliser un simple ObjectModel au lieu d'un JavaGenerator, j'ai du copier/coller beaucoup beaucoup de code. Essentiellement toutes les méthodes cloneXXX()
Je pense qu'il y aurait une factorisation possible sur un transformer qui fait de la copie, mais pas typé Java... Oui il faut absoluement revoir ça car il est vrai qu'il est peu normal qu'on clone à partir d'un javaBuilder...
De toute façon, il faudrait un peut revoir tout ça car c'est complexe, confu et pas assez flexible :( Je suis d'accord, les clones pourraient se situer au niveau ObjectModelBuilder. Après je serais presque d'avis d'utiliser directement le builder dans le
On 05/07/2011 16:30, Tony Chemit wrote: transformer sans délégation. A voir si d'autres solutions seraient plus adapté... Quel est ton cas d'utilisation Eric ? Tu transforme l'ObjectModel vers un autre ObjectModel plus Wikitty mais pas directement du Java ? Quel est le Generator de sorti ?
Le 06/07/2011 12:31, Florian Desbois a écrit :
Quel est ton cas d'utilisation Eric ? Tu transforme l'ObjectModel vers un autre ObjectModel plus Wikitty mais pas directement du Java ? Quel est le Generator de sorti ?
En entrée, le modèle utilisateur, qu'on transforme en un modèle purifié. Le modèle purifié lève tous les conflits de noms (dus à l'héritage multiple), en ajoutant une tagValue sur l'attribut pour le renommer. Au passage, ce mécanisme permet de poser une tagValue à la main pour régler un conflit à la main si on réutilise en dépendance de son propre modèle un modèle existant qu'on ne peut pas toucher. Après la purification, on passe dans les générateurs de Wikitty : génération des business-entity sous forme de contrats, abstract, implémentation et helper. -- Brendan Le Ny <bleny@codelutin.com> Code Lutin Conseil & Développement Logiciel Libre +33 (0)2 40 50 29 28 http://codelutin.com
participants (4)
-
Brendan Le Ny -
Eric Chatellier -
Florian Desbois -
Tony Chemit