Author: tchemit Date: 2011-01-17 19:36:18 +0100 (Mon, 17 Jan 2011) New Revision: 2015 Url: http://nuiton.org/repositories/revision/nuiton-utils/2015 Log: move all old code to a legacy package (will be removed before version 2.0) Added: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidator.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorDetector.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorEvent.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorField.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorListener.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorMessage.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorScope.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorUtil.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/ValidatorsMap.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/XWorkBeanValidator.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/ trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/AbstractBeanValidatorDetectorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/BeanValidatorDetectorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/BeanValidatorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/SimpleBean.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/XWorkBeanValidatorTest.java trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-error-validation.xml trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-fatal-validation.xml trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-info-validation.xml trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-simple-validation.xml trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-warning-validation.xml Removed: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidator.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorDetector.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorEvent.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorField.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorListener.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorMessage.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorScope.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorUtil.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/ValidatorsMap.java trunk/nuiton-validator/src/main/java/org/nuiton/validator/XWorkBeanValidator.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/AbstractBeanValidatorDetectorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorDetectorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorTest.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/SimpleBean.java trunk/nuiton-validator/src/test/java/org/nuiton/validator/XWorkBeanValidatorTest.java trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-error-validation.xml trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-fatal-validation.xml trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-info-validation.xml trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-simple-validation.xml trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-warning-validation.xml trunk/nuiton-validator/src/test/resources/org/nuiton/validator/field/ Deleted: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidator.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidator.java 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidator.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,635 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2011 CodeLutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.validator; - -import org.apache.commons.beanutils.ConversionException; -import org.apache.commons.beanutils.Converter; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.nuiton.util.converter.ConverterUtil; - -import javax.swing.event.EventListenerList; -import java.beans.EventSetDescriptor; -import java.beans.Introspector; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; -import java.util.ArrayList; -import java.util.Collections; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeMap; - -/** - * A customized validator for a given bean. - * <p/> - * <b>Note:</b> The bean must be listenable on properyChange events (means must - * have public addPropertychangeListener and removePropertyChangeListener - * methods). - * - * @author tchemit <chemit@codelutin.com> - * @param <B> type of the bean to validate. - */ -public class BeanValidator<B> { - - /** la nom de la propriété bean */ - static public final String BEAN_PROERTY = "bean"; - - /** la nom de la propriété contextName */ - static public final String CONTEXT_NAME_PROPERTY = "contextName"; - - /** la nom de l'état valid */ - static public final String VALID_PROERTY = "valid"; - - /** la nom de l'état changed */ - static public final String CHANGED_PROERTY = "changed"; - - /** Logger */ - static protected final Log log = LogFactory.getLog(BeanValidator.class); - - protected static final BeanValidatorScope[] FILTER_SCOPES_EMPTY = - new BeanValidatorScope[0]; - - /** the type of bean to watch */ - protected final Class<B> beanClass; - - /** the validation named context (can be null) */ - protected String contextName; - - /** to chain to a prent validator */ - protected BeanValidator<?> parentValidator; - - /** - * state to indicate that validator has changed since the last time bean was - * setted - */ - protected boolean changed; - - /** state of the validator (is true if no errors of error scope is found) */ - protected boolean valid = true; - - /** bean to be watched */ - protected B bean; - - /** to add and remove PropertyChangeListener on watched beans */ - protected EventSetDescriptor beanEventDescriptor; - - /** list of fields watched by this validator */ - protected Set<BeanValidatorField<B>> fields; - - /** map of conversion errors detected by this validator */ - protected Map<String, String> conversionErrors; - - /** xworks scope validator * */ - protected EnumMap<BeanValidatorScope, XWorkBeanValidator<B>> validators; - - /** filter scopes (if {@code null}, no filter on scopes) */ - protected BeanValidatorScope[] filterScopes; - - /** listener that listens on bean modification */ - protected PropertyChangeListener l; - - /** delegate property change support */ - protected PropertyChangeSupport pcs; - - /** A list of event listeners for this validators */ - protected EventListenerList listenerList = new EventListenerList(); - - public BeanValidator(Class<B> beanClass, - String contextName) { - this(beanClass, - contextName, - BeanValidatorScope.values() - ); - } - - public BeanValidator(Class<B> beanClass, - String contextName, - BeanValidatorScope... filterScopes) { - this.beanClass = beanClass; - if (filterScopes != null && filterScopes.length > 0) { - this.filterScopes = filterScopes; - } - pcs = new PropertyChangeSupport(this); - conversionErrors = new TreeMap<String, String>(); - validators = new EnumMap<BeanValidatorScope, XWorkBeanValidator<B>>( - BeanValidatorScope.class); - - setContextName(contextName); - - l = new PropertyChangeListener() { - - @Override - public void propertyChange(PropertyChangeEvent evt) { - // chaque modification lance la validation - doValidate(); - } - }; - } - - public Class<B> getBeanClass() { - return beanClass; - } - - public BeanValidator<?> getParentValidator() { - return parentValidator; - } - - public String getContextName() { - return contextName; - } - - public Set<BeanValidatorField<B>> getFields() { - return fields; - } - - public Set<BeanValidatorScope> getScopes() { - return new HashSet<BeanValidatorScope>(validators.keySet()); - } - - /** - * Retourne vrai si l'objet bean a ete modifie depuis le dernier {@link - * #setBean} - * - * @return <code>true</code> if bean was modify since last {@link - * #setBean(Object)} invocation - */ - public boolean isChanged() { - return changed; - } - - public boolean isValid() { - return valid; - } - - public B getBean() { - return bean; - } - - public BeanValidatorField<B> getField(String fieldName) { - for (BeanValidatorField<B> field : fields) { - if (fieldName.equals(field.getName())) { - return field; - } - } - return null; - } - - public boolean hasFatalErrors() { - for (BeanValidatorField<B> field : fields) { - if (field.hasFatalErrors()) { - return true; - } - } - return false; - } - - public boolean hasErrors() { - for (BeanValidatorField<B> field : fields) { - if (field.hasErrors()) { - return true; - } - } - return false; - } - - public boolean hasWarnings() { - for (BeanValidatorField<B> field : fields) { - if (field.hasWarnings()) { - return true; - } - } - return false; - } - - public boolean hasInfos() { - for (BeanValidatorField<B> field : fields) { - if (field.hasInfos()) { - return true; - } - } - return false; - } - - /** - * Test a the validator contains the field given his name - * - * @param fieldName the name of the searched field - * @return <code>true</code> if validator contaisn this field, - * <code>false</code> otherwise - */ - public boolean containsField(String fieldName) { - BeanValidatorField<B> field = getField(fieldName); - return field != null; - } - - public boolean isValid(String fieldName) { - BeanValidatorField<B> field = getField(fieldName); - if (field == null) { - throw new IllegalArgumentException( - "could not find a validator field " + fieldName); - } - return field.isValid(); - } - - /** - * Permet de force la remise a false de l'etat de changement du bean - * - * @param changed flag to force reset of property {@link #changed} - */ - public void setChanged(boolean changed) { - this.changed = changed; - // force the property to be fired (never pass the older value) - pcs.firePropertyChange(CHANGED_PROERTY, null, changed); - } - - public void setValid(boolean valid) { - this.valid = valid; - // force the property to be fired (never pass the older value) - pcs.firePropertyChange(VALID_PROERTY, null, valid); - } - - public void setBean(B bean) { - B oldBean = this.bean; - if (log.isDebugEnabled()) { - log.debug(this + " : " + bean); - } - - // clean conversions of previous bean - conversionErrors.clear(); - - if (oldBean != null) { - try { - EventSetDescriptor descriptor = getBeanEventDescriptor(oldBean); - descriptor.getRemoveListenerMethod().invoke(oldBean, l); - } catch (Exception eee) { - if (log.isInfoEnabled()) { - log.info("Can't register as listener for bean " + beanClass + - " for reason " + eee.getMessage(), eee); - } - } - } - this.bean = bean; - - if (bean == null) { - - // remove all messages for all fields of the validator - - for (BeanValidatorField<B> f : fields) { - - f.updateMessages(this, null, null); - } - - } else { - try { - EventSetDescriptor descriptor = getBeanEventDescriptor(bean); - descriptor.getAddListenerMethod().invoke(bean, l); - } catch (Exception eee) { - if (log.isInfoEnabled()) { - log.info("Can't register as listener for bean " + beanClass + - " for reason " + eee.getMessage(), eee); - } - } - validate(); - } - setChanged(false); - setValid(!hasFatalErrors() && !hasErrors()); - pcs.firePropertyChange(BEAN_PROERTY, oldBean, bean); - } - - public void setContextName(String contextName) { - String oldContextName = this.contextName; - this.contextName = contextName; - // changing contextName could change fields definition - // so dettach bean, must rebuild the fields - if (bean != null) { - setBean(null); - } - // rebuild the fields - initFields(); - pcs.firePropertyChange(CONTEXT_NAME_PROPERTY, - oldContextName, - contextName - ); - } - - /** - * Sets the filter scopes. - * - * @param filterScopes the scopes to used - */ - public void setFilterScopes(BeanValidatorScope... filterScopes) { - this.filterScopes = filterScopes; - // changing contextName could change fields definition - // so dettach bean, must rebuild the fields - if (bean != null) { - setBean(null); - } - // rebuild the fields - initFields(); - } - - public void setParentValidator(BeanValidator<?> parentValidator) { - this.parentValidator = parentValidator; - } - - /** - * Convert a value. - * <p/> - * If an error occurs, then add an error in validator. - * - * @param <T> the type of conversion - * @param fieldName the name of the bean property - * @param value the value to convert - * @param valueClass the type of converted value - * @return the converted value, or null if conversion was not ok - */ - @SuppressWarnings({"unchecked"}) - public <T> T convert(String fieldName, String value, Class<T> valueClass) { - if (fieldName == null) { - throw new IllegalArgumentException("fieldName can not be null"); - } - if (valueClass == null) { - throw new IllegalArgumentException("valueClass can not be null"); - } - - // on ne convertit pas si il y a un bean et que le resultat de la - // validation pourra etre affiche quelque part - if (!canValidate() || value == null) { - return null; - } - - // remove the previous conversion error for the field - conversionErrors.remove(fieldName); - - T result; - try { - Converter converter = ConverterUtil.getConverter(valueClass); - if (converter == null) { - throw new RuntimeException( - "could not find converter for the type " + valueClass); - } - result = (T) converter.convert(valueClass, value); - /* Why this test ? if (result != null && !value.equals(result.toString())) { - conversionErrors.put(fieldName, "error.convertor." + Introspector.decapitalize(valueClass.getSimpleName())); - result = null; - validate(); - }*/ - } catch (ConversionException e) { - // get - String s = Introspector.decapitalize(valueClass.getSimpleName()); - conversionErrors.put(fieldName, "error.convertor." + s); - result = null; - validate(); - } - return result; - } - - /** - * Methode pour forcer la revalidation d'un bean en mettant a jour les etats - * internes. - * <p/> - * La méthode appelle {@link #validate()} puis met à jour les etats internes - * {@link #valid} et {@link #changed}. - * - * @since 1.5 - */ - public void doValidate() { - validate(); - setValid(!hasFatalErrors() && !hasErrors()); - setChanged(true); - } - - /** - * il faut eviter le code re-intrant (durant une validation, une autre est - * demandee). Pour cela on fait la validation dans un thread, et tant que la - * premiere validation n'est pas fini, on ne repond pas aux solicitations. - * Cette method est public pour permettre de force une validation par - * programmation, ce qui est utile par exemple si le bean ne supporte pas - * les {@link PropertyChangeListener} - * <p/> - * <b>Note:</b> la methode est protected et on utilise la methode - * {@link #doValidate()} car la méthode ne modifie pas les etats - * internes et cela en rend son utilisation delicate (le validateur entre - * dans un etat incoherent par rapport aux messages envoyés). - */ - protected void validate() { - - // on ne valide que si il y a un bean et que le resultat de la validation - // pourra etre affiche quelque part - if (!canValidate()) { - return; - } - - for (BeanValidatorScope scope : validators.keySet()) { - - XWorkBeanValidator<B> validator = validators.get(scope); - - Map<String, List<String>> newMessages = validator.validate(bean); - - if (scope == BeanValidatorScope.ERROR) { - // treate conversion errors - // reinject them - for (Entry<String, String> entry : conversionErrors.entrySet()) { - // remove from validation, errors occurs on this field - List<String> errors = newMessages.get(entry.getKey()); - String conversionError = entry.getValue(); - if (errors != null) { - errors.clear(); - errors.add(conversionError); - } else { - errors = Collections.singletonList(conversionError); - if (XWorkBeanValidator.EMPTY_RESULT.equals(newMessages)) { - newMessages = new HashMap<String, List<String>>(); - } - // add the concrete conversion error - newMessages.put(entry.getKey(), errors); - } - } - } - - // for each field, update his list of messages - for (BeanValidatorField<B> field : fields) { - List<String> messagesForField = newMessages.get(field.getName()); - if (field.getScopes().contains(scope)) { - field.updateMessages(this, scope, messagesForField); - } - } - } - - if (parentValidator != null) { - // chained validation - // the parent validator should not be changed from this validation - boolean wasModified = parentValidator.isChanged(); - parentValidator.doValidate(); - if (!wasModified) { - // push back old state - parentValidator.setChanged(false); - } - } - - } - - @Override - public String toString() { - return super.toString() + "<beanClass:" + beanClass + - ", contextName:" + contextName + ">"; - } - - public void addBeanValidatorListener(BeanValidatorListener listener) { - listenerList.add(BeanValidatorListener.class, listener); - } - - public void removeBeanValidatorListener(BeanValidatorListener listener) { - listenerList.remove(BeanValidatorListener.class, listener); - } - - public BeanValidatorListener[] getBeanValidatorListeners() { - return listenerList.getListeners(BeanValidatorListener.class); - } - - public void addPropertyChangeListener(PropertyChangeListener listener) { - pcs.addPropertyChangeListener(listener); - } - - public void addPropertyChangeListener(String propertyName, - PropertyChangeListener listener) { - pcs.addPropertyChangeListener(propertyName, listener); - } - - public void removePropertyChangeListener(PropertyChangeListener listener) { - pcs.removePropertyChangeListener(listener); - } - - public void removePropertyChangeListener(String propertyName, - PropertyChangeListener listener) { - pcs.removePropertyChangeListener(propertyName, listener); - } - - /** - * @return <code>true</code> if validation is enabled, <code>false</code> - * otherwise. - */ - protected boolean canValidate() { - return !(bean == null || fields.isEmpty()); - } - - protected void fireFieldChanged(BeanValidatorField<B> field, - BeanValidatorScope scope, - String[] toAdd, - String[] toDelete) { - - BeanValidatorEvent evt = new BeanValidatorEvent( - this, - field, - scope, - toAdd, - toDelete - ); - - for (BeanValidatorListener listener : - listenerList.getListeners(BeanValidatorListener.class)) { - listener.onFieldChanged(evt); - } - } - - protected void initFields() { - - Set<String> detectedFieldNames = new HashSet<String>(); - EnumMap<BeanValidatorScope, Set<String>> tmp; - tmp = new EnumMap<BeanValidatorScope, Set<String>>( - BeanValidatorScope.class - ); - Set<BeanValidatorField<B>> detectedFields = - new HashSet<BeanValidatorField<B>>(); - - validators.clear(); - - BeanValidatorScope[] scopeUniverse; - if (filterScopes == null) { - // use all scopes - scopeUniverse = BeanValidatorScope.values(); - } else { - // use customized scopes - scopeUniverse = filterScopes; - } - - for (BeanValidatorScope scope : scopeUniverse) { - String scopeContext = - (contextName == null ? "" : contextName + "-") + - scope.name().toLowerCase(); - - XWorkBeanValidator<B> newValidator = - new XWorkBeanValidator<B>(beanClass, scopeContext, false); - Set<String> fieldNames = newValidator.getFieldNames(); - if (log.isDebugEnabled()) { - log.debug("detected validators for scope " + scopeContext + - " : " + fieldNames); - } - if (!fieldNames.isEmpty()) { - // fields detected in this validator, keep it - validators.put(scope, newValidator); - detectedFieldNames.addAll(fieldNames); - tmp.put(scope, fieldNames); - } - } - - List<BeanValidatorScope> scopes = new ArrayList<BeanValidatorScope>(); - for (String fieldName : detectedFieldNames) { - scopes.clear(); - // detect scopes for the field - for (BeanValidatorScope scope : scopeUniverse) { - if (tmp.containsKey(scope) && - tmp.get(scope).contains(fieldName)) { - scopes.add(scope); - } - } - BeanValidatorField<B> f = - new BeanValidatorField<B>(beanClass, fieldName, scopes); - detectedFields.add(f); - } - tmp.clear(); - detectedFieldNames.clear(); - - fields = Collections.unmodifiableSet(detectedFields); - } - - protected EventSetDescriptor getBeanEventDescriptor(B bean) { - if (beanEventDescriptor == null) { - // check that the bean is listenable, otherwise, can't use the - // validator on it - beanEventDescriptor = - BeanValidatorUtil.getPropertyChangeListenerDescriptor( - bean.getClass() - ); - } - return beanEventDescriptor; - } -} Deleted: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorDetector.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorDetector.java 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorDetector.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,342 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2011 CodeLutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.validator; - -import org.apache.commons.beanutils.ConstructorUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.io.File; -import java.io.FilenameFilter; -import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Un detecteur de validateurs pour un liste de classes données et un répertoire - * où chercher les fichiers de validation. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.6.0 - */ -public class BeanValidatorDetector { - - /** Logger */ - private static final Log log = - LogFactory.getLog(BeanValidatorDetector.class); - - public SortedSet<BeanValidator<?>> detect(File sourceRoot, - Class<?>... types) { - SortedSet<BeanValidator<?>> result = - detect(BeanValidator.class, sourceRoot, null, types); - return result; - } - - public SortedSet<BeanValidator<?>> detect(Class<?> validatorClass, - File sourceRoot, - Pattern contextFilter, - Class<?>... types) { - SortedSet<BeanValidator<?>> result = detect(validatorClass, - sourceRoot, - contextFilter, - null, - types); - return result; - } - - public SortedSet<BeanValidator<?>> detect(Class<?> validatorClass, - File sourceRoot, - Pattern contextFilter, - BeanValidatorScope[] scopes, - Class<?>... types) { - - SortedSet<BeanValidator<?>> result = - new TreeSet<BeanValidator<?>>(new BeanValidatorComparator()); - - for (Class<?> c : types) { - File dir = getClassDir(sourceRoot, c); - if (!dir.exists()) { - - // pas de repertoire adequate - if (log.isDebugEnabled()) { - log.debug("skip non existing directory " + dir); - } - continue; - } - String[] contexts = getContexts(c, dir); - if (log.isDebugEnabled()) { - log.debug("contexts : " + Arrays.toString(contexts)); - } - - if (contexts.length > 0) { - String[] realContexts = getContextsWithoutScopes(contexts); - - if (log.isDebugEnabled()) { - log.debug("realContexts : " + - Arrays.toString(realContexts)); - } - - if (contextFilter != null) { - - // filter contexts - realContexts = getFilterContexts(contextFilter, - realContexts - ); - if (log.isDebugEnabled()) { - log.debug("filterContexts : " + - Arrays.toString(realContexts)); - } - } - - for (String context : realContexts) { - - // on cherche le validateur - BeanValidator<?> validator = getValidator( - validatorClass, - c, - context.isEmpty() ? null : context, - scopes - ); - if (validator != null) { - // on enregistre le validateur - result.add(validator); - } - } - } - } - return result; - } - - /** - * Pour un context et un type d'entité donné, instancie un validateur et - * test si ce validateur est utilisable (i.e qu'il admet des champs à - * valider). - * <p/> - * Si aucun champ n'est trouvé dans le validateur, alors on retourne null. - * - * @param <B> le type du bean - * @param validatorClass le type de validateur a instancie - * @param klass le type du bean - * @param context le context du validateur - * @param scopes les scopes a utiliser (si {@code null} alors pas de - * filtre sur les scopes) - * @return le validateur initialisé, ou <code>null</code> si aucun scope - * détecté dans le validateur. - */ - protected <B> BeanValidator<B> getValidator(Class<?> validatorClass, - Class<B> klass, - String context, - BeanValidatorScope... scopes) { - - BeanValidator<B> valitator; - valitator = createValidator(validatorClass, klass, context, scopes); - - Set<BeanValidatorScope> resultScopes = valitator.getScopes(); - if (resultScopes.isEmpty()) { - valitator = null; - if (log.isDebugEnabled()) { - log.debug(klass + " : validator skip (no scopes detected)"); - } - } else { - if (log.isDebugEnabled()) { - log.debug(klass + " : keep validator " + valitator); - } - } - return valitator; - } - - protected <B> BeanValidator<B> createValidator( - Class<?> validatorClass, - Class<B> klass, - String context, - BeanValidatorScope[] scopes) { - BeanValidator<B> valitator; - Constructor<?> con; - try { - con = ConstructorUtils.getAccessibleConstructor( - validatorClass, - new Class<?>[]{ - Class.class, - String.class, - BeanValidatorScope[].class - } - ); - if (con != null) { - - valitator = (BeanValidator<B>) con.newInstance( - klass, - context, scopes - ); - - } else { - con = ConstructorUtils.getAccessibleConstructor( - validatorClass, - new Class<?>[]{ - Class.class, - String.class, - BeanValidatorScope[].class - } - ); - - if (con == null) { - throw new IllegalStateException( - "could not find a constructor with " + - "(Class.class, String) or " + - "(Class,String BeanValidatorScope[])"); - } - - valitator = (BeanValidator<B>) con.newInstance( - klass, - context - ); - if (scopes != null && scopes.length > 0) { - valitator.setFilterScopes(scopes); - } - } - - } catch (Exception ex) { - throw new RuntimeException( - "could not instanciate validator " + validatorClass + - " for reason " + ex.getMessage(), ex); - } - return valitator; - } - - protected File getClassDir(File sourceRoot, Class<?> clazz) { - String path = clazz.getPackage().getName(); - path = path.replaceAll("\\.", File.separator); - File dir = new File(sourceRoot, path); - return dir; - } - - protected String[] getContexts(Class<?> clazz, File dir) { - Set<String> result = new TreeSet<String>(); - ValidatorFilenameFilter filter = new ValidatorFilenameFilter(clazz); - if (log.isDebugEnabled()) { - log.debug("dir : " + dir); - } - String[] files = dir.list(filter); - for (String file : files) { - if (log.isDebugEnabled()) { - log.debug("file " + file); - } - String context = file.substring( - filter.prefix.length(), - file.length() - ValidatorFilenameFilter.SUFFIX.length() - ); - if (log.isDebugEnabled()) { - log.debug("detect " + clazz.getSimpleName() + - " context [" + context + "]"); - } - result.add(context); - } - return result.toArray(new String[result.size()]); - } - - protected String[] getContextsWithoutScopes(String[] contexts) { - Set<String> result = new TreeSet<String>(); - BeanValidatorScope[] scopes = BeanValidatorScope.values(); - for (String context : contexts) { - for (BeanValidatorScope scope : scopes) { - String scopeName = scope.name().toLowerCase(); - if (!context.endsWith(scopeName)) { - // pas concerne par ce scope - continue; - } - if (log.isDebugEnabled()) { - log.debug("detect context : " + context); - } - String realContext = context.substring( - 0, - context.length() - scopeName.length() - ); - if (realContext.endsWith("-")) { - realContext = realContext.substring( - 0, - realContext.length() - 1 - ); - } - result.add(realContext); - } - } - return result.toArray(new String[result.size()]); - } - - protected String[] getFilterContexts(Pattern contextFilter, - String[] realContexts) { - List<String> result = new ArrayList<String>(); - for (String c : realContexts) { - Matcher m = contextFilter.matcher(c); - if (m.matches()) { - result.add(c); - } - } - return result.toArray(new String[result.size()]); - } - - protected static class ValidatorFilenameFilter implements FilenameFilter { - - protected static final String SUFFIX = "-validation.xml"; - - protected Class<?> clazz; - - protected String prefix; - - public ValidatorFilenameFilter(Class<?> clazz) { - this.clazz = clazz; - prefix = clazz.getSimpleName() + "-"; - } - - @Override - public boolean accept(File dir, String name) { - boolean result = name.endsWith(SUFFIX); - if (result) { - result = name.startsWith(prefix); - } - return result; - } - } - - protected static class BeanValidatorComparator implements Comparator<BeanValidator<?>> { - - @Override - public int compare(BeanValidator<?> o1, BeanValidator<?> o2) { - String contextName1 = - o1.getBeanClass().getSimpleName() + "-" + - (o1.getContextName() == null ? "" : o1.getContextName()); - String contextName2 = - o2.getBeanClass().getSimpleName() + "-" + - (o2.getContextName() == null ? "" : o2.getContextName()); - return contextName1.compareTo(contextName2); - } - } -} Deleted: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorEvent.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorEvent.java 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorEvent.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,86 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2011 CodeLutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.validator; - -import java.util.EventObject; - -/** - * The definition of an event on {@link BeanValidatorListener} - * to be fired by a {@link BeanValidator}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.3 - */ -public class BeanValidatorEvent extends EventObject { - - private static final long serialVersionUID = 1L; - - /** the field impacted by the validator */ - protected BeanValidatorField<?> field; - - /** the scope impacted by the event */ - protected BeanValidatorScope scope; - - protected String[] messagestoAdd; - - protected String[] messagestoDelete; - - public BeanValidatorEvent(BeanValidator<?> source, - BeanValidatorField<?> field, - BeanValidatorScope scope, - String[] messagestoAdd, - String[] messagestoDelete) { - super(source); - this.field = field; - this.scope = scope; - this.messagestoAdd = messagestoAdd; - this.messagestoDelete = messagestoDelete; - } - - @Override - public BeanValidator<?> getSource() { - return (BeanValidator<?>) super.getSource(); - } - - public String getFieldName() { - return field.getName(); - } - - public String[] getMessagesToAdd() { - return messagestoAdd; - } - - public String[] getMessagesToDelete() { - return messagestoDelete; - } - - public BeanValidatorScope getScope() { - return scope; - } - - public BeanValidatorField<?> getField() { - return field; - } -} Deleted: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorField.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorField.java 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorField.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,286 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2011 CodeLutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.validator; - -import com.opensymphony.xwork2.validator.FieldValidator; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.StringTokenizer; - -import static org.nuiton.i18n.I18n._; - -/** - * Definition of a field to be handled in a {@link BeanValidator}. - * <p/> - * A such class is only registred in {@link BeanValidator } when the field of - * the bean was found in validator xml configuration file for a {@link - * FieldValidator} only. - * <p/> - * This class use properties {@link #beanClass}, {@link #name} to define his - * naturel order. - * - * @author tchemit <chemit@codelutin.com> - * @param <B> the type of the bean handled by the validator and this field of - * validation. - * @since 1.3 - */ -public class BeanValidatorField<B> implements Serializable { - - private static final long serialVersionUID = 1L; - - /** the class of bean */ - protected final Class<B> beanClass; - - /** name of field in bean */ - protected final String name; - - protected EnumMap<BeanValidatorScope, Set<String>> messages; - - public BeanValidatorField(Class<B> beanClass, - String name, - List<BeanValidatorScope> scopes) { - this.beanClass = beanClass; - this.name = name; - messages = new EnumMap<BeanValidatorScope, Set<String>>( - BeanValidatorScope.class - ); - for (BeanValidatorScope scope : scopes) { - messages.put(scope, new HashSet<String>()); - } - } - - public String getName() { - return name; - } - - public Class<B> getBeanClass() { - return beanClass; - } - - /** - * @return {@code true} if this field is valid : no fatal errors and no - * errors), {@code false} otherwise. - */ - public boolean isValid() { - return !hasFatalErrors() && !hasErrors(); - } - - public BeanValidatorScope getScope() { - if (hasErrors()) { - return BeanValidatorScope.ERROR; - } - if (hasWarnings()) { - return BeanValidatorScope.WARNING; - } - if (hasInfos()) { - return BeanValidatorScope.INFO; - } - return null; - } - - public Set<BeanValidatorScope> getScopes() { - return messages.keySet(); - } - - public boolean hasFatalErrors() { - return hasMessages(BeanValidatorScope.FATAL); - } - - public boolean hasErrors() { - return hasMessages(BeanValidatorScope.ERROR); - } - - public boolean hasWarnings() { - return hasMessages(BeanValidatorScope.WARNING); - } - - public boolean hasInfos() { - return hasMessages(BeanValidatorScope.INFO); - } - - public Set<String> getFatalErrors() { - return getMessages(BeanValidatorScope.FATAL); - } - - public Set<String> getErrors() { - return getMessages(BeanValidatorScope.ERROR); - } - - public Set<String> getWarnings() { - return getMessages(BeanValidatorScope.WARNING); - } - - public Set<String> getInfos() { - return getMessages(BeanValidatorScope.INFO); - } - - public boolean hasMessages(BeanValidatorScope scope) { - return messages.containsKey(scope) && !getMessages(scope).isEmpty(); - } - - public Set<String> getMessages(BeanValidatorScope scope) { - return messages.get(scope); - } - - public void updateMessages(BeanValidator<B> validator, - BeanValidatorScope scope, - List<String> messages) { - - if (scope == null) { - - // special case to reset all messages from all scopes - - for (BeanValidatorScope s : getScopes()) { - - clearMessages(s, validator); - } - return; - } - - if (!this.messages.containsKey(scope)) { - throw new IllegalArgumentException( - "the scope " + scope + " was not registred for " + this); - } - - if (messages == null || messages.isEmpty()) { - - // no incoming message for this scope - - clearMessages(scope, validator); - return; - } - - // build the diff of messages (the one to delete, the one to add) - - boolean hasChanged = false; - - Set<String> currentMessages = getMessages(scope); - - // detect messages to delete - Set<String> toDelete = new HashSet<String>(currentMessages); - toDelete.removeAll(messages); - - if (!toDelete.isEmpty()) { - // apply delete - currentMessages.removeAll(toDelete); - hasChanged = true; - } - - // detect messages to add - Set<String> toAdd = new HashSet<String>(messages); - toAdd.removeAll(currentMessages); - - if (!toAdd.isEmpty()) { - // apply add - currentMessages.addAll(toAdd); - hasChanged = true; - } - - if (hasChanged) { - - // something has changed, fire notifications - String[] del = toDelete.toArray(new String[toDelete.size()]); - String[] add = toAdd.toArray(new String[toAdd.size()]); - - validator.fireFieldChanged(this, scope, add, del); - } - toAdd.clear(); - toDelete.clear(); - - } - - public String getI18nError(String error) { - String text; - if (!error.contains("##")) { - text = _(error); - } else { - StringTokenizer stk = new StringTokenizer(error, "##"); - String errorName = stk.nextToken(); - List<String> args = new ArrayList<String>(); - while (stk.hasMoreTokens()) { - args.add(stk.nextToken()); - } - text = _(errorName, args.toArray()); - } - return text; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof BeanValidatorField<?>)) { - return false; - } - - BeanValidatorField<?> that = (BeanValidatorField<?>) o; - return beanClass.equals(that.beanClass) && name.equals(that.name); - } - - @Override - public int hashCode() { - int result = beanClass.hashCode(); - result = 31 * result + name.hashCode(); - return result; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("<").append(super.toString()); - sb.append(" beanClass:").append(beanClass); - sb.append(", name:").append(name); - sb.append(", scopes:"); - sb.append(messages == null ? "[]" : messages.keySet()); - sb.append(", scope:").append(getScope()); - //sb.append(", errors:").append(errors); - sb.append('>'); - return sb.toString(); - } - - protected void clearMessages(BeanValidatorScope scope, - BeanValidator<B> validator) { - // remove all messages - Set<String> toDelete = getMessages(scope); - - if (!toDelete.isEmpty()) { - - // there is some messages to delete - String[] toDel = toDelete.toArray(new String[toDelete.size()]); - - // apply deletion - toDelete.clear(); - - // fire - validator.fireFieldChanged(this, scope, null, toDel); - } - } -} Deleted: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorListener.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorListener.java 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorListener.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,43 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2011 CodeLutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.validator; - -import java.util.EventListener; - -/** - * The listener contract to be used on {@link BeanValidator} - * - * @author tchemit <chemit@codelutin.com> - * @since 1.3 - */ -public interface BeanValidatorListener extends EventListener { - - /** - * Invoked when a validator detects some changes on a field. - * - * @param event the event - */ - void onFieldChanged(BeanValidatorEvent event); -} Deleted: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorMessage.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorMessage.java 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorMessage.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,118 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2011 CodeLutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.validator; - -/** - * The object to box a validation message. - * - * @author tchemit <chemit@codelutin.com> - * @param <E> type of message (use for override {@link #compareTo(Object)} - * method. - * @since 1.3 - */ -public class BeanValidatorMessage<E extends BeanValidatorMessage<?>> implements Comparable<E> { - - /** the validator that produce the message */ - protected BeanValidator<?> validator; - - /** the field that produce the message */ - protected BeanValidatorField<?> field; - - /** the label of the message (to be displayed somewhere) */ - protected String message; - - /** the scope of the message */ - protected BeanValidatorScope scope; - - public BeanValidatorMessage(BeanValidator<?> validator, - BeanValidatorField<?> field, - String message, - BeanValidatorScope scope) { - this.field = field; - this.validator = validator; - this.message = message == null ? null : message.trim(); - this.scope = scope; - } - - public BeanValidator<?> getValidator() { - return validator; - } - - public BeanValidatorField<?> getField() { - return field; - } - - public BeanValidatorScope getScope() { - return scope; - } - - public String getMessage() { - return message; - } - - @Override - public int compareTo(E o) { - // sort on scope - int result = getScope().compareTo(o.getScope()); - if (result == 0) { - // sort on field name - result = field.getName().compareTo(o.field.getName()); - if (result == 0) { - // sort on message - result = message.compareTo(o.message); - } - } - return result; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - BeanValidatorMessage<?> that = (BeanValidatorMessage<?>) o; - - return field.equals(that.field) && - message.equals(that.message) && - scope == that.scope; - } - - @Override - public int hashCode() { - int result = field.hashCode(); - result = 31 * result + message.hashCode(); - result = 31 * result + scope.hashCode(); - return result; - } - - @Override - public String toString() { - return scope + " - " + field.getI18nError(message); - } -} Deleted: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorScope.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorScope.java 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorScope.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,79 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2011 CodeLutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.validator; - -import static org.nuiton.i18n.I18n.n_; - -/** - * The differents levels of messages in validation process. - * <p/> - * The order of the enum defines the severity of validation. - * <p/> - * Always begin with fatal, then error, then if no error found, try warning, then info... - * - * @author tchemit <chemit@codelutin.com> - */ -public enum BeanValidatorScope { - - /** - * the fatal error scope level. - * <p/> - * When a message of a such scope is found on a validator, then the - * validator is invalid and modified. - * @since 2.2.4 - */ - FATAL(n_("validator.scope.fatal.label")), - /** - * the error scope level. - * <p/> - * When a message of a such scope is found on a validator, then the - * validator is invalid and modified. - */ - ERROR(n_("validator.scope.error.label")), - /** - * the warning scope level. - * <p/> - * When a message of a such scope is found on a validator, then the - * validator is still valid but modified. - */ - WARNING(n_("validator.scope.warning.label")), - /** - * the information scope level. - * <p/> - * When a message of a sucg scope is found on a validator, then the - * validator is still valid and not modified. - */ - INFO(n_("validator.scope.info.label")); - - private final String label; - - BeanValidatorScope(String label) { - this.label = label; - } - - public String getLabel() { - return label; - } -} Deleted: trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorUtil.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorUtil.java 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorUtil.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,196 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2011 CodeLutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.validator; - -import com.opensymphony.xwork2.config.Configuration; -import com.opensymphony.xwork2.config.ConfigurationManager; -import com.opensymphony.xwork2.inject.Container; -import com.opensymphony.xwork2.util.ValueStack; -import com.opensymphony.xwork2.util.ValueStackFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.beans.BeanInfo; -import java.beans.EventSetDescriptor; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.util.EnumMap; -import java.util.EnumSet; -import java.util.List; - -/** - * The helper class for validation module. - * - * @author tchemit <chemit@codelutin.com> - */ -public class BeanValidatorUtil { - - /** Logger */ - static private final Log log = LogFactory.getLog(BeanValidatorUtil.class); - - /** - * a shared value stack to allow external operations on it (for example add - * some datas in stack to be usedby validators - */ - static private ValueStack sharedValueStack; - - public static ValueStack getSharedValueStack() { - if (sharedValueStack == null) { - - // init context - ConfigurationManager confManager = new ConfigurationManager(); - Configuration conf = confManager.getConfiguration(); - - Container container = conf.getContainer(); - ValueStackFactory stackFactory = container.getInstance( - ValueStackFactory.class); - sharedValueStack = stackFactory.createValueStack(); - if (log.isDebugEnabled()) { - log.debug("init shared value stack " + sharedValueStack); - } - } - return sharedValueStack; - } - - protected BeanValidatorUtil() { - // no instance - } - - /** - * Convert a value to a given type and then if was succesffull try to set it - * in the bean manage by the validator. - * - * @param validator validator to be involved - * @param fieldName the name of the bean property - * @param value the actual value to convert - * @param valueClass the type of the conversion - */ - public static void convert(BeanValidator<?> validator, - String fieldName, - String value, - Class<?> valueClass) { - - Object result = validator.convert(fieldName, value, valueClass); - if (result != null) { - try { - BeanInfo info = - Introspector.getBeanInfo(validator.getBean().getClass()); - - for (PropertyDescriptor descriptor : - info.getPropertyDescriptors()) { - if (fieldName.equals(descriptor.getName()) && - descriptor.getWriteMethod() != null) { - - descriptor.getWriteMethod().invoke( - validator.getBean(), - result - ); - break; - } - } - } catch (Exception e) { - if (log.isErrorEnabled()) { - log.error("could not obtain beanInfo for " + - valueClass.getClass() + ", reason : " + - e.getMessage(), e); - } - } - } else { - //fixme : conversion failed, we should be able to notify ui - // that values has changed ? - // otherwise, bean value has not changed,... - } - } - - public static EventSetDescriptor getPropertyChangeListenerDescriptor(Class<?> beanClass) { - try { - // check that the bean is listenable, otherwise, can't use - // the validator on it - BeanInfo infos = Introspector.getBeanInfo(beanClass); - EventSetDescriptor[] events = infos.getEventSetDescriptors(); - for (EventSetDescriptor event : events) { - if ("propertyChange".equals(event.getName())) { - - if (event.getAddListenerMethod() == null) { - // no property event listener, so can not use the validator - throw new IllegalStateException( - "no addPropertyChangeListener method found " + - "for " + beanClass); - } - if (event.getRemoveListenerMethod() == null) { - // no property event listener, so can not use the validator - throw new IllegalStateException( - "no removePropertyChangeListener method found" + - " for " + beanClass); - } - return event; - } - } - - // no property event listener, so can not use the validator - throw new IllegalStateException( - "no PropertyChangeListener access method found for " + - beanClass); - } catch (IntrospectionException ex) { - throw new IllegalStateException( - "could not acquire PropertyChangeListener bean info for " + - beanClass + " for reason " + ex.getMessage(), ex); - } - } - - public static EnumSet<BeanValidatorScope> getScopes( - List<BeanValidatorMessage<?>> messages) { - EnumSet<BeanValidatorScope> result = - EnumSet.noneOf(BeanValidatorScope.class); - for (BeanValidatorMessage<?> m : messages) { - result.add(m.getScope()); - } - return result; - } - - public static EnumMap<BeanValidatorScope, Integer> getScopesCount( - List<BeanValidatorMessage<?>> messages) { - EnumMap<BeanValidatorScope, Integer> result = - new EnumMap<BeanValidatorScope, Integer>(BeanValidatorScope.class); - for (BeanValidatorScope s : BeanValidatorScope.values()) { - result.put(s, 0); - } - for (BeanValidatorMessage<?> m : messages) { - - BeanValidatorScope scope = m.getScope(); - - result.put(scope, result.get(scope) + 1); - } - - for (BeanValidatorScope s : BeanValidatorScope.values()) { - if (result.get(s) == 0) { - result.remove(s); - } - } - return result; - } - -} Deleted: trunk/nuiton-validator/src/main/java/org/nuiton/validator/ValidatorsMap.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/ValidatorsMap.java 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/ValidatorsMap.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,126 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2011 CodeLutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.validator; - -import java.util.Collection; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -/** - * Un dictionnaire de validateurs ordonnees par le type de leur bean. - * - * @author tchemit <chemit@codelutin.com> - * @since 2.0.1 - */ -public class ValidatorsMap implements Map<Class<?>, BeanValidator<?>> { - - protected final Map<Class<?>, BeanValidator<?>> delegate; - - public ValidatorsMap() { - delegate = new HashMap<Class<?>, BeanValidator<?>>(); - } - - public BeanValidatorScope[] getScopes() { - EnumSet<BeanValidatorScope> result = - EnumSet.noneOf(BeanValidatorScope.class); - for (BeanValidator<?> b : values()) { - result.addAll(b.getScopes()); - } - return result.toArray(new BeanValidatorScope[result.size()]); - } - -// public <X> BeanValidator<X> getValidator(X klass) { -// BeanValidator<X> beanValidator = (BeanValidator<X>) get(klass.getClass()); -// return beanValidator; -// } - - public <X> BeanValidator<X> getValidator(Class<X> klass) { - BeanValidator<X> beanValidator = (BeanValidator<X>) get(klass); - return beanValidator; - } - - @Override - public int size() { - return delegate.size(); - } - - @Override - public boolean isEmpty() { - return delegate.isEmpty(); - } - - @Override - public boolean containsKey(Object key) { - return delegate.containsKey(key); - } - - @Override - public boolean containsValue(Object value) { - return delegate.containsValue(value); - } - - @Override - public BeanValidator<?> get(Object key) { - return delegate.get(key); - } - - @Override - public BeanValidator<?> put(Class<?> key, BeanValidator<?> value) { - return delegate.put(key, value); - } - - @Override - public BeanValidator<?> remove(Object key) { - return delegate.remove(key); - } - - @Override - public void putAll(Map<? extends Class<?>, ? extends BeanValidator<?>> m) { - delegate.putAll(m); - } - - @Override - public void clear() { - delegate.clear(); - } - - @Override - public Set<Class<?>> keySet() { - return delegate.keySet(); - } - - @Override - public Collection<BeanValidator<?>> values() { - return delegate.values(); - } - - @Override - public Set<Entry<Class<?>, BeanValidator<?>>> entrySet() { - return delegate.entrySet(); - } - -} Deleted: trunk/nuiton-validator/src/main/java/org/nuiton/validator/XWorkBeanValidator.java =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/XWorkBeanValidator.java 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/XWorkBeanValidator.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,324 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2011 CodeLutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.validator; - -import com.opensymphony.xwork2.ActionContext; -import com.opensymphony.xwork2.ValidationAwareSupport; -import com.opensymphony.xwork2.config.Configuration; -import com.opensymphony.xwork2.config.ConfigurationManager; -import com.opensymphony.xwork2.inject.Container; -import com.opensymphony.xwork2.util.ValueStack; -import com.opensymphony.xwork2.util.ValueStackFactory; -import com.opensymphony.xwork2.validator.ActionValidatorManager; -import com.opensymphony.xwork2.validator.DelegatingValidatorContext; -import com.opensymphony.xwork2.validator.FieldValidator; -import com.opensymphony.xwork2.validator.ValidationException; -import com.opensymphony.xwork2.validator.Validator; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * A customized validator for a given bean. - * <p/> - * Use the method {@link #validate(Object)} to obtain the messages detected by - * the validator for the given bean. - * - * @author tchemit <chemit@codelutin.com> - * @param <B> type of the bean to validate. - * @since 1.3 - */ -public class XWorkBeanValidator<B> { - - /** Logger */ - private static final Log log = LogFactory.getLog(XWorkBeanValidator.class); - - protected final static Map<String, List<String>> EMPTY_RESULT = - Collections.unmodifiableMap(new HashMap<String, List<String>>()); - - /** the type of bean to validate */ - protected final Class<B> beanClass; - - /** the validation named context (can be null) */ - protected String contextName; - - /** the list of field names detected for this validator */ - protected Set<String> fieldNames; - - /** a flag to include or not the default context validators */ - protected boolean includeDefaultContext; - - // -- - // XWorks fields - // -- - - protected ValidationAwareSupport validationSupport; - - protected DelegatingValidatorContext validationContext; - - protected ActionValidatorManager validator; - - protected ActionContext context; - - public XWorkBeanValidator(Class<B> beanClass, String contextName) { - this(beanClass, - contextName, - true, - BeanValidatorUtil.getSharedValueStack() - ); - } - - public XWorkBeanValidator(Class<B> beanClass, - String contextName, - ValueStack vs) { - this(beanClass, contextName, true, vs); - } - - public XWorkBeanValidator(Class<B> beanClass, - String contextName, - boolean includeDefaultContext) { - this(beanClass, - contextName, - includeDefaultContext, - BeanValidatorUtil.getSharedValueStack() - ); - } - - public XWorkBeanValidator(Class<B> beanClass, - String contextName, - boolean includeDefaultContext, - ValueStack vs) { - - this.beanClass = beanClass; - this.includeDefaultContext = includeDefaultContext; - validationSupport = new ValidationAwareSupport(); - validationContext = new DelegatingValidatorContext(validationSupport); - - if (vs == null) { - // create a standalone value stack - ConfigurationManager confManager = new ConfigurationManager(); - Configuration conf = confManager.getConfiguration(); - Container container = conf.getContainer(); - ValueStackFactory stackFactory = - container.getInstance(ValueStackFactory.class); - vs = stackFactory.createValueStack(); - if (log.isDebugEnabled()) { - log.debug("create a standalone value stack " + vs); - } - } else { - if (log.isDebugEnabled()) { - log.debug("use given value stack " + vs); - } - } - - context = new ActionContext(vs.getContext()); - ActionContext.setContext(context); - - // init validator - Container container = context.getContainer(); - validator = container.getInstance(ActionValidatorManager.class, - "no-annotations" - ); - - // init context - setContextName(contextName); - } - - public boolean isIncludeDefaultContext() { - return includeDefaultContext; - } - - public Class<B> getBeanClass() { - return beanClass; - } - - public String getContextName() { - return contextName; - } - - public Set<String> getFieldNames() { - return fieldNames; - } - - public ActionValidatorManager getValidator() { - return validator; - } - - /** - * Test a the validator contains the field given his name - * - * @param fieldName the name of the searched field - * @return <code>true</code> if validator contaisn this field, - * <code>false</code> otherwise - */ - public boolean containsField(String fieldName) { - return fieldNames.contains(fieldName); - } - - public void setIncludeDefaultContext(boolean includeDefaultContext) { - this.includeDefaultContext = includeDefaultContext; - if (contextName != null) { - // reload context - setContextName(contextName); - } - } - - public void setContextName(String contextName) { - this.contextName = contextName; - // changing contextName may change fields definition - // so reload fields - initFields(); - } - - /** - * Valide le bean donné et retourne les messages produits. - * - * @param bean le bean a valider (il doit etre non null) - * @return le dictionnaire des messages produits par la validation indexées - * par le nom du champs du bean impacté. - */ - public Map<String, List<String>> validate(B bean) { - - if (bean == null) { - throw new NullPointerException( - "bean can not be null in method validate"); - } - - Map<String, List<String>> result = EMPTY_RESULT; - - // on lance la validation uniquement si des champs sont a valider - if (!fieldNames.isEmpty()) { - - try { - - //TC - 20081024 : since context is in a ThreadLocal variable, - // we must do the check - if (ActionContext.getContext() == null) { - ActionContext.setContext(context); - } - - validator.validate(bean, contextName, validationContext); - - if (log.isTraceEnabled()) { - log.trace("Action errors: " + - validationContext.getActionErrors()); - log.trace("Action messages: " + - validationContext.getActionMessages()); - log.trace("Field errors: " + - validationContext.getFieldErrors()); - } - - if (log.isDebugEnabled()) { - log.debug(this + " : " + - validationContext.getFieldErrors()); - } - - // retreave errors by field - if (validationContext.hasFieldErrors()) { - Map<?, ?> messages = validationContext.getFieldErrors(); - result = new HashMap<String, List<String>>(messages.size()); - for (Object fieldName : messages.keySet()) { - Collection<?> c = - (Collection<?>) messages.get(fieldName); - List<String> mm = new ArrayList<String>(c.size()); - for (Object message : c) { - // tchemit 2010-08-28 : trim the incoming message - // (I18n will not translate it otherwise) - String messageStr = message == null ? "" : message + ""; - mm.add(messageStr.trim()); - } - result.put(fieldName + "", mm); - } - } - - } catch (ValidationException eee) { - if (log.isWarnEnabled()) { - log.warn("Error during validation on " + beanClass + - " for reason : " + eee.getMessage(), eee); - } - - } finally { - // on nettoye toujours le validateur apres operation - validationSupport.clearErrorsAndMessages(); - } - } - - return result; - } - - @Override - public String toString() { - return super.toString() + "<beanClass:" + beanClass + - ", contextName:" + contextName + ">"; - } - - /** update the property {@link #fieldNames}, says search in XWorks */ - protected void initFields() { - - if (fieldNames != null) { - fieldNames = null; - } - - Set<String> detectedFieldNames = new HashSet<String>(); - - int skip = 0; - if (contextName != null && !includeDefaultContext) { - // count the number of validator to skip - for (Validator<?> v : validator.getValidators(beanClass, null)) { - // we only work on FieldValidator at the moment - if (v instanceof FieldValidator) { - skip++; - } - } - } - - for (Validator<?> v : validator.getValidators(beanClass, contextName)) { - // we only work on FieldValidator at the moment - if (v instanceof FieldValidator) { - if (skip > 0) { - skip--; - continue; - } - FieldValidator fieldValidator = (FieldValidator) v; - if (log.isDebugEnabled()) { - log.debug("context " + contextName + " - field " + - fieldValidator.getFieldName()); - } - String fName = fieldValidator.getFieldName(); - detectedFieldNames.add(fName); - } - } - - fieldNames = Collections.unmodifiableSet(detectedFieldNames); - } -} Copied: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidator.java (from rev 2013, trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidator.java) =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidator.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidator.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,635 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.legacy; + +import org.apache.commons.beanutils.ConversionException; +import org.apache.commons.beanutils.Converter; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.util.converter.ConverterUtil; + +import javax.swing.event.EventListenerList; +import java.beans.EventSetDescriptor; +import java.beans.Introspector; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; + +/** + * A customized validator for a given bean. + * <p/> + * <b>Note:</b> The bean must be listenable on properyChange events (means must + * have public addPropertychangeListener and removePropertyChangeListener + * methods). + * + * @author tchemit <chemit@codelutin.com> + * @param <B> type of the bean to validate. + */ +public class BeanValidator<B> { + + /** la nom de la propriété bean */ + static public final String BEAN_PROERTY = "bean"; + + /** la nom de la propriété contextName */ + static public final String CONTEXT_NAME_PROPERTY = "contextName"; + + /** la nom de l'état valid */ + static public final String VALID_PROERTY = "valid"; + + /** la nom de l'état changed */ + static public final String CHANGED_PROERTY = "changed"; + + /** Logger */ + static protected final Log log = LogFactory.getLog(BeanValidator.class); + + protected static final BeanValidatorScope[] FILTER_SCOPES_EMPTY = + new BeanValidatorScope[0]; + + /** the type of bean to watch */ + protected final Class<B> beanClass; + + /** the validation named context (can be null) */ + protected String contextName; + + /** to chain to a prent validator */ + protected BeanValidator<?> parentValidator; + + /** + * state to indicate that validator has changed since the last time bean was + * setted + */ + protected boolean changed; + + /** state of the validator (is true if no errors of error scope is found) */ + protected boolean valid = true; + + /** bean to be watched */ + protected B bean; + + /** to add and remove PropertyChangeListener on watched beans */ + protected EventSetDescriptor beanEventDescriptor; + + /** list of fields watched by this validator */ + protected Set<BeanValidatorField<B>> fields; + + /** map of conversion errors detected by this validator */ + protected Map<String, String> conversionErrors; + + /** xworks scope validator * */ + protected EnumMap<BeanValidatorScope, XWorkBeanValidator<B>> validators; + + /** filter scopes (if {@code null}, no filter on scopes) */ + protected BeanValidatorScope[] filterScopes; + + /** listener that listens on bean modification */ + protected PropertyChangeListener l; + + /** delegate property change support */ + protected PropertyChangeSupport pcs; + + /** A list of event listeners for this validators */ + protected EventListenerList listenerList = new EventListenerList(); + + public BeanValidator(Class<B> beanClass, + String contextName) { + this(beanClass, + contextName, + BeanValidatorScope.values() + ); + } + + public BeanValidator(Class<B> beanClass, + String contextName, + BeanValidatorScope... filterScopes) { + this.beanClass = beanClass; + if (filterScopes != null && filterScopes.length > 0) { + this.filterScopes = filterScopes; + } + pcs = new PropertyChangeSupport(this); + conversionErrors = new TreeMap<String, String>(); + validators = new EnumMap<BeanValidatorScope, XWorkBeanValidator<B>>( + BeanValidatorScope.class); + + setContextName(contextName); + + l = new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + // chaque modification lance la validation + doValidate(); + } + }; + } + + public Class<B> getBeanClass() { + return beanClass; + } + + public BeanValidator<?> getParentValidator() { + return parentValidator; + } + + public String getContextName() { + return contextName; + } + + public Set<BeanValidatorField<B>> getFields() { + return fields; + } + + public Set<BeanValidatorScope> getScopes() { + return new HashSet<BeanValidatorScope>(validators.keySet()); + } + + /** + * Retourne vrai si l'objet bean a ete modifie depuis le dernier {@link + * #setBean} + * + * @return <code>true</code> if bean was modify since last {@link + * #setBean(Object)} invocation + */ + public boolean isChanged() { + return changed; + } + + public boolean isValid() { + return valid; + } + + public B getBean() { + return bean; + } + + public BeanValidatorField<B> getField(String fieldName) { + for (BeanValidatorField<B> field : fields) { + if (fieldName.equals(field.getName())) { + return field; + } + } + return null; + } + + public boolean hasFatalErrors() { + for (BeanValidatorField<B> field : fields) { + if (field.hasFatalErrors()) { + return true; + } + } + return false; + } + + public boolean hasErrors() { + for (BeanValidatorField<B> field : fields) { + if (field.hasErrors()) { + return true; + } + } + return false; + } + + public boolean hasWarnings() { + for (BeanValidatorField<B> field : fields) { + if (field.hasWarnings()) { + return true; + } + } + return false; + } + + public boolean hasInfos() { + for (BeanValidatorField<B> field : fields) { + if (field.hasInfos()) { + return true; + } + } + return false; + } + + /** + * Test a the validator contains the field given his name + * + * @param fieldName the name of the searched field + * @return <code>true</code> if validator contaisn this field, + * <code>false</code> otherwise + */ + public boolean containsField(String fieldName) { + BeanValidatorField<B> field = getField(fieldName); + return field != null; + } + + public boolean isValid(String fieldName) { + BeanValidatorField<B> field = getField(fieldName); + if (field == null) { + throw new IllegalArgumentException( + "could not find a validator field " + fieldName); + } + return field.isValid(); + } + + /** + * Permet de force la remise a false de l'etat de changement du bean + * + * @param changed flag to force reset of property {@link #changed} + */ + public void setChanged(boolean changed) { + this.changed = changed; + // force the property to be fired (never pass the older value) + pcs.firePropertyChange(CHANGED_PROERTY, null, changed); + } + + public void setValid(boolean valid) { + this.valid = valid; + // force the property to be fired (never pass the older value) + pcs.firePropertyChange(VALID_PROERTY, null, valid); + } + + public void setBean(B bean) { + B oldBean = this.bean; + if (log.isDebugEnabled()) { + log.debug(this + " : " + bean); + } + + // clean conversions of previous bean + conversionErrors.clear(); + + if (oldBean != null) { + try { + EventSetDescriptor descriptor = getBeanEventDescriptor(oldBean); + descriptor.getRemoveListenerMethod().invoke(oldBean, l); + } catch (Exception eee) { + if (log.isInfoEnabled()) { + log.info("Can't register as listener for bean " + beanClass + + " for reason " + eee.getMessage(), eee); + } + } + } + this.bean = bean; + + if (bean == null) { + + // remove all messages for all fields of the validator + + for (BeanValidatorField<B> f : fields) { + + f.updateMessages(this, null, null); + } + + } else { + try { + EventSetDescriptor descriptor = getBeanEventDescriptor(bean); + descriptor.getAddListenerMethod().invoke(bean, l); + } catch (Exception eee) { + if (log.isInfoEnabled()) { + log.info("Can't register as listener for bean " + beanClass + + " for reason " + eee.getMessage(), eee); + } + } + validate(); + } + setChanged(false); + setValid(!hasFatalErrors() && !hasErrors()); + pcs.firePropertyChange(BEAN_PROERTY, oldBean, bean); + } + + public void setContextName(String contextName) { + String oldContextName = this.contextName; + this.contextName = contextName; + // changing contextName could change fields definition + // so dettach bean, must rebuild the fields + if (bean != null) { + setBean(null); + } + // rebuild the fields + initFields(); + pcs.firePropertyChange(CONTEXT_NAME_PROPERTY, + oldContextName, + contextName + ); + } + + /** + * Sets the filter scopes. + * + * @param filterScopes the scopes to used + */ + public void setFilterScopes(BeanValidatorScope... filterScopes) { + this.filterScopes = filterScopes; + // changing contextName could change fields definition + // so dettach bean, must rebuild the fields + if (bean != null) { + setBean(null); + } + // rebuild the fields + initFields(); + } + + public void setParentValidator(BeanValidator<?> parentValidator) { + this.parentValidator = parentValidator; + } + + /** + * Convert a value. + * <p/> + * If an error occurs, then add an error in validator. + * + * @param <T> the type of conversion + * @param fieldName the name of the bean property + * @param value the value to convert + * @param valueClass the type of converted value + * @return the converted value, or null if conversion was not ok + */ + @SuppressWarnings({"unchecked"}) + public <T> T convert(String fieldName, String value, Class<T> valueClass) { + if (fieldName == null) { + throw new IllegalArgumentException("fieldName can not be null"); + } + if (valueClass == null) { + throw new IllegalArgumentException("valueClass can not be null"); + } + + // on ne convertit pas si il y a un bean et que le resultat de la + // validation pourra etre affiche quelque part + if (!canValidate() || value == null) { + return null; + } + + // remove the previous conversion error for the field + conversionErrors.remove(fieldName); + + T result; + try { + Converter converter = ConverterUtil.getConverter(valueClass); + if (converter == null) { + throw new RuntimeException( + "could not find converter for the type " + valueClass); + } + result = (T) converter.convert(valueClass, value); + /* Why this test ? if (result != null && !value.equals(result.toString())) { + conversionErrors.put(fieldName, "error.convertor." + Introspector.decapitalize(valueClass.getSimpleName())); + result = null; + validate(); + }*/ + } catch (ConversionException e) { + // get + String s = Introspector.decapitalize(valueClass.getSimpleName()); + conversionErrors.put(fieldName, "error.convertor." + s); + result = null; + validate(); + } + return result; + } + + /** + * Methode pour forcer la revalidation d'un bean en mettant a jour les etats + * internes. + * <p/> + * La méthode appelle {@link #validate()} puis met à jour les etats internes + * {@link #valid} et {@link #changed}. + * + * @since 1.5 + */ + public void doValidate() { + validate(); + setValid(!hasFatalErrors() && !hasErrors()); + setChanged(true); + } + + /** + * il faut eviter le code re-intrant (durant une validation, une autre est + * demandee). Pour cela on fait la validation dans un thread, et tant que la + * premiere validation n'est pas fini, on ne repond pas aux solicitations. + * Cette method est public pour permettre de force une validation par + * programmation, ce qui est utile par exemple si le bean ne supporte pas + * les {@link PropertyChangeListener} + * <p/> + * <b>Note:</b> la methode est protected et on utilise la methode + * {@link #doValidate()} car la méthode ne modifie pas les etats + * internes et cela en rend son utilisation delicate (le validateur entre + * dans un etat incoherent par rapport aux messages envoyés). + */ + protected void validate() { + + // on ne valide que si il y a un bean et que le resultat de la validation + // pourra etre affiche quelque part + if (!canValidate()) { + return; + } + + for (BeanValidatorScope scope : validators.keySet()) { + + XWorkBeanValidator<B> validator = validators.get(scope); + + Map<String, List<String>> newMessages = validator.validate(bean); + + if (scope == BeanValidatorScope.ERROR) { + // treate conversion errors + // reinject them + for (Entry<String, String> entry : conversionErrors.entrySet()) { + // remove from validation, errors occurs on this field + List<String> errors = newMessages.get(entry.getKey()); + String conversionError = entry.getValue(); + if (errors != null) { + errors.clear(); + errors.add(conversionError); + } else { + errors = Collections.singletonList(conversionError); + if (XWorkBeanValidator.EMPTY_RESULT.equals(newMessages)) { + newMessages = new HashMap<String, List<String>>(); + } + // add the concrete conversion error + newMessages.put(entry.getKey(), errors); + } + } + } + + // for each field, update his list of messages + for (BeanValidatorField<B> field : fields) { + List<String> messagesForField = newMessages.get(field.getName()); + if (field.getScopes().contains(scope)) { + field.updateMessages(this, scope, messagesForField); + } + } + } + + if (parentValidator != null) { + // chained validation + // the parent validator should not be changed from this validation + boolean wasModified = parentValidator.isChanged(); + parentValidator.doValidate(); + if (!wasModified) { + // push back old state + parentValidator.setChanged(false); + } + } + + } + + @Override + public String toString() { + return super.toString() + "<beanClass:" + beanClass + + ", contextName:" + contextName + ">"; + } + + public void addBeanValidatorListener(BeanValidatorListener listener) { + listenerList.add(BeanValidatorListener.class, listener); + } + + public void removeBeanValidatorListener(BeanValidatorListener listener) { + listenerList.remove(BeanValidatorListener.class, listener); + } + + public BeanValidatorListener[] getBeanValidatorListeners() { + return listenerList.getListeners(BeanValidatorListener.class); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + pcs.addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + pcs.addPropertyChangeListener(propertyName, listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + pcs.removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + pcs.removePropertyChangeListener(propertyName, listener); + } + + /** + * @return <code>true</code> if validation is enabled, <code>false</code> + * otherwise. + */ + protected boolean canValidate() { + return !(bean == null || fields.isEmpty()); + } + + protected void fireFieldChanged(BeanValidatorField<B> field, + BeanValidatorScope scope, + String[] toAdd, + String[] toDelete) { + + BeanValidatorEvent evt = new BeanValidatorEvent( + this, + field, + scope, + toAdd, + toDelete + ); + + for (BeanValidatorListener listener : + listenerList.getListeners(BeanValidatorListener.class)) { + listener.onFieldChanged(evt); + } + } + + protected void initFields() { + + Set<String> detectedFieldNames = new HashSet<String>(); + EnumMap<BeanValidatorScope, Set<String>> tmp; + tmp = new EnumMap<BeanValidatorScope, Set<String>>( + BeanValidatorScope.class + ); + Set<BeanValidatorField<B>> detectedFields = + new HashSet<BeanValidatorField<B>>(); + + validators.clear(); + + BeanValidatorScope[] scopeUniverse; + if (filterScopes == null) { + // use all scopes + scopeUniverse = BeanValidatorScope.values(); + } else { + // use customized scopes + scopeUniverse = filterScopes; + } + + for (BeanValidatorScope scope : scopeUniverse) { + String scopeContext = + (contextName == null ? "" : contextName + "-") + + scope.name().toLowerCase(); + + XWorkBeanValidator<B> newValidator = + new XWorkBeanValidator<B>(beanClass, scopeContext, false); + Set<String> fieldNames = newValidator.getFieldNames(); + if (log.isDebugEnabled()) { + log.debug("detected validators for scope " + scopeContext + + " : " + fieldNames); + } + if (!fieldNames.isEmpty()) { + // fields detected in this validator, keep it + validators.put(scope, newValidator); + detectedFieldNames.addAll(fieldNames); + tmp.put(scope, fieldNames); + } + } + + List<BeanValidatorScope> scopes = new ArrayList<BeanValidatorScope>(); + for (String fieldName : detectedFieldNames) { + scopes.clear(); + // detect scopes for the field + for (BeanValidatorScope scope : scopeUniverse) { + if (tmp.containsKey(scope) && + tmp.get(scope).contains(fieldName)) { + scopes.add(scope); + } + } + BeanValidatorField<B> f = + new BeanValidatorField<B>(beanClass, fieldName, scopes); + detectedFields.add(f); + } + tmp.clear(); + detectedFieldNames.clear(); + + fields = Collections.unmodifiableSet(detectedFields); + } + + protected EventSetDescriptor getBeanEventDescriptor(B bean) { + if (beanEventDescriptor == null) { + // check that the bean is listenable, otherwise, can't use the + // validator on it + beanEventDescriptor = + BeanValidatorUtil.getPropertyChangeListenerDescriptor( + bean.getClass() + ); + } + return beanEventDescriptor; + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorDetector.java (from rev 2013, trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorDetector.java) =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorDetector.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorDetector.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,342 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.legacy; + +import org.apache.commons.beanutils.ConstructorUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.File; +import java.io.FilenameFilter; +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Un detecteur de validateurs pour un liste de classes données et un répertoire + * où chercher les fichiers de validation. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.6.0 + */ +public class BeanValidatorDetector { + + /** Logger */ + private static final Log log = + LogFactory.getLog(BeanValidatorDetector.class); + + public SortedSet<BeanValidator<?>> detect(File sourceRoot, + Class<?>... types) { + SortedSet<BeanValidator<?>> result = + detect(BeanValidator.class, sourceRoot, null, types); + return result; + } + + public SortedSet<BeanValidator<?>> detect(Class<?> validatorClass, + File sourceRoot, + Pattern contextFilter, + Class<?>... types) { + SortedSet<BeanValidator<?>> result = detect(validatorClass, + sourceRoot, + contextFilter, + null, + types); + return result; + } + + public SortedSet<BeanValidator<?>> detect(Class<?> validatorClass, + File sourceRoot, + Pattern contextFilter, + BeanValidatorScope[] scopes, + Class<?>... types) { + + SortedSet<BeanValidator<?>> result = + new TreeSet<BeanValidator<?>>(new BeanValidatorComparator()); + + for (Class<?> c : types) { + File dir = getClassDir(sourceRoot, c); + if (!dir.exists()) { + + // pas de repertoire adequate + if (log.isDebugEnabled()) { + log.debug("skip non existing directory " + dir); + } + continue; + } + String[] contexts = getContexts(c, dir); + if (log.isDebugEnabled()) { + log.debug("contexts : " + Arrays.toString(contexts)); + } + + if (contexts.length > 0) { + String[] realContexts = getContextsWithoutScopes(contexts); + + if (log.isDebugEnabled()) { + log.debug("realContexts : " + + Arrays.toString(realContexts)); + } + + if (contextFilter != null) { + + // filter contexts + realContexts = getFilterContexts(contextFilter, + realContexts + ); + if (log.isDebugEnabled()) { + log.debug("filterContexts : " + + Arrays.toString(realContexts)); + } + } + + for (String context : realContexts) { + + // on cherche le validateur + BeanValidator<?> validator = getValidator( + validatorClass, + c, + context.isEmpty() ? null : context, + scopes + ); + if (validator != null) { + // on enregistre le validateur + result.add(validator); + } + } + } + } + return result; + } + + /** + * Pour un context et un type d'entité donné, instancie un validateur et + * test si ce validateur est utilisable (i.e qu'il admet des champs à + * valider). + * <p/> + * Si aucun champ n'est trouvé dans le validateur, alors on retourne null. + * + * @param <B> le type du bean + * @param validatorClass le type de validateur a instancie + * @param klass le type du bean + * @param context le context du validateur + * @param scopes les scopes a utiliser (si {@code null} alors pas de + * filtre sur les scopes) + * @return le validateur initialisé, ou <code>null</code> si aucun scope + * détecté dans le validateur. + */ + protected <B> BeanValidator<B> getValidator(Class<?> validatorClass, + Class<B> klass, + String context, + BeanValidatorScope... scopes) { + + BeanValidator<B> valitator; + valitator = createValidator(validatorClass, klass, context, scopes); + + Set<BeanValidatorScope> resultScopes = valitator.getScopes(); + if (resultScopes.isEmpty()) { + valitator = null; + if (log.isDebugEnabled()) { + log.debug(klass + " : validator skip (no scopes detected)"); + } + } else { + if (log.isDebugEnabled()) { + log.debug(klass + " : keep validator " + valitator); + } + } + return valitator; + } + + protected <B> BeanValidator<B> createValidator( + Class<?> validatorClass, + Class<B> klass, + String context, + BeanValidatorScope[] scopes) { + BeanValidator<B> valitator; + Constructor<?> con; + try { + con = ConstructorUtils.getAccessibleConstructor( + validatorClass, + new Class<?>[]{ + Class.class, + String.class, + BeanValidatorScope[].class + } + ); + if (con != null) { + + valitator = (BeanValidator<B>) con.newInstance( + klass, + context, scopes + ); + + } else { + con = ConstructorUtils.getAccessibleConstructor( + validatorClass, + new Class<?>[]{ + Class.class, + String.class, + BeanValidatorScope[].class + } + ); + + if (con == null) { + throw new IllegalStateException( + "could not find a constructor with " + + "(Class.class, String) or " + + "(Class,String BeanValidatorScope[])"); + } + + valitator = (BeanValidator<B>) con.newInstance( + klass, + context + ); + if (scopes != null && scopes.length > 0) { + valitator.setFilterScopes(scopes); + } + } + + } catch (Exception ex) { + throw new RuntimeException( + "could not instanciate validator " + validatorClass + + " for reason " + ex.getMessage(), ex); + } + return valitator; + } + + protected File getClassDir(File sourceRoot, Class<?> clazz) { + String path = clazz.getPackage().getName(); + path = path.replaceAll("\\.", File.separator); + File dir = new File(sourceRoot, path); + return dir; + } + + protected String[] getContexts(Class<?> clazz, File dir) { + Set<String> result = new TreeSet<String>(); + ValidatorFilenameFilter filter = new ValidatorFilenameFilter(clazz); + if (log.isDebugEnabled()) { + log.debug("dir : " + dir); + } + String[] files = dir.list(filter); + for (String file : files) { + if (log.isDebugEnabled()) { + log.debug("file " + file); + } + String context = file.substring( + filter.prefix.length(), + file.length() - ValidatorFilenameFilter.SUFFIX.length() + ); + if (log.isDebugEnabled()) { + log.debug("detect " + clazz.getSimpleName() + + " context [" + context + "]"); + } + result.add(context); + } + return result.toArray(new String[result.size()]); + } + + protected String[] getContextsWithoutScopes(String[] contexts) { + Set<String> result = new TreeSet<String>(); + BeanValidatorScope[] scopes = BeanValidatorScope.values(); + for (String context : contexts) { + for (BeanValidatorScope scope : scopes) { + String scopeName = scope.name().toLowerCase(); + if (!context.endsWith(scopeName)) { + // pas concerne par ce scope + continue; + } + if (log.isDebugEnabled()) { + log.debug("detect context : " + context); + } + String realContext = context.substring( + 0, + context.length() - scopeName.length() + ); + if (realContext.endsWith("-")) { + realContext = realContext.substring( + 0, + realContext.length() - 1 + ); + } + result.add(realContext); + } + } + return result.toArray(new String[result.size()]); + } + + protected String[] getFilterContexts(Pattern contextFilter, + String[] realContexts) { + List<String> result = new ArrayList<String>(); + for (String c : realContexts) { + Matcher m = contextFilter.matcher(c); + if (m.matches()) { + result.add(c); + } + } + return result.toArray(new String[result.size()]); + } + + protected static class ValidatorFilenameFilter implements FilenameFilter { + + protected static final String SUFFIX = "-validation.xml"; + + protected Class<?> clazz; + + protected String prefix; + + public ValidatorFilenameFilter(Class<?> clazz) { + this.clazz = clazz; + prefix = clazz.getSimpleName() + "-"; + } + + @Override + public boolean accept(File dir, String name) { + boolean result = name.endsWith(SUFFIX); + if (result) { + result = name.startsWith(prefix); + } + return result; + } + } + + protected static class BeanValidatorComparator implements Comparator<BeanValidator<?>> { + + @Override + public int compare(BeanValidator<?> o1, BeanValidator<?> o2) { + String contextName1 = + o1.getBeanClass().getSimpleName() + "-" + + (o1.getContextName() == null ? "" : o1.getContextName()); + String contextName2 = + o2.getBeanClass().getSimpleName() + "-" + + (o2.getContextName() == null ? "" : o2.getContextName()); + return contextName1.compareTo(contextName2); + } + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorDetector.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorEvent.java (from rev 2013, trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorEvent.java) =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorEvent.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorEvent.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,86 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.legacy; + +import java.util.EventObject; + +/** + * The definition of an event on {@link BeanValidatorListener} + * to be fired by a {@link BeanValidator}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.3 + */ +public class BeanValidatorEvent extends EventObject { + + private static final long serialVersionUID = 1L; + + /** the field impacted by the validator */ + protected BeanValidatorField<?> field; + + /** the scope impacted by the event */ + protected BeanValidatorScope scope; + + protected String[] messagestoAdd; + + protected String[] messagestoDelete; + + public BeanValidatorEvent(BeanValidator<?> source, + BeanValidatorField<?> field, + BeanValidatorScope scope, + String[] messagestoAdd, + String[] messagestoDelete) { + super(source); + this.field = field; + this.scope = scope; + this.messagestoAdd = messagestoAdd; + this.messagestoDelete = messagestoDelete; + } + + @Override + public BeanValidator<?> getSource() { + return (BeanValidator<?>) super.getSource(); + } + + public String getFieldName() { + return field.getName(); + } + + public String[] getMessagesToAdd() { + return messagestoAdd; + } + + public String[] getMessagesToDelete() { + return messagestoDelete; + } + + public BeanValidatorScope getScope() { + return scope; + } + + public BeanValidatorField<?> getField() { + return field; + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorEvent.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorField.java (from rev 2013, trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorField.java) =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorField.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorField.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,286 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.legacy; + +import com.opensymphony.xwork2.validator.FieldValidator; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.StringTokenizer; + +import static org.nuiton.i18n.I18n._; + +/** + * Definition of a field to be handled in a {@link BeanValidator}. + * <p/> + * A such class is only registred in {@link BeanValidator } when the field of + * the bean was found in validator xml configuration file for a {@link + * FieldValidator} only. + * <p/> + * This class use properties {@link #beanClass}, {@link #name} to define his + * naturel order. + * + * @author tchemit <chemit@codelutin.com> + * @param <B> the type of the bean handled by the validator and this field of + * validation. + * @since 1.3 + */ +public class BeanValidatorField<B> implements Serializable { + + private static final long serialVersionUID = 1L; + + /** the class of bean */ + protected final Class<B> beanClass; + + /** name of field in bean */ + protected final String name; + + protected EnumMap<BeanValidatorScope, Set<String>> messages; + + public BeanValidatorField(Class<B> beanClass, + String name, + List<BeanValidatorScope> scopes) { + this.beanClass = beanClass; + this.name = name; + messages = new EnumMap<BeanValidatorScope, Set<String>>( + BeanValidatorScope.class + ); + for (BeanValidatorScope scope : scopes) { + messages.put(scope, new HashSet<String>()); + } + } + + public String getName() { + return name; + } + + public Class<B> getBeanClass() { + return beanClass; + } + + /** + * @return {@code true} if this field is valid : no fatal errors and no + * errors), {@code false} otherwise. + */ + public boolean isValid() { + return !hasFatalErrors() && !hasErrors(); + } + + public BeanValidatorScope getScope() { + if (hasErrors()) { + return BeanValidatorScope.ERROR; + } + if (hasWarnings()) { + return BeanValidatorScope.WARNING; + } + if (hasInfos()) { + return BeanValidatorScope.INFO; + } + return null; + } + + public Set<BeanValidatorScope> getScopes() { + return messages.keySet(); + } + + public boolean hasFatalErrors() { + return hasMessages(BeanValidatorScope.FATAL); + } + + public boolean hasErrors() { + return hasMessages(BeanValidatorScope.ERROR); + } + + public boolean hasWarnings() { + return hasMessages(BeanValidatorScope.WARNING); + } + + public boolean hasInfos() { + return hasMessages(BeanValidatorScope.INFO); + } + + public Set<String> getFatalErrors() { + return getMessages(BeanValidatorScope.FATAL); + } + + public Set<String> getErrors() { + return getMessages(BeanValidatorScope.ERROR); + } + + public Set<String> getWarnings() { + return getMessages(BeanValidatorScope.WARNING); + } + + public Set<String> getInfos() { + return getMessages(BeanValidatorScope.INFO); + } + + public boolean hasMessages(BeanValidatorScope scope) { + return messages.containsKey(scope) && !getMessages(scope).isEmpty(); + } + + public Set<String> getMessages(BeanValidatorScope scope) { + return messages.get(scope); + } + + public void updateMessages(BeanValidator<B> validator, + BeanValidatorScope scope, + List<String> messages) { + + if (scope == null) { + + // special case to reset all messages from all scopes + + for (BeanValidatorScope s : getScopes()) { + + clearMessages(s, validator); + } + return; + } + + if (!this.messages.containsKey(scope)) { + throw new IllegalArgumentException( + "the scope " + scope + " was not registred for " + this); + } + + if (messages == null || messages.isEmpty()) { + + // no incoming message for this scope + + clearMessages(scope, validator); + return; + } + + // build the diff of messages (the one to delete, the one to add) + + boolean hasChanged = false; + + Set<String> currentMessages = getMessages(scope); + + // detect messages to delete + Set<String> toDelete = new HashSet<String>(currentMessages); + toDelete.removeAll(messages); + + if (!toDelete.isEmpty()) { + // apply delete + currentMessages.removeAll(toDelete); + hasChanged = true; + } + + // detect messages to add + Set<String> toAdd = new HashSet<String>(messages); + toAdd.removeAll(currentMessages); + + if (!toAdd.isEmpty()) { + // apply add + currentMessages.addAll(toAdd); + hasChanged = true; + } + + if (hasChanged) { + + // something has changed, fire notifications + String[] del = toDelete.toArray(new String[toDelete.size()]); + String[] add = toAdd.toArray(new String[toAdd.size()]); + + validator.fireFieldChanged(this, scope, add, del); + } + toAdd.clear(); + toDelete.clear(); + + } + + public String getI18nError(String error) { + String text; + if (!error.contains("##")) { + text = _(error); + } else { + StringTokenizer stk = new StringTokenizer(error, "##"); + String errorName = stk.nextToken(); + List<String> args = new ArrayList<String>(); + while (stk.hasMoreTokens()) { + args.add(stk.nextToken()); + } + text = _(errorName, args.toArray()); + } + return text; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof BeanValidatorField<?>)) { + return false; + } + + BeanValidatorField<?> that = (BeanValidatorField<?>) o; + return beanClass.equals(that.beanClass) && name.equals(that.name); + } + + @Override + public int hashCode() { + int result = beanClass.hashCode(); + result = 31 * result + name.hashCode(); + return result; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("<").append(super.toString()); + sb.append(" beanClass:").append(beanClass); + sb.append(", name:").append(name); + sb.append(", scopes:"); + sb.append(messages == null ? "[]" : messages.keySet()); + sb.append(", scope:").append(getScope()); + //sb.append(", errors:").append(errors); + sb.append('>'); + return sb.toString(); + } + + protected void clearMessages(BeanValidatorScope scope, + BeanValidator<B> validator) { + // remove all messages + Set<String> toDelete = getMessages(scope); + + if (!toDelete.isEmpty()) { + + // there is some messages to delete + String[] toDel = toDelete.toArray(new String[toDelete.size()]); + + // apply deletion + toDelete.clear(); + + // fire + validator.fireFieldChanged(this, scope, null, toDel); + } + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorField.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorListener.java (from rev 2013, trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorListener.java) =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorListener.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorListener.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,43 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.legacy; + +import java.util.EventListener; + +/** + * The listener contract to be used on {@link BeanValidator} + * + * @author tchemit <chemit@codelutin.com> + * @since 1.3 + */ +public interface BeanValidatorListener extends EventListener { + + /** + * Invoked when a validator detects some changes on a field. + * + * @param event the event + */ + void onFieldChanged(BeanValidatorEvent event); +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorListener.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorMessage.java (from rev 2013, trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorMessage.java) =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorMessage.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorMessage.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,118 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.legacy; + +/** + * The object to box a validation message. + * + * @author tchemit <chemit@codelutin.com> + * @param <E> type of message (use for override {@link #compareTo(Object)} + * method. + * @since 1.3 + */ +public class BeanValidatorMessage<E extends BeanValidatorMessage<?>> implements Comparable<E> { + + /** the validator that produce the message */ + protected BeanValidator<?> validator; + + /** the field that produce the message */ + protected BeanValidatorField<?> field; + + /** the label of the message (to be displayed somewhere) */ + protected String message; + + /** the scope of the message */ + protected BeanValidatorScope scope; + + public BeanValidatorMessage(BeanValidator<?> validator, + BeanValidatorField<?> field, + String message, + BeanValidatorScope scope) { + this.field = field; + this.validator = validator; + this.message = message == null ? null : message.trim(); + this.scope = scope; + } + + public BeanValidator<?> getValidator() { + return validator; + } + + public BeanValidatorField<?> getField() { + return field; + } + + public BeanValidatorScope getScope() { + return scope; + } + + public String getMessage() { + return message; + } + + @Override + public int compareTo(E o) { + // sort on scope + int result = getScope().compareTo(o.getScope()); + if (result == 0) { + // sort on field name + result = field.getName().compareTo(o.field.getName()); + if (result == 0) { + // sort on message + result = message.compareTo(o.message); + } + } + return result; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + BeanValidatorMessage<?> that = (BeanValidatorMessage<?>) o; + + return field.equals(that.field) && + message.equals(that.message) && + scope == that.scope; + } + + @Override + public int hashCode() { + int result = field.hashCode(); + result = 31 * result + message.hashCode(); + result = 31 * result + scope.hashCode(); + return result; + } + + @Override + public String toString() { + return scope + " - " + field.getI18nError(message); + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorMessage.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorScope.java (from rev 2013, trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorScope.java) =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorScope.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorScope.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,79 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.legacy; + +import static org.nuiton.i18n.I18n.n_; + +/** + * The differents levels of messages in validation process. + * <p/> + * The order of the enum defines the severity of validation. + * <p/> + * Always begin with fatal, then error, then if no error found, try warning, then info... + * + * @author tchemit <chemit@codelutin.com> + */ +public enum BeanValidatorScope { + + /** + * the fatal error scope level. + * <p/> + * When a message of a such scope is found on a validator, then the + * validator is invalid and modified. + * @since 2.2.4 + */ + FATAL(n_("validator.scope.fatal.label")), + /** + * the error scope level. + * <p/> + * When a message of a such scope is found on a validator, then the + * validator is invalid and modified. + */ + ERROR(n_("validator.scope.error.label")), + /** + * the warning scope level. + * <p/> + * When a message of a such scope is found on a validator, then the + * validator is still valid but modified. + */ + WARNING(n_("validator.scope.warning.label")), + /** + * the information scope level. + * <p/> + * When a message of a sucg scope is found on a validator, then the + * validator is still valid and not modified. + */ + INFO(n_("validator.scope.info.label")); + + private final String label; + + BeanValidatorScope(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorScope.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorUtil.java (from rev 2013, trunk/nuiton-validator/src/main/java/org/nuiton/validator/BeanValidatorUtil.java) =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorUtil.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorUtil.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,196 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.legacy; + +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.ConfigurationManager; +import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.util.ValueStackFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.beans.BeanInfo; +import java.beans.EventSetDescriptor; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.List; + +/** + * The helper class for validation module. + * + * @author tchemit <chemit@codelutin.com> + */ +public class BeanValidatorUtil { + + /** Logger */ + static private final Log log = LogFactory.getLog(BeanValidatorUtil.class); + + /** + * a shared value stack to allow external operations on it (for example add + * some datas in stack to be usedby validators + */ + static private ValueStack sharedValueStack; + + public static ValueStack getSharedValueStack() { + if (sharedValueStack == null) { + + // init context + ConfigurationManager confManager = new ConfigurationManager(); + Configuration conf = confManager.getConfiguration(); + + Container container = conf.getContainer(); + ValueStackFactory stackFactory = container.getInstance( + ValueStackFactory.class); + sharedValueStack = stackFactory.createValueStack(); + if (log.isDebugEnabled()) { + log.debug("init shared value stack " + sharedValueStack); + } + } + return sharedValueStack; + } + + protected BeanValidatorUtil() { + // no instance + } + + /** + * Convert a value to a given type and then if was succesffull try to set it + * in the bean manage by the validator. + * + * @param validator validator to be involved + * @param fieldName the name of the bean property + * @param value the actual value to convert + * @param valueClass the type of the conversion + */ + public static void convert(BeanValidator<?> validator, + String fieldName, + String value, + Class<?> valueClass) { + + Object result = validator.convert(fieldName, value, valueClass); + if (result != null) { + try { + BeanInfo info = + Introspector.getBeanInfo(validator.getBean().getClass()); + + for (PropertyDescriptor descriptor : + info.getPropertyDescriptors()) { + if (fieldName.equals(descriptor.getName()) && + descriptor.getWriteMethod() != null) { + + descriptor.getWriteMethod().invoke( + validator.getBean(), + result + ); + break; + } + } + } catch (Exception e) { + if (log.isErrorEnabled()) { + log.error("could not obtain beanInfo for " + + valueClass.getClass() + ", reason : " + + e.getMessage(), e); + } + } + } else { + //fixme : conversion failed, we should be able to notify ui + // that values has changed ? + // otherwise, bean value has not changed,... + } + } + + public static EventSetDescriptor getPropertyChangeListenerDescriptor(Class<?> beanClass) { + try { + // check that the bean is listenable, otherwise, can't use + // the validator on it + BeanInfo infos = Introspector.getBeanInfo(beanClass); + EventSetDescriptor[] events = infos.getEventSetDescriptors(); + for (EventSetDescriptor event : events) { + if ("propertyChange".equals(event.getName())) { + + if (event.getAddListenerMethod() == null) { + // no property event listener, so can not use the validator + throw new IllegalStateException( + "no addPropertyChangeListener method found " + + "for " + beanClass); + } + if (event.getRemoveListenerMethod() == null) { + // no property event listener, so can not use the validator + throw new IllegalStateException( + "no removePropertyChangeListener method found" + + " for " + beanClass); + } + return event; + } + } + + // no property event listener, so can not use the validator + throw new IllegalStateException( + "no PropertyChangeListener access method found for " + + beanClass); + } catch (IntrospectionException ex) { + throw new IllegalStateException( + "could not acquire PropertyChangeListener bean info for " + + beanClass + " for reason " + ex.getMessage(), ex); + } + } + + public static EnumSet<BeanValidatorScope> getScopes( + List<BeanValidatorMessage<?>> messages) { + EnumSet<BeanValidatorScope> result = + EnumSet.noneOf(BeanValidatorScope.class); + for (BeanValidatorMessage<?> m : messages) { + result.add(m.getScope()); + } + return result; + } + + public static EnumMap<BeanValidatorScope, Integer> getScopesCount( + List<BeanValidatorMessage<?>> messages) { + EnumMap<BeanValidatorScope, Integer> result = + new EnumMap<BeanValidatorScope, Integer>(BeanValidatorScope.class); + for (BeanValidatorScope s : BeanValidatorScope.values()) { + result.put(s, 0); + } + for (BeanValidatorMessage<?> m : messages) { + + BeanValidatorScope scope = m.getScope(); + + result.put(scope, result.get(scope) + 1); + } + + for (BeanValidatorScope s : BeanValidatorScope.values()) { + if (result.get(s) == 0) { + result.remove(s); + } + } + return result; + } + +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/BeanValidatorUtil.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/ValidatorsMap.java (from rev 2013, trunk/nuiton-validator/src/main/java/org/nuiton/validator/ValidatorsMap.java) =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/ValidatorsMap.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/ValidatorsMap.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,126 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.legacy; + +import java.util.Collection; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * Un dictionnaire de validateurs ordonnees par le type de leur bean. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.0.1 + */ +public class ValidatorsMap implements Map<Class<?>, BeanValidator<?>> { + + protected final Map<Class<?>, BeanValidator<?>> delegate; + + public ValidatorsMap() { + delegate = new HashMap<Class<?>, BeanValidator<?>>(); + } + + public BeanValidatorScope[] getScopes() { + EnumSet<BeanValidatorScope> result = + EnumSet.noneOf(BeanValidatorScope.class); + for (BeanValidator<?> b : values()) { + result.addAll(b.getScopes()); + } + return result.toArray(new BeanValidatorScope[result.size()]); + } + +// public <X> BeanValidator<X> getValidator(X klass) { +// BeanValidator<X> beanValidator = (BeanValidator<X>) get(klass.getClass()); +// return beanValidator; +// } + + public <X> BeanValidator<X> getValidator(Class<X> klass) { + BeanValidator<X> beanValidator = (BeanValidator<X>) get(klass); + return beanValidator; + } + + @Override + public int size() { + return delegate.size(); + } + + @Override + public boolean isEmpty() { + return delegate.isEmpty(); + } + + @Override + public boolean containsKey(Object key) { + return delegate.containsKey(key); + } + + @Override + public boolean containsValue(Object value) { + return delegate.containsValue(value); + } + + @Override + public BeanValidator<?> get(Object key) { + return delegate.get(key); + } + + @Override + public BeanValidator<?> put(Class<?> key, BeanValidator<?> value) { + return delegate.put(key, value); + } + + @Override + public BeanValidator<?> remove(Object key) { + return delegate.remove(key); + } + + @Override + public void putAll(Map<? extends Class<?>, ? extends BeanValidator<?>> m) { + delegate.putAll(m); + } + + @Override + public void clear() { + delegate.clear(); + } + + @Override + public Set<Class<?>> keySet() { + return delegate.keySet(); + } + + @Override + public Collection<BeanValidator<?>> values() { + return delegate.values(); + } + + @Override + public Set<Entry<Class<?>, BeanValidator<?>>> entrySet() { + return delegate.entrySet(); + } + +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/ValidatorsMap.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/XWorkBeanValidator.java (from rev 2013, trunk/nuiton-validator/src/main/java/org/nuiton/validator/XWorkBeanValidator.java) =================================================================== --- trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/XWorkBeanValidator.java (rev 0) +++ trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/XWorkBeanValidator.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,324 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.legacy; + +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ValidationAwareSupport; +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.ConfigurationManager; +import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.util.ValueStackFactory; +import com.opensymphony.xwork2.validator.ActionValidatorManager; +import com.opensymphony.xwork2.validator.DelegatingValidatorContext; +import com.opensymphony.xwork2.validator.FieldValidator; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.Validator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * A customized validator for a given bean. + * <p/> + * Use the method {@link #validate(Object)} to obtain the messages detected by + * the validator for the given bean. + * + * @author tchemit <chemit@codelutin.com> + * @param <B> type of the bean to validate. + * @since 1.3 + */ +public class XWorkBeanValidator<B> { + + /** Logger */ + private static final Log log = LogFactory.getLog(XWorkBeanValidator.class); + + protected final static Map<String, List<String>> EMPTY_RESULT = + Collections.unmodifiableMap(new HashMap<String, List<String>>()); + + /** the type of bean to validate */ + protected final Class<B> beanClass; + + /** the validation named context (can be null) */ + protected String contextName; + + /** the list of field names detected for this validator */ + protected Set<String> fieldNames; + + /** a flag to include or not the default context validators */ + protected boolean includeDefaultContext; + + // -- + // XWorks fields + // -- + + protected ValidationAwareSupport validationSupport; + + protected DelegatingValidatorContext validationContext; + + protected ActionValidatorManager validator; + + protected ActionContext context; + + public XWorkBeanValidator(Class<B> beanClass, String contextName) { + this(beanClass, + contextName, + true, + BeanValidatorUtil.getSharedValueStack() + ); + } + + public XWorkBeanValidator(Class<B> beanClass, + String contextName, + ValueStack vs) { + this(beanClass, contextName, true, vs); + } + + public XWorkBeanValidator(Class<B> beanClass, + String contextName, + boolean includeDefaultContext) { + this(beanClass, + contextName, + includeDefaultContext, + BeanValidatorUtil.getSharedValueStack() + ); + } + + public XWorkBeanValidator(Class<B> beanClass, + String contextName, + boolean includeDefaultContext, + ValueStack vs) { + + this.beanClass = beanClass; + this.includeDefaultContext = includeDefaultContext; + validationSupport = new ValidationAwareSupport(); + validationContext = new DelegatingValidatorContext(validationSupport); + + if (vs == null) { + // create a standalone value stack + ConfigurationManager confManager = new ConfigurationManager(); + Configuration conf = confManager.getConfiguration(); + Container container = conf.getContainer(); + ValueStackFactory stackFactory = + container.getInstance(ValueStackFactory.class); + vs = stackFactory.createValueStack(); + if (log.isDebugEnabled()) { + log.debug("create a standalone value stack " + vs); + } + } else { + if (log.isDebugEnabled()) { + log.debug("use given value stack " + vs); + } + } + + context = new ActionContext(vs.getContext()); + ActionContext.setContext(context); + + // init validator + Container container = context.getContainer(); + validator = container.getInstance(ActionValidatorManager.class, + "no-annotations" + ); + + // init context + setContextName(contextName); + } + + public boolean isIncludeDefaultContext() { + return includeDefaultContext; + } + + public Class<B> getBeanClass() { + return beanClass; + } + + public String getContextName() { + return contextName; + } + + public Set<String> getFieldNames() { + return fieldNames; + } + + public ActionValidatorManager getValidator() { + return validator; + } + + /** + * Test a the validator contains the field given his name + * + * @param fieldName the name of the searched field + * @return <code>true</code> if validator contaisn this field, + * <code>false</code> otherwise + */ + public boolean containsField(String fieldName) { + return fieldNames.contains(fieldName); + } + + public void setIncludeDefaultContext(boolean includeDefaultContext) { + this.includeDefaultContext = includeDefaultContext; + if (contextName != null) { + // reload context + setContextName(contextName); + } + } + + public void setContextName(String contextName) { + this.contextName = contextName; + // changing contextName may change fields definition + // so reload fields + initFields(); + } + + /** + * Valide le bean donné et retourne les messages produits. + * + * @param bean le bean a valider (il doit etre non null) + * @return le dictionnaire des messages produits par la validation indexées + * par le nom du champs du bean impacté. + */ + public Map<String, List<String>> validate(B bean) { + + if (bean == null) { + throw new NullPointerException( + "bean can not be null in method validate"); + } + + Map<String, List<String>> result = EMPTY_RESULT; + + // on lance la validation uniquement si des champs sont a valider + if (!fieldNames.isEmpty()) { + + try { + + //TC - 20081024 : since context is in a ThreadLocal variable, + // we must do the check + if (ActionContext.getContext() == null) { + ActionContext.setContext(context); + } + + validator.validate(bean, contextName, validationContext); + + if (log.isTraceEnabled()) { + log.trace("Action errors: " + + validationContext.getActionErrors()); + log.trace("Action messages: " + + validationContext.getActionMessages()); + log.trace("Field errors: " + + validationContext.getFieldErrors()); + } + + if (log.isDebugEnabled()) { + log.debug(this + " : " + + validationContext.getFieldErrors()); + } + + // retreave errors by field + if (validationContext.hasFieldErrors()) { + Map<?, ?> messages = validationContext.getFieldErrors(); + result = new HashMap<String, List<String>>(messages.size()); + for (Object fieldName : messages.keySet()) { + Collection<?> c = + (Collection<?>) messages.get(fieldName); + List<String> mm = new ArrayList<String>(c.size()); + for (Object message : c) { + // tchemit 2010-08-28 : trim the incoming message + // (I18n will not translate it otherwise) + String messageStr = message == null ? "" : message + ""; + mm.add(messageStr.trim()); + } + result.put(fieldName + "", mm); + } + } + + } catch (ValidationException eee) { + if (log.isWarnEnabled()) { + log.warn("Error during validation on " + beanClass + + " for reason : " + eee.getMessage(), eee); + } + + } finally { + // on nettoye toujours le validateur apres operation + validationSupport.clearErrorsAndMessages(); + } + } + + return result; + } + + @Override + public String toString() { + return super.toString() + "<beanClass:" + beanClass + + ", contextName:" + contextName + ">"; + } + + /** update the property {@link #fieldNames}, says search in XWorks */ + protected void initFields() { + + if (fieldNames != null) { + fieldNames = null; + } + + Set<String> detectedFieldNames = new HashSet<String>(); + + int skip = 0; + if (contextName != null && !includeDefaultContext) { + // count the number of validator to skip + for (Validator<?> v : validator.getValidators(beanClass, null)) { + // we only work on FieldValidator at the moment + if (v instanceof FieldValidator) { + skip++; + } + } + } + + for (Validator<?> v : validator.getValidators(beanClass, contextName)) { + // we only work on FieldValidator at the moment + if (v instanceof FieldValidator) { + if (skip > 0) { + skip--; + continue; + } + FieldValidator fieldValidator = (FieldValidator) v; + if (log.isDebugEnabled()) { + log.debug("context " + contextName + " - field " + + fieldValidator.getFieldName()); + } + String fName = fieldValidator.getFieldName(); + detectedFieldNames.add(fName); + } + } + + fieldNames = Collections.unmodifiableSet(detectedFieldNames); + } +} Property changes on: trunk/nuiton-validator/src/main/java/org/nuiton/validator/legacy/XWorkBeanValidator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/nuiton-validator/src/test/java/org/nuiton/validator/AbstractBeanValidatorDetectorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/AbstractBeanValidatorDetectorTest.java 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/AbstractBeanValidatorDetectorTest.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,196 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2011 CodeLutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.validator; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.File; -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.SortedSet; -import java.util.regex.Pattern; - -import static org.junit.Assert.assertEquals; - -/** - * An abstract test to detects validators for a given list of objets types and - * <p/> - * a given sourceroot directory where to find validations definitions. - * <p/> - * You just have to implements to {@link #assertDetect(SortedSet)} which contains - * the set of validators detected. - * <p/> - * See {@link BeanValidatorDetectorTest} for an example. - * <p/> - * Note : An implementation of this test should be produced in evry projects which - * defines some validation definitions just to test they are syntax valid. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.6.0 - */ -public abstract class AbstractBeanValidatorDetectorTest { - - /** Logger */ - private static final Log log = - LogFactory.getLog(AbstractBeanValidatorDetectorTest.class); - - protected static File basedir; - - protected BeanValidatorDetector instance; - - protected Class<?>[] classes; - - protected Class<?> validatorClass; - - protected File sourceRoot; - - protected AbstractBeanValidatorDetectorTest( - File sourceRoot, - Class<?>... classes) { - this(BeanValidator.class, sourceRoot, classes); - } - - protected AbstractBeanValidatorDetectorTest( - Class<?> validatorClass, - File sourceRoot, - Class<?>... classes) { - this.sourceRoot = sourceRoot; - this.classes = classes; - this.validatorClass = validatorClass; - - if (log.isInfoEnabled()) { - log.info("sourceRoot " + sourceRoot); - log.info("validatorClass " + validatorClass); - log.info("classes " + Arrays.toString(classes)); - } - } - - protected AbstractBeanValidatorDetectorTest( - File sourceRoot, - Collection<Class<?>> classes) { - this(sourceRoot, classes.toArray(new Class<?>[classes.size()])); - } - - public static void setUpClass() throws Exception { - String b = System.getenv("basedir"); - if (b == null) { - b = new File("").getAbsolutePath(); - } - basedir = new File(b); - if (log.isInfoEnabled()) { - log.info("basedir " + basedir); - } - } - - @Before - public void setUp() { - instance = new BeanValidatorDetector(); - } - - @After - public void tearDown() { - instance = null; - } - - /** Test of detect method, of class BeanValidatorDetector. */ - @Test - public void testDetect() { - SortedSet<BeanValidator<?>> result = detect(sourceRoot, classes, null); - if (log.isInfoEnabled()) { - log.info(printValidators("testDetect : ", result)); - } - assertDetect(result); - } - - protected abstract void assertDetect( - SortedSet<BeanValidator<?>> validators); - - protected SortedSet<BeanValidator<?>> detect( - File sourceRoot, - Class<?>[] classes, - Pattern contextPattern) { - - SortedSet<BeanValidator<?>> result = instance.detect( - validatorClass, - sourceRoot, - contextPattern, - classes); - return result; - } - - protected static void assertValidator( - Class<?> expectedBeanClass, - String expectedContextName, - BeanValidator<?> validator) { - assertEquals(expectedBeanClass, validator.getBeanClass()); - assertEquals(expectedContextName, validator.getContextName()); - } - - protected static void assertValidatorSetWithSameContextName( - SortedSet<BeanValidator<?>> validators, - String contextName, - Class<?>... expectedClasses) { - - assertEquals(expectedClasses.length, validators.size()); - Iterator<BeanValidator<?>> itrV = validators.iterator(); - - for (Class<?> expectedClass : expectedClasses) { - assertValidator(expectedClass, contextName, itrV.next()); - } - } - - protected static void assertValidatorSetWithMultiContextName( - SortedSet<BeanValidator<?>> validators, - Object... expecteds) { - - assertEquals(expecteds.length % 2, 0); - assertEquals(expecteds.length / 2, validators.size()); - Iterator<BeanValidator<?>> itrV = validators.iterator(); - - for (int i = 0; i < expecteds.length / 2; i++) { - String contextName = (String) expecteds[2 * i]; - Class<?> expectedClass = (Class<?>) expecteds[2 * i + 1]; - assertValidator(expectedClass, contextName, itrV.next()); - } - - } - - protected static String printValidators( - String prefix, - SortedSet<BeanValidator<?>> result) { - StringBuilder buffer; - buffer = new StringBuilder(result.size() * (prefix.length() + 50)); - buffer.append(prefix).append(result.size()).append('\n'); - for (BeanValidator<?> v : result) { - buffer.append(prefix).append(v).append('\n'); - } - return buffer.toString(); - } -} \ No newline at end of file Deleted: trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorDetectorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorDetectorTest.java 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorDetectorTest.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,116 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2011 CodeLutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.validator; - -import org.junit.BeforeClass; -import org.junit.Test; - -import java.io.File; -import java.util.SortedSet; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -/** @author tchemit <chemit@codelutin.com> */ -public class BeanValidatorDetectorTest extends AbstractBeanValidatorDetectorTest { - - private static final Class<?>[] TYPES = new Class<?>[]{Object.class}; - - @BeforeClass - public static void setUpClass() throws Exception { - AbstractBeanValidatorDetectorTest.setUpClass(); - - } - - public BeanValidatorDetectorTest() { - super(new File(basedir, "src" + File.separator + "test" + File.separator + "resources"), SimpleBean.class); - } - - /** Test of detect method, of class BeanValidatorDetector. */ - @Test - public void testDetectNothing() { - - SortedSet<BeanValidator<?>> validators = instance.detect(sourceRoot, TYPES); - assertEquals(0, validators.size()); - } - - @Override - protected void assertDetect(SortedSet<BeanValidator<?>> validators) { - assertEquals(1, validators.size()); - BeanValidator<?> validator = validators.iterator().next(); - assertEquals(classes[0], validator.getBeanClass()); - assertNull(validator.getContextName()); - } - - /** Test of getValidator method, of class BeanValidatorDetector. */ - @Test - public void testGetValidator() { - Class<?>[] types = {SimpleBean.class}; - SortedSet<BeanValidator<?>> result = instance.detect(sourceRoot, types); - assertEquals(1, result.size()); - BeanValidator<?> validator = result.iterator().next(); - assertEquals(types[0], validator.getBeanClass()); - assertNull(validator.getContextName()); - - types = TYPES; - result = instance.detect(sourceRoot, types); - assertEquals(0, result.size()); - - } - - /** Test of getClassDir method, of class BeanValidatorDetector. */ - @Test - public void testGetClassDir() { - Class<?> clazz = classes[0]; - - File expected = new File(sourceRoot, "org" + File.separator + "nuiton" + File.separator + "validator"); - File result = instance.getClassDir(sourceRoot, clazz); - assertEquals(expected, result); - } - - /** Test of getContexts method, of class BeanValidatorDetector. */ - @Test - public void testGetContexts() { - - String[] expResult = {"fatal", "error", "info", "simple", "warning"}; - Class<?> clazz = classes[0]; - File dir = instance.getClassDir(sourceRoot, clazz); - String[] result = instance.getContexts(clazz, dir); - assertEquals(expResult.length, result.length); - } - - /** Test of getContextsWithoutScopes method, of class BeanValidatorDetector. */ - @Test - public void testGetContextsWithoutScopes() { - - Class<?> clazz = SimpleBean.class; - String[] expResult = {""}; - File dir = instance.getClassDir(sourceRoot, clazz); - String[] contexts = instance.getContexts(clazz, dir); - String[] result = instance.getContextsWithoutScopes(contexts); - assertEquals(expResult.length, result.length); - - } -} \ No newline at end of file Deleted: trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorTest.java 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorTest.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,290 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2011 CodeLutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.validator; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** @author tchemit <chemit@codelutin.com> */ -public class BeanValidatorTest { - - /** Logger */ - static protected final Log log = LogFactory.getLog(BeanValidator.class); - - protected BeanValidator<SimpleBean> validator; - - protected SimpleBean bean; - - BeanValidatorListenerImpl fatalListener; - - BeanValidatorListenerImpl errorListener; - - BeanValidatorListenerImpl warningListener; - - BeanValidatorListenerImpl infoListener; - - @Before - public void setUp() { - bean = new SimpleBean(); - validator = new BeanValidator<SimpleBean>(SimpleBean.class, null); - validator.addBeanValidatorListener(fatalListener = new BeanValidatorListenerImpl(BeanValidatorScope.FATAL)); - validator.addBeanValidatorListener(errorListener = new BeanValidatorListenerImpl(BeanValidatorScope.ERROR)); - validator.addBeanValidatorListener(warningListener = new BeanValidatorListenerImpl(BeanValidatorScope.WARNING)); - validator.addBeanValidatorListener(infoListener = new BeanValidatorListenerImpl(BeanValidatorScope.INFO)); - } - - @After - public void tearDown() { - bean = null; - if (validator != null) { - validator.setBean(null); - validator = null; - } - } - - private static final String STRING_VALUE_FATAL= "stringValue.fatal"; - - private static final String STRING_VALUE_ERROR = "stringValue.error"; - - private static final String STRING_VALUE_WARNING = "stringValue.warning"; - - private static final String INT_VALUE_FATAL = "intValue.fatal"; - - private static final String INT_VALUE_ERROR = "intValue.error"; - - private static final String INT_VALUE_INFO = "intValue.info"; - - @Test - public void testValidate() { - - assertMessages(fatalListener); - assertMessages(errorListener); - assertMessages(warningListener); - assertMessages(infoListener); - - if (log.isInfoEnabled()) { - log.info("-----------------------------------------------"); - } - validator.setBean(bean); - - assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); - assertMessages(errorListener, STRING_VALUE_ERROR, INT_VALUE_ERROR); - assertMessages(warningListener, STRING_VALUE_WARNING); - assertMessages(infoListener, INT_VALUE_INFO); - - if (log.isInfoEnabled()) { - log.info("-----------------------------------------------"); - } - bean.setStringValue("one"); - - assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); - assertMessages(errorListener, INT_VALUE_ERROR); - assertMessages(warningListener, STRING_VALUE_WARNING); - assertMessages(infoListener, INT_VALUE_INFO); - - if (log.isInfoEnabled()) { - log.info("-----------------------------------------------"); - } - bean.setStringValue("oneone"); - - assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); - assertMessages(errorListener, INT_VALUE_ERROR); - assertMessages(warningListener); - assertMessages(infoListener, INT_VALUE_INFO); - - if (log.isInfoEnabled()) { - log.info("-----------------------------------------------"); - } - bean.setIntValue(1); - - assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); - assertMessages(errorListener); - assertMessages(warningListener); - assertMessages(infoListener, INT_VALUE_INFO); - - if (log.isInfoEnabled()) { - log.info("-----------------------------------------------"); - } - bean.setIntValue(10); - - assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); - assertMessages(errorListener); - assertMessages(warningListener); - assertMessages(infoListener); - - if (log.isInfoEnabled()) { - log.info("-----------------------------------------------"); - } - - bean.setStringValue(null); - bean.setIntValue(0); - - assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); - assertMessages(errorListener, STRING_VALUE_ERROR, INT_VALUE_ERROR); - assertMessages(warningListener, STRING_VALUE_WARNING); - assertMessages(infoListener, INT_VALUE_INFO); - - - if (log.isInfoEnabled()) { - log.info("-----------------------------------------------"); - } - - bean.setStringValue("5"); - bean.setIntValue(5); - assertMessages(fatalListener); - assertMessages(errorListener); - assertMessages(warningListener,STRING_VALUE_WARNING); - assertMessages(infoListener,INT_VALUE_INFO); - } - - @Test - public void testConvert() { - - - assertMessages(errorListener); - assertMessages(warningListener); - assertMessages(infoListener); - - if (log.isInfoEnabled()) { - log.info("-----------------------------------------------"); - } - - validator.setBean(bean); - - assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); - assertMessages(errorListener, STRING_VALUE_ERROR, INT_VALUE_ERROR); - assertMessages(warningListener, STRING_VALUE_WARNING); - assertMessages(infoListener, INT_VALUE_INFO); - - - if (log.isInfoEnabled()) { - log.info("-----------------------------------------------"); - } - - Object value = validator.convert("intValue", "abc", Class.class); - - Assert.assertNull(value); - - assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); - assertMessages(errorListener, STRING_VALUE_ERROR, "error.convertor.class"); - assertMessages(warningListener, STRING_VALUE_WARNING); - assertMessages(infoListener, INT_VALUE_INFO); - - if (log.isInfoEnabled()) { - log.info("-----------------------------------------------"); - } - bean.setStringValue("one"); - - assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); - assertMessages(errorListener, "error.convertor.class"); - assertMessages(warningListener, STRING_VALUE_WARNING); - assertMessages(infoListener, INT_VALUE_INFO); - - if (log.isInfoEnabled()) { - log.info("-----------------------------------------------"); - } - - value = validator.convert("intValue", "3", Integer.class); - - bean.setIntValue((Integer) value); - - assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); - assertMessages(errorListener); - assertMessages(warningListener, STRING_VALUE_WARNING); - assertMessages(infoListener, INT_VALUE_INFO); - - if (log.isInfoEnabled()) { - log.info("-----------------------------------------------"); - } - - bean.setIntValue(-1); - assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); - assertMessages(errorListener, INT_VALUE_ERROR); - assertMessages(warningListener, STRING_VALUE_WARNING); - assertMessages(infoListener, INT_VALUE_INFO); - - if (log.isInfoEnabled()) { - log.info("-----------------------------------------------"); - } - } - - void assertMessages(BeanValidatorListenerImpl listener, - String... expected) { - List<String> actual = listener.getMessages(); - Assert.assertEquals(" shoudl have " + - Arrays.toString(expected) + " but had " + actual, - expected.length, actual.size()); - for (String m : expected) { - Assert.assertEquals("could not find " + m + " in " + actual, - true, actual.contains(m)); - } - } - - class BeanValidatorListenerImpl implements BeanValidatorListener { - - final BeanValidatorScope scope; - - public BeanValidatorListenerImpl(BeanValidatorScope scope) { - this.scope = scope; - } - - List<String> messages = new ArrayList<String>(); - - public List<String> getMessages() { - return messages; - } - - @Override - public void onFieldChanged(BeanValidatorEvent event) { - if (scope != event.getScope()) { - return; - } - String[] messagesToDelete = event.getMessagesToDelete(); - if (messagesToDelete != null && messagesToDelete.length > 0) { - if (log.isInfoEnabled()) { - log.info(event.getScope() + " messages to delete : " + Arrays.toString(messagesToDelete)); - } - for (String m : messagesToDelete) { - messages.remove(m); - } - } - String[] messagesToAdd = event.getMessagesToAdd(); - if (messagesToAdd != null && messagesToAdd.length > 0) { - if (log.isInfoEnabled()) { - log.info(event.getScope() + " messages to add : " + Arrays.toString(messagesToAdd)); - } - messages.addAll(Arrays.asList(messagesToAdd)); - } - } - } -} Deleted: trunk/nuiton-validator/src/test/java/org/nuiton/validator/SimpleBean.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/SimpleBean.java 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/SimpleBean.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,79 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2011 CodeLutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.validator; - -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; - -public class SimpleBean { - - protected int intValue; - - protected String stringValue; - - final PropertyChangeSupport p; - - public SimpleBean() { - p = new PropertyChangeSupport(this); - } - - public int getIntValue() { - return intValue; - } - - public String getStringValue() { - return stringValue; - } - - public void setStringValue(String stringValue) { - String old = this.stringValue; - this.stringValue = stringValue; - p.firePropertyChange("stringValue", old, stringValue); - } - - public void setIntValue(int intValue) { - int old = this.intValue; - this.intValue = intValue; - p.firePropertyChange("intValue", old, intValue); - } - - public void addPropertyChangeListener(PropertyChangeListener listener) { - p.addPropertyChangeListener(listener); - } - - public void addPropertyChangeListener(String propertyName, - PropertyChangeListener listener) { - p.addPropertyChangeListener(propertyName, listener); - } - - public void removePropertyChangeListener(PropertyChangeListener listener) { - p.removePropertyChangeListener(listener); - } - - public void removePropertyChangeListener(String propertyName, - PropertyChangeListener listener) { - p.removePropertyChangeListener(propertyName, listener); - } -} \ No newline at end of file Deleted: trunk/nuiton-validator/src/test/java/org/nuiton/validator/XWorkBeanValidatorTest.java =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/XWorkBeanValidatorTest.java 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/XWorkBeanValidatorTest.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,182 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2011 CodeLutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.validator; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.util.List; -import java.util.Map; - -/** - * @author tchemit <chemit@codelutin.com> - * @since 1.3 - */ -public class XWorkBeanValidatorTest { - - protected XWorkBeanValidator<SimpleBean> validator; - - protected SimpleBean bean; - - protected Map<String, List<String>> messages; - - @Before - public void setUp() { - bean = new SimpleBean(); - validator = new XWorkBeanValidator<SimpleBean>(SimpleBean.class, "simple"); - } - - @After - public void tearDown() { - bean = null; - messages = null; - } - - @Test - public void testUnknownField() { - Assert.assertEquals(false, validator.containsField("fake_" + System.nanoTime())); - } - - @Test(expected = NullPointerException.class) - public void testValidateNPE() { - validator.validate(null); - } - - @Test - public void testValidate() { - - - messages = validator.validate(bean); - - assertFieldInError("stringValue", "stringValue.null", true, messages); - assertFieldInError("intValue", "intValue.null", true, messages); - - bean.setStringValue("notnull"); - messages = validator.validate(bean); - - assertFieldInError("stringValue", "stringValue.null", false, messages); - assertFieldInError("intValue", "intValue.null", true, messages); - - bean.setIntValue(1); - messages = validator.validate(bean); - - assertFieldInError("stringValue", "stringValue.null", false, messages); - assertFieldInError("intValue", "intValue.null", false, messages); - - } - - @Test - public void testSetContextName() { - - - String expected = "simple"; - - Assert.assertEquals(expected, validator.getContextName()); - Assert.assertEquals(true, validator.containsField("stringValue")); - Assert.assertEquals(true, validator.containsField("intValue")); - - validator.setContextName(expected = "error"); - - Assert.assertEquals(expected, validator.getContextName()); - Assert.assertEquals(true, validator.containsField("stringValue")); - Assert.assertEquals(true, validator.containsField("intValue")); - - validator.setContextName(expected = "warning"); - - Assert.assertEquals(expected, validator.getContextName()); - Assert.assertEquals(true, validator.containsField("stringValue")); - Assert.assertEquals(false, validator.containsField("intValue")); - - validator.setContextName(expected = "info"); - - Assert.assertEquals(expected, validator.getContextName()); - Assert.assertEquals(false, validator.containsField("stringValue")); - Assert.assertEquals(true, validator.containsField("intValue")); - - validator.setContextName(expected = "fake_" + System.nanoTime()); - - Assert.assertEquals(expected, validator.getContextName()); - Assert.assertEquals(false, validator.containsField("stringValue")); - Assert.assertEquals(false, validator.containsField("intValue")); - - } - - @Test - public void testSetIncludeDefaultContext() { - - validator.setIncludeDefaultContext(false); - - String expected = "simple"; - - Assert.assertEquals(expected, validator.getContextName()); - Assert.assertEquals(true, validator.containsField("stringValue")); - Assert.assertEquals(true, validator.containsField("intValue")); - - validator.setContextName(expected = "error"); - - Assert.assertEquals(expected, validator.getContextName()); - Assert.assertEquals(true, validator.containsField("stringValue")); - Assert.assertEquals(true, validator.containsField("intValue")); - - validator.setContextName(expected = "warning"); - - Assert.assertEquals(expected, validator.getContextName()); - Assert.assertEquals(true, validator.containsField("stringValue")); - Assert.assertEquals(false, validator.containsField("intValue")); - - validator.setContextName(expected = "info"); - - Assert.assertEquals(expected, validator.getContextName()); - Assert.assertEquals(false, validator.containsField("stringValue")); - Assert.assertEquals(true, validator.containsField("intValue")); - - validator.setContextName(expected = "fake_" + System.nanoTime()); - - Assert.assertEquals(expected, validator.getContextName()); - Assert.assertEquals(false, validator.containsField("stringValue")); - Assert.assertEquals(false, validator.containsField("intValue")); - - } - - protected void assertFieldInError(String fieldName, String error, boolean required, Map<String, List<String>> messages) { - - Assert.assertEquals(true, validator.containsField(fieldName)); - List<String> fieldMessages = messages.get(fieldName); - //Assert.assertEquals(true,validator.containsField(fieldName)); - if (fieldMessages != null) { - for (String o : fieldMessages) { - if (o.equals(error)) { - Assert.assertTrue(required); - return; - } - } - } - - // error was not found - Assert.assertFalse(required); - } -} Copied: trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/AbstractBeanValidatorDetectorTest.java (from rev 2013, trunk/nuiton-validator/src/test/java/org/nuiton/validator/AbstractBeanValidatorDetectorTest.java) =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/AbstractBeanValidatorDetectorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/AbstractBeanValidatorDetectorTest.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,196 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.legacy; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.SortedSet; +import java.util.regex.Pattern; + +import static org.junit.Assert.assertEquals; + +/** + * An abstract test to detects validators for a given list of objets types and + * <p/> + * a given sourceroot directory where to find validations definitions. + * <p/> + * You just have to implements to {@link #assertDetect(SortedSet)} which contains + * the set of validators detected. + * <p/> + * See {@link BeanValidatorDetectorTest} for an example. + * <p/> + * Note : An implementation of this test should be produced in evry projects which + * defines some validation definitions just to test they are syntax valid. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.6.0 + */ +public abstract class AbstractBeanValidatorDetectorTest { + + /** Logger */ + private static final Log log = + LogFactory.getLog(AbstractBeanValidatorDetectorTest.class); + + protected static File basedir; + + protected BeanValidatorDetector instance; + + protected Class<?>[] classes; + + protected Class<?> validatorClass; + + protected File sourceRoot; + + protected AbstractBeanValidatorDetectorTest( + File sourceRoot, + Class<?>... classes) { + this(BeanValidator.class, sourceRoot, classes); + } + + protected AbstractBeanValidatorDetectorTest( + Class<?> validatorClass, + File sourceRoot, + Class<?>... classes) { + this.sourceRoot = sourceRoot; + this.classes = classes; + this.validatorClass = validatorClass; + + if (log.isInfoEnabled()) { + log.info("sourceRoot " + sourceRoot); + log.info("validatorClass " + validatorClass); + log.info("classes " + Arrays.toString(classes)); + } + } + + protected AbstractBeanValidatorDetectorTest( + File sourceRoot, + Collection<Class<?>> classes) { + this(sourceRoot, classes.toArray(new Class<?>[classes.size()])); + } + + public static void setUpClass() throws Exception { + String b = System.getenv("basedir"); + if (b == null) { + b = new File("").getAbsolutePath(); + } + basedir = new File(b); + if (log.isInfoEnabled()) { + log.info("basedir " + basedir); + } + } + + @Before + public void setUp() { + instance = new BeanValidatorDetector(); + } + + @After + public void tearDown() { + instance = null; + } + + /** Test of detect method, of class BeanValidatorDetector. */ + @Test + public void testDetect() { + SortedSet<BeanValidator<?>> result = detect(sourceRoot, classes, null); + if (log.isInfoEnabled()) { + log.info(printValidators("testDetect : ", result)); + } + assertDetect(result); + } + + protected abstract void assertDetect( + SortedSet<BeanValidator<?>> validators); + + protected SortedSet<BeanValidator<?>> detect( + File sourceRoot, + Class<?>[] classes, + Pattern contextPattern) { + + SortedSet<BeanValidator<?>> result = instance.detect( + validatorClass, + sourceRoot, + contextPattern, + classes); + return result; + } + + protected static void assertValidator( + Class<?> expectedBeanClass, + String expectedContextName, + BeanValidator<?> validator) { + assertEquals(expectedBeanClass, validator.getBeanClass()); + assertEquals(expectedContextName, validator.getContextName()); + } + + protected static void assertValidatorSetWithSameContextName( + SortedSet<BeanValidator<?>> validators, + String contextName, + Class<?>... expectedClasses) { + + assertEquals(expectedClasses.length, validators.size()); + Iterator<BeanValidator<?>> itrV = validators.iterator(); + + for (Class<?> expectedClass : expectedClasses) { + assertValidator(expectedClass, contextName, itrV.next()); + } + } + + protected static void assertValidatorSetWithMultiContextName( + SortedSet<BeanValidator<?>> validators, + Object... expecteds) { + + assertEquals(expecteds.length % 2, 0); + assertEquals(expecteds.length / 2, validators.size()); + Iterator<BeanValidator<?>> itrV = validators.iterator(); + + for (int i = 0; i < expecteds.length / 2; i++) { + String contextName = (String) expecteds[2 * i]; + Class<?> expectedClass = (Class<?>) expecteds[2 * i + 1]; + assertValidator(expectedClass, contextName, itrV.next()); + } + + } + + protected static String printValidators( + String prefix, + SortedSet<BeanValidator<?>> result) { + StringBuilder buffer; + buffer = new StringBuilder(result.size() * (prefix.length() + 50)); + buffer.append(prefix).append(result.size()).append('\n'); + for (BeanValidator<?> v : result) { + buffer.append(prefix).append(v).append('\n'); + } + return buffer.toString(); + } +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/AbstractBeanValidatorDetectorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/BeanValidatorDetectorTest.java (from rev 2013, trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorDetectorTest.java) =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/BeanValidatorDetectorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/BeanValidatorDetectorTest.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,116 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.legacy; + +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.File; +import java.util.SortedSet; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +/** @author tchemit <chemit@codelutin.com> */ +public class BeanValidatorDetectorTest extends AbstractBeanValidatorDetectorTest { + + private static final Class<?>[] TYPES = new Class<?>[]{Object.class}; + + @BeforeClass + public static void setUpClass() throws Exception { + AbstractBeanValidatorDetectorTest.setUpClass(); + + } + + public BeanValidatorDetectorTest() { + super(new File(basedir, "src" + File.separator + "test" + File.separator + "resources"), SimpleBean.class); + } + + /** Test of detect method, of class BeanValidatorDetector. */ + @Test + public void testDetectNothing() { + + SortedSet<BeanValidator<?>> validators = instance.detect(sourceRoot, TYPES); + assertEquals(0, validators.size()); + } + + @Override + protected void assertDetect(SortedSet<BeanValidator<?>> validators) { + assertEquals(1, validators.size()); + BeanValidator<?> validator = validators.iterator().next(); + assertEquals(classes[0], validator.getBeanClass()); + assertNull(validator.getContextName()); + } + + /** Test of getValidator method, of class BeanValidatorDetector. */ + @Test + public void testGetValidator() { + Class<?>[] types = {SimpleBean.class}; + SortedSet<BeanValidator<?>> result = instance.detect(sourceRoot, types); + assertEquals(1, result.size()); + BeanValidator<?> validator = result.iterator().next(); + assertEquals(types[0], validator.getBeanClass()); + assertNull(validator.getContextName()); + + types = TYPES; + result = instance.detect(sourceRoot, types); + assertEquals(0, result.size()); + + } + + /** Test of getClassDir method, of class BeanValidatorDetector. */ + @Test + public void testGetClassDir() { + Class<?> clazz = classes[0]; + + File expected = new File(sourceRoot, "org" + File.separator + "nuiton" + File.separator + "validator" + File.separator + "legacy"); + File result = instance.getClassDir(sourceRoot, clazz); + assertEquals(expected, result); + } + + /** Test of getContexts method, of class BeanValidatorDetector. */ + @Test + public void testGetContexts() { + + String[] expResult = {"fatal", "error", "info", "simple", "warning"}; + Class<?> clazz = classes[0]; + File dir = instance.getClassDir(sourceRoot, clazz); + String[] result = instance.getContexts(clazz, dir); + assertEquals(expResult.length, result.length); + } + + /** Test of getContextsWithoutScopes method, of class BeanValidatorDetector. */ + @Test + public void testGetContextsWithoutScopes() { + + Class<?> clazz = SimpleBean.class; + String[] expResult = {""}; + File dir = instance.getClassDir(sourceRoot, clazz); + String[] contexts = instance.getContexts(clazz, dir); + String[] result = instance.getContextsWithoutScopes(contexts); + assertEquals(expResult.length, result.length); + + } +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/BeanValidatorDetectorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/BeanValidatorTest.java (from rev 2013, trunk/nuiton-validator/src/test/java/org/nuiton/validator/BeanValidatorTest.java) =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/BeanValidatorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/BeanValidatorTest.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,290 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.legacy; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** @author tchemit <chemit@codelutin.com> */ +public class BeanValidatorTest { + + /** Logger */ + static protected final Log log = LogFactory.getLog(BeanValidator.class); + + protected BeanValidator<SimpleBean> validator; + + protected SimpleBean bean; + + BeanValidatorListenerImpl fatalListener; + + BeanValidatorListenerImpl errorListener; + + BeanValidatorListenerImpl warningListener; + + BeanValidatorListenerImpl infoListener; + + @Before + public void setUp() { + bean = new SimpleBean(); + validator = new BeanValidator<SimpleBean>(SimpleBean.class, null); + validator.addBeanValidatorListener(fatalListener = new BeanValidatorListenerImpl(BeanValidatorScope.FATAL)); + validator.addBeanValidatorListener(errorListener = new BeanValidatorListenerImpl(BeanValidatorScope.ERROR)); + validator.addBeanValidatorListener(warningListener = new BeanValidatorListenerImpl(BeanValidatorScope.WARNING)); + validator.addBeanValidatorListener(infoListener = new BeanValidatorListenerImpl(BeanValidatorScope.INFO)); + } + + @After + public void tearDown() { + bean = null; + if (validator != null) { + validator.setBean(null); + validator = null; + } + } + + private static final String STRING_VALUE_FATAL= "stringValue.fatal"; + + private static final String STRING_VALUE_ERROR = "stringValue.error"; + + private static final String STRING_VALUE_WARNING = "stringValue.warning"; + + private static final String INT_VALUE_FATAL = "intValue.fatal"; + + private static final String INT_VALUE_ERROR = "intValue.error"; + + private static final String INT_VALUE_INFO = "intValue.info"; + + @Test + public void testValidate() { + + assertMessages(fatalListener); + assertMessages(errorListener); + assertMessages(warningListener); + assertMessages(infoListener); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + validator.setBean(bean); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener, STRING_VALUE_ERROR, INT_VALUE_ERROR); + assertMessages(warningListener, STRING_VALUE_WARNING); + assertMessages(infoListener, INT_VALUE_INFO); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + bean.setStringValue("one"); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener, INT_VALUE_ERROR); + assertMessages(warningListener, STRING_VALUE_WARNING); + assertMessages(infoListener, INT_VALUE_INFO); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + bean.setStringValue("oneone"); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener, INT_VALUE_ERROR); + assertMessages(warningListener); + assertMessages(infoListener, INT_VALUE_INFO); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + bean.setIntValue(1); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener); + assertMessages(warningListener); + assertMessages(infoListener, INT_VALUE_INFO); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + bean.setIntValue(10); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener); + assertMessages(warningListener); + assertMessages(infoListener); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + + bean.setStringValue(null); + bean.setIntValue(0); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener, STRING_VALUE_ERROR, INT_VALUE_ERROR); + assertMessages(warningListener, STRING_VALUE_WARNING); + assertMessages(infoListener, INT_VALUE_INFO); + + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + + bean.setStringValue("5"); + bean.setIntValue(5); + assertMessages(fatalListener); + assertMessages(errorListener); + assertMessages(warningListener,STRING_VALUE_WARNING); + assertMessages(infoListener,INT_VALUE_INFO); + } + + @Test + public void testConvert() { + + + assertMessages(errorListener); + assertMessages(warningListener); + assertMessages(infoListener); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + + validator.setBean(bean); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener, STRING_VALUE_ERROR, INT_VALUE_ERROR); + assertMessages(warningListener, STRING_VALUE_WARNING); + assertMessages(infoListener, INT_VALUE_INFO); + + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + + Object value = validator.convert("intValue", "abc", Class.class); + + Assert.assertNull(value); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener, STRING_VALUE_ERROR, "error.convertor.class"); + assertMessages(warningListener, STRING_VALUE_WARNING); + assertMessages(infoListener, INT_VALUE_INFO); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + bean.setStringValue("one"); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener, "error.convertor.class"); + assertMessages(warningListener, STRING_VALUE_WARNING); + assertMessages(infoListener, INT_VALUE_INFO); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + + value = validator.convert("intValue", "3", Integer.class); + + bean.setIntValue((Integer) value); + + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener); + assertMessages(warningListener, STRING_VALUE_WARNING); + assertMessages(infoListener, INT_VALUE_INFO); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + + bean.setIntValue(-1); + assertMessages(fatalListener,STRING_VALUE_FATAL,INT_VALUE_FATAL); + assertMessages(errorListener, INT_VALUE_ERROR); + assertMessages(warningListener, STRING_VALUE_WARNING); + assertMessages(infoListener, INT_VALUE_INFO); + + if (log.isInfoEnabled()) { + log.info("-----------------------------------------------"); + } + } + + void assertMessages(BeanValidatorListenerImpl listener, + String... expected) { + List<String> actual = listener.getMessages(); + Assert.assertEquals(" shoudl have " + + Arrays.toString(expected) + " but had " + actual, + expected.length, actual.size()); + for (String m : expected) { + Assert.assertEquals("could not find " + m + " in " + actual, + true, actual.contains(m)); + } + } + + class BeanValidatorListenerImpl implements BeanValidatorListener { + + final BeanValidatorScope scope; + + public BeanValidatorListenerImpl(BeanValidatorScope scope) { + this.scope = scope; + } + + List<String> messages = new ArrayList<String>(); + + public List<String> getMessages() { + return messages; + } + + @Override + public void onFieldChanged(BeanValidatorEvent event) { + if (scope != event.getScope()) { + return; + } + String[] messagesToDelete = event.getMessagesToDelete(); + if (messagesToDelete != null && messagesToDelete.length > 0) { + if (log.isInfoEnabled()) { + log.info(event.getScope() + " messages to delete : " + Arrays.toString(messagesToDelete)); + } + for (String m : messagesToDelete) { + messages.remove(m); + } + } + String[] messagesToAdd = event.getMessagesToAdd(); + if (messagesToAdd != null && messagesToAdd.length > 0) { + if (log.isInfoEnabled()) { + log.info(event.getScope() + " messages to add : " + Arrays.toString(messagesToAdd)); + } + messages.addAll(Arrays.asList(messagesToAdd)); + } + } + } +} Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/BeanValidatorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/SimpleBean.java (from rev 2013, trunk/nuiton-validator/src/test/java/org/nuiton/validator/SimpleBean.java) =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/SimpleBean.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/SimpleBean.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,79 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.legacy; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; + +public class SimpleBean { + + protected int intValue; + + protected String stringValue; + + final PropertyChangeSupport p; + + public SimpleBean() { + p = new PropertyChangeSupport(this); + } + + public int getIntValue() { + return intValue; + } + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(String stringValue) { + String old = this.stringValue; + this.stringValue = stringValue; + p.firePropertyChange("stringValue", old, stringValue); + } + + public void setIntValue(int intValue) { + int old = this.intValue; + this.intValue = intValue; + p.firePropertyChange("intValue", old, intValue); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + p.addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + p.addPropertyChangeListener(propertyName, listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + p.removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + p.removePropertyChangeListener(propertyName, listener); + } +} \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/SimpleBean.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/XWorkBeanValidatorTest.java (from rev 2013, trunk/nuiton-validator/src/test/java/org/nuiton/validator/XWorkBeanValidatorTest.java) =================================================================== --- trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/XWorkBeanValidatorTest.java (rev 0) +++ trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/XWorkBeanValidatorTest.java 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,182 @@ +/* + * #%L + * Nuiton Utils :: Nuiton Validator + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 CodeLutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.validator.legacy; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.List; +import java.util.Map; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 1.3 + */ +public class XWorkBeanValidatorTest { + + protected XWorkBeanValidator<SimpleBean> validator; + + protected SimpleBean bean; + + protected Map<String, List<String>> messages; + + @Before + public void setUp() { + bean = new SimpleBean(); + validator = new XWorkBeanValidator<SimpleBean>(SimpleBean.class, "simple"); + } + + @After + public void tearDown() { + bean = null; + messages = null; + } + + @Test + public void testUnknownField() { + Assert.assertEquals(false, validator.containsField("fake_" + System.nanoTime())); + } + + @Test(expected = NullPointerException.class) + public void testValidateNPE() { + validator.validate(null); + } + + @Test + public void testValidate() { + + + messages = validator.validate(bean); + + assertFieldInError("stringValue", "stringValue.null", true, messages); + assertFieldInError("intValue", "intValue.null", true, messages); + + bean.setStringValue("notnull"); + messages = validator.validate(bean); + + assertFieldInError("stringValue", "stringValue.null", false, messages); + assertFieldInError("intValue", "intValue.null", true, messages); + + bean.setIntValue(1); + messages = validator.validate(bean); + + assertFieldInError("stringValue", "stringValue.null", false, messages); + assertFieldInError("intValue", "intValue.null", false, messages); + + } + + @Test + public void testSetContextName() { + + + String expected = "simple"; + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(true, validator.containsField("stringValue")); + Assert.assertEquals(true, validator.containsField("intValue")); + + validator.setContextName(expected = "error"); + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(true, validator.containsField("stringValue")); + Assert.assertEquals(true, validator.containsField("intValue")); + + validator.setContextName(expected = "warning"); + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(true, validator.containsField("stringValue")); + Assert.assertEquals(false, validator.containsField("intValue")); + + validator.setContextName(expected = "info"); + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(false, validator.containsField("stringValue")); + Assert.assertEquals(true, validator.containsField("intValue")); + + validator.setContextName(expected = "fake_" + System.nanoTime()); + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(false, validator.containsField("stringValue")); + Assert.assertEquals(false, validator.containsField("intValue")); + + } + + @Test + public void testSetIncludeDefaultContext() { + + validator.setIncludeDefaultContext(false); + + String expected = "simple"; + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(true, validator.containsField("stringValue")); + Assert.assertEquals(true, validator.containsField("intValue")); + + validator.setContextName(expected = "error"); + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(true, validator.containsField("stringValue")); + Assert.assertEquals(true, validator.containsField("intValue")); + + validator.setContextName(expected = "warning"); + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(true, validator.containsField("stringValue")); + Assert.assertEquals(false, validator.containsField("intValue")); + + validator.setContextName(expected = "info"); + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(false, validator.containsField("stringValue")); + Assert.assertEquals(true, validator.containsField("intValue")); + + validator.setContextName(expected = "fake_" + System.nanoTime()); + + Assert.assertEquals(expected, validator.getContextName()); + Assert.assertEquals(false, validator.containsField("stringValue")); + Assert.assertEquals(false, validator.containsField("intValue")); + + } + + protected void assertFieldInError(String fieldName, String error, boolean required, Map<String, List<String>> messages) { + + Assert.assertEquals(true, validator.containsField(fieldName)); + List<String> fieldMessages = messages.get(fieldName); + //Assert.assertEquals(true,validator.containsField(fieldName)); + if (fieldMessages != null) { + for (String o : fieldMessages) { + if (o.equals(error)) { + Assert.assertTrue(required); + return; + } + } + } + + // error was not found + Assert.assertFalse(required); + } +} Property changes on: trunk/nuiton-validator/src/test/java/org/nuiton/validator/legacy/XWorkBeanValidatorTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-error-validation.xml =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-error-validation.xml 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-error-validation.xml 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,43 +0,0 @@ -<!-- - #%L - Nuiton Utils :: Nuiton Validator - - $Id$ - $HeadURL$ - %% - Copyright (C) 2011 CodeLutin, Tony Chemit - %% - 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% - --> -<!DOCTYPE validators PUBLIC - "-//OpenSymphony Group//XWork Validator 1.0.2//EN" - "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> -<validators> - - <field name="stringValue"> - <field-validator type="requiredstring"> - <message>stringValue.error</message> - </field-validator> - </field> - - <field name="intValue"> - <field-validator type="int"> - <param name="min">1</param> - <message>intValue.error</message> - </field-validator> - </field> - -</validators> \ No newline at end of file Deleted: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-fatal-validation.xml =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-fatal-validation.xml 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-fatal-validation.xml 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,47 +0,0 @@ -<!-- - #%L - Nuiton Utils :: Nuiton Validator - - $Id$ - $HeadURL$ - %% - Copyright (C) 2011 CodeLutin, Tony Chemit - %% - 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% - --> -<!DOCTYPE validators PUBLIC - "-//OpenSymphony Group//XWork Validator 1.0.2//EN" - "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> -<validators> - - <field name="stringValue"> - <field-validator type="fieldexpression"> - <param name="expression"> - <![CDATA[ stringValue != null && stringValue == "5"]]></param> - <message>stringValue.fatal</message> - </field-validator> - </field> - - - <field name="intValue"> - <field-validator type="int"> - <param name="min">5</param> - <param name="max">5</param> - <message>intValue.fatal</message> - </field-validator> - </field> - -</validators> \ No newline at end of file Deleted: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-info-validation.xml =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-info-validation.xml 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-info-validation.xml 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,37 +0,0 @@ -<!-- - #%L - Nuiton Utils :: Nuiton Validator - - $Id$ - $HeadURL$ - %% - Copyright (C) 2011 CodeLutin, Tony Chemit - %% - 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% - --> -<!DOCTYPE validators PUBLIC - "-//OpenSymphony Group//XWork Validator 1.0.2//EN" - "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> -<validators> - - <field name="intValue"> - <field-validator type="int"> - <param name="min">10</param> - <message>intValue.info</message> - </field-validator> - </field> - -</validators> \ No newline at end of file Deleted: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-simple-validation.xml =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-simple-validation.xml 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-simple-validation.xml 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,43 +0,0 @@ -<!-- - #%L - Nuiton Utils :: Nuiton Validator - - $Id$ - $HeadURL$ - %% - Copyright (C) 2011 CodeLutin, Tony Chemit - %% - 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% - --> -<!DOCTYPE validators PUBLIC - "-//OpenSymphony Group//XWork Validator 1.0.2//EN" - "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> -<validators> - - <field name="stringValue"> - <field-validator type="requiredstring"> - <message>stringValue.null</message> - </field-validator> - </field> - - <field name="intValue"> - <field-validator type="int"> - <param name="min">1</param> - <message>intValue.null</message> - </field-validator> - </field> - -</validators> \ No newline at end of file Deleted: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-warning-validation.xml =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-warning-validation.xml 2011-01-17 18:26:47 UTC (rev 2014) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-warning-validation.xml 2011-01-17 18:36:18 UTC (rev 2015) @@ -1,37 +0,0 @@ -<!-- - #%L - Nuiton Utils :: Nuiton Validator - - $Id$ - $HeadURL$ - %% - Copyright (C) 2011 CodeLutin, Tony Chemit - %% - 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% - --> -<!DOCTYPE validators PUBLIC - "-//OpenSymphony Group//XWork Validator 1.0.2//EN" - "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> -<validators> - - <field name="stringValue"> - <field-validator type="fieldexpression"> - <param name="expression"><![CDATA[ stringValue != null && stringValue.length() > 5]]></param> - <message>stringValue.warning</message> - </field-validator> - </field> - -</validators> \ No newline at end of file Copied: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-error-validation.xml (from rev 2013, trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-error-validation.xml) =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-error-validation.xml (rev 0) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-error-validation.xml 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,43 @@ +<!-- + #%L + Nuiton Utils :: Nuiton Validator + + $Id$ + $HeadURL$ + %% + Copyright (C) 2011 CodeLutin, Tony Chemit + %% + 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% + --> +<!DOCTYPE validators PUBLIC + "-//OpenSymphony Group//XWork Validator 1.0.2//EN" + "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> +<validators> + + <field name="stringValue"> + <field-validator type="requiredstring"> + <message>stringValue.error</message> + </field-validator> + </field> + + <field name="intValue"> + <field-validator type="int"> + <param name="min">1</param> + <message>intValue.error</message> + </field-validator> + </field> + +</validators> \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-error-validation.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-fatal-validation.xml (from rev 2013, trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-fatal-validation.xml) =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-fatal-validation.xml (rev 0) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-fatal-validation.xml 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,47 @@ +<!-- + #%L + Nuiton Utils :: Nuiton Validator + + $Id$ + $HeadURL$ + %% + Copyright (C) 2011 CodeLutin, Tony Chemit + %% + 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% + --> +<!DOCTYPE validators PUBLIC + "-//OpenSymphony Group//XWork Validator 1.0.2//EN" + "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> +<validators> + + <field name="stringValue"> + <field-validator type="fieldexpression"> + <param name="expression"> + <![CDATA[ stringValue != null && stringValue == "5"]]></param> + <message>stringValue.fatal</message> + </field-validator> + </field> + + + <field name="intValue"> + <field-validator type="int"> + <param name="min">5</param> + <param name="max">5</param> + <message>intValue.fatal</message> + </field-validator> + </field> + +</validators> \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-fatal-validation.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-info-validation.xml (from rev 2013, trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-info-validation.xml) =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-info-validation.xml (rev 0) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-info-validation.xml 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,37 @@ +<!-- + #%L + Nuiton Utils :: Nuiton Validator + + $Id$ + $HeadURL$ + %% + Copyright (C) 2011 CodeLutin, Tony Chemit + %% + 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% + --> +<!DOCTYPE validators PUBLIC + "-//OpenSymphony Group//XWork Validator 1.0.2//EN" + "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> +<validators> + + <field name="intValue"> + <field-validator type="int"> + <param name="min">10</param> + <message>intValue.info</message> + </field-validator> + </field> + +</validators> \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-info-validation.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-simple-validation.xml (from rev 2013, trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-simple-validation.xml) =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-simple-validation.xml (rev 0) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-simple-validation.xml 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,43 @@ +<!-- + #%L + Nuiton Utils :: Nuiton Validator + + $Id$ + $HeadURL$ + %% + Copyright (C) 2011 CodeLutin, Tony Chemit + %% + 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% + --> +<!DOCTYPE validators PUBLIC + "-//OpenSymphony Group//XWork Validator 1.0.2//EN" + "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> +<validators> + + <field name="stringValue"> + <field-validator type="requiredstring"> + <message>stringValue.null</message> + </field-validator> + </field> + + <field name="intValue"> + <field-validator type="int"> + <param name="min">1</param> + <message>intValue.null</message> + </field-validator> + </field> + +</validators> \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-simple-validation.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-warning-validation.xml (from rev 2013, trunk/nuiton-validator/src/test/resources/org/nuiton/validator/SimpleBean-warning-validation.xml) =================================================================== --- trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-warning-validation.xml (rev 0) +++ trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-warning-validation.xml 2011-01-17 18:36:18 UTC (rev 2015) @@ -0,0 +1,37 @@ +<!-- + #%L + Nuiton Utils :: Nuiton Validator + + $Id$ + $HeadURL$ + %% + Copyright (C) 2011 CodeLutin, Tony Chemit + %% + 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% + --> +<!DOCTYPE validators PUBLIC + "-//OpenSymphony Group//XWork Validator 1.0.2//EN" + "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> +<validators> + + <field name="stringValue"> + <field-validator type="fieldexpression"> + <param name="expression"><![CDATA[ stringValue != null && stringValue.length() > 5]]></param> + <message>stringValue.warning</message> + </field-validator> + </field> + +</validators> \ No newline at end of file Property changes on: trunk/nuiton-validator/src/test/resources/org/nuiton/validator/legacy/SimpleBean-warning-validation.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native