Author: bleny Date: 2010-08-10 17:41:25 +0200 (Tue, 10 Aug 2010) New Revision: 242 Url: http://nuiton.org/repositories/revision/wikitty/242 Log: un seul transformer quasi fonctionnel Modified: branches/wikitty-eugene-migration/wikitty-generators/pom.xml branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyMetaGenerator.java Modified: branches/wikitty-eugene-migration/wikitty-generators/pom.xml =================================================================== --- branches/wikitty-eugene-migration/wikitty-generators/pom.xml 2010-08-09 14:12:47 UTC (rev 241) +++ branches/wikitty-eugene-migration/wikitty-generators/pom.xml 2010-08-10 15:41:25 UTC (rev 242) @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> @@ -60,6 +61,19 @@ </filters> </configuration> </plugin> + + <!-- expose new plexus components --> + <plugin> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-component-metadata</artifactId> + <executions> + <execution> + <goals> + <goal>generate-metadata</goal> + </goals> + </execution> + </executions> + </plugin> </plugins> </build> Modified: branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyMetaGenerator.java =================================================================== --- branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyMetaGenerator.java 2010-08-09 14:12:47 UTC (rev 241) +++ branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyMetaGenerator.java 2010-08-10 15:41:25 UTC (rev 242) @@ -11,23 +11,38 @@ import org.nuiton.eugene.java.ObjectModelTransformerToJava; import org.nuiton.eugene.models.object.ObjectModelAttribute; import org.nuiton.eugene.models.object.ObjectModelClass; +import org.nuiton.eugene.models.object.ObjectModelClassifier; import org.nuiton.eugene.models.object.ObjectModelInterface; import org.nuiton.eugene.models.object.ObjectModelModifier; import org.nuiton.eugene.models.object.ObjectModelOperation; -import org.nuiton.util.StringUtil; +/** + * + * @author bleny + * + * FIXME 20100609 bleny plexus registering is only for generators, isn't it ? + * @plexus.component role="org.nuiton.eugene.Template" role-hint="org.nuiton.wikitty.generator.WikittyMetaGenerator" + */ + +// FIXME 20100609 bleny update name to WikittyEntity public class WikittyMetaGenerator extends ObjectModelTransformerToJava { private static final Log log = LogFactory.getLog(WikittyMetaGenerator.class); - protected static final String BUSINESS_ENTITY_STEREOTYPE_NAME = "BusinessEntity"; + protected static final String BUSINESS_ENTITY_STEREOTYPE_NAME = "entity"; + + /** @deprecated name change : see ticket #798. use BUSINESS_ENTITY_STEREOTYPE_NAME */ + @Deprecated + protected static final String BUSINESS_ENTITY_STEREOTYPE_OLD_NAME = "BusinessEntity"; + + protected static final String BUSINESS_ENTITY_CLASS_FQN = "org.nuiton.wikitty.BusinessEntity"; - protected static final String BUSINESS_ENTITY_WIKITTY_CLASS_FQN = "org.nuiton.wikitty.BusinessEntity"; + protected static final String BUSINESS_ENTITY_WIKITTY_CLASS_FQN = "org.nuiton.wikitty.BusinessEntityWikitty"; protected static final String WIKITTY_CLASS_FQN = "org.nuiton.wikitty.Wikitty"; /** current class read from model */ protected ObjectModelClass clazz; - + /** contract for this business entity */ protected ObjectModelInterface contract; @@ -45,6 +60,7 @@ @Override public void transformFromClass(ObjectModelClass clazz) { + this.clazz = clazz; Collection<ObjectModelClass> superClasses = clazz.getSuperclasses(); @@ -53,14 +69,24 @@ return ; } - if (clazz.getStereotypes().contains(BUSINESS_ENTITY_STEREOTYPE_NAME)) { - + if (clazz.getStereotypes().contains(BUSINESS_ENTITY_STEREOTYPE_OLD_NAME)) { + log.warn(clazz.getName() + " uses deprecated \"" + BUSINESS_ENTITY_STEREOTYPE_OLD_NAME + +"\" stereotype. use \"" + BUSINESS_ENTITY_STEREOTYPE_NAME + "\" instead"); + } + + if (clazz.getStereotypes().contains(BUSINESS_ENTITY_STEREOTYPE_OLD_NAME) + || clazz.getStereotypes().contains(BUSINESS_ENTITY_STEREOTYPE_NAME)) { // for a single business entity, we create a contract, an abstract and an implementation contract = createInterface(clazz.getName(), clazz.getPackageName()); abstractClass = createAbstractClass(clazz.getName() + "Abstract", clazz.getPackageName()); implementation = createClass(clazz.getName() + "Impl", clazz.getPackageName()); helper = createClass(clazz.getName() + "Helper", clazz.getPackageName()); + addImports(contract); + addImports(abstractClass); + addImports(implementation); + addImports(helper); + // now, deal with inheritance // implementation extends abstract and abstract realizes contract @@ -70,18 +96,23 @@ setSuperClass(helper, implementation.getQualifiedName()); // as it was in the old templates // dealing with inheritance between entities specified in the model - for (ObjectModelClass superClass : superClasses) { - // using "for" but there will be 0 or 1 iteration - addInterface(contract, superClass.getQualifiedName()); - addInterface(abstractClass, superClass.getQualifiedName()); - setSuperClass(abstractClass, superClass.getQualifiedName() + "Impl"); + 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(contract, superClass.getQualifiedName()); + addInterface(abstractClass, superClass.getQualifiedName()); + setSuperClass(abstractClass, superClass.getQualifiedName() + "Impl"); + } } // adding public static final String EXT_CLIENT = "Client"; addConstant(contract, "EXT_" + clazz.getName().toUpperCase(), "String", - clazz.getName(), + "\"" + clazz.getName() + "\"", ObjectModelModifier.PUBLIC); // adding serialVersionUIDs @@ -105,7 +136,7 @@ // making constructor for helper class (empty and private) ObjectModelOperation constructor = addConstructor(helper, ObjectModelModifier.PRIVATE); - setOperationBody(constructor, ""); // empty implementation + setOperationBody(constructor, "\n// utility class\n"); // empty implementation // adding some constants about extension to abstract addConstant(abstractClass, "extensions", "List<WikittyExtension>", null, ObjectModelModifier.PUBLIC); @@ -118,16 +149,7 @@ // preparing a static block to initialize those constants ObjectModelOperation staticInitialization = addBlock(abstractClass, ObjectModelModifier.STATIC); - String staticInitializationBody = "\nList<WikittyExtension> exts = new ArrayList<WikittyExtension>();"; - - for (ObjectModelClass superClass : superClasses) { - // using "for" but there will be 0 or 1 iteration - staticInitializationBody += "\nexts.addAll(" + superClass.getName() + "Abstract.extensions);\n" - + "// current after requires ones\n"; - } - staticInitializationBody += "exts.add(extension" + clazz.getName()+ ");\n" - + "extensions = Collections.unmodifiableList(exts);\n"; - + // generating constructor call for extensionClient // we will build a string to write a call List<String> buildFieldMapExtensionParameters = new ArrayList<String>(); @@ -140,12 +162,14 @@ // now process attributes for(ObjectModelAttribute attribute : clazz.getAttributes()) { - processAttribute(attribute); + if (attribute.isNavigable()) { + processAttribute(attribute); + + // equalsBody will be updated in processAttribute + buildFieldMapExtensionParameters.add("\"" + attribute.getType() + " " + attribute.getName() + "\""); + } + } - // equalsBody will be updated in processAttribute - buildFieldMapExtensionParameters.add("\"" + attribute.getType() + " " + attribute.getName() + "\""); - } - // finishing equals body equalsBody += "\nreturn result;\n"; setOperationBody(equals, equalsBody); @@ -156,9 +180,12 @@ extensionVersion = "0.1"; log.warn("no version specified in model for " + clazz.getQualifiedName() + " using " + extensionVersion); } - staticInitializationBody += "\n\n extensionClient = new WikittyExtension(" + + String staticInitializationBody = "\n\nextension" + clazz.getName() + " = new WikittyExtension(" + "EXT_" + clazz.getName().toUpperCase() + ", " - + extensionVersion + ", "; + + "\"" + extensionVersion + "\"" + ", "; + + // a piece of code used in the static block String requires = null; for (ObjectModelClass superClass : superClasses) { // using "for" but there will be 0 or 1 iteration @@ -168,10 +195,41 @@ staticInitializationBody += requires + ", " + "WikittyUtil.buildFieldMapExtension(" + StringUtils.join(buildFieldMapExtensionParameters, ", \n") + "));"; + + staticInitializationBody += "\n\n// init extensions\nList<WikittyExtension> exts = new ArrayList<WikittyExtension>();"; + + for (ObjectModelClass superClass : superClasses) { + // using "for" but there will be 0 or 1 iteration + staticInitializationBody += "\nexts.addAll(" + superClass.getName() + "Abstract.extensions);\n" + + "// current after requires ones\n"; + } + staticInitializationBody += "exts.add(extension" + clazz.getName()+ ");\n" + + "extensions = Collections.unmodifiableList(exts);\n"; + setOperationBody(staticInitialization, staticInitializationBody); } } + protected void addImports(ObjectModelClassifier classifier) { + addImport(classifier, BUSINESS_ENTITY_CLASS_FQN); + addImport(classifier, BUSINESS_ENTITY_WIKITTY_CLASS_FQN); + addImport(classifier, WIKITTY_CLASS_FQN); + addImport(classifier, "org.nuiton.wikitty.WikittyExtension"); + addImport(classifier, "org.nuiton.wikitty.WikittyUtil"); + addImport(classifier, "org.nuiton.wikitty.WikittyUser"); + addImport(classifier, "org.nuiton.wikitty.WikittyUserAbstract"); + addImport(classifier, "org.nuiton.wikitty.WikittyUserImpl"); + addImport(classifier, "org.nuiton.wikitty.TreeNode"); + addImport(classifier, "org.nuiton.wikitty.TreeNodeAbstract"); + addImport(classifier, "org.nuiton.wikitty.TreeNodeImpl"); + addImport(classifier, java.util.List.class); + addImport(classifier, java.util.ArrayList.class); + addImport(classifier, java.util.Collection.class); + addImport(classifier, java.util.Collections.class); + addImport(classifier, java.util.Set.class); + addImport(classifier, java.util.Date.class); + } + /** add three constructors : empty, from business entity wikitty, from wikitty */ protected void addConstructors(ObjectModelClass clazz) { ObjectModelOperation constructor = addConstructor(clazz, ObjectModelModifier.PUBLIC); @@ -207,69 +265,211 @@ ObjectModelModifier.PUBLIC); } - // getters and setters + // considering field in equals body { - // adding a getter - String getterName = attribute.getTagValue("getter"); - if (getterName == null) { // no name specified - getterName = "get" + StringUtils.capitalize(attribute.getName()); - if (! contract.getOperations(getterName).isEmpty()) { - getterName += "From" + clazz.getName(); - } - } // TODO 20100609 bleny deal with conflicts - - - // adding a setter - String setterName = attribute.getTagValue("setter"); - if (setterName == null) { // no name specified - setterName = "set" + StringUtils.capitalize(attribute.getName()); - if (! contract.getOperations(setterName).isEmpty()) { - setterName += "From" + clazz.getName(); - } - } // TODO 20100609 bleny deal with conflicts + equalsBody += "\nif (result) {\n" + + "Object f1 = w1.getFieldAsObject(" + extensionVariableName + ", " + fieldVariableName + ");\n" + + "Object f2 = w2.getFieldAsObject(" + extensionVariableName + ", " + fieldVariableName + ");\n" + + "result = f1 == f2 || (f1 != null && f1.equals(f2));\n" + + "}"; + } + // let's find a name for the getter + String getterName = getMethodName("get", contract, attribute, attribute.getTagValue("getter")); + + // let's find a name for the setter + String setterName = getMethodName("set", contract, attribute, attribute.getTagValue("setter")); + + // attribute type simple name as it should be in signature + String attributeTypeSimpleName = FQNtoSimpleName(attribute.getType()); + if ("boolean".equals(attributeTypeSimpleName)) { + attributeTypeSimpleName = "Boolean"; + } else if ("int".equals(attributeTypeSimpleName)) { + attributeTypeSimpleName = "Integer"; + } + + if (attribute.getMaxMultiplicity() > 1 || attribute.getMaxMultiplicity() == -1) { + String attributeTypeSimpleNameInSet = "Set<" + attributeTypeSimpleName + ">"; + + // now, for this attribute, we will generate add, remove and clear methods + + // adding operations to contract + ObjectModelOperation getter = addOperation(contract, getterName, attributeTypeSimpleNameInSet); + + + + /* no setter for collections + ObjectModelOperation setter = addOperation(contract, setterName, "void"); + addParameter(setter, attributeTypeSimpleNameInSet, attribute.getName()); + */ + + String addName = getMethodName("add", contract, attribute, attribute.getTagValue("adder")); + ObjectModelOperation adder = addOperation(contract, addName, "void"); + addParameter(adder, "String", "element"); + + String removeName = getMethodName("remove", contract, attribute, attribute.getTagValue("remover")); + ObjectModelOperation remover = addOperation(contract, removeName, "void"); + addParameter(remover, "String", "element"); + + String clearName = getMethodName("clear", contract, attribute, attribute.getTagValue("clear")); + ObjectModelOperation clear = addOperation(contract, clearName, "void"); + + // adding operations to abstract with bodies + getter = cloneOperationSignature(getter, abstractClass, true, ObjectModelModifier.PUBLIC); + String getterBody = "\n" + attributeTypeSimpleNameInSet + " result = getWikitty().getFieldAsSet("+extensionVariableName+", "+fieldVariableName+", " + attributeTypeSimpleName + ".class);\n"; + getterBody += "return result;\n"; + setOperationBody(getter, getterBody); + + /* no setter for collections + setter = addOperation(abstractClass, setterName, "void"); + addParameter(setter, attributeTypeSimpleNameInSet, attribute.getName()); + setOperationBody(setter, setterBody); + */ + + adder = cloneOperationSignature(adder, abstractClass, true, ObjectModelModifier.PUBLIC); + String adderBody = "\ngetWikitty().addToField("+extensionVariableName+", "+fieldVariableName+", element);" + + "\ngetPropertyChangeSupport().firePropertyChange("+fieldVariableName+", null, " + getter.getName() + "());\n"; + setOperationBody(adder, adderBody); + + remover = cloneOperationSignature(remover, abstractClass, true, ObjectModelModifier.PUBLIC); + String removerBody = "\ngetWikitty().removeFromField("+extensionVariableName+", "+fieldVariableName+", element);" + + "\ngetPropertyChangeSupport().firePropertyChange("+fieldVariableName+", null, " + getter.getName() + "());\n"; + setOperationBody(remover, removerBody); + + clear = cloneOperationSignature(clear, abstractClass, true, ObjectModelModifier.PUBLIC); + String clearBody = "\ngetWikitty().clearField("+extensionVariableName+", "+fieldVariableName+");" + + "\ngetPropertyChangeSupport().firePropertyChange("+fieldVariableName+", null, " + getter.getName() + "());\n"; + setOperationBody(clear, clearBody); + + // adding operations to Helper with bodies + getter = addOperation(helper, getterName, attributeTypeSimpleNameInSet, ObjectModelModifier.STATIC); + addParameter(getter, WIKITTY_CLASS_FQN, "wikitty"); + String helperBody = "\n" + attributeTypeSimpleNameInSet + " result = wikitty.getFieldAsSet("+extensionVariableName+", "+fieldVariableName+", "+attributeTypeSimpleName+".class);" + + "return result;\n"; + setOperationBody(getter, helperBody); + + adder = addOperation(helper, addName, "void", ObjectModelModifier.STATIC); + addParameter(adder, WIKITTY_CLASS_FQN, "wikitty"); + addParameter(adder, attributeTypeSimpleName, "element"); + adderBody = "\nwikitty.addToField("+extensionVariableName+", "+clazz.getName() + "."+fieldVariableName+", element);\n"; + setOperationBody(adder, adderBody); + + remover = addOperation(helper, removeName, "void", ObjectModelModifier.STATIC); + addParameter(remover, WIKITTY_CLASS_FQN, "wikitty"); + addParameter(remover, attributeTypeSimpleName, "element"); + removerBody = "\nwikitty.removeFromField("+extensionVariableName+", "+clazz.getName() + "."+fieldVariableName+", element);\n"; + setOperationBody(remover, removerBody); + + clear = addOperation(helper, clearName, "void", ObjectModelModifier.STATIC); + addParameter(clear, WIKITTY_CLASS_FQN, "wikitty"); + clearBody = "\nwikitty.clearField("+extensionVariableName+", "+clazz.getName() + "."+fieldVariableName+");\n"; + setOperationBody(clear, clearBody); + + } else { + String getFieldMethodName = generateGetFieldAsCall(attribute.getType()); + String resultType = generateResultType(attribute.getType()); + attributeTypeSimpleName = resultType; + // adding getter and setter to contract - addOperation(contract, getterName, attribute.getType()); + ObjectModelOperation getter = addOperation(contract, getterName, attributeTypeSimpleName); ObjectModelOperation setter = addOperation(contract, setterName, "void"); - addParameter(setter, attribute.getType(), attribute.getName()); + addParameter(setter, attributeTypeSimpleName, attribute.getName()); - // adding getter and setter to abstract with bodies - ObjectModelOperation getter = addOperation(abstractClass, getterName, attribute.getType()); - String getterBody = "\n" + attribute.getType() + - " result = getWikitty().getFieldAs" + - attribute.getType() + "(" + extensionVariableName + ", " + fieldVariableName + ");\n" - + "return result;\n"; + getter = cloneOperationSignature(getter, abstractClass, true, ObjectModelModifier.PUBLIC); + String getterBody = "\n" + resultType + + " result = getWikitty()." + getFieldMethodName + + "(" + extensionVariableName + ", " + fieldVariableName + ");\n" + + "return result;\n"; setOperationBody(getter, getterBody); - setter = addOperation(abstractClass, setterName, "void"); - addParameter(setter, attribute.getType(), attribute.getName()); + setter = cloneOperationSignature(setter, abstractClass, true, ObjectModelModifier.PUBLIC); String setterBody = "\nObject oldValue = getField("+extensionVariableName+", " + fieldVariableName + ");\n" - + "getWikitty().setField("+extensionVariableName+", " + fieldVariableName + ", "+attribute.getName()+");\n" - + "getPropertyChangeSupport().firePropertyChange(" + fieldVariableName + ", oldValue, "+attribute.getName()+");\n"; + + "getWikitty().setField("+extensionVariableName+", " + fieldVariableName + ", "+attribute.getName()+");\n" + + "getPropertyChangeSupport().firePropertyChange(" + fieldVariableName + ", oldValue, "+attribute.getName()+");\n"; setOperationBody(setter, setterBody); - + // adding getter and setter to Helper with bodies - getter = addOperation(helper, getterName, attribute.getType(), ObjectModelModifier.STATIC); + getter = addOperation(helper, getterName, attributeTypeSimpleName, ObjectModelModifier.STATIC); addParameter(getter, WIKITTY_CLASS_FQN, "wikitty"); - getterBody = "\n" + attribute.getType() + " result = wikitty.getFieldAs" + attribute.getType() + "(" + extensionVariableName + ", " + fieldVariableName + ");\n" - + "return result;\n"; - setOperationBody(getter, getterBody); + String helperGetterBody = "\n" + resultType + " result = wikitty." + getFieldMethodName + "(" + extensionVariableName + ", " + fieldVariableName + ");\n" + "return result;\n"; + setOperationBody(getter, helperGetterBody); setter = addOperation(helper, setterName, "void", ObjectModelModifier.STATIC); addParameter(setter, WIKITTY_CLASS_FQN, "wikitty"); - addParameter(setter, attribute.getType(), attribute.getName()); - setterBody = "wikitty.setField("+extensionVariableName+", " + clazz.getName() + "."+fieldVariableName+", " + attribute.getName() + ");\n"; - setOperationBody(setter, setterBody); + addParameter(setter, attributeTypeSimpleName, attribute.getName()); + String helperSetterBody = "wikitty.setField("+extensionVariableName+", " + clazz.getName() + "."+fieldVariableName+", " + attribute.getName() + ");\n"; + setOperationBody(setter, helperSetterBody); } - - // considering field in equals body - { - equalsBody += "\nif (result) {\n" - + "Object f1 = w1.getFieldAsObject(" + extensionVariableName + ", " + fieldVariableName + ");\n" - + "Object f2 = w2.getFieldAsObject(" + extensionVariableName + ", " + fieldVariableName + ");\n" - + "result = f1 == f2 || (f1 != null && f1.equals(f2));\n" - + "}"; + } + + /** given "my.java.package.MyClass" or "MyClass" return "MyClass" */ + protected static String FQNtoSimpleName(String fqn) { + int lastDotIndex = fqn.lastIndexOf("."); + String simpleName = fqn; + if (lastDotIndex != -1) { + simpleName = fqn.substring(lastDotIndex + 1); } + return simpleName; } + + /** + * wikitty interface provide getFieldAsString, getFieldAsDate etc. methods + * this method returns the good name of the method to call depending the + * type given as parameter + * @param typeName a name of a business entity or "String", "Integer" etc. + * @return the name of a method "getFieldAsInt" for example + */ + protected static String generateGetFieldAsCall(String typeName) { + String asWhat = FQNtoSimpleName(typeName); + if ("boolean".equals(asWhat)) { + asWhat = "Boolean"; + } else if ("int".equals(asWhat) || "Integer".equals(asWhat)) { + asWhat = "Int"; + } else if ("Date".equals(asWhat)) { + // asWhat = "Date"; + } else { + asWhat = "String"; + } + return "getFieldAs" + asWhat; + } + + protected static String generateResultType(String typeName) { + String asWhat = FQNtoSimpleName(typeName); + if ("boolean".equals(asWhat)) { + // asWhat = "boolean"; + } else if ("int".equals(asWhat) || "Integer".equals(asWhat)) { + // asWhat = "Int"; + } else if ("Date".equals(asWhat)) { + // asWhat = "Date"; + } else { + asWhat = "String"; + } + return asWhat; + } + + /** getMethodName("add", contract, attribute, "myNameForThisAdder") + * will return "myNameForThisAdder" if not already defined in contract + * if already defined, will try add<attributeName>. If it already exists + * will return add<attributeName>From<ExtensionName> */ + protected String getMethodName(String operatorName, + ObjectModelClassifier classifier, + ObjectModelAttribute attribute, + String claimedValue) { + String methodName = claimedValue; + if (methodName != null) { + if (! classifier.getOperations(methodName).isEmpty()) { + log.warn(methodName + " operation already exists in " + clazz.getQualifiedName() + " ignoring tagValue"); + methodName = null; + } + } + + if (methodName == null) { + methodName = operatorName + StringUtils.capitalize(attribute.getName()); + if (! classifier.getOperations(methodName).isEmpty()) { + methodName += "From" + clazz.getName(); + } + } + return methodName; + } }