Author: tchemit Date: 2012-03-29 02:15:57 +0200 (Thu, 29 Mar 2012) New Revision: 2426 Url: http://nuiton.org/repositories/revision/topia/2426 Log: fixes #2040 (Manage in the EntityEnum contract the properties marked as not-null) Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/DAOHelperTransformer.java trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/TopiaGeneratorUtil.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 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 2012-03-20 13:34:53 UTC (rev 2425) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/DAOHelperTransformer.java 2012-03-29 00:15:57 UTC (rev 2426) @@ -25,6 +25,7 @@ package org.nuiton.topia.generator; +import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.eugene.models.object.ObjectModelType; @@ -97,6 +98,7 @@ addImport(entityEnum, EntityOperatorStore.class); addImport(entityEnum, Arrays.class); addImport(entityEnum, TopiaRuntimeException.class); + addImport(entityEnum, ArrayUtils.class); } else { entityEnum = (ObjectModelEnumerationImpl) @@ -108,6 +110,7 @@ addImport(daoHelper, TopiaEntityEnum.class); addImport(daoHelper, EntityOperatorStore.class); addImport(daoHelper, Arrays.class); + addImport(daoHelper, ArrayUtils.class); } // generate DAOHelper @@ -316,22 +319,33 @@ Collection<ObjectModelAttribute> attributes = clazz.getAttributes(); boolean withNatural = false; - StringBuilder sb = new StringBuilder(); + boolean withNotNull = false; + StringBuilder naturalIdsParams = new StringBuilder(); + StringBuilder notNullParams = new StringBuilder(); for (ObjectModelAttribute attr2 : attributes) { if (TopiaGeneratorUtil.isNaturalId(attr2)) { withNatural = true; // attribut metier - sb.append(", \"").append(attr2.getName()).append("\""); + naturalIdsParams.append(", \"").append(attr2.getName()).append("\""); } + if (TopiaGeneratorUtil.isNotNull(attr2)) { + withNotNull = true; + // attribut not-null + notNullParams.append(", \"").append(attr2.getName()).append("\""); + } } - if (withNatural) { - String naturalIds = sb.substring(2); - addLiteral(entityEnum, clazzName + '(' + clazzName + ".class, " + naturalIds + ")"); + StringBuilder params = new StringBuilder(clazzName + ".class"); + if (withNotNull) { + params.append(", new String[]{ " + notNullParams.substring(2) + " }"); } else { - addLiteral(entityEnum, clazzName + '(' + clazzName + ".class)"); + params.append(", ArrayUtils.EMPTY_STRING_ARRAY"); } + if (withNatural) { + params.append(", ").append(naturalIdsParams.substring(2)); + } + addLiteral(entityEnum, clazzName + '(' + params.toString() + ')'); if (generateStandaloneEnum) { addImport(entityEnum, clazz); @@ -350,13 +364,18 @@ attr = (ObjectModelAttributeImpl) addAttribute(entityEnum, "naturalIds", "String[]"); attr.setDocumentation("The array of property involved in the natural key of the entity."); + attr = (ObjectModelAttributeImpl) addAttribute(entityEnum, "notNulls", "String[]"); + attr.setDocumentation("The array of not null properties of the entity."); + // constructor op = addConstructor(entityEnum, ObjectModelModifier.PACKAGE); addParameter(op,"Class<? extends TopiaEntity >","contract"); + addParameter(op,"String[]","notNulls"); addParameter(op,"String...","naturalIds"); setOperationBody(op, "" /*{ this.contract = contract; + this.notNulls = notNulls; this.naturalIds = naturalIds; implementationFQN = contract.getName() + "Impl"; }*/ @@ -371,7 +390,7 @@ }*/ ); - // getContract method + // getNaturalIds method op = addOperation(entityEnum, "getNaturalIds", "String[]", ObjectModelModifier.PUBLIC); addAnnotation(entityEnum,op,Override.class.getSimpleName()); setOperationBody(op, "" @@ -380,6 +399,33 @@ }*/ ); + // isUseNaturalIds method + op = addOperation(entityEnum, "isUseNaturalIds", "boolean", ObjectModelModifier.PUBLIC); + addAnnotation(entityEnum,op,Override.class.getSimpleName()); + setOperationBody(op, "" +/*{ + return naturalIds.length > 0; + }*/ + ); + + // getNotNulls method + op = addOperation(entityEnum, "getNotNulls", "String[]", ObjectModelModifier.PUBLIC); + addAnnotation(entityEnum,op,Override.class.getSimpleName()); + setOperationBody(op, "" +/*{ + return notNulls; + }*/ + ); + + // isUseNotNulls method + op = addOperation(entityEnum, "isUseNotNulls", "boolean", ObjectModelModifier.PUBLIC); + addAnnotation(entityEnum,op,Override.class.getSimpleName()); + setOperationBody(op, "" +/*{ + return notNulls.length > 0; + }*/ + ); + // getImplementationFQN method op = addOperation(entityEnum, "getImplementationFQN","String",ObjectModelModifier.PUBLIC); addAnnotation(entityEnum,op,Override.class.getSimpleName()); Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/TopiaGeneratorUtil.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/TopiaGeneratorUtil.java 2012-03-20 13:34:53 UTC (rev 2425) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/TopiaGeneratorUtil.java 2012-03-29 00:15:57 UTC (rev 2426) @@ -443,6 +443,28 @@ } /** + * Detecte si un attribut est marué comme non null. + * + * @param attribute l'attribut à tester + * @return {@code true} si l'attribut doit être non null, {@code false} sinon.. + * @since 2.6.9 + */ + public static boolean isNotNull(ObjectModelAttribute attribute) { + String value = getNotNullTagValue(attribute); + if (StringUtils.isEmpty(value)) { + // valeur null, donc pas positionnee + return false; + } + try { + return Boolean.valueOf(value.trim()); + } catch (Exception e) { + // on a pas reussi a convertir en boolean. + //todo peut-être declancher une exception ? + return false; + } + } + + /** * Cherches et renvoie le copyright a utiliser sur le model. * * @param model le modele utilisé 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 2012-03-20 13:34:53 UTC (rev 2425) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaEntityEnum.java 2012-03-29 00:15:57 UTC (rev 2426) @@ -29,19 +29,19 @@ /** * The contract to be realised by the generated enumeration in any DAOHelper. - * + * <p/> * Example : for a model Test, we will have a * <code>TestDOAHelper.TestEntityEnum</code> enumeration generated. - * + * <p/> * The contract gives some informations about the classes for any entity dealed * by the dao helper. More precisely : - * + * <p/> * - contract class of the entity (this must be an interface class) * - the implementation fqn class of an entity (at generation time, we might - * not have the implementation class) + * not have the implementation class) * - the implementation class (will be looked up at runtime execution, in that - * way we make possible to used a different implementation at runtime. - * + * way we make possible to used a different implementation at runtime. + * <p/> * - a method to accept any TopiaEntity class for this entity description * * @author tchemit <chemit@codelutin.com> @@ -50,10 +50,7 @@ */ public interface TopiaEntityEnum extends Serializable { - /** - * - * @return the contract class of the entity - */ + /** @return the contract class of the entity */ Class<? extends TopiaEntity> getContract(); /** @@ -63,37 +60,51 @@ */ Class<? extends TopiaEntity> getImplementation(); - /** - * - * @return the fully qualifed name of the implementation class of the entity - */ + /** @return the fully qualifed name of the implementation class of the entity */ String getImplementationFQN(); /** - * * @return the array of property names involved in the natural key - * of the entity. + * of the entity. */ String[] getNaturalIds(); - + /** + * @return the array of property names which are marked as not-null. + * @since 2.6.9 + */ + String[] getNotNulls(); + + /** + * @return {@code true} if entity use natural ids, {@code false} otherwise. + * @since 2.6.9 + */ + boolean isUseNaturalIds(); + + /** + * @return {@code true} if entity use some not-null properties, + * {@code false} otherwise. + * @since 2.6.9 + */ + boolean isUseNotNulls(); + + /** * Change the implementation class of the entity. - * + * <p/> * Note : this method should reset all states of the objet - * (implementation class, operators,...). + * (implementation class, operators,...). * * @param implementationFQN the new fully qualifed name of the new - * implementation class of the entity. + * implementation class of the entity. */ void setImplementationFQN(String implementationFQN); /** - * * Test if a given type of entity is matching the contract of this entity. - * + * <p/> * Note : make sure to accept type only on the given contract class of this entity, * can not accept an ancestor type, since there is a specific contract for this. - * + * <p/> * Example : A -> B * <pre> * EntityEnum.A.accept(Class<A>) -> true @@ -101,10 +112,10 @@ * EntityEnum.B.accept(Class<B>) -> true * EntityEnum.B.accept(Class<A>) -> false * </pre> - * + * * @param klass the type of an entity to test. * @return {@code true} if given type is dealed directly by this entity, - * {@code false} otherwise. + * {@code false} otherwise. */ boolean accept(Class<? extends TopiaEntity> klass); } 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 2012-03-20 13:34:53 UTC (rev 2425) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/EntityOperator.java 2012-03-29 00:15:57 UTC (rev 2426) @@ -57,8 +57,8 @@ * permet de modifier ces valeurs : * <p/> * {@link #get(String, TopiaEntity)} - * {@link #set(String, TopiaEntity,Object)} - * {@link #copy(String, TopiaEntity,TopiaEntity)} + * {@link #set(String, TopiaEntity, Object)} + * {@link #copy(String, TopiaEntity, TopiaEntity)} * {@link #getChild(String, TopiaEntity, String)} * {@link #addChild(String, TopiaEntity, Object)} * {@link #removeChild(String, TopiaEntity, Object)} @@ -73,8 +73,8 @@ * <p/> * Note : cet objet ne permet pas d'operation vers les bases. * + * @param <B> type de l'entite * @author tchemit <chemit@codelutin.com> - * @param <B> type de l'entite * @since 2.2.0 */ public class EntityOperator<B extends TopiaEntity> { @@ -88,6 +88,14 @@ /** list of property names available on the entity. */ protected List<String> properties; + /** + * list of property names available on the entity used in a natural ids or + * marked as not-null. + * + * @since 2.6.9 + */ + protected Set<String> naturalIdsOnNotNullsProperties; + /** list of association names available on the entity. */ protected List<String> associationProperties; @@ -162,6 +170,7 @@ * * @param bean le bean a inspecter * @return le dictionnaire de la clef naturel du bean + * @see TopiaEntityEnum#getNaturalIds() * @since 2.4.1 */ public Map<String, Object> getNaturalId(B bean) { @@ -176,6 +185,59 @@ } /** + * Pour obtenir un dictionnaire des propriétés marqués not-null du + * {@code bean} donne. + * + * @param bean le bean a inspecter + * @return le dictionnaire des propriétés marquées not-null du bean + * @see TopiaEntityEnum#getNotNulls() + * @since 2.6.9 + */ + public Map<String, Object> getNotNull(B bean) { + Map<String, Object> result = new TreeMap<String, Object>(); + String[] ids = contract.getNotNulls(); + if (ids != null) { + for (String id : ids) { + result.put(id, get(id, bean)); + } + } + return result; + } + + /** + * Get all properties from a natural id or marked as not-null. + * + * @return all property names froma natural id or marked as not-null + * @since 2.6.9 + */ + public String[] getNaturalIdsOnNotNullsProperties() { + return naturalIdsOnNotNullsProperties.toArray(new String[naturalIdsOnNotNullsProperties.size()]); + } + + /** + * Pour obtenir un dictionnaire des propriétés marqués not-null et la clef naturelle + * du {@code bean} donne. + * <p/> + * Cette methode est utilisée pour faire un dao.create, pour s'assurer que + * tout ce qui ne doit pas pas être à null est bien fourni à la création de + * l'objet, sinon on obtient des erreurs. + * + * @param bean le bean a inspecter + * @return le dictionnaire des propriétés marquées not-null + la clef + * naturelle du bean + * @see TopiaEntityEnum#getNotNulls() + * @see TopiaEntityEnum#getNaturalIds() + * @since 2.6.9 + */ + public Map<String, Object> getNaturalIsdAndNotNulls(B bean) { + Map<String, Object> result = new TreeMap<String, Object>(); + for (String id : naturalIdsOnNotNullsProperties) { + result.put(id, get(id, bean)); + } + return result; + } + + /** * Copie une propriete de src vers dst. * <p/> * Note : cela apellera la methode <code>setXXX(value)</code>. @@ -436,6 +498,7 @@ protected void finalize() throws Throwable { super.finalize(); properties = null; + naturalIdsOnNotNullsProperties = null; associationProperties = null; getMethods = null; setMethods = null; @@ -454,7 +517,7 @@ } protected Collection<String> getProperties(String[] properties) { - Collection<String> names = null; + Collection<String> names; if (properties.length == 0) { names = this.properties; } else { @@ -497,7 +560,7 @@ Set<Class<?>> explored = new HashSet<Class<?>>(); properties = new ArrayList<String>(); associationProperties = new ArrayList<String>(); - + naturalIdsOnNotNullsProperties = new HashSet<String>(); try { @@ -531,6 +594,15 @@ associationProperties = Collections.unmodifiableList( associationProperties); } + + if (contract.isUseNaturalIds()) { + Collections.addAll(naturalIdsOnNotNullsProperties, + contract.getNaturalIds()); + } + if (contract.isUseNotNulls()) { + Collections.addAll(naturalIdsOnNotNullsProperties, + contract.getNotNulls()); + } if (log.isDebugEnabled()) { log.debug("===== end for " + getClazz() + " (" + properties.size() + " properties, " +