r873 - in trunk/eugene/src/main/java/org/nuiton/eugene: . java
Author: tchemit Date: 2010-04-23 16:25:24 +0200 (Fri, 23 Apr 2010) New Revision: 873 Log: - Evolution #551: Introduce a neutral JavaBeanTransformer - Add getAssociationName method in GeneratorUtil -from TopiaGeneratorUtil) Added: trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaBeanTransformer.java trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaGeneratorUtil.java Modified: trunk/eugene/src/main/java/org/nuiton/eugene/GeneratorUtil.java trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaGenerator.java Modified: trunk/eugene/src/main/java/org/nuiton/eugene/GeneratorUtil.java =================================================================== --- trunk/eugene/src/main/java/org/nuiton/eugene/GeneratorUtil.java 2010-04-22 09:00:19 UTC (rev 872) +++ trunk/eugene/src/main/java/org/nuiton/eugene/GeneratorUtil.java 2010-04-23 14:25:24 UTC (rev 873) @@ -446,7 +446,7 @@ /** * ToString contract for ObjectModelParameter with type and name. This * contract is used in - * {@link StringUtil#join(Iterable, StringUtil.ToString, String, boolean)} + * {@link StringUtil#join(Iterable, org.nuiton.util.StringUtil.ToString, String, boolean)} */ static final StringUtil.ToString<ObjectModelParameter> OBJECT_MODEL_PARAMETER_TO_STRING_TYPE = @@ -464,7 +464,7 @@ /** * ToString contract for ObjectModelParameter with name only. This contract * is used in - * {@link StringUtil#join(Iterable, StringUtil.ToString, String, boolean)} + * {@link StringUtil#join(Iterable, org.nuiton.util.StringUtil.ToString, String, boolean)} */ static final StringUtil.ToString<ObjectModelParameter> OBJECT_MODEL_PARAMETER_TO_STRING_NAME = @@ -700,4 +700,24 @@ return buffer.toString(); } + /** + * 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 + * @since 2.0.2 + */ + 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 += StringUtils.capitalize( + attr.getAssociationClass().getName()); + } + return result; + } + } // GeneratorUtil Added: trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaBeanTransformer.java =================================================================== --- trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaBeanTransformer.java (rev 0) +++ trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaBeanTransformer.java 2010-04-23 14:25:24 UTC (rev 873) @@ -0,0 +1,544 @@ +/* + * #%L + * ToPIA :: Persistence + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2010 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>. + * #L% + */ +package org.nuiton.eugene.java; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.eugene.models.object.*; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/*{generator option: parentheses = false}*/ +/*{generator option: writeString = +}*/ + +/** + * JavaBeanTransformer generates simple bean with pcs support + * (and nothing else) according to the JavaBeans 1.1 norm. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0.2 + * @plexus.component role="org.nuiton.eugene.Template" role-hint="org.nuiton.eugene.java.JavaBeanTransformer" + */ +public class JavaBeanTransformer extends ObjectModelTransformerToJava { + + private static final Log log = LogFactory.getLog(JavaBeanTransformer.class); + + @Override + public void transformFromClass(ObjectModelClass clazz) { + if (!canGenerate(clazz)) { + return; + } + + ObjectModelClass resultClass = + createAbstractClass(clazz.getName(), clazz.getPackageName()); + + if (log.isDebugEnabled()) { + log.debug("will generate "+ resultClass.getQualifiedName()); + } + + ObjectModelClass resultClassImpl = generateImpl(clazz, resultClass); + + if (log.isDebugEnabled()) { + if (resultClassImpl == null) { + log.debug("will generate impl " + + resultClass.getQualifiedName()); + } else { + log.debug("do not generate existing impl " + + resultClass.getQualifiedName()); + } + } + + addSuperClass(clazz, resultClass, resultClassImpl); + + addInterfaces(clazz, resultClass); + + // Get available properties + List<ObjectModelAttribute> properties = getProperties(clazz); + + // Add properties constant + for (ObjectModelAttribute attr : properties) { + + createPropertyConstant(resultClass, attr); + } + + // Add properties field + javabean methods + for (ObjectModelAttribute attr : properties) { + + createProperty(resultClass, attr); + } + + // Add operations + for (ObjectModelOperation op : clazz.getOperations()) { + + createAbstractOperation(resultClass, op); + } + + // Add property change support + createPropertyChangeSupport(resultClass); + + boolean hasAMultipleProperty = containsMutiple(properties); + + // Add helper operations + if (hasAMultipleProperty) { + createGetChildMethod(resultClass); + } + } + + @Override + public String getConstantName(String propertyName) { + return "PROPERTY_" + super.getConstantName(propertyName); + } + + protected void createPropertyConstant(ObjectModelClass resultClass, + ObjectModelAttribute attr) { + + String attrName = getAttributeName(attr); + + String constantName = getConstantName(attrName); + + addConstant(resultClass, + constantName, + String.class, + "\"" + attrName + "\"", + ObjectModelModifier.PUBLIC + ); + + } + + protected String getAttributeName(ObjectModelAttribute attr) { + String attrName = attr.getName(); + if (attr.hasAssociationClass()) { + String assocAttrName = JavaGeneratorUtil.getAssocAttrName(attr); + attrName = JavaGeneratorUtil.toLowerCaseFirstLetter(assocAttrName); + } + return attrName; + } + + protected String getAttributeType(ObjectModelAttribute attr) { + String attrType = attr.getType(); + if (attr.hasAssociationClass()) { + attrType = attr.getAssociationClass().getName(); + } + return attrType; + } + + protected boolean containsMutiple(List<ObjectModelAttribute> attributes) { + + boolean result = false; + + for (ObjectModelAttribute attr : attributes) { + + if (JavaGeneratorUtil.isNMultiplicity(attr)) { + result = true; + + break; + } + + } + return result; + } + + protected void createProperty( + ObjectModelClass resultClass, + ObjectModelAttribute attr) { + + String attrName = getAttributeName(attr); + String attrType = getAttributeType(attr); + + boolean multiple = JavaGeneratorUtil.isNMultiplicity(attr); + + String attrNameCapitalized = StringUtils.capitalize(attrName); + + String constantName = getConstantName(attrName); + String simpleType = JavaGeneratorUtil.getSimpleName(attrType); + + if (multiple) { + + createGetChildMethod(resultClass, + attrName, + attrNameCapitalized, + attrType, + simpleType + ); + + createAddChildMethod(resultClass, + attrName, + attrNameCapitalized, + attrType, + constantName + ); + + createRemoveChildMethod(resultClass, + attrName, + attrNameCapitalized, + attrType, + constantName + ); + + // Change type for Multiple attribute + if (attr.isOrdered()) { + attrType = List.class.getName() + "<" + attrType + ">"; + } else { + attrType = Collection.class.getName() + "<" + attrType + ">"; + } + + simpleType = JavaGeneratorUtil.getSimpleName(attrType); + } + + createGetMethod(resultClass, + attrName, + attrNameCapitalized, + attrType + ); + + createSetMethod(resultClass, + attrName, + attrNameCapitalized, + attrType, + simpleType, + constantName + ); + + // Add attribute to the class + addAttribute(resultClass, + attrName, + attrType, + "", + ObjectModelModifier.PROTECTED + ); + + } + + protected List<ObjectModelAttribute> getProperties(ObjectModelClass clazz) { + List<ObjectModelAttribute> attributes = + (List<ObjectModelAttribute>) clazz.getAttributes(); + + List<ObjectModelAttribute> attrs = + new ArrayList<ObjectModelAttribute>(); + for (ObjectModelAttribute attr : attributes) { + if (attr.isNavigable()) { + + // only keep navigable attributes + attrs.add(attr); + } + } + return attrs; + } + + protected void createGetMethod(ObjectModelClass resultClass, + String attrName, + String attrNameCapitalized, + String attrType) { + ObjectModelOperation getter = addOperation( + resultClass, + "get" + attrNameCapitalized, + attrType, + ObjectModelModifier.PUBLIC + ); + setOperationBody(getter, "" + /*{ + return <%=attrName%>; + }*/ + ); + } + protected void createGetChildMethod(ObjectModelClass resultClass, + String attrName, + String attrNameCapitalized, + String attrType, + String simpleType) { + ObjectModelOperation getChild = addOperation( + resultClass, + "get" + attrNameCapitalized, + attrType, + ObjectModelModifier.PUBLIC + ); + addParameter(getChild, "int", "index"); + setOperationBody(getChild, "" + /*{ + <%=simpleType%> o = getChild(<%=attrName%>, index); + return o; + }*/ + ); + } + + protected void createAddChildMethod(ObjectModelClass resultClass, + String attrName, + String attrNameCapitalized, + String attrType, + String constantName) { + ObjectModelOperation addChild = addOperation( + resultClass, + "add" + attrNameCapitalized, + "void", + ObjectModelModifier.PUBLIC + ); + addParameter(addChild, attrType, attrName); + setOperationBody(addChild, "" + /*{ + get<%=attrNameCapitalized%>().add(<%=attrName%>); + firePropertyChange(<%=constantName%>, null, <%=attrName%>); + }*/ + ); + } + + protected void createRemoveChildMethod(ObjectModelClass resultClass, + String attrName, + String attrNameCapitalized, + String attrType, + String constantName) { + ObjectModelOperation operation = addOperation( + resultClass, + "remove" + attrNameCapitalized, + "boolean", + ObjectModelModifier.PUBLIC + ); + addParameter(operation, attrType, attrName); + setOperationBody(operation, "" + /*{ + boolean removed = get<%=attrNameCapitalized%>().remove(<%=attrName%>); + if (removed) { + firePropertyChange(<%=constantName%>, <%=attrName%>, null); + } + return removed; + }*/ + ); + } + + protected void createSetMethod(ObjectModelClass resultClass, + String attrName, + String attrNameCapitalized, + String attrType, + String simpleType, + String constantName) { + ObjectModelOperation operation = addOperation( + resultClass, + "set" + attrNameCapitalized, + "void", + ObjectModelModifier.PUBLIC + ); + addParameter(operation, attrType, attrName); + + setOperationBody(operation, "" + /*{ + <%=simpleType%> oldValue = get<%=attrNameCapitalized%>(); + this.<%=attrName%> = <%=attrName%>; + firePropertyChange(<%=constantName%>, oldValue, <%=attrName%>); + }*/ + ); + } + + protected void createGetChildMethod(ObjectModelClass resultClass) { + ObjectModelOperation getChild = addOperation( + resultClass, + "getChild", "<T> T", + ObjectModelModifier.PROTECTED + ); + addParameter(getChild, "java.util.Collection<T>", "childs"); + addParameter(getChild, "int", "index"); + setOperationBody(getChild, "" + /*{ + if (childs != null) { + int i = 0; + for (T o : childs) { + if (index == i) { + return o; + } + i++; + } + } + return null; + }*/ + ); + } + + protected void addInterfaces(ObjectModelClass clazz, + ObjectModelClass resultClass) { + // Add interfaces from inputModel + for (ObjectModelInterface parentInterface : clazz.getInterfaces()) { + addInterface(resultClass, parentInterface.getQualifiedName()); + } + } + + protected void addSuperClass(ObjectModelClass clazz, + ObjectModelClass resultClass, + ObjectModelClass resultClassImpl) { + // Set superclass + if (resultClassImpl == null) { + Iterator<ObjectModelClass> j = clazz.getSuperclasses().iterator(); + if (j.hasNext()) { + ObjectModelClass p = j.next(); + // We want to set the inheritance to the implementation class of the father + // Ex for model : A -> B (a inherits B) we want : A -> BImpl -> B + String qualifiedName = p.getQualifiedName() + "Impl"; + setSuperClass(resultClass, qualifiedName); + } + } + } + + protected ObjectModelClass generateImpl(ObjectModelClass clazz, + ObjectModelClass resultClass) { + + // Get name for Impl class + String implQualifiedName = clazz.getQualifiedName() + "Impl"; + + // Does bean own operations ? + boolean hasOperations = !clazz.getAllOtherOperations(true).isEmpty() || + !clazz.getOperations().isEmpty(); + + String resourceName = "/" + implQualifiedName.replaceAll("\\.", "/"); + ObjectModelClass resultClassImpl=null; + // Generate the Impl class if not already exist in classpath and no operation is defined in model + if(getClass().getResource(resourceName) == null && !hasOperations) { + String implName = clazz.getName() + "Impl"; + resultClassImpl = createClass(implName, clazz.getPackageName()); + // set the abstract resulClass as the resultClassImpl super class + setSuperClass(resultClassImpl, resultClass.getQualifiedName()); + } + return resultClassImpl; + } + + protected void createAbstractOperation(ObjectModelClass resultClass, + ObjectModelOperation op) { + String visibility = op.getVisibility(); + ObjectModelOperation operation = addOperation( + resultClass, + op.getName(), + op.getReturnType(), + ObjectModelModifier.toValue(visibility), + ObjectModelModifier.ABSTRACT + ); + + for (ObjectModelParameter param : op.getParameters()) { + addParameter(operation, param.getType(), param.getName()); + } + + for (String exception : op.getExceptions()) { + addException(operation, exception); + } + } + + protected boolean canGenerate(ObjectModelClass clazz) { + return clazz.hasStereotype(JavaGeneratorUtil.STEREOTYPE_BEAN); + } + + protected void createPropertyChangeSupport(ObjectModelClass resultClass) { + + addAttribute(resultClass, + "pcs", + PropertyChangeSupport.class, + "new PropertyChangeSupport(this);", + ObjectModelModifier.PROTECTED, + ObjectModelModifier.FINAL + ); + + // Add PropertyListener + + ObjectModelOperation operation; + + operation = addOperation(resultClass, + "addPropertyChangeListener", + "void", + ObjectModelModifier.PUBLIC + ); + addParameter(operation, PropertyChangeListener.class, "listener"); + setOperationBody(operation, "" + /*{ + pcs.addPropertyChangeListener(listener); + }*/ + ); + + operation = addOperation(resultClass, + "addPropertyChangeListener", + "void", + ObjectModelModifier.PUBLIC + ); + addParameter(operation, String.class, "propertyName"); + addParameter(operation, PropertyChangeListener.class, "listener"); + setOperationBody(operation, "" + /*{ + pcs.addPropertyChangeListener(propertyName, listener); + }*/ + ); + + operation = addOperation(resultClass, + "removePropertyChangeListener", + "void", + ObjectModelModifier.PUBLIC + ); + addParameter(operation, PropertyChangeListener.class, "listener"); + setOperationBody(operation, "" + /*{ + pcs.removePropertyChangeListener(listener); + }*/ + ); + + operation= addOperation(resultClass, + "removePropertyChangeListener", + "void", + ObjectModelModifier.PUBLIC + ); + addParameter(operation, String.class, "propertyName"); + addParameter(operation, PropertyChangeListener.class, "listener"); + setOperationBody(operation, "" + /*{ + pcs.removePropertyChangeListener(propertyName, listener); + }*/ + ); + + operation = addOperation(resultClass, + "firePropertyChange", + "void", + ObjectModelModifier.PROTECTED + ); + addParameter(operation, String.class, "propertyName"); + addParameter(operation, Object.class, "oldValue"); + addParameter(operation, Object.class, "newValue"); + setOperationBody(operation, "" + /*{ + pcs.firePropertyChange(propertyName, oldValue, newValue); + }*/ + ); + + operation = addOperation(resultClass, + "firePropertyChange", + "void", + ObjectModelModifier.PROTECTED + ); + addParameter(operation, String.class, "propertyName"); + addParameter(operation, Object.class, "newValue"); + setOperationBody(operation, "" + /*{ + firePropertyChange(propertyName, null, newValue); + }*/ + ); + } + +} \ No newline at end of file Property changes on: trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaBeanTransformer.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL Modified: trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaGenerator.java =================================================================== --- trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaGenerator.java 2010-04-22 09:00:19 UTC (rev 872) +++ trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaGenerator.java 2010-04-23 14:25:24 UTC (rev 873) @@ -38,6 +38,10 @@ import org.nuiton.eugene.GeneratorUtil; import org.nuiton.eugene.models.object.*; + +/*{generator option: parentheses = true}*/ +/*{generator option: writeString = output.write}*/ + /** * JavaGenerator * Added: trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaGeneratorUtil.java =================================================================== --- trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaGeneratorUtil.java (rev 0) +++ trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaGeneratorUtil.java 2010-04-23 14:25:24 UTC (rev 873) @@ -0,0 +1,16 @@ +package org.nuiton.eugene.java; + +import org.nuiton.eugene.GeneratorUtil; + +/** + * Utility class for pure java templates. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0.2 + */ +public class JavaGeneratorUtil extends GeneratorUtil { + /** + * Stereotype for JavaBean objects. + */ + public static final String STEREOTYPE_BEAN = "bean"; +} Property changes on: trunk/eugene/src/main/java/org/nuiton/eugene/java/JavaGeneratorUtil.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL
participants (1)
-
tchemit@users.nuiton.org