Author: bpoussin Date: 2012-03-14 20:11:21 +0100 (Wed, 14 Mar 2012) New Revision: 1456 Url: http://nuiton.org/repositories/revision/wikitty/1456 Log: Evolution #2013: add new constraints tag value on field (min, max, allow) change contraint field validation implementation, add new constraints Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldTypeConstaintChecker.java Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldFactory.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldType.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java trunk/wikitty-api/src/test/java/org/nuiton/wikitty/WikittyClientTest.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTagValue.java Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldFactory.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldFactory.java 2012-03-14 18:14:38 UTC (rev 1455) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldFactory.java 2012-03-14 19:11:21 UTC (rev 1456) @@ -74,7 +74,12 @@ minOccur = min; return this; } - + + /** + * Si le champs est une collection indique que la collection ne peut pas + * contenir de doublon (Set) + * @return + */ public FieldFactory unique() { addTagValue(FieldType.TAG_UNIQUE, "true"); return this; @@ -100,18 +105,33 @@ } /** - * Ajoute le nom des extensions autorise pour ce champs (doit etre de type - * Wikitty). Par exemple: "Person,Employee;Company" - * Soit l'objet doit avoir Person et Employee soit Company seul + * Ajoute la liste de valeurs autorises pour ce champs. + * Par exemple pour un champs de type Wikitty: "Person,Employee,Company" * - * @param extNames + * @param values La liste de valeur en representation chaine (le separateur + * est la virgule) * @return */ - public FieldFactory extensionAllowed(String extNames) { - addTagValue(FieldType.TAG_EXTENSION_ALLOWED, extNames); + public FieldFactory allowed(String values) { + addTagValue(FieldType.TAG_ALLOWED, values); return this; } + public FieldFactory allowedQuery(String allowedQuery) { + addTagValue(FieldType.TAG_ALLOWED_QUERY, allowedQuery); + return this; + } + + public FieldFactory choice(String values) { + addTagValue(FieldType.TAG_CHOICE, values); + return this; + } + + public FieldFactory choiceQuery(String choiceQuery) { + addTagValue(FieldType.TAG_CHOICE_QUERY, choiceQuery); + return this; + } + /** * Met a vrai la valeur indexed * @return @@ -141,8 +161,36 @@ return this; } + public FieldFactory subtype(String type) { + addTagValue(FieldType.TAG_SUBTYPE, type); + return this; + } + + public FieldFactory min(String v) { + addTagValue(FieldType.TAG_MIN, v); + return this; + } + + public FieldFactory minQuery(String query) { + addTagValue(FieldType.TAG_MIN_QUERY, query); + return this; + } + + public FieldFactory max(String v) { + addTagValue(FieldType.TAG_MAX, v); + return this; + } + + public FieldFactory maxQuery(String query) { + addTagValue(FieldType.TAG_MAX_QUERY, query); + return this; + } + + public FieldFactory addTagValue(String tag, String value) { tagValues.put(tag, value); return this; } + + } Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldType.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldType.java 2012-03-14 18:14:38 UTC (rev 1455) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldType.java 2012-03-14 19:11:21 UTC (rev 1456) @@ -294,37 +294,116 @@ } /** - * @see #TAG_EXTENSION_ALLOWED + * @see #TAG_SUBTYPE */ - public String getExtensionAllowed() { - String allowed = getTagValue(TAG_EXTENSION_ALLOWED); + public String getSubtype() { + String result = getTagValue(TAG_SUBTYPE); + return result; + } + /** + * @see #TAG_ALLOWED + */ + public String getAllowed() { + String allowed = getTagValue(TAG_ALLOWED); return allowed; } /** + * @see #TAG_ALLOWED_QUERY + */ + public String getAllowedQuery() { + String allowed = getTagValue(TAG_ALLOWED_QUERY); + return allowed; + } + /** + * @see #TAG_CHOICE + */ + public String getChoice() { + String result = getTagValue(TAG_CHOICE); + return result; + } + /** + * @see #TAG_CHOICE_QUERY + */ + public String getChoiceQuery() { + String result = getTagValue(TAG_CHOICE_QUERY); + return result; + } + /** + * @see #TAG_MIN + */ + public String getMin() { + String result = getTagValue(TAG_MIN); + return result; + } + /** + * @see #TAG_MIN_QUERY + */ + public String getMinQuery() { + String result = getTagValue(TAG_MIN_QUERY); + return result; + } + /** + * @see #TAG_MAX + */ + public String getMax() { + String result = getTagValue(TAG_MAX); + return result; + } + /** + * @see #TAG_MAX_QUERY + */ + public String getMaxQuery() { + String result = getTagValue(TAG_MAX_QUERY); + return result; + } + /** * @return list or null if not spcified allowed extension - * @see #TAG_EXTENSION_ALLOWED + * @see #TAG_ALLOWED */ - public List<List<String>> getExtensionAllowedAsList() { - List<List<String>> result = null; - if (isExtensionRestrited()) { - result = new ArrayList<List<String>>(); - String allowed = getTagValue(TAG_EXTENSION_ALLOWED); - String[] exts = allowed.split("\\s*;\\s*"); - for (String s : exts) { - String [] e = s.split("\\s*,\\s*"); - result.add(Arrays.asList(e)); - } + public List<String> getAllowedAsList() { + List<String> result = null; + String allowed = getAllowed(); + if (StringUtils.isNotBlank(allowed)) { + String[] v = allowed.split("\\s*,\\s*"); + result = Arrays.asList(v); } return result; } /** * Si les extensions autorisees pour ce champs est contrainte par le tag value - * {@link #TAG_EXTENSION_ALLOWED} alors retourne true, sinon false. - * @see #TAG_EXTENSION_ALLOWED + * {@link #TAG_ALLOWED} alors retourne true, sinon false. + * @see #TAG_ALLOWED */ - public boolean isExtensionRestrited() { - boolean result = StringUtils.isNotBlank(getExtensionAllowed()); + public boolean isRestrited() { + boolean result = hasAllowed() || hasAllowedQuery(); return result; } + + public boolean hasAllowed() { + boolean result = StringUtils.isNotBlank(getAllowed()); + return result; + } + + public boolean hasAllowedQuery() { + boolean result = StringUtils.isNotBlank(getAllowedQuery()); + return result; + } + public boolean hasMin() { + boolean result = StringUtils.isNotBlank(getMin()); + return result; + } + public boolean hasMinQuery() { + boolean result = StringUtils.isNotBlank(getMinQuery()); + return result; + } + + public boolean hasMax() { + boolean result = StringUtils.isNotBlank(getMax()); + return result; + } + public boolean hasMaxQuery() { + boolean result = StringUtils.isNotBlank(getMaxQuery()); + return result; + } } Added: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldTypeConstaintChecker.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldTypeConstaintChecker.java (rev 0) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/entities/FieldTypeConstaintChecker.java 2012-03-14 19:11:21 UTC (rev 1456) @@ -0,0 +1,445 @@ +package org.nuiton.wikitty.entities; + + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.wikitty.WikittyClient; +import org.nuiton.wikitty.WikittyService; +import org.nuiton.wikitty.query.WikittyQuery; +import org.nuiton.wikitty.query.WikittyQueryMaker; +import org.nuiton.wikitty.query.WikittyQueryParser; +import org.nuiton.wikitty.query.WikittyQueryResult; + +/** + * Cet objets sert a gerer les contraintes qui peuvent exister sur un champs. + * On ne les implantes pas dans le champs directement, car l'objet champs aurait + * alors des dependances vers des objets complexe (WikittyClient, WikittyService, + * Wikitty) chose que l'on ne veut pas. + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class FieldTypeConstaintChecker { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(FieldTypeConstaintChecker.class); + + protected WikittyService ws; + protected String token; + + /** + * Create FieldTypeConstaintChecker usable in client side + * @param client client used to do request if needed by tag value + */ + public FieldTypeConstaintChecker(WikittyClient client) { + this.ws = client.getWikittyService(); + this.token = client.getSecurityToken(); + } + + /** + * this constructor must be used only be framework in WikittyServiceStorage. + * @param ws + */ + public FieldTypeConstaintChecker(WikittyService ws) { + this.ws = ws; + } + + /** + * check all contraints + * + * @param fqfield + * @param field + * @param value + * @param errors can be null + * + * @return true if all contraints is satified, otherwize false + */ + public boolean isValid(String fqfield, FieldType field, Object value, Collection<String> errors) { + boolean result = true; + // notnull + result = result && isNotNull(fqfield, field, value, errors); + // unique de collection + result = result && isUnique(fqfield, field, value, errors); + // pattern + result = result && checkPattern(fqfield, field, value, errors); + // min et max pour les date et numeric + result = result && checkMin(fqfield, field, value, errors); + result = result && checkMax(fqfield, field, value, errors); + // allowed + result = result && isAllowed(fqfield, field, value, errors); + return result; + } + + public Object getMin(FieldType field) { + String min = null; + if (field.hasMinQuery()) { + String query = field.getMinQuery(); + WikittyQuery q = WikittyQueryParser.parse(query); + List<String> queryResult = ws.findByQuery(token, Collections.singletonList(q)); + min = queryResult.get(0); + } + + if (min == null && field.hasMin()) { + min = field.getMin(); + } + + Object result = null; + if (min != null) { + result = field.getContainedValidObject(min); + } + return result; + } + public Date getMinAsDate(FieldType field) { + Date result = (Date)getMin(field); + return result; + } + public BigDecimal getMinAsBigDecimal(FieldType field) { + BigDecimal result = (BigDecimal)getMin(field); + return result; + } + public Object getMax(FieldType field) { + String max = null; + if (field.hasMaxQuery()) { + String query = field.getMaxQuery(); + WikittyQuery q = WikittyQueryParser.parse(query); + List<String> queryResult = ws.findByQuery(token, Collections.singletonList(q)); + max = queryResult.get(0); + } + + if (max == null && field.hasMax()) { + max = field.getMax(); + } + + Object result = null; + if (max != null) { + result = field.getContainedValidObject(max); + } + return result; + } + public Date getMaxAsDate(FieldType field) { + Date result = (Date)getMax(field); + return result; + } + public BigDecimal getMaxAsBigDecimal(FieldType field) { + BigDecimal result = (BigDecimal)getMax(field); + return result; + } + + public boolean isAllowed(String fqfield, FieldType field, Object value, Collection<String> errors) { + boolean result = true; + if (value != null && (field.hasAllowed() || field.hasAllowedQuery())) { + switch(field.getType()) { + case STRING: + if (field.isCollection()) { + result = isAllowedString(fqfield, field, (Collection<String>)value, errors); + } else { + result = isAllowedString(fqfield, field, Collections.singleton((String)value), errors); + } + break; + case WIKITTY: + if (field.isCollection()) { + result = isAllowedWikitty(fqfield, field, (Collection<String>)value, errors); + } else { + result = isAllowedWikitty(fqfield, field, Collections.singleton((String)value), errors); + } + break; + default: + result = true; + } + } + return result; + } + + /** + * allowed contient une liste d'extension possible, allowedQuery retourne + * une liste d'objet possible. Si les deux existes seul allowedQuery est + * utilisee, allowed dans ce cas a d'autre usage comme la navigation + * entre entity, ou permettre la creation d'une nouvelle entity pour ce + * champs suivant une des extensions declaree. + * + * @param fqfield + * @param field + * @param ids + * @param errors + * @return + */ + protected boolean isAllowedWikitty(String fqfield, FieldType field, + Collection<String> ids, Collection<String> errors) { + boolean result = false; + + WikittyQuery q = null; + if (field.hasAllowedQuery()) { + // construire les requetes + q = WikittyQueryParser.parse(field.getAllowedQuery()); + + } else if (field.hasAllowed()) { + WikittyQueryMaker maker = new WikittyQueryMaker().or(); + for (String extName : field.getAllowedAsList()) { + maker.exteq(extName); + } + q = maker.end(); + } + + List<String> allowed = null; + if (q != null) { + q.setOffset(0); + q.setLimit(WikittyQuery.MAX); + + WikittyQuery wq = new WikittyQueryMaker().containsOne(Element.ID, ids).end(); + wq.setOffset(0); + wq.setLimit(WikittyQuery.MAX); + + List<WikittyQueryResult<String>> queryResult = + ws.findAllByQuery(token, Arrays.asList(q, wq)); + allowed = queryResult.get(0).getAll(); + List<String> findedIds = queryResult.get(1).getAll(); + + // on ne check que sur les ids trouve dans la base et on espere + // que les autres sont bon :). En fait, lorsqu'on store plusieurs + // wikitties en meme temps donc un wikitty qui doit etre la valeur + // d'un champs d'un autre. Celui ci n'est pas retrouvable dans la + // base et donc on ne peut pas verifier facilement la contrainte. + // Pour l'instant on ne fait rien, car les solutions seraient trop + // couteuse (creeer un storage in memory y mettre les objets a + // checker, faire le check en requetant le vrai repo et le in memory + // si tout va bien faire le store reel sur le vrai repo. + result = allowed.containsAll(findedIds); + if (log.isDebugEnabled() && findedIds.size() != ids.size()) { + log.debug(String.format( + "For field '%s' allowed contraint not checked for: %s", + fqfield, CollectionUtils.disjunction(findedIds, ids))); + } + } + + if (errors != null && !result) { + errors.add(String.format( + "Field '%s' contains unallowed Wikitty values %s allowed %s", + fqfield, ids, allowed)); + } + return result; + } + + protected boolean isAllowedString(String fqfield, FieldType field, + Collection<String> values, Collection<String> errors) { + boolean result = false; + + List<String> allowed = null; + // on commence par ce qui ne demande pas a faire une requete + if (field.hasAllowed()) { + allowed = field.getAllowedAsList(); + result = allowed.containsAll(values); + } + + if (!result && field.hasAllowedQuery()) { + // construire les requetes + String query = field.getAllowedQuery(); + WikittyQuery q = WikittyQueryParser.parse(query); + q.setOffset(0).setLimit(WikittyQuery.MAX); + List<WikittyQueryResult<String>> queryResult = + ws.findAllByQuery(token, Collections.singletonList(q)); + allowed = queryResult.get(0).getAll(); + result = allowed.containsAll(values); + } + + if (errors != null && !result) { + errors.add(String.format( + "Field '%s' contains unallowed string values: %s allowed: %s", + fqfield, values, allowed)); + } + return result; + } + + public boolean checkPattern(String fqfield, FieldType field, Object value, Collection<String> errors) { + boolean result = true; + if (value != null && field.hasPattern() && field.getType() == WikittyTypes.STRING) { + String pattern = field.getPattern(); + result = Pattern.matches(pattern, (String)value); + if (errors != null && !result) { + errors.add(String.format( + "Field '%s' must match pattern '%s' but value is '%s'", + fqfield, pattern, value)); + } + } + return result; + } + + public boolean isNotNull(String fqfield, FieldType field, Object value, Collection<String> errors) { + boolean result = true; + if (field.isNotNull()) { + result = value != null; + } + + if (errors != null && !result) { + errors.add(String.format("Field '%s' contains null value", fqfield)); + } + return result; + } + + /** + * Vrai si la collection ne contient pas de doublon. + * @param field + * @param value + * @return + */ + public boolean isUnique(String fqfield, FieldType field, Object value, Collection<String> errors) { + boolean result = true; + if (field.isUnique() && value != null && field.isCollection() && !(value instanceof Set)) { + Collection c = (Collection)value; + Set s = new HashSet(c); + result = s.size() == c.size(); + } + + if (errors != null && !result) { + errors.add(String.format("Field '%s' contains duplicate value", fqfield)); + } + return result; + } + + public boolean checkMin(String fqfield, FieldType field, Object value, Collection<String> errors) { + boolean result = true; + if (value != null && (field.hasMin() || field.hasMinQuery())) { + switch(field.getType()) { + case DATE: { + if (field.isCollection()) { + result = checkMinDate(fqfield, field, + (Collection<Date>)value, errors); + } else { + result = checkMinDate(fqfield, field, + Collections.singleton((Date)value), errors); + } + } + break; + case NUMERIC: { + if (field.isCollection()) { + result = checkMinBigDecimal(fqfield, field, + (Collection<BigDecimal>)value, errors); + } else { + result = checkMinBigDecimal(fqfield, field, + Collections.singleton((BigDecimal)value), errors); + } + } + break; + default: + result = true; + } + } + return result; + } + + protected boolean checkMinDate(String fqfield, FieldType field, + Collection<Date> values, Collection<String> errors) { + boolean result = true; + Date min = getMinAsDate(field); + for (Date b : values) { + result = min.compareTo(b) <= 0; + if (!result) { + break; + } + } + if (errors != null && !result) { + errors.add(String.format( + "Field '%s' contains value higher then '%s': %s", + fqfield, min, values)); + } + return result; + } + + protected boolean checkMinBigDecimal(String fqfield, FieldType field, + Collection<BigDecimal> values, Collection<String> errors) { + boolean result = true; + BigDecimal min = getMinAsBigDecimal(field); + for (BigDecimal b : values) { + result = min.compareTo(b) <= 0; + if (!result) { + break; + } + } + if (errors != null && !result) { + errors.add(String.format( + "Field '%s' contains value higher then '%s': %s", + fqfield, min, values)); + } + return result; + } + + public boolean checkMax(String fqfield, FieldType field, Object value, Collection<String> errors) { + boolean result = true; + if (value != null && (field.hasMax() || field.hasMaxQuery())) { + switch(field.getType()) { + case DATE: { + if (field.isCollection()) { + result = checkMaxDate(fqfield, field, + (Collection<Date>)value, errors); + } else { + result = checkMaxDate(fqfield, field, + Collections.singleton((Date)value), errors); + } + } + break; + case NUMERIC: { + if (field.isCollection()) { + result = checkMaxBigDecimal(fqfield, field, + (Collection<BigDecimal>)value, errors); + } else { + result = checkMaxBigDecimal(fqfield, field, + Collections.singleton((BigDecimal)value), errors); + } + } + break; + default: + result = true; + } + } + return result; + } + + protected boolean checkMaxDate(String fqfield, FieldType field, + Collection<Date> values, Collection<String> errors) { + boolean result = true; + Date max = getMaxAsDate(field); + for (Date b : values) { + result = max.compareTo(b) >= 0; + if (!result) { + break; + } + } + if (errors != null && !result) { + errors.add(String.format( + "Field '%s' contains value lower then '%s': %s", + fqfield, max, values)); + } + return result; + } + + protected boolean checkMaxBigDecimal(String fqfield, FieldType field, + Collection<BigDecimal> values, Collection<String> errors) { + boolean result = true; + BigDecimal max = getMaxAsBigDecimal(field); + for (BigDecimal b : values) { + result = max.compareTo(b) >= 0; + if (!result) { + break; + } + } + if (errors != null && !result) { + errors.add(String.format( + "Field '%s' contains value lower then '%s': %s", + fqfield, max, values)); + } + return result; + } + +} Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java 2012-03-14 18:14:38 UTC (rev 1455) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/services/WikittyServiceStorage.java 2012-03-14 19:11:21 UTC (rev 1456) @@ -38,8 +38,10 @@ import java.util.Map; import java.util.Set; import java.util.LinkedHashSet; +import java.util.LinkedList; import java.util.regex.Pattern; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -55,6 +57,7 @@ import org.nuiton.wikitty.entities.WikittyTreeNode; import org.nuiton.wikitty.entities.WikittyTreeNodeHelper; import org.nuiton.wikitty.WikittyUtil; +import org.nuiton.wikitty.entities.FieldTypeConstaintChecker; import org.nuiton.wikitty.entities.WikittyTypes; import org.nuiton.wikitty.query.WikittyQuery; import org.nuiton.wikitty.query.WikittyQueryMaker; @@ -83,6 +86,9 @@ protected WikittyExtensionMigration defaultExtensionMigration = new WikittyExtensionMigrationRename(); + protected FieldTypeConstaintChecker contraintChecker = + new FieldTypeConstaintChecker(this); + protected ApplicationConfig config; protected WikittySearchEngine searchEngine; protected WikittyExtensionStorage extensionStorage; @@ -174,44 +180,17 @@ for(Wikitty w : wikitties) { for(WikittyExtension ext : w.getExtensions()) { for (String fieldName : ext.getFieldNames()) { + String fqfield = WikittyUtil.getFQFieldName(ext.getName(), fieldName); FieldType type = ext.getFieldType(fieldName); - if (type.isNotNull()) { - if (null == w.getFieldAsObject(ext.getName(), fieldName)) { - throw new WikittyException(String.format( - "Field '%s.%s' must not be null", - ext.getName(), fieldName)); - } - } - if (type.hasPattern() && type.getType() == WikittyTypes.STRING) { - String pattern = type.getPattern(); - String value = w.getFieldAsString(ext.getName(), fieldName); - if (!Pattern.matches(pattern, value)) { - throw new WikittyException(String.format( - "Field '%s.%s' must match pattern '%s' but value is '%s'", - ext.getName(), fieldName, pattern, value)); - } - } - if (type.isExtensionRestrited() && type.getType() == WikittyTypes.WIKITTY) { - String id = w.getFieldAsWikitty(ext.getName(), fieldName); - Wikitty wikittyField = restore(null, id); - if (wikittyField != null) { - Collection<String> extensionNames = - wikittyField.getExtensionNames(); + Object value = w.getFqField(fqfield); - boolean authorized = false; - List<List<String>> allowed = type.getExtensionAllowedAsList(); - for (List<String> l : allowed) { - if (extensionNames.containsAll(l)) { - authorized = true; - break; - } - } - if (!authorized) { - throw new WikittyException(String.format( - "Field '%s.%s' must have extension '%s' but have '%s'", - ext.getName(), fieldName, allowed, extensionNames)); - } - } + List<String> errors = new LinkedList<String>(); + + if (!contraintChecker.isValid(fqfield, type, value, errors)) { + throw new WikittyException(String.format( + "Field constraint error %s", + StringUtils.join(errors, "\n"))); + } } } Modified: trunk/wikitty-api/src/test/java/org/nuiton/wikitty/WikittyClientTest.java =================================================================== --- trunk/wikitty-api/src/test/java/org/nuiton/wikitty/WikittyClientTest.java 2012-03-14 18:14:38 UTC (rev 1455) +++ trunk/wikitty-api/src/test/java/org/nuiton/wikitty/WikittyClientTest.java 2012-03-14 19:11:21 UTC (rev 1456) @@ -1066,7 +1066,7 @@ // test strict equals WikittyQuery query = new WikittyQueryMaker().bw(Product.FQ_FIELD_PRODUCT_PRICE, 14, 99).end(); - query.setLimit(-1); + query.setLimit(0); WikittyQueryResult<Product> results = wikittyClient.findAllByQuery(Product.class, query); Assert.assertEquals(2, results.getTotalResult()); Assert.assertEquals(0, results.getAll().size()); Modified: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java 2012-03-14 18:14:38 UTC (rev 1455) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java 2012-03-14 19:11:21 UTC (rev 1456) @@ -239,12 +239,12 @@ // si le champs est de type wikitty et qu'il n'y a pas de tag value // on regarde s'il faut en generer un if (StringUtils.equals("Wikitty", wikittyType) - && null == attribute.getTagValue(TAG_EXTENSION_ALLOWED)) { + && null == attribute.getTagValue(TAG_ALLOWED)) { String type = WikittyTransformerUtil.FQNtoSimpleName(attribute.getType()); if (!StringUtils.equals("Wikitty", type)) { // dans le modele on a specifie un type particulier, on // le met comme contrainte - attribute.getTagValues().put(TAG_EXTENSION_ALLOWED, type); + attribute.getTagValues().put(TAG_ALLOWED, type); } } Modified: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTagValue.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTagValue.java 2012-03-14 18:14:38 UTC (rev 1455) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTagValue.java 2012-03-14 19:11:21 UTC (rev 1456) @@ -112,24 +112,120 @@ public static final String TAG_CRYPT = "crypt"; /** - * extensionAllowed: indique que le champs wikitty ne peut prendre comme - * valeur que des wikitties ayant les extensions specifiees. + * preload: indique les champs de type Wikitty qui doivent etre preloade + * lors du chargement de cette extension. * exemple: - * <li>Person,Employee;Company - * Ici il faut que l'objet ait les extensions Person et Employee ou - * l'extension Company + * <li> preload="Company.employee,Employee.person;Company.address" * <p> - * <li> target: wikitty type field + * <li> target: extension */ - public static final String TAG_EXTENSION_ALLOWED = "extensionAllowed"; + public static final String TAG_PRELOAD = "preload"; /** - * preload: indique les champs de type Wikitty qui doivent etre preloade - * lors du chargement de cette extension. + * subtype: indique que le champs a un sous type. Ce sous type est différent + * pour chaque type possible d'un champs + * <li> Boolean: aucun pour l'instant + * <li> Binary: aucun pour l'instant + * <li> Date + * <li> 'date' (defaut) indique que seule la date est pertinante</li> + * <li> 'month' indique que seule le mois et l'annee sont pertinants</li> + * <li> 'time' indique que seule l'heure est pertinante</li> + * <li> 'datetime' indique que la date et l'heure sont pertinantes</li> + * <li> Numeric + * <li> 'real' (defaut) indique que le nombre est de type reel</li> + * <li> 'integer' indique que le nombre est de type entier</li> + * <li> 'currency' indique que le nombre est de type reel et represente une somme d'argent</li> + * <li> String + * <li> 'char' indique que la chaine ne peut qu'un caractere</li> + * <li> 'monoline' (defaut) indique que la chaine ne peut contenir qu'une ligne</li> + * <li> 'multiline' indique que la chaine peut-etre multiligne</li> + * <li> '[mime type]' indique que la chaine represente le type mime + * precisse. exemple: 'text/plain' ou 'text/javascript' ou 'text/html' + * <li> Wikitty: aucun pour l'instant + * + * <p> + * <li> target: field + */ + public static final String TAG_SUBTYPE = "subtype"; + + /** + * allowed: indique que le champs devra prendre sa valeur dans une des valeurs + * de ce tag. Les differentes valeurs sont separees par une virgule. + * <li> Boolean ne s'applique pas + * <li> Binary: l'utilisateur ne pourra importer des binaires que du type + * mime indique (s'additionne avec les resultats de allowedQuery). + * Ne s'applique que si le champs binaire doit contenir un fichier. + * Cette contrainte n'est utilisable que cote client lors de la selection + * du fichier. Pour une verification cote serveur, il faut associer un + * champs texte (par exemple 'mimetype') qui contiendra la valeur du fichier + * mis dans le champs binaire et mettre sur ce champs le meme tag value + * allowed que sur le champs binaire</li> + * <li> Date ne s'applique pas (voir {@link #TAG_MIN} {@link #TAG_MAX}) + * <li> Numeric ne s'applique pas (voir {@link #TAG_MIN} {@link #TAG_MAX}) + * <li> String: l'utilisateur ne pourra mettre comme valeur que des valeurs + * presentes dans allowed (s'additionne avec les resultats de allowedQuery).</li> + * <li> Wikitty: l'utilisateur devra choisir l'objet dans la liste des objets + * qui ont une des extensions listee. Si allowedQuery est aussi specifie + * allowedQuery prend le dessus sur allowed. + *<p> * exemple: - * <li> preload="Company.employee,Employee.person;Company.address" + * <li> String companyType allowed="SA,SARL,SAS" allowedQuery="SELECT Company.companyType WHERE extension=Company" + * <li> Wikitty target allowed="Person,Employee,Company" * <p> - * <li> target: extension + * <li> target: field */ - public static final String TAG_PRELOAD = "preload"; + public static final String TAG_ALLOWED = "allowed"; + /** + * Sert a la meme chose que allowed et vient en plus ou en remplacement + * (pour les Wikitties) des valeur de allowed. La valeur de ce tag doit + * etre une requete bien formee qui retourne le bon type d'element en + * fonction du champs (pour cela la requete commencera le plus souvent par + * un select). + */ + public static final String TAG_ALLOWED_QUERY = "allowedQuery"; + /** + * choice indique que l'utilisateur sera guide dans son choix de valeurs + * grace aux valeurs listees, mais il pourra s'il le souhaite mettre une + * nouvelle valeur. Les valeurs sont separees par des virgules + * <p> + * exemple: + * <li>String type choice="SA,SAS,SARL,SARL SCOOP,EURL" + * + */ + public static final String TAG_CHOICE = "choice"; + /** + * Sert a la meme chose que choice et vient en plus des valeur de choice. + * La valeur de ce tag doit etre une requete bien formee qui retourne le bon + * type d'element en fonction du champs (pour cela la requete commencera le + * plus souvent par un select). + */ + public static final String TAG_CHOICE_QUERY = "choiceQuery"; + + /** + * min indique la valeur minimal que peut prendre le champs. Cela s'applique + * au Date et Numeric. + */ + public static final String TAG_MIN = "min"; + + /** + * minQuery sert a la meme chose que min mais prend sa valeur grace a une + * requete. Si min et minQuery sont tous les deux présents, minQuery est + * utilisee sauf si aucun resultat n'est retourne par la requete. + */ + public static final String TAG_MIN_QUERY = "minQuery"; + + /** + * max indique la valeur maximal que peut prendre le champs. Cela s'applique + * au Date et Numeric. + */ + public static final String TAG_MAX = "max"; + + /** + * maxQuery sert a la meme chose que max mais prend sa valeur grace a une + * requete. Si max et maxQuery sont tous les deux présents, maxQuery est + * utilisee sauf si aucun resultat n'est retourne par la requete. + */ + public static final String TAG_MAX_QUERY = "maxQuery"; + + }
participants (1)
-
bpoussin@users.nuiton.org