r628 - in nuiton-jpa: . nuiton-jpa-api nuiton-jpa-api/src/main/java/org/nuiton/jpa/api nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit nuiton-jpa-templates nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates
Author: tchemit Date: 2013-05-25 16:13:01 +0200 (Sat, 25 May 2013) New Revision: 628 Url: http://nuiton.org/projects/sandbox/repository/revisions/628 Log: continue nuiton-jpa (works now on magalie project) Added: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntities.java nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntity.java Modified: nuiton-jpa/nuiton-jpa-api/pom.xml nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaDao.java nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaEntity.java nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaDao.java nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit/JpaEntityManagerRule.java nuiton-jpa/nuiton-jpa-templates/pom.xml nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/AbstractJpaTransformer.java nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaDaoTransformer.java nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaPersistenceContextTransformer.java nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesStereoTypes.java nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesTagValues.java nuiton-jpa/pom.xml Modified: nuiton-jpa/nuiton-jpa-api/pom.xml =================================================================== --- nuiton-jpa/nuiton-jpa-api/pom.xml 2013-05-24 22:19:58 UTC (rev 627) +++ nuiton-jpa/nuiton-jpa-api/pom.xml 2013-05-25 14:13:01 UTC (rev 628) @@ -36,6 +36,11 @@ </dependency> <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + + <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </dependency> Modified: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaDao.java =================================================================== --- nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaDao.java 2013-05-24 22:19:58 UTC (rev 627) +++ nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaDao.java 2013-05-25 14:13:01 UTC (rev 628) @@ -45,7 +45,7 @@ * * @since 0.1 */ -public abstract class AbstractJpaDao<E extends AbstractJpaEntity> implements JpaDao<E> { +public abstract class AbstractJpaDao<E extends JpaEntity> implements JpaDao<E> { protected EntityManager entityManager; Modified: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaEntity.java =================================================================== --- nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaEntity.java 2013-05-24 22:19:58 UTC (rev 627) +++ nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaEntity.java 2013-05-25 14:13:01 UTC (rev 628) @@ -26,17 +26,15 @@ /** * A AbstractJpaEntity must have a technical id. - * + * <p/> * Also equals() is defined for compliance with JPA expectations. * * @author bleny <leny@codelutin.com> * @author tchemit <chemit@codelutin.com> * @since 0.1 */ -public abstract class AbstractJpaEntity { +public abstract class AbstractJpaEntity implements JpaEntity{ - public abstract String getId(); - @Override public boolean equals(Object other) { String id = getId(); @@ -55,7 +53,7 @@ @Override public String toString() { - return "AbstractJpaEntity{id=" + getId() + "}"; + return getClass().getSimpleName() + "{id=" + getId() + "}"; } } Modified: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaDao.java =================================================================== --- nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaDao.java 2013-05-24 22:19:58 UTC (rev 627) +++ nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaDao.java 2013-05-25 14:13:01 UTC (rev 628) @@ -2,7 +2,7 @@ /* * #%L - * MagaLiE :: Persistence + * nuiton-jpa-api * $Id$ * $HeadURL$ * %% @@ -35,7 +35,7 @@ * @author tchemit <chemit@codelutin.com> * @since 0.1 */ -public interface JpaDao<E extends AbstractJpaEntity> { +public interface JpaDao<E extends JpaEntity> { E findById(String id); Added: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntities.java =================================================================== --- nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntities.java (rev 0) +++ nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntities.java 2013-05-25 14:13:01 UTC (rev 628) @@ -0,0 +1,74 @@ +package org.nuiton.jpa.api; + +/* + * #%L + * nuiton-jpa-api + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2013 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% + */ + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import org.apache.commons.lang3.ObjectUtils; + +import java.io.Serializable; +import java.util.Comparator; + +/** + * Helper class around {@link JpaEntity}. + * + * @author bleny <leny@codelutin.com> + * @author tchemit <chemit@codelutin.com> + * @since 0.1 + */ +public class JpaEntities { + + public static class GetIdFunction implements Function<JpaEntity, String> { + + @Override + public String apply(JpaEntity entity) { + return entity.getId(); + } + } + + public static class ArbitraryComparator<E extends JpaEntity> implements Comparator<E>, Serializable { + + private static final long serialVersionUID = 1L; + + @Override + public int compare(E x, E y) { + return ObjectUtils.compare(x.getId(), y.getId()); + } + + } + + public static Function<JpaEntity, String> getIdFunction() { + return new GetIdFunction(); + } + + public static Predicate<JpaEntity> entityHasId(String id) { + return Predicates.compose(Predicates.equalTo(id), getIdFunction()); + } + + public static <E extends JpaEntity> Comparator<E> arbitraryComparator() { + return new ArbitraryComparator<E>(); + } +} Property changes on: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntities.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntity.java =================================================================== --- nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntity.java (rev 0) +++ nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntity.java 2013-05-25 14:13:01 UTC (rev 628) @@ -0,0 +1,42 @@ +package org.nuiton.jpa.api; + +/* + * #%L + * nuiton-jpa-api + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2013 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% + */ + +/** + * A JpaEntity must have a technical id. + * <p/> + * Also {@link #equals(Object)} and {@link #hashCode()} {@code MUST} be defined + * for compliance with JPA expectations. + * + * @author bleny <leny@codelutin.com> + * @author tchemit <chemit@codelutin.com> + * @see AbstractJpaEntity + * @since 0.1 + */ +public interface JpaEntity { + + String getId(); + +} Property changes on: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntity.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit/JpaEntityManagerRule.java =================================================================== --- nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit/JpaEntityManagerRule.java 2013-05-24 22:19:58 UTC (rev 627) +++ nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit/JpaEntityManagerRule.java 2013-05-25 14:13:01 UTC (rev 628) @@ -2,7 +2,7 @@ /* * #%L - * MagaLiE :: Services + * nuiton-jpa-junit * $Id$ * $HeadURL$ * %% Modified: nuiton-jpa/nuiton-jpa-templates/pom.xml =================================================================== --- nuiton-jpa/nuiton-jpa-templates/pom.xml 2013-05-24 22:19:58 UTC (rev 627) +++ nuiton-jpa/nuiton-jpa-templates/pom.xml 2013-05-25 14:13:01 UTC (rev 628) @@ -39,6 +39,11 @@ </dependency> <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + </dependency> + + <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> </dependency> Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/AbstractJpaTransformer.java =================================================================== --- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/AbstractJpaTransformer.java 2013-05-24 22:19:58 UTC (rev 627) +++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/AbstractJpaTransformer.java 2013-05-25 14:13:01 UTC (rev 628) @@ -31,6 +31,7 @@ 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.ObjectModelElement; import org.nuiton.eugene.models.object.ObjectModelInterface; import org.nuiton.eugene.models.object.ObjectModelJavaModifier; import org.nuiton.eugene.models.object.ObjectModelOperation; @@ -39,9 +40,7 @@ import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.io.Serializable; -import java.util.ArrayList; import java.util.Collection; -import java.util.List; import java.util.Set; /** @@ -55,6 +54,27 @@ public static final String DEFAULT_CONSTANT_PREFIX = "PROPERTY_"; + public String getDefaultPackageName() { + String packageName = + getOutputProperties().getProperty(PROP_DEFAULT_PACKAGE); + return packageName; + } + + protected void addAnnotation( + ObjectModelClass output, + Class annotation) { + addAnnotation(output, output, annotation.getSimpleName()); + addImport(output, annotation); + } + + protected void addAnnotation( + ObjectModelClass output, + ObjectModelElement element, + Class annotation) { + addAnnotation(output, element, annotation.getSimpleName()); + addImport(output, annotation); + } + protected void addConstructorWithEntityManager(ObjectModelClass output) { ObjectModelOperation constructor = addConstructor( @@ -105,7 +125,7 @@ String prefix, Set<String> constantNames) { - String attrName = getAttributeName(attr); + String attrName = JpaTemplatesGeneratorUtil.getAttributeName(attr); String constantName = prefix + builder.getConstantName(attrName); @@ -120,330 +140,6 @@ } } - protected String getAttributeName(ObjectModelAttribute attr) { - String attrName = attr.getName(); - if (attr.hasAssociationClass()) { - String assocAttrName = JpaTemplatesGeneratorUtil.getAssocAttrName(attr); - attrName = JpaTemplatesGeneratorUtil.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 (JpaTemplatesGeneratorUtil.isNMultiplicity(attr)) { - result = true; - - break; - } - - } - return result; - } - - - protected List<ObjectModelAttribute> getProperties(ObjectModelClass input) { - List<ObjectModelAttribute> attributes = - (List<ObjectModelAttribute>) input.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 output, - String attrName, - String attrType, - String methodPrefix) { - - ObjectModelOperation operation = addOperation( - output, - getJavaBeanMethodName(methodPrefix, attrName), - attrType, - ObjectModelJavaModifier.PUBLIC - ); - setOperationBody(operation, "" - /*{ - return <%=attrName%>; - }*/ - ); - } - - protected void createGetChildMethod(ObjectModelClass output, - String attrName, - String attrType, - String simpleType) { - ObjectModelOperation operation = addOperation( - output, - getJavaBeanMethodName("get", attrName), - attrType, - ObjectModelJavaModifier.PUBLIC - ); - addParameter(operation, "int", "index"); - setOperationBody(operation, "" - /*{ - <%=simpleType%> o = getChild(<%=attrName%>, index); - return o; - }*/ - ); - } - - protected void createIsEmptyMethod(ObjectModelClass output, - String attrName) { - ObjectModelOperation operation = addOperation( - output, - getJavaBeanMethodName("is", attrName) + "Empty", - boolean.class, - ObjectModelJavaModifier.PUBLIC - ); - setOperationBody(operation, "" - /*{ - return <%=attrName%> == null || <%=attrName%>.isEmpty(); - }*/ - ); - } - - protected void createSizeMethod(ObjectModelClass output, - String attrName) { - ObjectModelOperation operation = addOperation( - output, - getJavaBeanMethodName("size", attrName), - int.class, - ObjectModelJavaModifier.PUBLIC - ); - setOperationBody(operation, "" - /*{ - return <%=attrName%> == null ? 0 : <%=attrName%>.size(); - }*/ - ); - } - - protected void createAddChildMethod(ObjectModelClass output, - String attrName, - String attrType, - String constantName, - boolean usePCS) { - ObjectModelOperation operation = addOperation( - output, - getJavaBeanMethodName("add", attrName), - "void", - ObjectModelJavaModifier.PUBLIC - ); - addParameter(operation, attrType, attrName); - - String methodName = getJavaBeanMethodName("get", attrName); - StringBuilder buffer = new StringBuilder("" - /*{ - <%=methodName%>().add(<%=attrName%>); - }*/ - ); - if (usePCS) { - buffer.append("" - /*{ firePropertyChange(<%=constantName%>, null, <%=attrName%>); - }*/ - ); - } - setOperationBody(operation, buffer.toString()); - } - - protected void createAddAllChildrenMethod(ObjectModelClass output, - String attrName, - String attrType, - String constantName, - boolean usePCS) { - ObjectModelOperation operation = addOperation( - output, - getJavaBeanMethodName("addAll", attrName), - "void", - ObjectModelJavaModifier.PUBLIC - ); - addParameter(operation, Collection.class.getName() + "<" + attrType + ">", attrName); - - String methodName = getJavaBeanMethodName("get", attrName); - StringBuilder buffer = new StringBuilder("" - /*{ - <%=methodName%>().addAll(<%=attrName%>); - }*/ - ); - if (usePCS) { - buffer.append("" - /*{ firePropertyChange(<%=constantName%>, null, <%=attrName%>); - }*/ - ); - } - setOperationBody(operation, buffer.toString()); - } - - protected void createRemoveChildMethod(ObjectModelClass output, - String attrName, - String attrType, - String constantName, - boolean usePCS) { - ObjectModelOperation operation = addOperation( - output, - getJavaBeanMethodName("remove", attrName), - "boolean", - ObjectModelJavaModifier.PUBLIC - ); - addParameter(operation, attrType, attrName); - String methodName = getJavaBeanMethodName("get", attrName); - StringBuilder buffer = new StringBuilder(); - buffer.append("" - /*{ - boolean removed = <%=methodName%>().remove(<%=attrName%>);}*/ - ); - - if (usePCS) { - buffer.append("" - /*{ - if (removed) { - firePropertyChange(<%=constantName%>, <%=attrName%>, null); - }}*/ - ); - } - buffer.append("" - /*{ - return removed; - }*/ - ); - setOperationBody(operation, buffer.toString()); - } - - protected void createRemoveAllChildrenMethod(ObjectModelClass output, - String attrName, - String attrType, - String constantName, - boolean usePCS) { - - ObjectModelOperation operation = addOperation( - output, - getJavaBeanMethodName("removeAll", attrName), - "boolean", - ObjectModelJavaModifier.PUBLIC - ); - addParameter(operation, "java.util.Collection<" + attrType + ">", attrName); - StringBuilder buffer = new StringBuilder(); - String methodName = getJavaBeanMethodName("get", attrName); - buffer.append("" - /*{ - boolean removed = <%=methodName%>().removeAll(<%=attrName%>);}*/ - ); - - if (usePCS) { - buffer.append("" - /*{ - if (removed) { - firePropertyChange(<%=constantName%>, <%=attrName%>, null); - }}*/ - ); - } - buffer.append("" - /*{ - return removed; - }*/ - ); - setOperationBody(operation, buffer.toString()); - } - - protected void createContainsChildMethod(ObjectModelClass output, - String attrName, - String attrType, - String constantName, - boolean usePCS) { - - ObjectModelOperation operation = addOperation( - output, - getJavaBeanMethodName("contains", attrName), - "boolean", - ObjectModelJavaModifier.PUBLIC - ); - addParameter(operation, attrType, attrName); - StringBuilder buffer = new StringBuilder(); - String methodName = getJavaBeanMethodName("get", attrName); - buffer.append("" - /*{ - boolean contains = <%=methodName%>().contains(<%=attrName%>); - return contains; - }*/ - ); - setOperationBody(operation, buffer.toString()); - } - - protected void createContainsAllChildrenMethod(ObjectModelClass output, - String attrName, - String attrType, - String constantName, - boolean usePCS) { - - ObjectModelOperation operation = addOperation( - output, - getJavaBeanMethodName("containsAll", attrName), - "boolean", - ObjectModelJavaModifier.PUBLIC - ); - addParameter(operation, Collection.class.getName() + "<" + attrType + ">", attrName); - StringBuilder buffer = new StringBuilder(); - String methodName = getJavaBeanMethodName("get", attrName); - buffer.append("" - /*{ - boolean contains = <%=methodName%>().containsAll(<%=attrName%>); - return contains; - }*/ - ); - setOperationBody(operation, buffer.toString()); - } - - protected void createSetMethod(ObjectModelClass output, - String attrName, - String attrType, - String simpleType, - String constantName, - boolean usePCS) { - ObjectModelOperation operation = addOperation( - output, - getJavaBeanMethodName("set", attrName), - "void", - ObjectModelJavaModifier.PUBLIC - ); - addParameter(operation, attrType, attrName); - - if (usePCS) { - String methodName = getJavaBeanMethodName("get", attrName); - setOperationBody(operation, "" - /*{ - <%=simpleType%> oldValue = <%=methodName%>(); - this.<%=attrName%> = <%=attrName%>; - firePropertyChange(<%=constantName%>, oldValue, <%=attrName%>); - }*/ - ); - } else { - setOperationBody(operation, "" - /*{ - this.<%=attrName%> = <%=attrName%>; - }*/ - ); - } - } - protected void addSerializable(ObjectModelClass input, ObjectModelClass output, boolean interfaceFound) { @@ -577,37 +273,4 @@ ); } - protected void createGetChildMethod(ObjectModelClass output) { - ObjectModelOperation getChild = addOperation( - output, - "getChild", "<T> T", - ObjectModelJavaModifier.PROTECTED - ); - addImport(output, List.class); - - addParameter(getChild, "java.util.Collection<T>", "childs"); - addParameter(getChild, "int", "index"); - setOperationBody(getChild, "" - /*{ - T result = null; - if (childs != null) { - if (childs instanceof List) { - if (index < childs.size()) { - result = ((List<T>) childs).get(index); - } - } else { - int i = 0; - for (T o : childs) { - if (index == i) { - result = o; - break; - } - i++; - } - } - } - return result; - }*/ - ); - } } Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaDaoTransformer.java =================================================================== --- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaDaoTransformer.java 2013-05-24 22:19:58 UTC (rev 627) +++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaDaoTransformer.java 2013-05-25 14:13:01 UTC (rev 628) @@ -31,6 +31,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.eugene.models.object.ObjectModelClass; +import org.nuiton.eugene.models.object.ObjectModelJavaModifier; import org.nuiton.eugene.models.object.ObjectModelOperation; import org.nuiton.jpa.api.AbstractJpaDao; @@ -41,7 +42,6 @@ * <li>{@code AbstractXXXJpaDao}: abstract jpa dao for entity named {@code XXX}, will find here the generated stuff (with jpa mapping, technical stuff)</li> * <li>{@code XXXJpaDao}: concrete public jpa dao to use in your persistence layer</li> * </ul> - * <p/> * {@code Note:} All classes found in class-path are not generated. * * @author tchemit <chemit@codelutin.com> @@ -56,35 +56,38 @@ @Override public void transformFromClass(ObjectModelClass input) { - String entityAbstractName = "Abstract" + input.getName() + "JpaDao"; + String packageName = JpaTemplatesGeneratorUtil.getDaoPackage(this, model, input); - String entityConcreteName = JpaTemplatesGeneratorUtil.getDaoConcreteName(input); + String abstractDaoName = JpaTemplatesGeneratorUtil.getDaoAbstractName(input); - boolean generateAbstract = !isInClassPath(input.getPackageName(), - entityAbstractName); + String concreteDaoName = JpaTemplatesGeneratorUtil.getDaoConcreteName(input); - boolean generateConcrete = !isInClassPath(input.getPackageName(), - entityConcreteName); + String concreteEntityQualifiedName= + JpaTemplatesGeneratorUtil.getConcreteEntityQualifiedName(this, model, input); + boolean generateAbstract = !isInClassPath(packageName, abstractDaoName); + + boolean generateConcrete = !isInClassPath(packageName, concreteDaoName); + if (generateAbstract) { - generateAbstract(input, entityAbstractName); + generateAbstract(input, packageName, abstractDaoName, concreteEntityQualifiedName); } if (generateConcrete) { - generateImpl(input, entityAbstractName, entityConcreteName); + generateImpl(input, packageName, abstractDaoName, concreteDaoName, concreteEntityQualifiedName); } } protected ObjectModelClass generateAbstract(ObjectModelClass input, - String entityAbstractName) { + String packageName, + String abstractDaoName, + String concreteEntityQualifiedName) { - String packageName = input.getPackageName(); - ObjectModelClass output = - createAbstractClass(entityAbstractName + "<E extends " + input.getName() + ">", packageName); - addImport(output, input.getQualifiedName()); + createAbstractClass(abstractDaoName + "<E extends " + input.getName() + ">", packageName); + addImport(output, concreteEntityQualifiedName); // test if a super class is in same package (so is yet another entity) boolean superClassIsEntity = isSuperClassEntity(input); @@ -95,7 +98,9 @@ // get first super-class ObjectModelClass superClassModel = input.getSuperclasses().iterator().next(); - superClass = JpaTemplatesGeneratorUtil.getDaoConcreteName(superClassModel); + superClass = JpaTemplatesGeneratorUtil.getDaoPackage(this, model, superClassModel) + + "." + + JpaTemplatesGeneratorUtil.getDaoConcreteName(superClassModel); } else { @@ -110,56 +115,50 @@ addImport(output, superClass); } } - - // detect if there is a contract to set on abstract - String daoContractName = input.getPackageName() + "." + input.getName() + "Dao"; - - boolean addUserDaoContract = isInClassPath(daoContractName); - setSuperClass(output, superClass); - if (addUserDaoContract) { - addInterface(output, daoContractName); - } - addConstructorWithEntityManager(output); // Add getEntityClass - if (log.isDebugEnabled()) { - log.debug("will generate " + output.getQualifiedName()); - } - ObjectModelOperation operation = addOperation(output, "getEntityClass", "Class<E>"); - addAnnotation(output, operation, Override.class.getSimpleName()); + ObjectModelOperation operation = addOperation(output, "getEntityClass", "Class<E>", ObjectModelJavaModifier.PROTECTED); + addAnnotation(output, operation, Override.class); setOperationBody(operation, "" /*{ return (Class<E>) <%=input.getName()%>.class; }*/ ); - + if (isVerbose()) { + log.info("will generate " + output.getQualifiedName()); + } return output; } protected ObjectModelClass generateImpl(ObjectModelClass input, - String entityAbstractName, - String entityConcreteName) { + String packageName, + String abstractDaoName, + String concreteDaoName, + String concreteEntityQualifiedName) { - ObjectModelClass output = createClass( - entityConcreteName, - input.getPackageName() - ); + ObjectModelClass output = createClass(concreteDaoName, packageName); - // set the abstract resulClass as the resultClassImpl super class - setSuperClass(output, input.getPackageName() + '.' + entityAbstractName + "<" + input.getName() + ">"); - addImport(output, input); + setSuperClass(output, packageName + '.' + abstractDaoName + "<" + input.getName() + ">"); + addImport(output, concreteEntityQualifiedName); addConstructorWithEntityManager(output); - output.getSuperclasses(); - if (log.isDebugEnabled()) { - log.debug("will generate " + output.getQualifiedName()); + // detect if there is a contract to set on abstract + String daoContractName = packageName + "." + input.getName() + "Dao"; + + boolean addUserDaoContract = isInClassPath(daoContractName); + + if (addUserDaoContract) { + addInterface(output, daoContractName); } + if (isVerbose()) { + log.info("will generate " + output.getQualifiedName()); + } return output; } Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java =================================================================== --- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java 2013-05-24 22:19:58 UTC (rev 627) +++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java 2013-05-25 14:13:01 UTC (rev 628) @@ -24,9 +24,12 @@ * #L% */ -import com.google.common.base.Preconditions; +import com.google.common.base.Joiner; import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Lists; import com.google.common.collect.Multimap; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.eugene.models.object.ObjectModelAttribute; @@ -36,9 +39,11 @@ import org.nuiton.eugene.models.object.xml.ObjectModelAttributeImpl; import org.nuiton.jpa.api.AbstractJpaEntity; +import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; @@ -47,7 +52,6 @@ import javax.persistence.OneToOne; import javax.persistence.OrderColumn; import java.util.Collection; -import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -63,7 +67,6 @@ * <p/> * {@code Note:} All classes found in class-path are not generated. * - * TODO Deal with @GeneratedValue * @author tchemit <chemit@codelutin.com> * @plexus.component role="org.nuiton.eugene.Template" role-hint="org.nuiton.jpa.templates.JpaEntityTransformer" * @since 0.1 @@ -73,44 +76,34 @@ private static final Log log = LogFactory.getLog(JpaEntityTransformer.class); - protected String getConcreteName(ObjectModelClass input) { - return input.getName(); - } + public static final String PROPERTY_ID = "id"; @Override public void transformFromClass(ObjectModelClass input) { - String entityAbstractName = "Jpa" + input.getName(); + String packageName = JpaTemplatesGeneratorUtil.getEntityPackage(this, model, input); - String entityConcreteName = getConcreteName(input); + String entityAbstractName = JpaTemplatesGeneratorUtil.getEntityAbstractName(input); - boolean generateAbstract = !isInClassPath(input.getPackageName(), entityAbstractName); + String entityConcreteName = JpaTemplatesGeneratorUtil.getEntityConcreteName(input); - boolean generateConcrete = !isInClassPath(input.getPackageName(), entityConcreteName); + boolean generateAbstract = !isInClassPath(packageName, entityAbstractName); + boolean generateConcrete = !isInClassPath(packageName, entityConcreteName); + if (generateAbstract) { - generateAbstract(input, entityAbstractName); + generateAbstract(input, packageName, entityAbstractName); } if (generateConcrete) { - generateImpl(input, entityAbstractName, entityConcreteName); + generateImpl(input, packageName, entityAbstractName, entityConcreteName); } } - protected void createAbstractOperations(ObjectModelClass ouput, - Iterable<ObjectModelOperation> operations) { - JpaTemplatesGeneratorUtil.cloneOperations( - this, - operations, - ouput, - true, - ObjectModelJavaModifier.ABSTRACT - ); - } - protected ObjectModelClass generateAbstract(ObjectModelClass input, + String packageName, String entityAbstractName) { // test if a super class is in same package (so is yet another entity) @@ -123,8 +116,9 @@ // get first super-class ObjectModelClass superClassModel = input.getSuperclasses().iterator().next(); - superClass = getConcreteName(superClassModel); - + superClass = JpaTemplatesGeneratorUtil.getEntityPackage(this, model, superClassModel) + + "." + + JpaTemplatesGeneratorUtil.getEntityConcreteName(superClassModel); } else { // try to find a super class by tag-value @@ -144,18 +138,12 @@ } ObjectModelClass output = - createAbstractClass(entityAbstractName, input.getPackageName()); + createAbstractClass(entityAbstractName, packageName); setSuperClass(output, superClass); - // Add annotation MappedSuperclass - addAnnotation(output, output, MappedSuperclass.class.getSimpleName()); - addImport(output, MappedSuperclass.class); + addAnnotation(output, MappedSuperclass.class); - if (log.isDebugEnabled()) { - log.debug("will generate " + output.getQualifiedName()); - } - String prefix = getConstantPrefix(input, DEFAULT_CONSTANT_PREFIX); setConstantPrefix(prefix); @@ -171,29 +159,22 @@ Set<String> constantNames = addConstantsFromDependency(input, output); // Get available properties - List<ObjectModelAttribute> properties = getProperties(input); + List<ObjectModelAttribute> properties = + JpaTemplatesGeneratorUtil.getProperties(input); - //TODO Deal with @GeneratedValue + // Create an id property ObjectModelAttributeImpl idAttr = new ObjectModelAttributeImpl(); idAttr.setDeclaringElement(input); - idAttr.setName("id"); + idAttr.setName(PROPERTY_ID); idAttr.setType(String.class.getName()); - properties.add(idAttr); + properties.add(0, idAttr); - //TODO Add attribute id (+ @Id) - //TODO 1 -> 1 @OnetoOne (uniquement navigeable sans bidi) si composition (Cascade = ALL) si aggregeation Cascade = (tout sauf ALL TODO A check) + orphanRemoval = true) - //TODO * -> 1 @ManyToOne (uniquement navigeable sans bidi) si composition (Cascade = ALL) si aggregeation Cascade = (tout sauf ALL TODO A check) + orphanRemoval = true) - //TODO 1 -> * @OneToMany (uniquement navigeable sans bidi) si composition (Cascade = ALL) si aggregeation Cascade = (tout sauf ALL TODO A check) + orphanRemoval = true) - //TODO * -> * @ManyToMany (uniquement navigeable sans bidi) si composition (Cascade = ALL) si aggregeation Cascade = (tout sauf ALL TODO A check) + orphanRemoval = true) - //TODO Si ORDERED ou et UNIQUE choisir le bon type de collection (O+U = LHS (laisser ça comme definition), (U = HS + S), (O = ArrayList +L), ( = ArrayList + C) - //TODO Si ORDERED ajouter l'annotation @OrderColumn //TODO Si enumeration @Enumeration(value = EnumType.STRING) (Voir pour mettre une tag-value pour mettre en ordinal) + voir comment ça marche pour les collections Multimap<ObjectModelAttribute, String> annotationsForAttributes = generateAnnotationsForProperties(input, output, properties); - // Add properties constant for (ObjectModelAttribute attr : properties) { @@ -206,18 +187,48 @@ createProperty(output, attr, annotationsForAttributes.get(attr)); } - boolean hasAMultipleProperty = containsMutiple(properties); + boolean hasAMultipleProperty = + JpaTemplatesGeneratorUtil.containsMutiple(properties); // Add helper operations if (hasAMultipleProperty) { - // add getChild methods createGetChildMethod(output); } + + if (isVerbose()) { + log.info("will generate " + output.getQualifiedName()); + } return output; } + protected ObjectModelClass generateImpl(ObjectModelClass input, + String packageName, + String entityAbstractName, + String entityConcreteName) { + + ObjectModelClass output = createClass(entityConcreteName, packageName); + + setSuperClass(output, entityAbstractName); + + // add Entity annotation + addAnnotation(output, Entity.class); + + // add a fix serialVersionUID, since the class has no field nor method + addConstant(output, + JpaTemplatesGeneratorUtil.SERIAL_VERSION_UID, + "long", + "1L", + ObjectModelJavaModifier.PRIVATE + ); + + if (isVerbose()) { + log.info("will generate " + output.getQualifiedName()); + } + return output; + } + protected Multimap<ObjectModelAttribute, String> generateAnnotationsForProperties(ObjectModelClass input, ObjectModelClass output, List<ObjectModelAttribute> properties) { @@ -227,10 +238,12 @@ for (ObjectModelAttribute property : properties) { String propertyName = property.getName(); String propertyType = property.getType(); - if ("id".equals(propertyName)) { + if (PROPERTY_ID.equals(propertyName)) { - result.put(property, Id.class.getSimpleName()); - addImport(output, Id.class); + addAnnotation(result, property, output, Id.class); + if (JpaTemplatesGeneratorUtil.hasGeneratedValueStereotype(input)) { + addAnnotation(result, property, output, GeneratedValue.class); + } continue; } @@ -243,34 +256,61 @@ boolean bidirection = reverseAttribute != null && reverseAttribute.isNavigable(); - //TODO Deal with bidirection - Preconditions.checkState( - !bidirection, - "Still can not deal with bidirection, but found one " + input.getQualifiedName() + "#" + propertyName); + boolean isInverse = false; + if (bidirection) { + + + // compute which is master of relation + String inverseValue = JpaTemplatesGeneratorUtil.getInverseTagValue(property); + if (StringUtils.isNotEmpty(inverseValue)) { + isInverse &= Boolean.parseBoolean(inverseValue); + // Si aucun tagvalue n'est défini, le choix est arbitraire : le + // premier attribut dans l'ordre alphabétique sera choisi pour porter le + // inverse="true" + } else { + isInverse &= JpaTemplatesGeneratorUtil.isFirstAttribute(property); + } + } + + boolean composite = property.isComposite(); + boolean entity = isEntity(input, propertyType); boolean enumeration = getModel().getEnumeration(propertyType) != null; if (JpaTemplatesGeneratorUtil.isNMultiplicity(property)) { + List<String> annotationParams = Lists.newArrayList(); + + if (composite) { + annotationParams.add("cascade = CascadeType.ALL"); + annotationParams.add("orphanRemoval = true"); + addImport(output, CascadeType.class); + } + + if (bidirection && !isInverse) { + + // add the mappedBy parameter + annotationParams.add("mappedBy = " + reverseAttribute.getName()); + } + if (nMultiplicity) { // * -> * (ManyToMany) - result.put(property, ManyToMany.class.getSimpleName()); - addImport(output, ManyToMany.class); + addAnnotation(result, property, output, ManyToMany.class, annotationParams.toArray(new String[annotationParams.size()])); + } else { // 0..1 -> * (OneToMany) - result.put(property, OneToMany.class.getSimpleName()); - addImport(output, OneToMany.class); + addAnnotation(result, property, output, OneToMany.class, annotationParams.toArray(new String[annotationParams.size()])); } - boolean withOrdererStereotype = property.isOrdered() || + boolean withOrdererStereotype = + property.isOrdered() || JpaTemplatesGeneratorUtil.hasOrderedStereotype(property); if (withOrdererStereotype) { - result.put(property, OrderColumn.class.getSimpleName()); - addImport(output, OrderColumn.class); + addAnnotation(result, property, output, OrderColumn.class); } continue; } @@ -278,8 +318,8 @@ if (enumeration) { // is an enumeration - result.put(property, Enumerated.class.getSimpleName() + "( value = " + EnumType.class.getSimpleName() + "." + EnumType.STRING + ")"); - addImport(output, Enumerated.class); + addAnnotation(result, property, output, Enumerated.class, + "value = EnumType.STRING"); addImport(output, EnumType.class); } @@ -288,13 +328,11 @@ if (nMultiplicity) { // * -> 0..1 (ManyToOne) - result.put(property, ManyToOne.class.getSimpleName()); - addImport(output, ManyToOne.class); + addAnnotation(result, property, output, ManyToOne.class); } else { // 0..1 -> 0..1 (OneToOne) - result.put(property, OneToOne.class.getSimpleName()); - addImport(output, OneToOne.class); + addAnnotation(result, property, output, OneToOne.class); } continue; @@ -306,30 +344,18 @@ return result; } - protected ObjectModelClass generateImpl(ObjectModelClass input, - String entityAbstractName, - String entityConcreteName) { - - ObjectModelClass output = createClass( - entityConcreteName, - input.getPackageName() - ); - - // set the abstract resulClass as the resultClassImpl super class - setSuperClass(output, entityAbstractName); - - // add Entity annotation - addAnnotation(output, output, Entity.class.getSimpleName()); - addImport(output, Entity.class); - - // add a fix serialVersionUID, since the class has no field nor method - addConstant(output, - JpaTemplatesGeneratorUtil.SERIAL_VERSION_UID, - "long", - "1L", - ObjectModelJavaModifier.PRIVATE - ); - return output; + protected void addAnnotation( + ListMultimap<ObjectModelAttribute, String> result, + ObjectModelAttribute property, + ObjectModelClass output, + Class annotation, + String... extraPart) { + String annotationStr = annotation.getSimpleName(); + if (extraPart.length > 0) { + annotationStr += "(" + Joiner.on(',').join(extraPart) + ")"; + } + result.put(property, annotationStr); + addImport(output, annotation); } protected void createProperty(ObjectModelClass output, @@ -338,8 +364,8 @@ boolean usePCS = false; - String attrName = getAttributeName(attr); - String attrType = getAttributeType(attr); + String attrName = JpaTemplatesGeneratorUtil.getAttributeName(attr); + String attrType = JpaTemplatesGeneratorUtil.getAttributeType(attr); boolean multiple = JpaTemplatesGeneratorUtil.isNMultiplicity(attr); @@ -404,29 +430,10 @@ usePCS ); - boolean ordered = attr.isOrdered() || - JpaTemplatesGeneratorUtil.hasOrderedStereotype(attr); - boolean unique = JpaTemplatesGeneratorUtil.hasUniqueStereotype(attr); - // Change type for Multiple attribute - if (ordered) { + Class<?> collectionType = JpaTemplatesGeneratorUtil.getCollectionType(attr); + attrType = collectionType.getName() + "<" + attrType + ">"; - if (unique) { - - attrType = LinkedHashSet.class.getName() + "<" + attrType + ">"; - } else { - - attrType = List.class.getName() + "<" + attrType + ">"; - } - } else { - - if (unique) { - attrType = Set.class.getName() + "<" + attrType + ">"; - } else { - attrType = Collection.class.getName() + "<" + attrType + ">"; - } - } - simpleType = JpaTemplatesGeneratorUtil.getSimpleName(attrType); } @@ -444,12 +451,16 @@ if (multiple || !booleanProperty) { - createGetMethod(output, - attrName, - attrType, - JpaTemplatesGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX + ObjectModelOperation getMethod = createGetMethod(output, + attrName, + attrType, + JpaTemplatesGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX ); + if (PROPERTY_ID.equals(attrName)) { + addAnnotation(output, getMethod, Override.class); + } + } createSetMethod(output, attrName, @@ -473,4 +484,312 @@ } + protected ObjectModelOperation createGetMethod(ObjectModelClass output, + String attrName, + String attrType, + String methodPrefix) { + + ObjectModelOperation operation = addOperation( + output, + getJavaBeanMethodName(methodPrefix, attrName), + attrType, + ObjectModelJavaModifier.PUBLIC + ); + setOperationBody(operation, "" + /*{ + return <%=attrName%>; + }*/ + ); + return operation; + } + + protected void createGetChildMethod(ObjectModelClass output, + String attrName, + String attrType, + String simpleType) { + ObjectModelOperation operation = addOperation( + output, + getJavaBeanMethodName("get", attrName), + attrType, + ObjectModelJavaModifier.PUBLIC + ); + addParameter(operation, "int", "index"); + setOperationBody(operation, "" + /*{ + <%=simpleType%> o = getChild(<%=attrName%>, index); + return o; + }*/ + ); + } + + protected void createIsEmptyMethod(ObjectModelClass output, + String attrName) { + ObjectModelOperation operation = addOperation( + output, + getJavaBeanMethodName("is", attrName) + "Empty", + boolean.class, + ObjectModelJavaModifier.PUBLIC + ); + setOperationBody(operation, "" + /*{ + return <%=attrName%> == null || <%=attrName%>.isEmpty(); + }*/ + ); + } + + protected void createSizeMethod(ObjectModelClass output, + String attrName) { + ObjectModelOperation operation = addOperation( + output, + getJavaBeanMethodName("size", attrName), + int.class, + ObjectModelJavaModifier.PUBLIC + ); + setOperationBody(operation, "" + /*{ + return <%=attrName%> == null ? 0 : <%=attrName%>.size(); + }*/ + ); + } + + protected void createAddChildMethod(ObjectModelClass output, + String attrName, + String attrType, + String constantName, + boolean usePCS) { + ObjectModelOperation operation = addOperation( + output, + getJavaBeanMethodName("add", attrName), + "void", + ObjectModelJavaModifier.PUBLIC + ); + addParameter(operation, attrType, attrName); + + String methodName = getJavaBeanMethodName("get", attrName); + StringBuilder buffer = new StringBuilder("" + /*{ + <%=methodName%>().add(<%=attrName%>); + }*/ + ); + if (usePCS) { + buffer.append("" + /*{ firePropertyChange(<%=constantName%>, null, <%=attrName%>); + }*/ + ); + } + setOperationBody(operation, buffer.toString()); + } + + protected void createAddAllChildrenMethod(ObjectModelClass output, + String attrName, + String attrType, + String constantName, + boolean usePCS) { + ObjectModelOperation operation = addOperation( + output, + getJavaBeanMethodName("addAll", attrName), + "void", + ObjectModelJavaModifier.PUBLIC + ); + addParameter(operation, Collection.class.getName() + "<" + attrType + ">", attrName); + + String methodName = getJavaBeanMethodName("get", attrName); + StringBuilder buffer = new StringBuilder("" + /*{ + <%=methodName%>().addAll(<%=attrName%>); + }*/ + ); + if (usePCS) { + buffer.append("" + /*{ firePropertyChange(<%=constantName%>, null, <%=attrName%>); + }*/ + ); + } + setOperationBody(operation, buffer.toString()); + } + + protected void createRemoveChildMethod(ObjectModelClass output, + String attrName, + String attrType, + String constantName, + boolean usePCS) { + ObjectModelOperation operation = addOperation( + output, + getJavaBeanMethodName("remove", attrName), + "boolean", + ObjectModelJavaModifier.PUBLIC + ); + addParameter(operation, attrType, attrName); + String methodName = getJavaBeanMethodName("get", attrName); + StringBuilder buffer = new StringBuilder(); + buffer.append("" + /*{ + boolean removed = <%=methodName%>().remove(<%=attrName%>);}*/ + ); + + if (usePCS) { + buffer.append("" + /*{ + if (removed) { + firePropertyChange(<%=constantName%>, <%=attrName%>, null); + }}*/ + ); + } + buffer.append("" + /*{ + return removed; + }*/ + ); + setOperationBody(operation, buffer.toString()); + } + + protected void createRemoveAllChildrenMethod(ObjectModelClass output, + String attrName, + String attrType, + String constantName, + boolean usePCS) { + + ObjectModelOperation operation = addOperation( + output, + getJavaBeanMethodName("removeAll", attrName), + "boolean", + ObjectModelJavaModifier.PUBLIC + ); + addParameter(operation, "java.util.Collection<" + attrType + ">", attrName); + StringBuilder buffer = new StringBuilder(); + String methodName = getJavaBeanMethodName("get", attrName); + buffer.append("" + /*{ + boolean removed = <%=methodName%>().removeAll(<%=attrName%>);}*/ + ); + + if (usePCS) { + buffer.append("" + /*{ + if (removed) { + firePropertyChange(<%=constantName%>, <%=attrName%>, null); + }}*/ + ); + } + buffer.append("" + /*{ + return removed; + }*/ + ); + setOperationBody(operation, buffer.toString()); + } + + protected void createContainsChildMethod(ObjectModelClass output, + String attrName, + String attrType, + String constantName, + boolean usePCS) { + + ObjectModelOperation operation = addOperation( + output, + getJavaBeanMethodName("contains", attrName), + "boolean", + ObjectModelJavaModifier.PUBLIC + ); + addParameter(operation, attrType, attrName); + StringBuilder buffer = new StringBuilder(); + String methodName = getJavaBeanMethodName("get", attrName); + buffer.append("" + /*{ + boolean contains = <%=methodName%>().contains(<%=attrName%>); + return contains; + }*/ + ); + setOperationBody(operation, buffer.toString()); + } + + protected void createContainsAllChildrenMethod(ObjectModelClass output, + String attrName, + String attrType, + String constantName, + boolean usePCS) { + + ObjectModelOperation operation = addOperation( + output, + getJavaBeanMethodName("containsAll", attrName), + "boolean", + ObjectModelJavaModifier.PUBLIC + ); + addParameter(operation, Collection.class.getName() + "<" + attrType + ">", attrName); + StringBuilder buffer = new StringBuilder(); + String methodName = getJavaBeanMethodName("get", attrName); + buffer.append("" + /*{ + boolean contains = <%=methodName%>().containsAll(<%=attrName%>); + return contains; + }*/ + ); + setOperationBody(operation, buffer.toString()); + } + + protected void createSetMethod(ObjectModelClass output, + String attrName, + String attrType, + String simpleType, + String constantName, + boolean usePCS) { + ObjectModelOperation operation = addOperation( + output, + getJavaBeanMethodName("set", attrName), + "void", + ObjectModelJavaModifier.PUBLIC + ); + addParameter(operation, attrType, attrName); + + if (usePCS) { + String methodName = getJavaBeanMethodName("get", attrName); + setOperationBody(operation, "" + /*{ + <%=simpleType%> oldValue = <%=methodName%>(); + this.<%=attrName%> = <%=attrName%>; + firePropertyChange(<%=constantName%>, oldValue, <%=attrName%>); + }*/ + ); + } else { + setOperationBody(operation, "" + /*{ + this.<%=attrName%> = <%=attrName%>; + }*/ + ); + } + } + + protected void createGetChildMethod(ObjectModelClass output) { + ObjectModelOperation getChild = addOperation( + output, + "getChild", "<T> T", + ObjectModelJavaModifier.PROTECTED + ); + addImport(output, List.class); + + addParameter(getChild, "java.util.Collection<T>", "childs"); + addParameter(getChild, "int", "index"); + setOperationBody(getChild, "" + /*{ + T result = null; + if (childs != null) { + if (childs instanceof List) { + if (index < childs.size()) { + result = ((List<T>) childs).get(index); + } + } else { + int i = 0; + for (T o : childs) { + if (index == i) { + result = o; + break; + } + i++; + } + } + } + return result; + }*/ + ); + } } \ No newline at end of file Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaPersistenceContextTransformer.java =================================================================== --- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaPersistenceContextTransformer.java 2013-05-24 22:19:58 UTC (rev 627) +++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaPersistenceContextTransformer.java 2013-05-25 14:13:01 UTC (rev 628) @@ -33,6 +33,13 @@ /*{generator option: writeString = +}*/ /** + * JpaPersistenceContextTransformer generates the persistence context for an model. + * <ul> + * <li>{@code AbstractXXXJpaPersistenceContext}: abstract jpa persistence context with all the technical stuff</li> + * <li>{@code XXXJpaPersistenceContext}: concrete public jpa persistence context to use in your persistence layer</li> + * </ul> + * {@code Note:} All classes found in class-path are not generated. + * <p/> * TODO Liste des entités (A voir meta-modèle...) * * @author tchemit <chemit@codelutin.com> @@ -44,20 +51,29 @@ @Override public void transformFromModel(ObjectModel model) { - String className = "Jpa" + model.getName() + "PersistenceContext"; + String packageName = JpaTemplatesGeneratorUtil.getPersistenceContextPackage(this, model); - String packageName = - getOutputProperties().getProperty(PROP_DEFAULT_PACKAGE); + String entityAbstractName = JpaTemplatesGeneratorUtil.getPersistenceContextAbstractName(model); - boolean generateAbstract = !isInClassPath(packageName, className); + String entityConcreteName = JpaTemplatesGeneratorUtil.getPersistenceContextConcreteName(model); + boolean generateAbstract = !isInClassPath(packageName, entityAbstractName); + + boolean generateConcrete = !isInClassPath(packageName, entityConcreteName); + if (generateAbstract) { - generate(packageName, className); + generateAbstract(packageName, entityAbstractName); } + + if (generateConcrete) { + + generateImpl(packageName, entityAbstractName, entityConcreteName); + } } - protected void generate(String packageName, String className) { + protected void generateAbstract(String packageName, + String className) { // try to find a super class by tag-value String superClass = JpaTemplatesGeneratorUtil.getPersistenceContextSuperClassTagValue( @@ -69,30 +85,44 @@ superClass = AbstractJpaPersistenceContext.class.getName(); } - ObjectModelClass output = createClass(className, packageName); + ObjectModelClass output = createAbstractClass(className, packageName); setSuperClass(output, superClass); addConstructorWithEntityManager(output); + // add dao factories for (ObjectModelClass aClass : getModel().getClasses()) { - if (packageName.equals(aClass.getPackageName())) { + //FIXME Find a way to exclude none entities classes +// if (packageName.equals(aClass.getPackageName())) { - // add dao factory method - String daoConcreteName = JpaTemplatesGeneratorUtil.getDaoConcreteName(aClass); + // add dao factory method + String daoPackageName = JpaTemplatesGeneratorUtil.getDaoPackage(this, model, aClass); + String daoConcreteName = JpaTemplatesGeneratorUtil.getDaoConcreteName(aClass); - ObjectModelOperation operation = addOperation( - output, - "get" + daoConcreteName, - packageName + "." + daoConcreteName); - setOperationBody(operation, "" + ObjectModelOperation operation = addOperation( + output, + "get" + aClass.getName() + "Dao", + daoPackageName + "." + daoConcreteName); + setOperationBody(operation, "" /*{ return new <%=daoConcreteName%>(entityManager); }*/ - ); - - } + ); +// } } } + + protected ObjectModelClass generateImpl(String packageName, + String entityAbstractName, + String entityConcreteName) { + + ObjectModelClass output = createClass(entityConcreteName, packageName); + + setSuperClass(output, entityAbstractName); + + addConstructorWithEntityManager(output); + return output; + } } Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java =================================================================== --- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java 2013-05-24 22:19:58 UTC (rev 627) +++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java 2013-05-25 14:13:01 UTC (rev 628) @@ -30,6 +30,12 @@ import org.nuiton.eugene.models.object.ObjectModelClass; import org.nuiton.eugene.models.object.ObjectModelClassifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + /** * Utility class for pure jpa templates. * @@ -38,10 +44,157 @@ */ public class JpaTemplatesGeneratorUtil extends JavaGeneratorUtil { + public static String getPersistenceContextPackage(AbstractJpaTransformer transformer, + ObjectModel model) { + + String result = getPersistenceContextPackageTagValue(model); + if (result == null) { + + // use default package + result = transformer.getDefaultPackageName(); + } + + return result; + } + + public static String getEntityPackage(AbstractJpaTransformer transformer, + ObjectModel model, + ObjectModelClassifier input) { + + String result = getEntityPackageTagValue(model, input); + if (result == null) { + + // use default package + result = transformer.getDefaultPackageName() + ".entity"; + } + + return result; + } + + public static String getDaoPackage(AbstractJpaTransformer transformer, + ObjectModel model, + ObjectModelClassifier input) { + + String result = getDaoPackageTagValue(model, input); + if (result == null) { + + // use default package + result = transformer.getDefaultPackageName() + ".dao"; + } + + return result; + } + + public static String getPersistenceContextAbstractName(ObjectModel model) { + return "AbstractJpa" + model.getName() + "PersistenceContext"; + } + + public static String getPersistenceContextConcreteName(ObjectModel model) { + return "Jpa" + model.getName() + "PersistenceContext"; + } + + public static String getEntityAbstractName(ObjectModelClass input) { + return "AbstractJpa" + input.getName(); + } + + public static String getEntityConcreteName(ObjectModelClass input) { + return input.getName(); + } + + public static String getDaoAbstractName(ObjectModelClass input) { + return "Abstract" + input.getName() + "JpaDao"; + } + public static String getDaoConcreteName(ObjectModelClass input) { return input.getName() + "JpaDao"; } + public static String getConcreteEntityQualifiedName(AbstractJpaTransformer transformer, ObjectModel model, ObjectModelClass input) { + return getEntityPackage(transformer, model, input) + "." + getEntityConcreteName(input); + } + + public static String getConcreteDaoQualifiedName(AbstractJpaTransformer transformer, ObjectModel model, ObjectModelClass input) { + return getDaoPackage(transformer, model, input) + "." + getDaoConcreteName(input); + } + + public static Class<?> getCollectionType(ObjectModelAttribute attr) { + + boolean ordered = attr.isOrdered() || + JpaTemplatesGeneratorUtil.hasOrderedStereotype(attr); + boolean unique = JpaTemplatesGeneratorUtil.hasUniqueStereotype(attr); + + // Change type for Multiple attribute + Class<?> result; + + if (ordered) { + + if (unique) { + + result = LinkedHashSet.class; + } else { + + result = List.class; + } + } else { + + if (unique) { + result = Set.class; + } else { + result = Collection.class; + } + } + return result; + } + + public static boolean containsMutiple(List<ObjectModelAttribute> attributes) { + + boolean result = false; + + for (ObjectModelAttribute attr : attributes) { + + if (isNMultiplicity(attr)) { + result = true; + + break; + } + + } + return result; + } + + public static String getAttributeName(ObjectModelAttribute attr) { + String attrName = attr.getName(); + if (attr.hasAssociationClass()) { + String assocAttrName = getAssocAttrName(attr); + attrName = toLowerCaseFirstLetter(assocAttrName); + } + return attrName; + } + + public static String getAttributeType(ObjectModelAttribute attr) { + String attrType = attr.getType(); + if (attr.hasAssociationClass()) { + attrType = attr.getAssociationClass().getName(); + } + return attrType; + } + + public static List<ObjectModelAttribute> getProperties(ObjectModelClass input) { + List<ObjectModelAttribute> attributes = + (List<ObjectModelAttribute>) input.getAttributes(); + + List<ObjectModelAttribute> attrs = + new ArrayList<ObjectModelAttribute>(); + for (ObjectModelAttribute attr : attributes) { + if (attr.isNavigable()) { + + // only keep navigable attributes + attrs.add(attr); + } + } + return attrs; + } + /** * Obtain the value of the {@link JpaTemplatesTagValues#TAG_ENTITY_SUPER_CLASS} * tag value on the given model or classifier. @@ -60,6 +213,24 @@ } /** + * Obtain the value of the {@link JpaTemplatesTagValues#TAG_ENTITY_PACKAGE} + * tag value on the given model. + * <p/> + * It will first look on the model, and then in the given classifier. + * + * @param model model to seek + * @param classifier classifier to seek + * @return the none empty value of the found tag value or {@code null} if not found nor empty. + * @see JpaTemplatesTagValues#TAG_ENTITY_PACKAGE + * @since 2.3 + */ + public static String getEntityPackageTagValue(ObjectModel model, + ObjectModelClassifier classifier) { + String value = findTagValue(JpaTemplatesTagValues.TAG_ENTITY_PACKAGE, classifier, model); + return value; + } + + /** * Obtain the value of the {@link JpaTemplatesTagValues#TAG_DAO_SUPER_CLASS} * tag value on the given model or classifier. * <p/> @@ -77,6 +248,24 @@ } /** + * Obtain the value of the {@link JpaTemplatesTagValues#TAG_DAO_PACKAGE} + * tag value on the given model. + * <p/> + * It will first look on the model, and then in the given classifier. + * + * @param model model to seek + * @param classifier classifier to seek + * @return the none empty value of the found tag value or {@code null} if not found nor empty. + * @see JpaTemplatesTagValues#TAG_DAO_PACKAGE + * @since 2.3 + */ + public static String getDaoPackageTagValue(ObjectModel model, + ObjectModelClassifier classifier) { + String value = findTagValue(JpaTemplatesTagValues.TAG_DAO_PACKAGE, classifier, model); + return value; + } + + /** * Obtain the value of the {@link JpaTemplatesTagValues#TAG_PERSISTENCE_CONTEXT_SUPER_CLASS} * tag value on the given model. * @@ -91,6 +280,36 @@ } /** + * Obtain the value of the {@link JpaTemplatesTagValues#TAG_PERSISTENCE_CONTEXT_PACKAGE} + * tag value on the given model. + * <p/> + * + * @param model model to seek + * @return the none empty value of the found tag value or {@code null} if not found nor empty. + * @see JpaTemplatesTagValues#TAG_PERSISTENCE_CONTEXT_PACKAGE + * @since 2.3 + */ + public static String getPersistenceContextPackageTagValue(ObjectModel model) { + String value = findTagValue(JpaTemplatesTagValues.TAG_PERSISTENCE_CONTEXT_PACKAGE, null, model); + return value; + } + + /** + * Obtain the value of the {@link JpaTemplatesTagValues#TAG_INVERSE} + * tag value on the given attribute. + * <p/> + * + * @param attribute attribute to seek + * @return the none empty value of the found tag value or {@code null} if not found nor empty. + * @see JpaTemplatesTagValues#TAG_INVERSE + * @since 2.5 + */ + public static String getInverseTagValue(ObjectModelAttribute attribute) { + String value = findTagValue(JpaTemplatesTagValues.TAG_INVERSE, attribute, null); + return value; + } + + /** * Check if the given attribute has the * {@link JpaTemplatesStereoTypes#STEREOTYPE_UNIQUE} stereotype. * @@ -102,4 +321,17 @@ public static boolean hasUniqueStereotype(ObjectModelAttribute attribute) { return attribute.hasStereotype(JpaTemplatesStereoTypes.STEREOTYPE_UNIQUE); } + + /** + * Check if the given class has the + * {@link JpaTemplatesStereoTypes#STEREOTYPE_GENERATED_VALUE} stereotype. + * + * @param aClass class to test + * @return {@code true} if stereotype was found, {@code false otherwise} + * @see JpaTemplatesStereoTypes#STEREOTYPE_GENERATED_VALUE + * @since 2.5 + */ + public static boolean hasGeneratedValueStereotype(ObjectModelClassifier aClass) { + return aClass.hasStereotype(JpaTemplatesStereoTypes.STEREOTYPE_GENERATED_VALUE); + } } Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesStereoTypes.java =================================================================== --- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesStereoTypes.java 2013-05-24 22:19:58 UTC (rev 627) +++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesStereoTypes.java 2013-05-25 14:13:01 UTC (rev 628) @@ -27,7 +27,10 @@ import org.nuiton.eugene.EugeneStereoTypes; import org.nuiton.eugene.ModelPropertiesUtil; import org.nuiton.eugene.models.object.ObjectModelAttribute; +import org.nuiton.eugene.models.object.ObjectModelClassifier; +import javax.persistence.GeneratedValue; + /** * Defines all stereotypes managed by JPA templates. * @@ -44,4 +47,13 @@ @ModelPropertiesUtil.StereotypeDefinition(target = ObjectModelAttribute.class, documentation = "To specify that an attribute is unique (JPA mapping)") String STEREOTYPE_UNIQUE = "unique"; + + /** + * Stéréotype pour ajouter l'annoation {@link GeneratedValue} sur l'id. + * + * @see JpaTemplatesGeneratorUtil#hasGeneratedValueStereotype(ObjectModelClassifier) + */ + @ModelPropertiesUtil.StereotypeDefinition(target = ObjectModelClassifier.class, + documentation = "To specify that an entity has a generated id (see GeneratedValue annotation) (JPA mapping)") + String STEREOTYPE_GENERATED_VALUE = "generatedValue"; } Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesTagValues.java =================================================================== --- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesTagValues.java 2013-05-24 22:19:58 UTC (rev 627) +++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesTagValues.java 2013-05-25 14:13:01 UTC (rev 628) @@ -27,6 +27,7 @@ import org.nuiton.eugene.EugeneTagValues; import org.nuiton.eugene.ModelPropertiesUtil; import org.nuiton.eugene.models.object.ObjectModel; +import org.nuiton.eugene.models.object.ObjectModelAttribute; import org.nuiton.eugene.models.object.ObjectModelClassifier; /** @@ -49,6 +50,16 @@ "for a class or any class of a model") String TAG_ENTITY_SUPER_CLASS = "entitySuperClass"; + /** + * Tag value to specify where to generate entities. + * + * @see JpaTemplatesGeneratorUtil#getEntityPackage(ObjectModel) + * @since 0.1 + */ + @ModelPropertiesUtil.TagValueDefinition( + target = {ObjectModel.class}, + documentation = "To specify the package where to generate entities") + String TAG_ENTITY_PACKAGE = "entityPackage"; /** * Tag value to use a super class for generated bean. @@ -62,6 +73,16 @@ "for a class or any class of a model") String TAG_DAO_SUPER_CLASS = "daoSuperClass"; + /** + * Tag value to specify where to generate daos. + * + * @see JpaTemplatesGeneratorUtil#getDaoPackage(ObjectModel) + * @since 0.1 + */ + @ModelPropertiesUtil.TagValueDefinition( + target = {ObjectModel.class}, + documentation = "To specify the package where to generate daos") + String TAG_DAO_PACKAGE = "daoPackage"; /** * Tag value to use a super class for generated bean. @@ -72,6 +93,31 @@ @ModelPropertiesUtil.TagValueDefinition( target = {ObjectModel.class}, documentation = "To specify a super-class to used on generated persistence context") - String TAG_PERSISTENCE_CONTEXT_SUPER_CLASS = "daoSuperClass"; + String TAG_PERSISTENCE_CONTEXT_SUPER_CLASS = "persistenceContextSuperClass"; + /** + * Tag value to specify where to generate persistenceContexts. + * + * @see JpaTemplatesGeneratorUtil#getPersistenceContextPackage(ObjectModel) + * @since 0.1 + */ + @ModelPropertiesUtil.TagValueDefinition( + target = {ObjectModel.class}, + documentation = "To specify the package where to generate persistenceContexts") + String TAG_PERSISTENCE_CONTEXT_PACKAGE = "persistenceContextPackage"; + + + /** + * Tag pour permettre de choisir qui contrôle la relation N-N + * bidirectionnelle. On a inverse=true sur le père de la relation.. + * <p/> + * Par défaut le inverse=true est placé sur le premier rôle trouvé dans + * l'ordre alphabétique. + * + * @see JpaTemplatesGeneratorUtil#getInverseTagValue(ObjectModelAttribute) + * @since 2.5 + */ + @ModelPropertiesUtil.TagValueDefinition(target = {ObjectModelAttribute.class}, + documentation = "Sets which part of a N-N relation is master (inverse=true) and slave (inverse=false) (must be put on each side on a such relation) (Hibernate mapping)") + String TAG_INVERSE = "inverse"; } Modified: nuiton-jpa/pom.xml =================================================================== --- nuiton-jpa/pom.xml 2013-05-24 22:19:58 UTC (rev 627) +++ nuiton-jpa/pom.xml 2013-05-25 14:13:01 UTC (rev 628) @@ -31,6 +31,8 @@ <!-- pour un muli module on doit fixer le projectId --> <projectId>nuiton-jpa</projectId> + <redmine.skipGenerateChanges>true</redmine.skipGenerateChanges> + <!-- libs version --> <eugeneVersion>2.6.3-SNAPSHOT</eugeneVersion> <nuitonUtilsVersion>2.6.12</nuitonUtilsVersion>
participants (1)
-
tchemit@users.nuiton.org