Author: tchemit Date: 2011-01-25 12:56:47 +0100 (Tue, 25 Jan 2011) New Revision: 2161 Url: http://nuiton.org/repositories/revision/jaxx/2161 Log: Evolution #1178: Use nuiton-validator 2.0 Evolution #1240: Review the validation api Added: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/meta/ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/meta/Validator.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/meta/ValidatorField.java Removed: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorDetector.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorEvent.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorField.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorListener.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorMessage.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorScope.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorUtil.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/ValidatorsMap.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/XWorkBeanValidator.java trunk/jaxx-validator/src/test/java/jaxx/runtime/validator/ Modified: trunk/jaxx-validator/pom.xml trunk/jaxx-validator/src/main/java/jaxx/runtime/JAXXValidator.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessage.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListModel.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListRenderer.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableModel.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableRenderer.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorUtil.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/ui/AbstractBeanValidatorUI.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/ui/IconValidationUI.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/ui/ImageValidationUI.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/ui/TranslucentValidationUI.java Modified: trunk/jaxx-validator/pom.xml =================================================================== --- trunk/jaxx-validator/pom.xml 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/pom.xml 2011-01-25 11:56:47 UTC (rev 2161) @@ -62,6 +62,11 @@ </dependency> <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-validator</artifactId> + </dependency> + + <dependency> <groupId>org.nuiton.i18n</groupId> <artifactId>nuiton-i18n</artifactId> </dependency> Modified: trunk/jaxx-validator/src/main/java/jaxx/runtime/JAXXValidator.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/JAXXValidator.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/JAXXValidator.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -25,7 +25,7 @@ package jaxx.runtime; -import jaxx.runtime.validator.BeanValidator; +import org.nuiton.validator.bean.BeanValidator; import jaxx.runtime.validator.swing.SwingValidator; import javax.swing.JComponent; Deleted: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -1,637 +0,0 @@ -/* - * #%L - * JAXX :: Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2008 - 2010 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 jaxx.runtime.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. - * @deprecated since 2.2.4, the code is moved into the org.nuiton:nuiton-validator project, will be removed in version 2.3 - */ -@Deprecated -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/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorDetector.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorDetector.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorDetector.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -1,344 +0,0 @@ -/* - * #%L - * JAXX :: Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2008 - 2010 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 jaxx.runtime.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 - * @deprecated since 2.2.4, the code is moved into the org.nuiton:nuiton-validator project, will be removed in version 2.3 - */ -@Deprecated -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/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorEvent.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorEvent.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorEvent.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -1,88 +0,0 @@ -/* - * #%L - * JAXX :: Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2008 - 2010 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 jaxx.runtime.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 - * @deprecated since 2.2.4, the code is moved into the org.nuiton:nuiton-validator project, will be removed in version 2.3 - */ -@Deprecated -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/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorField.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorField.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorField.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -1,288 +0,0 @@ -/* - * #%L - * JAXX :: Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2008 - 2010 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 jaxx.runtime.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 - * @deprecated since 2.2.4, the code is moved into the org.nuiton:nuiton-validator project, will be removed in version 2.3 - */ -@Deprecated -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/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorListener.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorListener.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorListener.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -1,45 +0,0 @@ -/* - * #%L - * JAXX :: Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2008 - 2010 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 jaxx.runtime.validator; - -import java.util.EventListener; - -/** - * The listener contract to be used on {@link BeanValidator} - * - * @author tchemit <chemit@codelutin.com> - * @since 1.3 - * @deprecated since 2.2.4, the code is moved into the org.nuiton:nuiton-validator project, will be removed in version 2.3 - */ -@Deprecated -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/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorMessage.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorMessage.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorMessage.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -1,120 +0,0 @@ -/* - * #%L - * JAXX :: Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2008 - 2010 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 jaxx.runtime.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 - * @deprecated since 2.2.4, the code is moved into the org.nuiton:nuiton-validator project, will be removed in version 2.3 - */ -@Deprecated -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/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorScope.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorScope.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorScope.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -1,81 +0,0 @@ -/* - * #%L - * JAXX :: Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2008 - 2010 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 jaxx.runtime.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> - * @deprecated since 2.2.4, the code is moved into the org.nuiton:nuiton-validator project, will be removed in version 2.3 - */ -@Deprecated -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/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorUtil.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorUtil.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/BeanValidatorUtil.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -1,268 +0,0 @@ -/* - * #%L - * JAXX :: Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2008 - 2010 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 jaxx.runtime.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 jaxx.runtime.JAXXObject; -import jaxx.runtime.JAXXValidator; -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.ArrayList; -import java.util.EnumMap; -import java.util.EnumSet; -import java.util.List; - -/** - * The helper class for validation module. - * - * @author tchemit <chemit@codelutin.com> - * @deprecated since 2.2.4, the code is moved into the org.nuiton:nuiton-validator project, will be removed in version 2.3 - */ -@Deprecated -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 - } - - /** - * Convinient method to attach a bean to all validators of an JAXXObject. - * <p/> - * It is possible to exclude some validator to be treated. - * - * @param ui the ui containing the validatros to treate - * @param bean the bean to attach in validators (can be null) - * @param excludeIds the list of validator id to exclude - */ - @SuppressWarnings({"unchecked"}) - public static void setValidatorBean(JAXXObject ui, - Object bean, - String... excludeIds) { - if (!JAXXValidator.class.isAssignableFrom(ui.getClass())) { - return; - } - JAXXValidator jaxxValidator = (JAXXValidator) ui; - List<String> validatorIds = jaxxValidator.getValidatorIds(); - if (excludeIds.length > 0) { - validatorIds = new ArrayList<String>(validatorIds); - for (String excludeId : excludeIds) { - validatorIds.remove(excludeId); - } - } - for (String validatorId : validatorIds) { - BeanValidator beanValidator = - jaxxValidator.getValidator(validatorId); - if (bean == null || beanValidator.getBeanClass().isAssignableFrom( - bean.getClass())) { - // touch validator, only if fits the bean type (or bean is null) - beanValidator.setBean(bean); - } - } - } - - /** - * Convinient method to set the changed property to all validators of an - * JAXXObject. - * <p/> - * It is possible to exclude some validator to be treated. - * - * @param ui the ui containing the validatros to treate - * @param newValue the new value to set in changed validator property - * @param excludeIds the list of validator id to exclude - */ - @SuppressWarnings({"unchecked"}) - public static void setValidatorChanged(JAXXObject ui, - boolean newValue, - String... excludeIds) { - if (!JAXXValidator.class.isAssignableFrom(ui.getClass())) { - return; - } - JAXXValidator jaxxValidator = (JAXXValidator) ui; - List<String> validatorIds = jaxxValidator.getValidatorIds(); - if (excludeIds.length > 0) { - validatorIds = new ArrayList<String>(validatorIds); - for (String excludeId : excludeIds) { - validatorIds.remove(excludeId); - } - } - for (String validatorId : validatorIds) { - BeanValidator<?> beanValidator = - jaxxValidator.getValidator(validatorId); - beanValidator.setChanged(newValue); - } - } - - /** - * 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/jaxx-validator/src/main/java/jaxx/runtime/validator/ValidatorsMap.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/ValidatorsMap.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/ValidatorsMap.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -1,128 +0,0 @@ -/* - * #%L - * JAXX :: Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2008 - 2010 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 jaxx.runtime.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 - * @deprecated since 2.2.4, the code is moved into the org.nuiton:nuiton-validator project, will be removed in version 2.3 - */ -@Deprecated -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/jaxx-validator/src/main/java/jaxx/runtime/validator/XWorkBeanValidator.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/XWorkBeanValidator.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/XWorkBeanValidator.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -1,326 +0,0 @@ -/* - * #%L - * JAXX :: Validator - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2008 - 2010 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 jaxx.runtime.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 - * @deprecated since 2.2.4, the code is moved into the org.nuiton:nuiton-validator project, will be removed in version 2.3 - */ -@Deprecated -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); - } -} Modified: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -24,17 +24,17 @@ */ package jaxx.runtime.validator.swing; -import jaxx.runtime.validator.BeanValidator; -import jaxx.runtime.validator.BeanValidatorField; -import jaxx.runtime.validator.BeanValidatorScope; import jaxx.runtime.validator.swing.ui.AbstractBeanValidatorUI; import jaxx.runtime.validator.swing.ui.IconValidationUI; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jdesktop.jxlayer.JXLayer; +import org.nuiton.validator.NuitonValidatorFactory; +import org.nuiton.validator.NuitonValidatorProvider; +import org.nuiton.validator.NuitonValidatorScope; +import org.nuiton.validator.bean.BeanValidator; import javax.swing.JComponent; -import javax.swing.SwingUtilities; import java.awt.Container; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -116,10 +116,10 @@ * } * </pre> * + * @param <B> le type de bean a valider * @author poussin <poussin@codelutin.com> * @author tchemit <chemit@codelutin.com> * @version 1.0 - * @param <B> le type de bean a valider */ public class SwingValidator<B> extends BeanValidator<B> { @@ -144,15 +144,27 @@ /** ui renderer class */ protected Class<? extends AbstractBeanValidatorUI> uiClass; + public SwingValidator(NuitonValidatorProvider provider, + Class<B> beanClass, + String contextName, + NuitonValidatorScope... filterScopes) { + super(provider, beanClass, contextName, filterScopes); + fieldRepresentation = new HashMap<String, JComponent>(); + } + public SwingValidator(Class<B> beanClass, String contextName, - BeanValidatorScope... filterScopes) { - super(beanClass, contextName, filterScopes); + NuitonValidatorScope... filterScopes) { + super(NuitonValidatorFactory.getDefaultProvider(), + beanClass, + contextName, + filterScopes + ); fieldRepresentation = new HashMap<String, JComponent>(); } public SwingValidator(Class<B> beanClass, String contextName) { - this(beanClass, contextName, FILTER_SCOPES_EMPTY); + this(beanClass, contextName, NuitonValidatorScope.values()); } /** @@ -163,6 +175,9 @@ */ public void reloadBean() { B b = getBean(); + if (log.isInfoEnabled()) { + log.info("Will reload bean : " + b); + } if (b != null) { setBean(null); setBean(b); @@ -200,14 +215,18 @@ } @Override - public void setContextName(String contextName) { + public void setContext(String context) { + String oldContext = getContext(); - super.setContextName(contextName); + super.setContext(context); - // install uis only when fieldRepresentation is not null - // this case is possible since we come here from parent in constructor. + if (context == null && oldContext == null || context != null && context.equals(oldContext)) { + + // same context do nothing + return; + } if (fieldRepresentation != null) { - + // must reinstall ui installUIs(); } @@ -221,8 +240,10 @@ * @param c the editor component for the field */ public void setFieldRepresentation(String fieldname, JComponent c) { - BeanValidatorField<B> field = getField(fieldname); - if (field == null) { + boolean fieldFound = getDelegate().getEffectiveFields().contains(fieldname); + +// BeanValidatorField<B> field = getField(fieldname); + if (!fieldFound) { // no field registred in the validator if (log.isWarnEnabled()) { log.warn("the field '" + fieldname + @@ -261,29 +282,47 @@ "fieldRepresentation is null, must init before " + "invoking installUIs method..."); } - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - if (uiClass == null) { - // use the default one - uiClass = DEFAULT_UI_CLASS; - } - for (Entry<String, JComponent> entry : - fieldRepresentation.entrySet()) { - try { - setMessageRepresentation( - entry.getKey(), - null, - entry.getValue(), - uiClass - ); - } catch (Exception e) { - throw new RuntimeException(e); - } - } + if (uiClass == null) { + // use the default one + uiClass = DEFAULT_UI_CLASS; + } + for (Entry<String, JComponent> entry : + fieldRepresentation.entrySet()) { + try { + setMessageRepresentation( + entry.getKey(), + null, + entry.getValue(), + uiClass + ); + } catch (Exception e) { + throw new RuntimeException(e); } - }); + } +// SwingUtilities.invokeLater(new Runnable() { +// +// @Override +// public void run() { +// if (uiClass == null) { +// // use the default one +// uiClass = DEFAULT_UI_CLASS; +// } +// for (Entry<String, JComponent> entry : +// fieldRepresentation.entrySet()) { +// try { +// setMessageRepresentation( +// entry.getKey(), +// null, +// entry.getValue(), +// uiClass +// ); +// } catch (Exception e) { +// throw new RuntimeException(e); +// } +// } +// } +// }); } protected void setMessageRepresentation( @@ -299,9 +338,12 @@ // same component, nothing to do return; } - BeanValidatorField<B> field = getField(fieldname); - if (field == null) { + boolean fieldFound = getDelegate().getEffectiveFields().contains(fieldname); + +// BeanValidatorField<B> field = getField(fieldname); + + if (!fieldFound) { // this case should not appear since fieldName has already been // check in method addFieldRepresentation return; @@ -323,14 +365,21 @@ // ajout du jxlayer sous ce composant Container container = c.getParent(); if (container instanceof JXLayer<?>) { + JXLayer jx = (JXLayer<?>) container; + Object oldUI = jx.getUI(); + if (oldUI != null && oldUI instanceof AbstractBeanValidatorUI) { + + // supression de l'ancien layer + removeBeanValidatorListener((AbstractBeanValidatorUI) oldUI); + } Constructor<? extends AbstractBeanValidatorUI> cons = - uiClass.getConstructor(BeanValidatorField.class); - AbstractBeanValidatorUI ui = cons.newInstance(field); + uiClass.getConstructor(String.class); + AbstractBeanValidatorUI ui = cons.newInstance(fieldname); ui.setEnabled(true); - JXLayer<JComponent> jx = (JXLayer<JComponent>) container; addBeanValidatorListener(ui); jx.setUI(ui); } } } + } Modified: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessage.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessage.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessage.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -24,9 +24,8 @@ */ package jaxx.runtime.validator.swing; -import jaxx.runtime.validator.BeanValidatorField; -import jaxx.runtime.validator.BeanValidatorMessage; -import jaxx.runtime.validator.BeanValidatorScope; +import org.nuiton.validator.NuitonValidatorScope; +import org.nuiton.validator.bean.BeanValidatorMessage; import javax.swing.JComponent; @@ -39,28 +38,17 @@ */ public class SwingValidatorMessage extends BeanValidatorMessage<SwingValidatorMessage> { + private static final long serialVersionUID = 1L; + /** the optional field's editor */ protected JComponent editor; - protected String fieldName; - public SwingValidatorMessage(SwingValidator<?> validator, - BeanValidatorField<?> field, - String message, - BeanValidatorScope scope, - JComponent editor) { - super(validator, field, message, scope); - fieldName = field.getName(); - this.editor = editor; - } - - public SwingValidatorMessage(SwingValidator<?> validator, String fieldName, String message, - BeanValidatorScope scope, + NuitonValidatorScope scope, JComponent editor) { - super(validator, null, message, scope); - this.fieldName = fieldName; + super(validator, fieldName, message, scope); this.editor = editor; } @@ -68,53 +56,58 @@ return editor; } + /** + * @return the field name + * @deprecated since 2.3, will not be replaced + */ + @Deprecated public String getFieldName() { - return fieldName; + return getField(); } - @Override - public int compareTo(SwingValidatorMessage o) { - // sort on scope - int result = getScope().compareTo(o.getScope()); - if (result == 0) { - // sort on field name - result = fieldName.compareTo(o.getFieldName()); - if (result == 0) { - // sort on message - result = message.compareTo(o.getMessage()); - } - } - return result; - } +// @Override +// public int compareTo(SwingValidatorMessage o) { +// // sort on scope +// int result = getScope().compareTo(o.getScope()); +// if (result == 0) { +// // sort on field name +// result = fieldName.compareTo(o.getField()); +// if (result == 0) { +// // sort on message +// result = message.compareTo(o.getMessage()); +// } +// } +// return result; +// } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } +// @Override +// public boolean equals(Object o) { +// if (this == o) { +// return true; +// } +// if (o == null || getClass() != o.getClass()) { +// return false; +// } +// +// SwingValidatorMessage that = (SwingValidatorMessage) o; +// +// return fieldName.equals(that.fieldName) && +// message.equals(that.message) && +// scope == that.scope; +// } - SwingValidatorMessage that = (SwingValidatorMessage) o; +// @Override +// public int hashCode() { +// int result = fieldName.hashCode(); +// result = 31 * result + message.hashCode(); +// result = 31 * result + scope.hashCode(); +// return result; +// } - return fieldName.equals(that.fieldName) && - message.equals(that.message) && - scope == that.scope; - } - @Override - public int hashCode() { - int result = fieldName.hashCode(); - result = 31 * result + message.hashCode(); - result = 31 * result + scope.hashCode(); - return result; - } - - @Override public String toString() { String s = scope + " - " + - (field == null ? message : field.getI18nError(message)); + (field == null ? message : field + " - " + message); if (editor == null) { return s; } Modified: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListModel.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListModel.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListModel.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -24,12 +24,11 @@ */ package jaxx.runtime.validator.swing; -import jaxx.runtime.validator.BeanValidatorEvent; -import jaxx.runtime.validator.BeanValidatorField; -import jaxx.runtime.validator.BeanValidatorListener; -import jaxx.runtime.validator.BeanValidatorScope; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.nuiton.validator.NuitonValidatorScope; +import org.nuiton.validator.bean.BeanValidatorEvent; +import org.nuiton.validator.bean.BeanValidatorListener; import javax.swing.AbstractListModel; import javax.swing.JComponent; @@ -100,8 +99,8 @@ public void onFieldChanged(BeanValidatorEvent event) { String[] toDelete = event.getMessagesToDelete(); String[] toAdd = event.getMessagesToAdd(); - BeanValidatorField<?> field = event.getField(); - BeanValidatorScope scope = event.getScope(); + String field = event.getField(); + NuitonValidatorScope scope = event.getScope(); boolean mustAdd = toAdd != null && toAdd.length > 0; boolean mustDel = toDelete != null && toDelete.length > 0; @@ -135,12 +134,12 @@ } protected void addMessages(SwingValidator<?> validator, - BeanValidatorField<?> field, - BeanValidatorScope scope, + String field, + NuitonValidatorScope scope, boolean sort, String... messages) { - JComponent editor = validator.getFieldRepresentation(field.getName()); + JComponent editor = validator.getFieldRepresentation(field); // add new errors for (String error : messages) { SwingValidatorMessage row = new SwingValidatorMessage( @@ -167,8 +166,8 @@ } protected void removeMessages(SwingValidator<?> validator, - BeanValidatorField<?> field, - BeanValidatorScope scope, + String field, + NuitonValidatorScope scope, boolean notify, String... messages) { Modified: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListRenderer.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListRenderer.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListRenderer.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -24,7 +24,7 @@ */ package jaxx.runtime.validator.swing; -import jaxx.runtime.validator.BeanValidatorScope; +import org.nuiton.validator.NuitonValidatorScope; import javax.swing.DefaultListCellRenderer; import javax.swing.ImageIcon; @@ -89,7 +89,7 @@ // field name String fieldName = getFieldName( list, - model.getField().getName(), + model.getField(), index ); @@ -113,7 +113,7 @@ return rendererComponent; } - public ImageIcon getIcon(BeanValidatorScope scope) { + public ImageIcon getIcon(NuitonValidatorScope scope) { ImageIcon icon = SwingValidatorUtil.getIcon(scope); return icon; } Modified: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableModel.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableModel.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableModel.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -24,12 +24,11 @@ */ package jaxx.runtime.validator.swing; -import jaxx.runtime.validator.BeanValidatorEvent; -import jaxx.runtime.validator.BeanValidatorField; -import jaxx.runtime.validator.BeanValidatorListener; -import jaxx.runtime.validator.BeanValidatorScope; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.nuiton.validator.NuitonValidatorScope; +import org.nuiton.validator.bean.BeanValidatorEvent; +import org.nuiton.validator.bean.BeanValidatorListener; import javax.swing.JComponent; import javax.swing.table.AbstractTableModel; @@ -60,7 +59,7 @@ {"validator.scope", "validator.field", "validator.message"}; public static final Class<?>[] columnClasses = - {BeanValidatorScope.class, String.class, String.class}; + {NuitonValidatorScope.class, String.class, String.class}; /** list of registred validators */ protected transient List<SwingValidator<?>> validators; @@ -93,27 +92,20 @@ public void addMessages(SwingValidator<?> validator, String fieldName, - BeanValidatorScope scope, + NuitonValidatorScope scope, String... messages) { addMessages(validator, fieldName, scope, true, messages); } public void addMessages(JComponent editor, String fieldName, - BeanValidatorScope scope, + NuitonValidatorScope scope, String... messages) { addMessages(editor, fieldName, scope, true, messages); } - public void addMessages(SwingValidator<?> validator, - BeanValidatorField<?> field, - BeanValidatorScope scope, - String... messages) { - addMessages(validator, field, scope, true, messages); - } + public void removeMessages(JComponent editor, NuitonValidatorScope scope) { - public void removeMessages(JComponent editor, BeanValidatorScope scope) { - if (editor == null) { // no editor, so nothing to do return; @@ -134,24 +126,17 @@ public void removeMessages(SwingValidator<?> validator, String fieldName, - BeanValidatorScope scope, + NuitonValidatorScope scope, String... messages) { removeMessages(validator, fieldName, scope, true, messages); } public void removeMessages(JComponent editor, String fieldName, - BeanValidatorScope scope) { + NuitonValidatorScope scope) { removeMessages(editor, fieldName, scope, true); } - public void removeMessages(SwingValidator<?> validator, - BeanValidatorField<?> field, - BeanValidatorScope scope, - String... messages) { - removeMessages(validator, field, scope, true, messages); - } - public void clear() { int i = data.size(); if (i > 0) { @@ -200,8 +185,8 @@ public void onFieldChanged(BeanValidatorEvent event) { String[] toDelete = event.getMessagesToDelete(); String[] toAdd = event.getMessagesToAdd(); - BeanValidatorField<?> field = event.getField(); - BeanValidatorScope scope = event.getScope(); + String field = event.getField(); + NuitonValidatorScope scope = event.getScope(); boolean mustAdd = toAdd != null && toAdd.length > 0; boolean mustDel = toDelete != null && toDelete.length > 0; @@ -248,7 +233,7 @@ } if (columnIndex == 1) { // the field - return row.getFieldName(); + return row.getField(); } if (columnIndex == 2) { // the message @@ -278,43 +263,8 @@ } protected void addMessages(SwingValidator<?> validator, - BeanValidatorField<?> field, - BeanValidatorScope scope, - boolean sort, - String... messages) { - - JComponent editor = validator == null ? - null : - validator.getFieldRepresentation(field.getName()); - // add new errors - for (String error : messages) { - SwingValidatorMessage row = - new SwingValidatorMessage( - validator, - field, - error, - scope, - editor - ); - data.add(row); - if (!sort) { - fireTableRowsInserted(data.size() - 1, data.size() - 1); - } - } - - if (sort) { - - // resort datas - Collections.sort(data); - - // notify - fireTableDataChanged(); - } - } - - protected void addMessages(SwingValidator<?> validator, String fieldName, - BeanValidatorScope scope, + NuitonValidatorScope scope, boolean sort, String... messages) { @@ -349,7 +299,7 @@ protected void addMessages(JComponent editor, String fieldName, - BeanValidatorScope scope, + NuitonValidatorScope scope, boolean sort, String... messages) { @@ -380,35 +330,8 @@ } protected void removeMessages(SwingValidator<?> validator, - BeanValidatorField<?> field, - BeanValidatorScope scope, - boolean notify, - String... messages) { - - List<String> messagesToDel = - new ArrayList<String>(Arrays.asList(messages)); - - // do it in reverse mode (only one pass in that way since index - // will stay coherent while removing them) - - for (int i = getRowCount() - 1; i > -1; i--) { - SwingValidatorMessage error = data.get(i); - if (validator.equals(error.getValidator()) && - error.getScope() == scope && - error.getFieldName().equals(field.getName()) && - messagesToDel.contains(error.getMessage())) { - // remove the message - data.remove(i); - if (notify) { - fireTableRowsDeleted(i, i); - } - } - } - } - - protected void removeMessages(SwingValidator<?> validator, String fieldName, - BeanValidatorScope scope, + NuitonValidatorScope scope, boolean notify, String... messages) { @@ -422,7 +345,7 @@ SwingValidatorMessage error = data.get(i); if (validator.equals(error.getValidator()) && error.getScope() == scope && - error.getFieldName().equals(fieldName) && + error.getField().equals(fieldName) && messagesToDel.contains(error.getMessage())) { // remove the message data.remove(i); @@ -435,7 +358,7 @@ protected void removeMessages(JComponent editor, String fieldName, - BeanValidatorScope scope, + NuitonValidatorScope scope, boolean notify) { // do it in reverse mode (only one pass in that way since index @@ -445,7 +368,7 @@ SwingValidatorMessage error = data.get(i); if (editor.equals(error.getEditor()) && (scope == null || error.getScope() == scope) && - error.getFieldName().equals(fieldName)) { + error.getField().equals(fieldName)) { // remove the message data.remove(i); if (notify) { Modified: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableRenderer.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableRenderer.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableRenderer.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -24,7 +24,7 @@ */ package jaxx.runtime.validator.swing; -import jaxx.runtime.validator.BeanValidatorScope; +import org.nuiton.validator.NuitonValidatorScope; import javax.swing.ImageIcon; import javax.swing.JLabel; @@ -72,11 +72,10 @@ row = table.getRowSorter().convertRowIndexToModel(row); } - switch (column) { case 0: // scope - BeanValidatorScope scope = (BeanValidatorScope) value; + NuitonValidatorScope scope = (NuitonValidatorScope) value; icon = SwingValidatorUtil.getIcon(scope); String label = _(scope.getLabel()); toolTipText = _("validator.scope.tip", label); @@ -101,7 +100,7 @@ return rendererComponent; } - public ImageIcon getIcon(BeanValidatorScope scope) { + public ImageIcon getIcon(NuitonValidatorScope scope) { ImageIcon icon = SwingValidatorUtil.getIcon(scope); return icon; } Modified: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorUtil.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorUtil.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorUtil.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -26,10 +26,13 @@ import jaxx.runtime.JAXXValidator; import jaxx.runtime.SwingUtil; -import jaxx.runtime.validator.BeanValidatorScope; -import jaxx.runtime.validator.BeanValidatorUtil; +import jaxx.runtime.validator.swing.meta.Validator; +import jaxx.runtime.validator.swing.meta.ValidatorField; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.nuiton.util.ReflectUtil; +import org.nuiton.validator.NuitonValidatorScope; +import org.nuiton.validator.bean.BeanValidatorUtil; import javax.swing.ImageIcon; import javax.swing.JComponent; @@ -37,10 +40,17 @@ import javax.swing.JTable; import javax.swing.RowSorter; import javax.swing.SortOrder; +import java.awt.Color; import java.awt.event.MouseListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.lang.reflect.Field; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; import static org.nuiton.i18n.I18n.n_; @@ -51,48 +61,138 @@ */ public class SwingValidatorUtil extends BeanValidatorUtil { - static ImageIcon fatalIcon; + /** Logger */ + static private final Log log = LogFactory.getLog(SwingValidatorUtil.class); - static ImageIcon errorIcon; + protected static EnumMap<NuitonValidatorScope, ImageIcon> icons; - static ImageIcon warningIcon; + protected static EnumMap<NuitonValidatorScope, Color> colors; - static ImageIcon infoIcon; + public static EnumMap<NuitonValidatorScope, ImageIcon> getIcons() { + if (icons == null) { + icons = new EnumMap<NuitonValidatorScope, ImageIcon>(NuitonValidatorScope.class); + icons.put(NuitonValidatorScope.FATAL, SwingUtil.createImageIcon("fatal.png")); + icons.put(NuitonValidatorScope.ERROR, SwingUtil.createImageIcon("error.png")); + icons.put(NuitonValidatorScope.WARNING, SwingUtil.createImageIcon("warning.png")); + icons.put(NuitonValidatorScope.INFO, SwingUtil.createImageIcon("info.png")); + } + return icons; + } - /** Logger */ - static private final Log log = LogFactory.getLog(SwingValidatorUtil.class); + public static EnumMap<NuitonValidatorScope, Color> getColors() { + if (colors == null) { + colors = new EnumMap<NuitonValidatorScope, Color>(NuitonValidatorScope.class); + colors.put(NuitonValidatorScope.FATAL, Color.MAGENTA); + colors.put(NuitonValidatorScope.ERROR, Color.RED); + colors.put(NuitonValidatorScope.WARNING, Color.YELLOW); + colors.put(NuitonValidatorScope.INFO, Color.GREEN); + } + return colors; + } + public static Color getColor(NuitonValidatorScope scope) { + Color c = scope == null ? null : getColors().get(scope); + return c; + } + public static ImageIcon getIcon(NuitonValidatorScope scope) { + ImageIcon icon = scope == null ? null : getIcons().get(scope); + return icon; + } + public static ImageIcon getFatalIcon() { - if (fatalIcon == null) { - fatalIcon = SwingUtil.createImageIcon("fatal.png"); - } - return fatalIcon; + return getIcons().get(NuitonValidatorScope.FATAL); } public static ImageIcon getErrorIcon() { - if (errorIcon == null) { - errorIcon = SwingUtil.createImageIcon("error.png"); - } - return errorIcon; + return getIcons().get(NuitonValidatorScope.ERROR); } + public static ImageIcon getWarningIcon() { + return getIcons().get(NuitonValidatorScope.WARNING); + } + public static ImageIcon getInfoIcon() { - if (infoIcon == null) { - infoIcon = SwingUtil.createImageIcon("info.png"); + return getIcons().get(NuitonValidatorScope.INFO); + } + + protected SwingValidatorUtil() { + // no instance + } + + public static List<String> initUI(JAXXValidator ui) { + List<String> validatorIds = new ArrayList<String>(); + Map<Field, Validator> validators = ReflectUtil.getFieldAnnotation( + ui.getClass(), + Validator.class + ); + + for (Map.Entry<Field, Validator> entry : validators.entrySet()) { + Field field = entry.getKey(); + Validator annotation = entry.getValue(); + String validatorId = annotation.validatorId(); + validatorIds.add(validatorId); + if (log.isInfoEnabled()) { + log.info("Detect validator [" + annotation.validatorId() + "] on field " + field.getName()); + } } - return infoIcon; + return Collections.unmodifiableList(validatorIds); } - public static ImageIcon getWarningIcon() { - if (warningIcon == null) { - warningIcon = SwingUtil.createImageIcon("warning.png"); + public static void installFields(JAXXValidator ui) { + + Map<Field, ValidatorField> validatorFields = ReflectUtil.getFieldAnnotation( + ui.getClass(), + ValidatorField.class + ); + + List<String> validatorIds = ui.getValidatorIds(); + + try { + for (String validatorId : validatorIds) { + SwingValidator<?> validator = (SwingValidator<?>) ui.getValidator(validatorId); + for (Map.Entry<Field, ValidatorField> fieldEntry : validatorFields.entrySet()) { + Field validatorField = fieldEntry.getKey(); + validatorField.setAccessible(true); + ValidatorField fieldAnnotation = fieldEntry.getValue(); + JComponent editor = (JComponent) validatorField.get(ui); + if (!validatorId.equals(fieldAnnotation.validatorId())) { + + // not good validator, skip this field + continue; + } + String propertyName = fieldAnnotation.propertyName(); + if (log.isInfoEnabled()) { + log.info("Detects for validator [" + validatorId + "] property " + propertyName + " for editor " + fieldAnnotation.editorName()); + } + validator.setFieldRepresentation(propertyName, editor); + } + } + } catch (IllegalAccessException e) { + throw new IllegalStateException("Could not init validators on ui " + ui, e); } - return warningIcon; + } - protected SwingValidatorUtil() { - // no instance + public static void installUI(JAXXValidator ui) { + + // first install fields with validation + installFields(ui); + + // for each validator install uis + reload bean + + List<String> validatorIds = ui.getValidatorIds(); + for (String validatorId : validatorIds) { + SwingValidator<?> validator = (SwingValidator<?>) ui.getValidator(validatorId); + + // install uis + validator.installUIs(); + + // reload attached bean (to see validation on uis) + validator.reloadBean(); + } + + } /** @@ -206,7 +306,7 @@ public static String getMessage(SwingValidatorMessage model) { String text = model.getMessage(); if (model.getField() != null) { - text = model.getField().getI18nError(text); + text = model.getI18nError(text); } return text; } @@ -228,25 +328,6 @@ return text; } - public static ImageIcon getIcon(BeanValidatorScope scope) { - ImageIcon icon = null; - switch (scope) { - case FATAL: - icon = getFatalIcon(); - break; - case ERROR: - icon = getErrorIcon(); - break; - case WARNING: - icon = getWarningIcon(); - break; - case INFO: - icon = getInfoIcon(); - break; - } - return icon; - } - /** * Method to listen the modification of the context name and at each time * reload fields of the ui. @@ -262,13 +343,13 @@ SwingValidator<?> validator = (SwingValidator<?>) evt.getSource(); if (log.isInfoEnabled()) { log.info("Context name changed to [" + evt.getNewValue() + - "] for validator " + validator.getBeanClass()); + "] for validator " + validator.getType()); } ui.registerValidatorFields(); } }; validator.addPropertyChangeListener( - SwingValidator.CONTEXT_NAME_PROPERTY, + SwingValidator.CONTEXT_PROPERTY, listener ); } Added: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/meta/Validator.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/meta/Validator.java (rev 0) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/meta/Validator.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -0,0 +1,24 @@ +package jaxx.runtime.validator.swing.meta; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation to put on each field validator. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.3 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Validator { + + /** + * Obtain the id of the validator. + * + * @return the id of the validator. + */ + String validatorId(); +} Property changes on: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/meta/Validator.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/meta/ValidatorField.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/meta/ValidatorField.java (rev 0) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/meta/ValidatorField.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -0,0 +1,39 @@ +package jaxx.runtime.validator.swing.meta; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation to put on each field linked to a validator. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.3 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface ValidatorField { + /** + * Obtain the id of the validator used for the field. + * + * @return the id of the validator used for the field. + */ + String validatorId(); + + /** + * Obtain the name of the bean property to validate. + * + * @return the name of the property to validate + */ + String propertyName(); + + /** + * Obtain the name of the property editor. + * <p/> + * If empty, then use the {@link #propertyName()}. + * + * @return the name of the property editor + */ + String editorName() default ""; +} Property changes on: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/meta/ValidatorField.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/ui/AbstractBeanValidatorUI.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/ui/AbstractBeanValidatorUI.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/ui/AbstractBeanValidatorUI.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -24,12 +24,12 @@ */ package jaxx.runtime.validator.swing.ui; -import jaxx.runtime.validator.BeanValidatorEvent; -import jaxx.runtime.validator.BeanValidatorField; -import jaxx.runtime.validator.BeanValidatorListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jdesktop.jxlayer.plaf.AbstractLayerUI; +import org.nuiton.validator.NuitonValidatorScope; +import org.nuiton.validator.bean.BeanValidatorEvent; +import org.nuiton.validator.bean.BeanValidatorListener; import javax.swing.JComponent; @@ -43,19 +43,36 @@ /** Logger */ private static final Log log = LogFactory.getLog(AbstractBeanValidatorUI.class); - /** the field to render */ - protected BeanValidatorField<?> field; + /** + * Actual scope to display in the layer. + * <p/> + * This field will be recomputed each time a new event arrived on this + * field. + */ + protected NuitonValidatorScope scope; - public AbstractBeanValidatorUI(BeanValidatorField<?> field) { + /** Field name in validator. */ + protected final String field; + + public AbstractBeanValidatorUI(String field) { this.field = field; if (log.isDebugEnabled()) { log.debug("install " + this + "<field:" + field + ">"); } } + public NuitonValidatorScope getScope() { + return scope; + } + @Override public void onFieldChanged(BeanValidatorEvent event) { if (field.equals(event.getField())) { + + scope = event.getSource().getHighestScope(field); + if (log.isDebugEnabled()) { + log.debug("set new scope : " + scope + " to field " + field); + } // ask to repaint the layer setDirty(true); } Modified: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/ui/IconValidationUI.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/ui/IconValidationUI.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/ui/IconValidationUI.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -24,9 +24,9 @@ */ package jaxx.runtime.validator.swing.ui; -import jaxx.runtime.validator.BeanValidatorField; -import jaxx.runtime.validator.BeanValidatorScope; +import jaxx.runtime.validator.swing.SwingValidatorUtil; import org.jdesktop.jxlayer.JXLayer; +import org.nuiton.validator.NuitonValidatorScope; import javax.swing.BorderFactory; import javax.swing.JComponent; @@ -34,6 +34,7 @@ import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; +import java.util.EnumMap; /** @@ -46,28 +47,17 @@ // The icon to be shown at the layer's corner - protected static BufferedImage fatalIcon; + protected EnumMap<NuitonValidatorScope, BufferedImage> icons; - protected static BufferedImage errorIcon; + public IconValidationUI(String field) { + super(field); + icons = new EnumMap<NuitonValidatorScope, BufferedImage>(NuitonValidatorScope.class); - protected static BufferedImage warningIcon; + for (NuitonValidatorScope scope : NuitonValidatorScope.values()) { - protected static BufferedImage infoIcon; - - public IconValidationUI(BeanValidatorField<?> field) { - super(field); - if (fatalIcon == null) { - fatalIcon = prepareIcon(Color.MAGENTA); + BufferedImage image = prepareIcon(SwingValidatorUtil.getColor(scope)); + icons.put(scope, image); } - if (errorIcon == null) { - errorIcon = prepareIcon(Color.RED); - } - if (warningIcon == null) { - warningIcon = prepareIcon(Color.ORANGE); - } - if (infoIcon == null) { - infoIcon = prepareIcon(Color.GREEN); - } } @Override @@ -86,26 +76,10 @@ protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) { super.paintLayer(g2, l); // There is no need to take insets into account for this painter - BeanValidatorScope scope = field.getScope(); + NuitonValidatorScope scope = getScope(); if (scope != null) { - BufferedImage icon = null; - switch (scope) { - case FATAL: - icon = fatalIcon; - break; - case ERROR: - icon = errorIcon; - break; - case WARNING: - icon = warningIcon; - break; - case INFO: - icon = infoIcon; - break; - } - if (icon != null) { - g2.drawImage(icon, l.getWidth() - icon.getWidth() - 1, 0, null); - } + BufferedImage icon = icons.get(scope); + g2.drawImage(icon, l.getWidth() - icon.getWidth() - 1, 0, null); } } @@ -124,4 +98,6 @@ g2.dispose(); return icon; } + + } Modified: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/ui/ImageValidationUI.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/ui/ImageValidationUI.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/ui/ImageValidationUI.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -24,10 +24,9 @@ */ package jaxx.runtime.validator.swing.ui; -import jaxx.runtime.SwingUtil; -import jaxx.runtime.validator.BeanValidatorField; -import jaxx.runtime.validator.BeanValidatorScope; +import jaxx.runtime.validator.swing.SwingValidatorUtil; import org.jdesktop.jxlayer.JXLayer; +import org.nuiton.validator.NuitonValidatorScope; import javax.swing.BorderFactory; import javax.swing.ImageIcon; @@ -35,6 +34,7 @@ import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; +import java.util.EnumMap; /** @@ -45,28 +45,17 @@ */ public class ImageValidationUI extends AbstractBeanValidatorUI { - protected static BufferedImage fatalIcon; + protected EnumMap<NuitonValidatorScope, BufferedImage> icons; - protected static BufferedImage errorIcon; + public ImageValidationUI(String field) { + super(field); + icons = new EnumMap<NuitonValidatorScope, BufferedImage>(NuitonValidatorScope.class); - protected static BufferedImage warningIcon; + for (NuitonValidatorScope scope : NuitonValidatorScope.values()) { - protected static BufferedImage infoIcon; - - public ImageValidationUI(BeanValidatorField<?> field) { - super(field); - if (fatalIcon == null) { - fatalIcon = prepareIcon(SwingUtil.createImageIcon("fatal.png")); + BufferedImage image = prepareIcon(SwingValidatorUtil.getIcon(scope)); + icons.put(scope, image); } - if (errorIcon == null) { - errorIcon = prepareIcon(SwingUtil.createImageIcon("error.png")); - } - if (warningIcon == null) { - warningIcon = prepareIcon(SwingUtil.createImageIcon("warning.png")); - } - if (infoIcon == null) { - infoIcon = prepareIcon(SwingUtil.createImageIcon("info.png")); - } } protected static BufferedImage prepareIcon(ImageIcon image) { @@ -94,26 +83,27 @@ @Override protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) { super.paintLayer(g2, l); - BeanValidatorScope scope = field.getScope(); + NuitonValidatorScope scope = getScope(); if (scope != null) { - BufferedImage icon = null; - switch (scope) { - case FATAL: - icon = fatalIcon; - break; - case ERROR: - icon = errorIcon; - break; - case WARNING: - icon = warningIcon; - break; - case INFO: - icon = infoIcon; - break; - } - if (icon != null) { - g2.drawImage(icon, l.getWidth() - icon.getWidth() - 1, 0, null); - } + BufferedImage icon = icons.get(scope); + g2.drawImage(icon, l.getWidth() - icon.getWidth() - 1, 0, null); +// switch (scope) { +// case FATAL: +// icon = fatalIcon; +// break; +// case ERROR: +// icon = errorIcon; +// break; +// case WARNING: +// icon = warningIcon; +// break; +// case INFO: +// icon = infoIcon; +// break; +// } +// if (icon != null) { +// g2.drawImage(icon, l.getWidth() - icon.getWidth() - 1, 0, null); +// } } } } Modified: trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/ui/TranslucentValidationUI.java =================================================================== --- trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/ui/TranslucentValidationUI.java 2011-01-25 11:44:38 UTC (rev 2160) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/ui/TranslucentValidationUI.java 2011-01-25 11:56:47 UTC (rev 2161) @@ -24,9 +24,9 @@ */ package jaxx.runtime.validator.swing.ui; -import jaxx.runtime.validator.BeanValidatorField; -import jaxx.runtime.validator.BeanValidatorScope; +import jaxx.runtime.validator.swing.SwingValidatorUtil; import org.jdesktop.jxlayer.JXLayer; +import org.nuiton.validator.NuitonValidatorScope; import javax.swing.JComponent; import java.awt.AlphaComposite; @@ -44,20 +44,8 @@ */ public class TranslucentValidationUI extends AbstractBeanValidatorUI { - protected Color fatalHightlight; - - protected Color errorHightlight; - - protected Color warningHightlight; - - protected Color infoHightlight; - - public TranslucentValidationUI(BeanValidatorField<?> field) { + public TranslucentValidationUI(String field) { super(field); - fatalHightlight = Color.MAGENTA; - errorHightlight = Color.RED; - warningHightlight = Color.YELLOW; - infoHightlight = Color.GREEN; } @Override @@ -76,27 +64,10 @@ view.getWidth() - insets.left - insets.right, view.getHeight() - insets.top - insets.bottom)); - BeanValidatorScope scope = field.getScope(); + NuitonValidatorScope scope = getScope(); - if (scope == null) { - g2.setColor(Color.WHITE); - } else { - switch (scope) { - case FATAL: - g2.setColor(fatalHightlight); - break; - case ERROR: - g2.setColor(errorHightlight); - break; - case WARNING: - g2.setColor(warningHightlight); - break; - case INFO: - g2.setColor(infoHightlight); - break; - } - } - + Color c = scope == null ? Color.WHITE : SwingValidatorUtil.getColor(scope); + g2.setColor(c); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .2f)); g2.fillRect(0, 0, l.getWidth(), l.getHeight()); }