Author: bleny Date: 2010-08-16 16:00:32 +0200 (Mon, 16 Aug 2010) New Revision: 263 Url: http://nuiton.org/repositories/revision/wikitty/263 Log: multiple inheritence, refactoring Modified: branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyContractGenerator.java branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyImplementationGenerator.java branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTransformerUtil.java Modified: branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java =================================================================== --- branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java 2010-08-16 09:06:20 UTC (rev 262) +++ branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java 2010-08-16 14:00:32 UTC (rev 263) @@ -2,7 +2,9 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Random; import org.apache.commons.lang.StringUtils; @@ -13,6 +15,7 @@ import org.nuiton.eugene.models.object.ObjectModel; import org.nuiton.eugene.models.object.ObjectModelAttribute; import org.nuiton.eugene.models.object.ObjectModelClass; +import org.nuiton.eugene.models.object.ObjectModelClassifier; import org.nuiton.eugene.models.object.ObjectModelModifier; import org.nuiton.eugene.models.object.ObjectModelOperation; @@ -32,76 +35,106 @@ return new WikittyPurifierTransformer(); } + protected Map<ObjectModelClass, ObjectModelClass> processedClasses = + new HashMap<ObjectModelClass, ObjectModelClass>(); + @Override - public void transformFromClass(ObjectModelClass clazz) { - ObjectModelClass abstractClass = createAbstractClass(clazz.getName() + "Abstract", clazz.getPackageName()); + public void transformFromModel(ObjectModel model) { + for (ObjectModelClass businessEntity : model.getClasses()) { + ObjectModelClass abstractClass = createAbstractClass(businessEntity.getName() + "Abstract", businessEntity.getPackageName()); + processedClasses.put(businessEntity, abstractClass); + setSuperClass(abstractClass, "BusinessEntityWikitty"); + addInterface(abstractClass, businessEntity.getQualifiedName()); + } + + for (ObjectModelClass businessEntity : model.getClasses()) { + addOperations(businessEntity, processedClasses.get(businessEntity)); + } + + // at this time, all operations in generated abstracts are just the operations + // like get/set etc. we will copy all operations of a given class to all children + // that's why constructors and others operations are not yet added + for (ObjectModelClass businessEntity : model.getClasses()) { + addInheritedOperations(businessEntity, processedClasses.get(businessEntity)); + } - // TODO 20100811 bleny remove unused imports - addImport(abstractClass, WikittyTransformerUtil.BUSINESS_ENTITY_CLASS_FQN); - addImport(abstractClass, WikittyTransformerUtil.BUSINESS_ENTITY_WIKITTY_CLASS_FQN); - addImport(abstractClass, WikittyTransformerUtil.WIKITTY_CLASS_FQN); - addImport(abstractClass, "org.nuiton.wikitty.WikittyExtension"); - addImport(abstractClass, "org.nuiton.wikitty.WikittyUtil"); - addImport(abstractClass, "org.nuiton.wikitty.WikittyUser"); - addImport(abstractClass, "org.nuiton.wikitty.WikittyUserAbstract"); - addImport(abstractClass, "org.nuiton.wikitty.WikittyUserImpl"); - addImport(abstractClass, "org.nuiton.wikitty.TreeNode"); - addImport(abstractClass, "org.nuiton.wikitty.TreeNodeAbstract"); - addImport(abstractClass, "org.nuiton.wikitty.TreeNodeImpl"); - addImport(abstractClass, java.util.List.class); - addImport(abstractClass, java.util.ArrayList.class); - addImport(abstractClass, java.util.Collection.class); - addImport(abstractClass, java.util.Collections.class); - addImport(abstractClass, java.util.Set.class); - addImport(abstractClass, java.util.Date.class); + for (ObjectModelClass businessEntity : model.getClasses()) { - addInterface(abstractClass, clazz.getQualifiedName()); + addImports(processedClasses.get(businessEntity)); - Collection<ObjectModelClass> superClasses = clazz.getSuperclasses(); - if (superClasses.isEmpty()) { - // no inheritance so inheritance from BusinessEntityWikitty - setSuperClass(abstractClass, "BusinessEntityWikitty"); - } else { - for (ObjectModelClass superClass : superClasses) { - // using "for" but there will be 0 or 1 iteration - addInterface(abstractClass, superClass.getQualifiedName()); - setSuperClass(abstractClass, superClass.getQualifiedName() + "Impl"); - } + addConstructors(processedClasses.get(businessEntity)); + + addStaticEquals(businessEntity, processedClasses.get(businessEntity)); + + addConstants(businessEntity, processedClasses.get(businessEntity)); } + processedClasses.clear(); + } + + + protected void addImports(ObjectModelClass clazz) { + // TODO 20100811 bleny remove unused imports + addImport(clazz, WikittyTransformerUtil.BUSINESS_ENTITY_CLASS_FQN); + addImport(clazz, WikittyTransformerUtil.BUSINESS_ENTITY_WIKITTY_CLASS_FQN); + addImport(clazz, WikittyTransformerUtil.WIKITTY_CLASS_FQN); + addImport(clazz, "org.nuiton.wikitty.WikittyExtension"); + addImport(clazz, "org.nuiton.wikitty.WikittyUtil"); + addImport(clazz, "org.nuiton.wikitty.WikittyUser"); + addImport(clazz, "org.nuiton.wikitty.WikittyUserAbstract"); + addImport(clazz, "org.nuiton.wikitty.WikittyUserImpl"); + addImport(clazz, "org.nuiton.wikitty.TreeNode"); + addImport(clazz, "org.nuiton.wikitty.TreeNodeAbstract"); + addImport(clazz, "org.nuiton.wikitty.TreeNodeImpl"); + addImport(clazz, java.util.List.class); + addImport(clazz, java.util.ArrayList.class); + addImport(clazz, java.util.Collection.class); + addImport(clazz, java.util.Collections.class); + addImport(clazz, java.util.Set.class); + addImport(clazz, java.util.Date.class); + addImport(clazz, java.util.LinkedHashSet.class); + } + + protected void addSerialVersionUID(ObjectModelClass clazz) { // adding a generated serialVersionUID Random random = new Random(); Long serialVersionUIDs = random.nextLong(); - addConstant(abstractClass, + addConstant(clazz, "serialVersionUID", "long", serialVersionUIDs.toString() + "L", ObjectModelModifier.PRIVATE); - ObjectModelOperation constructor = addConstructor(abstractClass, ObjectModelModifier.PUBLIC); + } + + protected void addConstructors(ObjectModelClass clazz) { + + ObjectModelOperation constructor = addConstructor(clazz, ObjectModelModifier.PUBLIC); setOperationBody(constructor, "" /*{ super(); }*/); - constructor = addConstructor(abstractClass, ObjectModelModifier.PUBLIC); + constructor = addConstructor(clazz, ObjectModelModifier.PUBLIC); addParameter(constructor, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "wikitty"); setOperationBody(constructor, "" /*{ super(wikitty); }*/); - constructor = addConstructor(abstractClass, ObjectModelModifier.PUBLIC); + constructor = addConstructor(clazz, ObjectModelModifier.PUBLIC); addParameter(constructor, WikittyTransformerUtil.BUSINESS_ENTITY_WIKITTY_CLASS_FQN, "businessEntityWikitty"); setOperationBody(constructor, "" /*{ super(businessEntityWikitty.getWikitty()); }*/); - + } + + protected void addConstants(ObjectModelClass businessEntity, ObjectModelClass abstractClass) { // adding some constants about extension to abstract addConstant(abstractClass, "extensions", "List<WikittyExtension>", null, ObjectModelModifier.PUBLIC); - addConstant(abstractClass, "extension" + clazz.getName(), "WikittyExtension", null, ObjectModelModifier.PUBLIC); + addConstant(abstractClass, "extension" + businessEntity.getName(), "WikittyExtension", null, ObjectModelModifier.PUBLIC); // ... and a getter ObjectModelOperation getStaticExtensions = addOperation(abstractClass, "getStaticExtensions", "Collection<WikittyExtension>", ObjectModelModifier.PUBLIC); @@ -111,45 +144,6 @@ return extensions; }*/); - - //// preparing static equals(w1, w2) - - ObjectModelOperation equals = addOperation(abstractClass, "equals", "boolean", ObjectModelModifier.STATIC); - addParameter(equals, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "w1"); - addParameter(equals, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "w2"); - - // the body of the equals method, will be assembled while reading attributes - String equalsBody = "" -/*{ - boolean result = true; -}*/; - String extensionVariableName = WikittyTransformerUtil.classToExtensionVariableName(clazz, true); - for(ObjectModelAttribute attribute : clazz.getAttributes()) { - if (attribute.isNavigable()) { - // two variables needed below - // String fieldVariableName = "FIELD_" + clazz.getName().toUpperCase() + "_" + attribute.getName().toUpperCase(); - String fieldVariableName = WikittyTransformerUtil.attributeToFielVariableName(attribute, true); - - // considering field in equals body - equalsBody += "" -/*{ - if (result) { - Object f1 = w1.getFieldAsObject(<%= extensionVariableName %>, <%= fieldVariableName %>); - Object f2 = w2.getFieldAsObject(<%= extensionVariableName %>, <%= fieldVariableName %>); - result = f1 == f2 || (f1 != null && f1.equals(f2)); - }; -}*/; - } - } - - // finishing equals body - equalsBody += "" -/*{ - return result; -}*/; - setOperationBody(equals, equalsBody); - - //// preparing a static block to initialize those constants ObjectModelOperation staticInitialization = addBlock(abstractClass, ObjectModelModifier.STATIC); @@ -160,7 +154,7 @@ // now process attributes - for(ObjectModelAttribute attribute : clazz.getAttributes()) { + for(ObjectModelAttribute attribute : businessEntity.getAttributes()) { if (attribute.isNavigable()) { // now add the attribute to the piece of code that build the extension String wikittyType = WikittyTransformerUtil.typeToWikittyColumn(attribute.getType()); @@ -189,24 +183,25 @@ } // finishing static block - String extensionVersion = clazz.getTagValue("version"); + String extensionVersion = businessEntity.getTagValue("version"); if (extensionVersion == null || "".equals(extensionVersion)) { extensionVersion = "0.1"; - log.warn("no version specified in model for " + clazz.getQualifiedName() + " using " + extensionVersion); + log.warn("no version specified in model for " + businessEntity.getQualifiedName() + " using " + extensionVersion); } // a piece of code used in the static block String requires = null; - for (ObjectModelClass superClass : superClasses) { + for (ObjectModelClass superClass : businessEntity.getSuperclasses()) { // using "for" but there will be 0 or 1 iteration requires = WikittyTransformerUtil.classToExtensionVariableName(superClass, true); } String buildFieldMapExtensionParametersInLine = StringUtils.join(buildFieldMapExtensionParameters, ", \n"); + String extensionVariableName = WikittyTransformerUtil.classToExtensionVariableName(businessEntity, false); String staticInitializationBody = "" /*{ - extension<%=clazz.getName()%> = - new WikittyExtension(EXT_<%=clazz.getName().toUpperCase()%>, + extension<%=businessEntity.getName()%> = + new WikittyExtension(<%=extensionVariableName%>, "<%=extensionVersion%>", // version <%= requires %>, WikittyUtil.buildFieldMapExtension( // building field map @@ -216,7 +211,7 @@ List<WikittyExtension> exts = new ArrayList<WikittyExtension>(); }*/; - for (ObjectModelClass superClass : superClasses) { + for (ObjectModelClass superClass : businessEntity.getSuperclasses()) { // using "for" but there will be 0 or 1 iteration staticInitializationBody += "" /*{ @@ -227,15 +222,56 @@ staticInitializationBody += "" /*{ - exts.add(extension<%=clazz.getName()%>); + exts.add(extension<%=businessEntity.getName()%>); extensions = Collections.unmodifiableList(exts); }*/; setOperationBody(staticInitialization, staticInitializationBody); + } + + protected void addStaticEquals(ObjectModelClass businessEntity, ObjectModelClass abstractClass) { + ObjectModelOperation equals = addOperation(abstractClass, "equals", "boolean", ObjectModelModifier.STATIC); + addParameter(equals, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "w1"); + addParameter(equals, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "w2"); + + // the body of the equals method, will be assembled while reading attributes + String equalsBody = "" +/*{ + boolean result = true; +}*/; + String extensionVariableName = WikittyTransformerUtil.classToExtensionVariableName(businessEntity, true); + for(ObjectModelAttribute attribute : businessEntity.getAttributes()) { + if (attribute.isNavigable()) { + // two variables needed below + String fieldVariableName = WikittyTransformerUtil.attributeToFielVariableName(attribute, true); + // considering field in equals body + equalsBody += "" +/*{ + if (result) { + Object f1 = w1.getFieldAsObject(<%= extensionVariableName %>, <%= fieldVariableName %>); + Object f2 = w2.getFieldAsObject(<%= extensionVariableName %>, <%= fieldVariableName %>); + result = f1 == f2 || (f1 != null && f1.equals(f2)); + }; +}*/; + } + } + + // finishing equals body + equalsBody += "" +/*{ + return result; +}*/; + setOperationBody(equals, equalsBody); + + } + + protected void addOperations(ObjectModelClass businessEntity, ObjectModelClass abstractClass) { + String extensionVariableName = WikittyTransformerUtil.classToExtensionVariableName(businessEntity, true); + // generating operations with bodies to realize contract - for (ObjectModelAttribute attribute : clazz.getAttributes()) { + for (ObjectModelAttribute attribute : businessEntity.getAttributes()) { if (attribute.isNavigable()) { // needed below, in templates String fieldVariableName = WikittyTransformerUtil.attributeToFielVariableName(attribute, true); @@ -323,5 +359,28 @@ } } } + } + + protected void addInheritedOperations(ObjectModelClass businessEntity, ObjectModelClass abstractClass) { + // now, add to this abstract all operation due to inheritence from + // other business entities + + for (ObjectModelClass superClass : businessEntity.getSuperclasses()) { + addInterface(abstractClass, superClass.getQualifiedName()); // extends ? + // setSuperClass(abstractClass, superClass.getQualifiedName() + "Impl"); + if (WikittyTransformerUtil.isBusinessEntity(superClass)) { + // getting the signatures and bodies of those operations + for (ObjectModelOperation operation : processedClasses.get(superClass).getOperations()) { + + ObjectModelOperation operationClone = cloneOperationSignature(operation, abstractClass, true); + setOperationBody(operationClone, operation.getBodyCode()); + + // XXX 20100816 bleny should be a call to cloneOperation(operation, abstractClass, true); + } + } + } + + + } } Modified: branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyContractGenerator.java =================================================================== --- branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyContractGenerator.java 2010-08-16 09:06:20 UTC (rev 262) +++ branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyContractGenerator.java 2010-08-16 14:00:32 UTC (rev 263) @@ -1,6 +1,10 @@ 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.lang.StringUtils; import org.apache.commons.logging.Log; @@ -32,9 +36,25 @@ return new WikittyPurifierTransformer(); } + + protected Map<ObjectModelClass, ObjectModelInterface> processedClasses = + new HashMap<ObjectModelClass, ObjectModelInterface>(); + @Override - public void transformFromClass(ObjectModelClass clazz) { + public void transformFromModel(ObjectModel model) { + + log.info(model.getClasses().size() + " classes to process"); + for (ObjectModelClass clazz : model.getClasses()) { + processClass(clazz); + } + + processedClasses.clear(); + + } + + protected void processClass(ObjectModelClass clazz) { + log.info("will process " + clazz.getPackageName() + ".." + clazz.getName()); ObjectModelInterface contract = createInterface(clazz.getName(), clazz.getPackageName()); addInterface(contract, WikittyTransformerUtil.BUSINESS_ENTITY_CLASS_FQN); @@ -56,24 +76,17 @@ addImport(contract, java.util.Collections.class); addImport(contract, java.util.Set.class); addImport(contract, java.util.Date.class); + addImport(contract, java.util.LinkedHashSet.class); setDocumentation(contract, clazz.getDocumentation()); - - Collection<ObjectModelClass> superClasses = clazz.getSuperclasses(); - if (! superClasses.isEmpty()) { - for (ObjectModelClass superClass : superClasses) { - // using "for" but there will be 0 or 1 iteration - addInterface(contract, superClass.getQualifiedName()); - } - } - + // adding public static final String EXT_CLIENT = "Client"; addConstant(contract, "EXT_" + clazz.getName().toUpperCase(), "String", "\"" + clazz.getName() + "\"", ObjectModelModifier.PUBLIC); - + String extensionVariableName = WikittyTransformerUtil.classToExtensionVariableName(clazz, false); for(ObjectModelAttribute attribute : clazz.getAttributes()) { @@ -107,9 +120,9 @@ // there is a conflict, purifier transformer give as the right name to use attributeName = attribute.getTagValue(WikittyTransformerUtil.TAG_ALTERNATIVE_NAME); } - + ObjectModelOperation getter; - + if (attribute.getMaxMultiplicity() > 1 || attribute.getMaxMultiplicity() == -1) { // attributed is a collection, we will generate operations get, add, remove and clear @@ -145,5 +158,25 @@ setDocumentation(getter, attribute.getDocumentation()); } } + + // now, add to this contract all operation due to inheritence from + // other business entities + Collection<ObjectModelClass> superClasses = clazz.getSuperclasses(); + for (ObjectModelClass superClass : superClasses) { + addInterface(contract, superClass.getQualifiedName()); // extends ? + if (WikittyTransformerUtil.isBusinessEntity(superClass)) { + // superclass must have benn processed first to have its operations set + if (! processedClasses.containsKey(superClass)) { + processClass(superClass); + } + + // getting the signatures of thoses operation + for (ObjectModelOperation operation : processedClasses.get(superClass).getOperations()) { + cloneOperationSignature(operation, contract, true); + } + } + } + + processedClasses.put(clazz, contract); } } Modified: branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java =================================================================== --- branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java 2010-08-16 09:06:20 UTC (rev 262) +++ branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java 2010-08-16 14:00:32 UTC (rev 263) @@ -39,6 +39,7 @@ addImport(helper, java.util.Collections.class); addImport(helper, java.util.Set.class); addImport(helper, java.util.Date.class); + addImport(helper, java.util.LinkedHashSet.class); // making constructor for helper class (empty and private) ObjectModelOperation constructor = addConstructor(helper, ObjectModelModifier.PRIVATE); Modified: branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyImplementationGenerator.java =================================================================== --- branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyImplementationGenerator.java 2010-08-16 09:06:20 UTC (rev 262) +++ branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyImplementationGenerator.java 2010-08-16 14:00:32 UTC (rev 263) @@ -38,6 +38,7 @@ addImport(implementation, java.util.Collections.class); addImport(implementation, java.util.Set.class); addImport(implementation, java.util.Date.class); + addImport(implementation, java.util.LinkedHashSet.class); setSuperClass(implementation, clazz.getQualifiedName() + "Abstract"); Modified: branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTransformerUtil.java =================================================================== --- branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTransformerUtil.java 2010-08-16 09:06:20 UTC (rev 262) +++ branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTransformerUtil.java 2010-08-16 14:00:32 UTC (rev 263) @@ -55,6 +55,7 @@ /** given "my.java.package.MyClass" or "MyClass" return "MyClass" */ protected static String FQNtoSimpleName(String fqn) { + // XXX should use GeneratorUtil#getSimpleName(String) int lastDotIndex = fqn.lastIndexOf("."); String simpleName = fqn; if (lastDotIndex != -1) { @@ -84,6 +85,8 @@ asWhat = "Int"; } else if ("Date".equals(asWhat)) { // asWhat = "Date"; + } else if (commonStrings.contains(asWhat)) { + asWhat = "String"; } else { asWhat = "String"; } @@ -110,8 +113,7 @@ result = "Collection<" + type + ">"; if (attribute.isUnique()) { if (attribute.isOrdered()) { - // FIXME 20100813 bleny doesn't take isUnique into account - result = "List<" + type + ">"; + result = "LinkedHashSet<" + type + ">"; } else { result = "Set<" + type + ">"; }