r2178 - in trunk: jaxx-compiler/src/main/java/jaxx/compiler/finalizers jaxx-compiler/src/main/java/jaxx/compiler/tags/validator jaxx-validator/src/main/java/jaxx/runtime/validator/swing jaxx-validator/src/main/java/jaxx/runtime/validator/swing/meta
Author: tchemit Date: 2011-01-26 15:41:27 +0100 (Wed, 26 Jan 2011) New Revision: 2178 Url: http://nuiton.org/repositories/revision/jaxx/2178 Log: Evolution #1240: Review the validation api Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorFinalizer.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/validator/BeanValidatorHandler.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorUtil.java trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/meta/ValidatorField.java Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorFinalizer.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorFinalizer.java 2011-01-26 14:39:52 UTC (rev 2177) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorFinalizer.java 2011-01-26 14:41:27 UTC (rev 2178) @@ -27,9 +27,11 @@ import jaxx.compiler.CompiledObject; import jaxx.compiler.CompiledObject.ChildRef; +import jaxx.compiler.CompilerException; import jaxx.compiler.JAXXCompiler; import jaxx.compiler.JAXXCompilerFinalizer; import jaxx.compiler.java.JavaArgument; +import jaxx.compiler.java.JavaElement; import jaxx.compiler.java.JavaField; import jaxx.compiler.java.JavaFile; import jaxx.compiler.java.JavaFileGenerator; @@ -37,14 +39,19 @@ import jaxx.compiler.reflect.ClassDescriptorHelper; import jaxx.compiler.tags.validator.BeanValidatorHandler; import jaxx.compiler.tags.validator.BeanValidatorHandler.CompiledBeanValidator; +import jaxx.compiler.types.TypeManager; import jaxx.runtime.JAXXValidator; import jaxx.runtime.SwingUtil; +import jaxx.runtime.validator.swing.SwingValidator; import jaxx.runtime.validator.swing.SwingValidatorUtil; 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 java.lang.reflect.Modifier; import java.util.List; +import java.util.Map; /** * To finalize validators fields. @@ -54,6 +61,9 @@ */ public class ValidatorFinalizer implements JAXXCompilerFinalizer { + /** Logger. */ + static Log log = LogFactory.getLog(ValidatorFinalizer.class); + protected static final JavaField VALIDATOR_IDS_FIELD = JavaFileGenerator.newField( Modifier.PROTECTED, @@ -124,7 +134,8 @@ builder.append(eol); compiler.appendLateInitializer(builder.toString()); for (CompiledBeanValidator validator : validators) { - validator.registerValidator(compiler, javaFile); + + registerValidator(validator, compiler, javaFile); } // StringBuilder registerValidatorFieldsMethod = new StringBuilder(); @@ -169,8 +180,8 @@ JavaFile javaFile, String packageName, String className) throws ClassNotFoundException { - Class<?> validatorClass = - compiler.getConfiguration().getValidatorClass(); + Class<?> validatorClass = SwingValidator.class; +// compiler.getConfiguration().getValidatorClass(); String validatorFQN = validatorClass.getName(); javaFile.addImport(validatorFQN); @@ -206,4 +217,72 @@ new JavaArgument("String", "validatorId")) ); } + + public void registerValidator(CompiledBeanValidator validator, + JAXXCompiler compiler, + JavaFile javaFile) { + + JavaField validatorField = javaFile.getField(validator.getId()); + + String validatorId = TypeManager.getJavaCode(validator.getId()); + + String validatorAnnotation = Validator.class.getSimpleName() + + "( validatorId = " + validatorId + + ")"; + validatorField.addAnnotation(validatorAnnotation); + Map<String, String> fields = validator.getFields(); + + for (Map.Entry<String, String> entry : fields.entrySet()) { + String propertyName = entry.getKey(); + String component = entry.getValue(); + + if (!validator.checkBeanProperty(compiler, propertyName)) { + // property not find on bean + continue; + } + + String keyCode = TypeManager.getJavaCode(propertyName); + String editorCode = TypeManager.getJavaCode(component); + JavaElement editor = javaFile.getField(component); + if (editor == null) { + String message = "Could not find editor [" + + component + "] for property [" + propertyName + + "] for file " + javaFile.getName(); + log.warn(message); + + // find in the compiler the object + CompiledObject compiledObject = compiler.getCompiledObject(component); + + if (compiledObject == null) { + + // this is an error, editor is unknown (this case should + // not happen) + + String errorMessage = "Could not find editor [" + + component + "] for property [" + propertyName + + "] for file " + javaFile.getName(); + + throw new CompilerException(errorMessage); + } + + // now must add a getter in the javaFile + + String fqn = JAXXCompiler.getCanonicalName(compiledObject); + + editor = javaFile.addGetterMethod(component, + Modifier.PUBLIC, + fqn, + true, + true); + } + + String annotation = ValidatorField.class.getSimpleName() + + "( validatorId = " + validatorId + "," + + " propertyName = " + keyCode + "," + + " editorName = " + editorCode + "" + + ")"; + editor.addAnnotation(annotation); + } + } + } Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/validator/BeanValidatorHandler.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/validator/BeanValidatorHandler.java 2011-01-26 14:39:52 UTC (rev 2177) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/validator/BeanValidatorHandler.java 2011-01-26 14:41:27 UTC (rev 2178) @@ -40,7 +40,6 @@ import jaxx.runtime.JAXXValidator; import jaxx.runtime.validator.swing.SwingValidator; import jaxx.runtime.validator.swing.SwingValidatorUtil; -import jaxx.runtime.validator.swing.meta.Validator; import jaxx.runtime.validator.swing.meta.ValidatorField; import jaxx.runtime.validator.swing.ui.AbstractBeanValidatorUI; import org.apache.commons.logging.Log; @@ -260,8 +259,8 @@ protected static ClassDescriptor getDescriptor( ClassDescriptor objectClass, JAXXCompiler compiler) { - Class<?> validatorClass = - compiler.getConfiguration().getValidatorClass(); + Class<?> validatorClass = SwingValidator.class; +// compiler.getConfiguration().getValidatorClass(); ClassDescriptor result = ClassDescriptorHelper.getClassDescriptor(validatorClass); return result; @@ -754,7 +753,7 @@ setInitializer( SwingValidatorUtil.class.getSimpleName() + ".newValidator(" + constructorParams + ")" ); - + // add generic type to validator setGenericTypes(new String[]{beanClassName}); @@ -835,35 +834,6 @@ } } - public void registerValidator(JAXXCompiler compiler, - JavaFile javaFile) { - - JavaField validatorField = javaFile.getField(getId()); - - String validatorId = TypeManager.getJavaCode(getId()); - String validatorAnnotation = Validator.class.getSimpleName() + - "( validatorId = " + validatorId + - ")"; - validatorField.addAnnotation(validatorAnnotation); - for (Entry<String, String> entry : fields.entrySet()) { - String propertyName = entry.getKey(); - String component = entry.getValue(); - if (!checkBeanProperty(compiler, propertyName)) { - // property not find on bean - continue; - } - String keyCode = TypeManager.getJavaCode(propertyName); - String editorCode = TypeManager.getJavaCode(component); - JavaField editor = javaFile.getField(component); - String annotation = ValidatorField.class.getSimpleName() + - "( validatorId = " + validatorId + "," + - " propertyName = " + keyCode + "," + - " editorName = " + editorCode + "" + - ")"; - editor.addAnnotation(annotation); - } - } - protected void registerAutoFieldBean(Element tag, JAXXCompiler compiler, JAXXBeanInfo beanInfo) { @@ -939,8 +909,8 @@ } } - protected boolean checkBeanProperty(JAXXCompiler compiler, - String propertyName) { + public boolean checkBeanProperty(JAXXCompiler compiler, + String propertyName) { for (JAXXPropertyDescriptor beanProperty : getBeanDescriptor(compiler).getJAXXPropertyDescriptors()) { 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-26 14:39:52 UTC (rev 2177) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java 2011-01-26 14:41:27 UTC (rev 2178) @@ -220,7 +220,8 @@ super.setContext(context); - if (context == null && oldContext == null || context != null && context.equals(oldContext)) { + if (context == null && oldContext == null || + context != null && context.equals(oldContext)) { // same context do nothing return; @@ -242,7 +243,6 @@ public void setFieldRepresentation(String fieldname, JComponent c) { boolean fieldFound = getDelegate().getEffectiveFields().contains(fieldname); -// BeanValidatorField<B> field = getField(fieldname); if (!fieldFound) { // no field registred in the validator if (log.isWarnEnabled()) { @@ -300,29 +300,6 @@ 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( @@ -341,8 +318,6 @@ 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 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-26 14:39:52 UTC (rev 2177) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorUtil.java 2011-01-26 14:41:27 UTC (rev 2178) @@ -24,6 +24,7 @@ */ package jaxx.runtime.validator.swing; +import jaxx.runtime.JAXXObject; import jaxx.runtime.JAXXValidator; import jaxx.runtime.SwingUtil; import jaxx.runtime.validator.swing.meta.Validator; @@ -48,10 +49,12 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.EnumMap; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -139,7 +142,8 @@ List<String> validatorIds = new ArrayList<String>(); Map<Field, Validator> validators = ReflectUtil.getFieldAnnotation( ui.getClass(), - Validator.class + Validator.class, + true ); for (Map.Entry<Field, Validator> entry : validators.entrySet()) { @@ -156,21 +160,16 @@ public static void installFields(JAXXValidator ui) { - Map<Field, ValidatorField> validatorFields = ReflectUtil.getFieldAnnotation( - ui.getClass(), - ValidatorField.class - ); + Map<JComponent, ValidatorField> editors = getValidatorEditors(ui); - List<String> validatorIds = ui.getValidatorIds(); + try { - try { - for (String validatorId : validatorIds) { + for (String validatorId : ui.getValidatorIds()) { 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); + + for (Map.Entry<JComponent, ValidatorField> entry : editors.entrySet()) { + ValidatorField fieldAnnotation = entry.getValue(); + JComponent editor = entry.getKey(); if (!validatorId.equals(fieldAnnotation.validatorId())) { // not good validator, skip this field @@ -182,11 +181,13 @@ } validator.setFieldRepresentation(propertyName, editor); } + } - } catch (IllegalAccessException e) { - throw new IllegalStateException("Could not init validators on ui " + ui, e); + + } finally { + + editors.clear(); } - } public static void installUI(JAXXValidator ui) { @@ -377,6 +378,7 @@ * @since 2.1 */ public static class DefaultSwingValidatorCreator implements BeanValidatorFactory.BeanValidatorCreator { + @Override public <O> BeanValidator<O> newBeanValidator(NuitonValidatorProvider provider, Class<O> type, String context, NuitonValidatorScope... scopes) { BeanValidator<O> beanValidator = new SwingValidator<O>(provider, @@ -387,4 +389,122 @@ return beanValidator; } } + + /** + * 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.getType().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); + } + } + + protected static Map<JComponent, ValidatorField> getValidatorEditors(JAXXValidator ui) { + + + Map<JComponent, ValidatorField> editors = new HashMap<JComponent, ValidatorField>(); + + + Map<Field, ValidatorField> validatorFields = null; + Map<Method, ValidatorField> validatorMethods = null; + try { + + validatorFields = ReflectUtil.getFieldAnnotation( + ui.getClass(), + ValidatorField.class, + true + ); + + validatorMethods = ReflectUtil.getMethodAnnotation( + ui.getClass(), + ValidatorField.class, + true + ); + for (Map.Entry<Field, ValidatorField> fieldEntry : validatorFields.entrySet()) { + Field field = fieldEntry.getKey(); + field.setAccessible(true); + ValidatorField fieldAnnotation = fieldEntry.getValue(); + JComponent editor = (JComponent) field.get(ui); + editors.put(editor, fieldAnnotation); + } + + for (Map.Entry<Method, ValidatorField> fieldEntry : validatorMethods.entrySet()) { + Method method = fieldEntry.getKey(); + method.setAccessible(true); + ValidatorField fieldAnnotation = fieldEntry.getValue(); + JComponent editor = (JComponent) method.invoke(ui); + editors.put(editor, fieldAnnotation); + } + + } catch (Exception e) { + throw new IllegalStateException("Could not init validators on ui " + ui, e); + } finally { + if (validatorFields != null) { + validatorFields.clear(); + } + if (validatorMethods != null) { + validatorMethods.clear(); + } + } + return editors; + } + } Modified: 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 2011-01-26 14:39:52 UTC (rev 2177) +++ trunk/jaxx-validator/src/main/java/jaxx/runtime/validator/swing/meta/ValidatorField.java 2011-01-26 14:41:27 UTC (rev 2178) @@ -30,12 +30,12 @@ import java.lang.annotation.Target; /** - * Annotation to put on each field linked to a validator. + * Annotation to put on each field or method linked to a validator. * * @author tchemit <chemit@codelutin.com> * @since 2.3 */ -@Target(ElementType.FIELD) +@Target(value = {ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface ValidatorField { /**
participants (1)
-
tchemit@users.nuiton.org