r1000 - in lutinjaxx/trunk/jaxx-core: . src/main/java/jaxx/runtime src/main/java/jaxx/runtime/validator
Author: tchemit Date: 2008-10-27 11:08:21 +0000 (Mon, 27 Oct 2008) New Revision: 1000 Modified: lutinjaxx/trunk/jaxx-core/changelog lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/Util.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidator.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidatorErrorListModel.java Log: add conversion support in validator Modified: lutinjaxx/trunk/jaxx-core/changelog =================================================================== --- lutinjaxx/trunk/jaxx-core/changelog 2008-10-27 10:40:48 UTC (rev 999) +++ lutinjaxx/trunk/jaxx-core/changelog 2008-10-27 11:08:21 UTC (rev 1000) @@ -1,4 +1,5 @@ ver-0-6 chemit 200811?? + * 20081027 [chemit] add conversion support in validator * 20081025 [chemit] improve BeanValidator tag : - add a errorList attribute for set a ErrorListMouseListener on the errorList - add a beanInitializer attribute for set the validator's bean at runtime Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/Util.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/Util.java 2008-10-27 10:40:48 UTC (rev 999) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/Util.java 2008-10-27 11:08:21 UTC (rev 1000) @@ -1,5 +1,6 @@ package jaxx.runtime; +import jaxx.runtime.validator.BeanValidator; import jaxx.runtime.validator.ErrorListMouseListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -276,6 +277,38 @@ } /** + * 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 (IntrospectionException e) { + log.error("could not obtain beanInfo for " + valueClass.getClass() + ", reason : " + e.getMessage(), e); + } catch (InvocationTargetException e) { + log.error("could not obtain beanInfo for " + valueClass.getClass() + ", reason : " + e.getMessage(), e); + } catch (IllegalAccessException e) { + log.error("could not obtain beanInfo for " + valueClass.getClass() + ", reason : " + e.getMessage(), e); + } + } + } + + /** * recherche les composants portant le meme nom que les champs de la classe * clazz. Cette methode est statique pour pouvoir eventuellement l'utiliser * dans un autre context (je pense par exemple a la generation jaxx). Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidator.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidator.java 2008-10-27 10:40:48 UTC (rev 999) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidator.java 2008-10-27 11:08:21 UTC (rev 1000) @@ -32,13 +32,17 @@ import com.opensymphony.xwork2.validator.ValidationException; import jaxx.runtime.validator.ui.AbstractBeanValidatorUI; import jaxx.runtime.validator.ui.IconValidationUI; +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.codelutin.util.ConverterUtil; import org.jdesktop.jxlayer.JXLayer; import javax.swing.JComponent; import javax.swing.SwingUtilities; import java.awt.Container; +import java.beans.Introspector; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; @@ -46,8 +50,12 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; /** * <p/> @@ -153,17 +161,20 @@ /** Object servant a contenir la liste des erreurs */ protected BeanValidatorErrorListModel errorListModel; - /** ui renderer class*/ + /** ui renderer class */ protected Class<? extends AbstractBeanValidatorUI> uiClass; /** validator context */ protected ActionContext context; - + + protected Map<String, String> conversionErrors; + public BeanValidator() { pcs = new PropertyChangeSupport(this); validationSupport = new ValidationAwareSupport(); validationContext = new DelegatingValidatorContext(validationSupport); fieldRepresentation = new HashMap<String, JComponent>(); + conversionErrors = new TreeMap<String, String>(); } public BeanValidatorErrorListModel getErrorListModel() { @@ -229,6 +240,9 @@ public void setBean(T bean) { T oldBean = this.bean; + + // clean conversions of previous bean + conversionErrors.clear(); if (this.bean != null) { try { Method method = this.bean.getClass().getMethod("removePropertyChangeListener", PropertyChangeListener.class); @@ -261,7 +275,7 @@ /** @return <code>true</code> if errors are detected, <code>false</code> otherwise */ public boolean hasErrors() { //todo should also detecte actionErrors ? - return validationContext.hasFieldErrors(); + return validationContext.hasFieldErrors() || !conversionErrors.isEmpty(); //return validationContext.hasFieldErrors() || validationContext.hasActionErrors(); } @@ -277,6 +291,10 @@ return validationContext.getActionMessages(); } + public Map<String, String> getConversionErrors() { + return conversionErrors; + } + /** install ui on required components */ public void installUIs() { SwingUtilities.invokeLater(new Runnable() { @@ -298,6 +316,52 @@ } /** + * Convert a value. + * <p/> + * If an error occurs, then add an error in validator. + * + * @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 + */ + public <T> T convert(String fieldName, String value, Class<T> valueClass) { + 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 (bean == null || getErrorListModel() == null || fieldRepresentation.size() == 0 || 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); + if (result != null && !value.equals(result.toString())) { + conversionErrors.put(fieldName, "error.convertor." + Introspector.decapitalize(valueClass.getSimpleName())); + result = null; + validate(); + } + } catch (ConversionException e) { + // get + conversionErrors.put(fieldName, "error.convertor." + Introspector.decapitalize(valueClass.getSimpleName())); + result = null; + validate(); + } + + return result; + } + + /** * 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 @@ -319,6 +383,9 @@ getValidator().validate(bean, null, validationContext); + // add the registred conversion errors + transfertConversionErrorsToFieldErrors(); + if (log.isDebugEnabled()) { log.debug("Action errors: " + validationContext.getActionErrors()); log.debug("Action messages: " + validationContext.getActionMessages()); @@ -357,7 +424,7 @@ ActionValidatorManager.class, "no-annotations"); } //TC - 20081024 : since context is in a ThreadLocal variable, we must do the check - if (ActionContext.getContext()==null) { + if (ActionContext.getContext() == null) { ActionContext.setContext(context); } return validator; @@ -387,6 +454,29 @@ } } + /** + * Transfer the registred conversion errors to fieldErrors. + * <p/> + * The previously filed errors of a given field where a conversion error occurs will be removed. + */ + protected void transfertConversionErrorsToFieldErrors() { + Map map = getFieldErrors(); + for (Entry<String, String> entry : conversionErrors.entrySet()) { + // remove from validation, errors occurs on this field + List errors = (List) map.get(entry.getKey()); + if (errors != null) { + errors.clear(); + errors.add(entry.getValue()); + } else { + errors = Collections.singletonList(entry.getValue()); + } + // add the concrete conversion error + map.put(entry.getKey(), errors); + } + validationContext.setFieldErrors(map); + } + + protected class Listener implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent evt) { Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidatorErrorListModel.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidatorErrorListModel.java 2008-10-27 10:40:48 UTC (rev 999) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidatorErrorListModel.java 2008-10-27 11:08:21 UTC (rev 1000) @@ -93,7 +93,6 @@ Map.Entry<?, ?> r = (Map.Entry<?, ?>) o; BeanValidatorError<T> error; String field = (String) r.getKey(); - JComponent component = validator.getFieldRepresentation(field); if (component!=null) { for (Object errorString : (List<?>) r.getValue()) {
participants (1)
-
tchemit@users.labs.libre-entreprise.org