Author: tchemit Date: 2010-07-18 18:51:11 +0200 (Sun, 18 Jul 2010) New Revision: 2079 Url: http://nuiton.org/repositories/revision/topia/2079 Log: Evolution #775: Add getNaturalIds method on TopiaEntityEnum and use it to obtain an entity natural id in EntityStore Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/DAOHelperTransformer.java trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaEntityEnum.java trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/EntityOperator.java trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/EntityOperatorStore.java Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/DAOHelperTransformer.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/DAOHelperTransformer.java 2010-07-18 15:20:33 UTC (rev 2078) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/DAOHelperTransformer.java 2010-07-18 16:51:11 UTC (rev 2079) @@ -25,6 +25,7 @@ package org.nuiton.topia.generator; +import org.apache.commons.lang.BooleanUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.eugene.models.object.ObjectModelType; @@ -40,9 +41,12 @@ import org.nuiton.topia.persistence.TopiaEntityEnum; import org.nuiton.topia.persistence.util.EntityOperator; import org.nuiton.topia.persistence.util.EntityOperatorStore; +import org.nuiton.util.StringUtil; import java.lang.reflect.Array; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.List; @@ -94,7 +98,8 @@ String entityEnumName = modelName+"EntityEnum"; // add non public constructor - ObjectModelOperation constructor = addConstructor(resultClass, ObjectModelModifier.PROTECTED); + ObjectModelOperation constructor = + addConstructor(resultClass, ObjectModelModifier.PROTECTED); setOperationBody(constructor," "); ObjectModelOperation op; @@ -260,15 +265,35 @@ addImport(resultClass, TopiaEntityEnum.class); addInterface(entityEnum, TopiaEntityEnum.class); -// addImport(entityEnum,TopiaEntityEnum.class); for (ObjectModelClass clazz : classes) { String clazzName = clazz.getName(); - addLiteral(entityEnum, clazzName + '(' + clazzName + ".class)"); + Collection<ObjectModelAttribute> attributes = clazz.getAttributes(); + + boolean withNatural = false; + StringBuilder sb = new StringBuilder(); + + for (ObjectModelAttribute attr2 : attributes) { + if (TopiaGeneratorUtil.isNaturalId(attr2)) { + withNatural = true; + // attribut metier + sb.append(", \"").append(attr2.getName()).append("\""); + } + } + + if (withNatural) { + String naturalIds = sb.substring(2); + addLiteral(entityEnum, clazzName + '(' + clazzName + ".class, " + naturalIds + ")"); + } else { + addLiteral(entityEnum, clazzName + '(' + clazzName + ".class)"); + } + if (generateStandaloneEnum) { addImport(entityEnum, clazz); } } + + attr = (ObjectModelAttributeImpl) addAttribute(entityEnum, "contract", "Class<? extends TopiaEntity>"); attr.setDocumentation("the contract of the entity"); @@ -278,102 +303,121 @@ attr = (ObjectModelAttributeImpl) addAttribute(entityEnum, "implementation", "Class<? extends TopiaEntity>"); attr.setDocumentation("the implementation class of the entity (will be lazy computed at runtime)"); + attr = (ObjectModelAttributeImpl) addAttribute(entityEnum, "naturalIds", "String[]"); + attr.setDocumentation("the array of property involved in the natural key of the entity."); + // constructor op = addConstructor(entityEnum, ObjectModelModifier.PACKAGE); addParameter(op,"Class<? extends TopiaEntity >","contract"); + addParameter(op,"String...","naturalIds"); setOperationBody(op, "" - /*{ - this.contract = contract; - this.implementationFQN = contract.getName()+"Impl"; - }*/ +/*{ + this.contract = contract; + this.naturalIds = naturalIds; + this.implementationFQN = contract.getName()+"Impl"; +}*/ ); // getContract method - op = addOperation(entityEnum, "getContract","Class<? extends TopiaEntity>",ObjectModelModifier.PUBLIC); + op = addOperation(entityEnum, "getContract", "Class<? extends TopiaEntity>", ObjectModelModifier.PUBLIC); + addAnnotation(entityEnum,op,"Override"); setOperationBody(op, "" - /*{ - return contract; - }*/ +/*{ + return contract; +}*/ ); + // getContract method + op = addOperation(entityEnum, "getNaturalIds", "String[]", ObjectModelModifier.PUBLIC); + addAnnotation(entityEnum,op,"Override"); + setOperationBody(op, "" +/*{ + return naturalIds; +}*/ + ); + // getImplementationFQN method op = addOperation(entityEnum, "getImplementationFQN","String",ObjectModelModifier.PUBLIC); + addAnnotation(entityEnum,op,"Override"); setOperationBody(op, "" - /*{ - return implementationFQN; - }*/ +/*{ + return implementationFQN; +}*/ ); // setImplementationFQN method op = addOperation(entityEnum, "setImplementationFQN","void",ObjectModelModifier.PUBLIC); + addAnnotation(entityEnum,op,"Override"); addParameter(op,"String","implementationFQN"); if (generateOperator) { setOperationBody(op, "" - /*{ - this.implementationFQN = implementationFQN; - this.implementation = null; - // on reinitialise le magasin d'operators - EntityOperatorStore.clear(); - }*/ +/*{ + this.implementationFQN = implementationFQN; + this.implementation = null; + // on reinitialise le magasin d'operators + EntityOperatorStore.clear(); +}*/ ); } else { setOperationBody(op, "" - /*{ - this.implementationFQN = implementationFQN; - this.implementation = null; - }*/ +/*{ + this.implementationFQN = implementationFQN; + this.implementation = null; +}*/ ); } // accept method op = addOperation(entityEnum, "accept","boolean",ObjectModelModifier.PUBLIC); + addAnnotation(entityEnum,op,"Override"); addParameter(op,"Class<? extends TopiaEntity>","klass"); setOperationBody(op, "" - /*{ - return <%=daoHelperClazzName%>.getContractClass(klass) == contract; - }*/ +/*{ + return <%=daoHelperClazzName%>.getContractClass(klass) == contract; +}*/ ); // getImplementation method op = addOperation(entityEnum, "getImplementation","Class<? extends TopiaEntity>",ObjectModelModifier.PUBLIC); + addAnnotation(entityEnum,op,"Override"); setOperationBody(op, "" - /*{ - if (implementation == null) { - try { - implementation = (Class<? extends TopiaEntity>) Class.forName(implementationFQN); - } catch (ClassNotFoundException e) { - throw new RuntimeException("could not find class " + implementationFQN); - } - } - return implementation; - }*/ +/*{ + if (implementation == null) { + try { + implementation = (Class<? extends TopiaEntity>) Class.forName(implementationFQN); + } catch (ClassNotFoundException e) { + throw new RuntimeException("could not find class " + implementationFQN); + } + } + return implementation; +}*/ ); // valueOf method op = addOperation(entityEnum, "valueOf", entityEnumName, ObjectModelModifier.PUBLIC,ObjectModelModifier.STATIC); addParameter(op,"TopiaEntity","entity"); setOperationBody(op, "" - /*{ - return valueOf(entity.getClass()); - }*/ + /*{ + return valueOf(entity.getClass()); + }*/ ); // valueOf method op = addOperation(entityEnum, "valueOf", entityEnumName, ObjectModelModifier.PUBLIC,ObjectModelModifier.STATIC); addParameter(op,"Class<?>","klass"); setOperationBody(op, "" - /*{ - if (klass.isInterface()) { - return <%=entityEnumName%>.valueOf(klass.getSimpleName()); + /*{ + if (klass.isInterface()) { + return <%=entityEnumName%>.valueOf(klass.getSimpleName()); + } + for (<%=entityEnumName%> entityEnum : <%=entityEnumName%>.values()) { + if (entityEnum.getContract().isAssignableFrom(klass)) { + //todo check it works for inheritance + return entityEnum; } - for (<%=entityEnumName%> entityEnum : <%=entityEnumName%>.values()) { - if (entityEnum.getContract().isAssignableFrom(klass)) { - //todo check it works for inheritance - return entityEnum; - } - } - throw new IllegalArgumentException("no entity defined for the class " + klass + " in : " + Arrays.toString(<%=entityEnumName%>.values())); - }*/ + } + throw new IllegalArgumentException("no entity defined for the class " + klass + " in : " + Arrays.toString(<%=entityEnumName%>.values())); + }*/ ); } } Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaEntityEnum.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaEntityEnum.java 2010-07-18 15:20:33 UTC (rev 2078) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaEntityEnum.java 2010-07-18 16:51:11 UTC (rev 2079) @@ -68,6 +68,13 @@ String getImplementationFQN(); /** + * + * @return the array of property names involved in the natural key + * of the entity. + */ + String[] getNaturalIds(); + + /** * Change the implementation class of the entity. * * Note : this method should reset all states of the objet Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/EntityOperator.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/EntityOperator.java 2010-07-18 15:20:33 UTC (rev 2078) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/EntityOperator.java 2010-07-18 16:51:11 UTC (rev 2079) @@ -40,6 +40,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TreeMap; + import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -77,25 +79,73 @@ */ public class EntityOperator<B extends TopiaEntity> { - /** to use log facility, just put in your code: log.info(\"...\"); */ + /** Logger */ private static Log log = LogFactory.getLog(EntityOperator.class); + + /** + * the constant of the entity + */ protected final TopiaEntityEnum contract; + + /** + * list of property names available on the entity. + */ protected List<String> properties; + + /** + * list of association names available on the entity. + */ protected List<String> associationProperties; + + /** + * cache of getter methods. + */ protected Method[] getMethods; + + /** + * cache of setter methods. + */ protected Method[] setMethods; + + /** + * cache of assocation {@code get} methods. + */ protected Method[] childGetMethods; + + /** + * cache of assocation {@code add} methods. + */ protected Method[] childAddMethods; + + /** + * cache of assocation {@code addAll} methods. + */ protected Method[] childAddAllMethods; + + /** + * cache of assocation {@code remove} methods. + */ protected Method[] childRemoveMethods; + + /** + * cache of assocation {@code size} methods. + */ protected Method[] childSizeMethods; + + /** + * cache of assocation {@code isEmpty} methods. + */ protected Method[] childIsEmptyMethods; + + /** + * cache of assocation {@code clear}methods. + */ protected Method[] childClearMethods; protected EntityOperator(TopiaEntityEnum contract) { if (contract == null) { - throw new NullPointerException("contract parameter can not be " + - "null!"); + throw new NullPointerException( + "'contract' parameter can not be null!"); } this.contract = contract; init(); @@ -131,6 +181,21 @@ } /** + * Pour obtenir un dictionnaire de la clef naturelle (clef métier) du {@code bean} + * donne. + * @param bean le bean a inspecter + * @return le dictionnaire de la clef naturel du bean + * @since 2.4.1 + */ + public Map<String,Object> getNaturalId(B bean) { + Map<String,Object> result = new TreeMap<String, Object>(); + String[] ids = contract.getNaturalIds(); + for (String id : ids) { + result.put(id,get(id, bean)); + } + return result; + } + /** * Copie une propriete de src vers dst. * * Note : cela apellera la methode <code>setXXX(value)</code>. @@ -439,7 +504,7 @@ } } - protected synchronized void init() { + protected void init() { List<Method> getters = new ArrayList<Method>(); List<Method> setters = new ArrayList<Method>(); List<Method> childGetters = new ArrayList<Method>(); @@ -564,7 +629,7 @@ } } - protected synchronized void init(Class<?> entityClass, + protected void init(Class<?> entityClass, Set<Class<?>> explored, List<String> properties, List<String> associationProperties, Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/EntityOperatorStore.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/EntityOperatorStore.java 2010-07-18 15:20:33 UTC (rev 2078) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/EntityOperatorStore.java 2010-07-18 16:51:11 UTC (rev 2079) @@ -61,10 +61,10 @@ EntityOperator<E> operator = (EntityOperator<E>) shared.store.get(contract); if (operator == null) { - synchronized (shared.store) { +// synchronized (shared.store) { operator = new EntityOperator<E>(contract); shared.store.put(contract, operator); - } +// } } return operator; //TODO on devrait peut-etre toujours retourner un clone ? @@ -73,9 +73,9 @@ } public static void clear() { - synchronized (shared.store) { +// synchronized (shared.store) { shared.store.clear(); - } +// } } protected EntityOperatorStore() {