Author: bleny Date: 2010-08-12 18:19:16 +0200 (Thu, 12 Aug 2010) New Revision: 956 Url: http://nuiton.org/repositories/revision/eugene/956 Log: added clone operation for classifiers, classes, enumerations, interfaces, attributes and operations Modified: trunk/eugene/src/main/java/org/nuiton/eugene/java/ObjectModelTransformerToJava.java Modified: trunk/eugene/src/main/java/org/nuiton/eugene/java/ObjectModelTransformerToJava.java =================================================================== --- trunk/eugene/src/main/java/org/nuiton/eugene/java/ObjectModelTransformerToJava.java 2010-08-12 16:18:13 UTC (rev 955) +++ trunk/eugene/src/main/java/org/nuiton/eugene/java/ObjectModelTransformerToJava.java 2010-08-12 16:19:16 UTC (rev 956) @@ -48,6 +48,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.Map; import java.util.Set; /** @@ -382,6 +383,18 @@ builder.addAnnotation(classifier, element, annotation); } + /** + * add an operation to the classifier with the form of a simple block + * of code. + * + * use it to add a "static {}" block into an classifier, then use + * setOperationBody with the returned value of this method to complete + * the creation of the static block + * + * @param classifier the classifier where the block will be added + * @param modifiers modifiers for the block + * @return the block added + */ public ObjectModelOperation addBlock(ObjectModelClassifier classifier, ObjectModelModifier... modifiers) { return builder.addBlock(classifier, modifiers); @@ -400,24 +413,25 @@ /** * Clone the {@code source} operation into the {@code destination} classifier. - * Name, returnType, Parameters and Exceptions will be cloned. You can specify - * {@code modifiers} for the result operation. + * 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 documentation flag to add documentation if some found in model + * @param cloneDocumentation flag to add documentation if some found in model * @param modifiers extra modifiers * @return the new operation created in destination classifier + * @since 2.1.2 */ public ObjectModelOperation cloneOperationSignature(ObjectModelOperation source, ObjectModelClassifier destination, - boolean documentation, + boolean cloneDocumentation, ObjectModelModifier... modifiers) { ObjectModelOperation outputOperation = addOperation(destination, source.getName(), source.getReturnType(), modifiers); - if (documentation && GeneratorUtil.hasDocumentation(source)) { + if (cloneDocumentation && GeneratorUtil.hasDocumentation(source)) { setDocumentation(outputOperation, source.getDocumentation()); } @@ -426,7 +440,7 @@ ObjectModelParameter outputParam = addParameter(outputOperation, parameter.getType(), parameter.getName()); - if (documentation && GeneratorUtil.hasDocumentation(parameter)) { + if (cloneDocumentation && GeneratorUtil.hasDocumentation(parameter)) { setDocumentation(outputParam, parameter.getDocumentation()); } } @@ -435,10 +449,211 @@ addException(outputOperation, exception); } + for (Map.Entry<String, String> tagValue : source.getTagValues().entrySet()) { + addTagValue(destination, tagValue.getKey(), tagValue.getValue()); + } + return outputOperation; } /** + * 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 + * @since 2.1.2 + */ + public ObjectModelOperation cloneOperation(ObjectModelOperation source, + ObjectModelClassifier destination, + boolean cloneDocumentation, + ObjectModelModifier... modifiers) { + ObjectModelOperation outputOperation = cloneOperationSignature(source, destination, cloneDocumentation, modifiers); + setOperationBody(outputOperation, source.getBodyCode()); + return outputOperation; + } + + /** + * clone a given attribute into a classifier of the output model + * + * @param attribute 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 + * @since 2.1.2 + */ + protected ObjectModelAttribute cloneAttribute(ObjectModelAttribute source, + ObjectModelClassifier destination, + boolean cloneDocumentation, + ObjectModelModifier... modifiers) { + + ObjectModelAttribute outputAttribute = addAttribute(destination, + source.getName(), source.getType(), + source.getDefaultValue(), modifiers); + + for (Map.Entry<String, String> tagValue : source.getTagValues().entrySet()) { + addTagValue(outputAttribute, tagValue.getKey(), tagValue.getValue()); + } + + if (cloneDocumentation) { + setDocumentation(outputAttribute, source.getDocumentation()); + } + + for (String comment : source.getComments()) { + addComment(outputAttribute, comment); + } + + setMinMultiplicity(outputAttribute, source.getMinMultiplicity()); + setMaxMultiplicity(outputAttribute, source.getMaxMultiplicity()); + + return outputAttribute; + } + + /** + * copy attributes, interfaces declartion 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 {@link #cloneClassifier(ObjectModelClassifier, boolean)} + * + * @param source the classifier to clone from the source model + * @param destination + * @param copyDocumentation flag to add documentation if some found in model + * @since 2.1.2 + */ + protected void copyClassifier(ObjectModelClassifier source, + ObjectModelClassifier destination, + boolean copyDocumentation) { + + for (ObjectModelAttribute attribute : source.getAttributes()) { + cloneAttribute(attribute, destination, copyDocumentation); + } + + for (ObjectModelInterface interfacez : source.getInterfaces()) { + addInterface(destination, interfacez.getQualifiedName()); + } + + for (ObjectModelOperation operation : source.getOperations()) { + cloneOperation(operation, destination, copyDocumentation); + } + } + + /** + * creates a clone of the given {@code source} class in the output model + * and clones attributes, inheritence 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 + * @since 2.1.2 + */ + public ObjectModelClass cloneClass(ObjectModelClass source, + boolean cloneDocumentation) { + ObjectModelClass outputClass = createClass(source.getName(), + source.getPackageName()); + copyClassifier(source, outputClass, cloneDocumentation); + + if (source.getSuperclasses().size() > 1) { + log.warn(source.getQualifiedName() + " has multiple inheritence, some of them will be ignored"); + } + + for (ObjectModelClass superClass : source.getSuperclasses()) { + setSuperClass(outputClass, superClass.getQualifiedName()); + + // TODO 20100812 bleny is there something to do with discriminator for superClass ? + } + + for (ObjectModelClassifier innerClassifier : source.getInnerClassifiers()) { + ObjectModelClassifier innerClassifierClone = cloneClassifier(innerClassifier, cloneDocumentation); + addInnerClassifier(outputClass, + ObjectModelType.OBJECT_MODEL_CLASSIFIER, + innerClassifierClone.getName()); + } + + return outputClass; + } + + /** + * creates a clone of the given {@code source} interface in the output model + * and clones attributes, inheritence 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 + * @since 2.1.2 + */ + public ObjectModelInterface cloneInterface(ObjectModelInterface source, + boolean cloneDocumentation) { + ObjectModelInterface outputInterface = createInterface(source.getName(), source.getPackageName()); + + copyClassifier(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, inheritence 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 + * @since 2.1.2 + */ + public ObjectModelEnumeration cloneEnumeration(ObjectModelEnumeration source, + boolean cloneDocumentation) { + ObjectModelEnumeration outputEnumeration = + createEnumeration(source.getName(), source.getPackageName()); + + copyClassifier(source, outputEnumeration, cloneDocumentation); + + for (String literal : source.getLiterals()) { + addLiteral(outputEnumeration, literal); + } + + return outputEnumeration; + } + + /** + * creates a clone of the given {@code source} classifier in the output + * model and clones attributes, inheritence 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 + * @since 2.1.2 + */ + 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; + } + + /** * Search in {@code input} model, for a enumeration dependency named * {@link JavaGeneratorUtil#DEPENDENCIES_CONSTANTS}. * <p/>