Author: tchemit Date: 2009-02-03 01:38:07 +0000 (Tue, 03 Feb 2009) New Revision: 1194 Added: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/SimpleBeanValidator.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidationUtil.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorEvent.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorListener.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorField.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListModel.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListMouseListener.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorModel.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableModel.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableMouseListener.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableRenderer.java Removed: jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/types/ jaxx/trunk/jaxx-compiler-validator/src/test/java/jaxx/junit/BeanValidatorScopeConverterTest.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorError.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorListModel.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorTableModel.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorListMouseListener.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableMouseListener.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableRenderer.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/Util.java Modified: jaxx/trunk/jaxx-compiler-validator/changelog.txt jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/compiler/ValidatorGenerator.java jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ExcludeFieldValidatorHandler.java jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ValidatorInitializer.java jaxx/trunk/jaxx-example/changelog.txt jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-en_GB.properties jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-fr_FR.properties jaxx/trunk/jaxx-runtime-validator/changelog.txt jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/JAXXValidator.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/AbstractBeanValidatorUI.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/IconValidationUI.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/ImageValidationUI.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/TranslucentValidationUI.java jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractValidatorTest.java jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/field/ValidatorBean-validation.xml jaxx/trunk/maven-jaxx-plugin/changelog.txt jaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java jaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/JaxxBaseTest.java jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/errors/DuplicatedErrorListModel.jaxx jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/errors/DuplicatedErrorTableModel.jaxx jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/Validation.jaxx jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/ValidationBeanClass.jaxx Log: refactoring validation (a finir en creant un nouveau module jaxx-runtime-swing-validator et en renomman jaxx-runtime-validator en jaxx-runtaime-validator en jaxx-runtime-validator-api ou bien en jaxx-validator-api et jaxx-validator-swing) Modified: jaxx/trunk/jaxx-compiler-validator/changelog.txt =================================================================== --- jaxx/trunk/jaxx-compiler-validator/changelog.txt 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-compiler-validator/changelog.txt 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,4 +1,5 @@ 1.1 chemit 200901?? + * 20090202 [chemit] - refactor validators (this module will soon disappear to jaxx-compiler-swing-validator) * 20090122 [chemit] - refactor poms (sibling dependencies, pluginsManagment,...) 1.0 chemit 20090111 Modified: jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/compiler/ValidatorGenerator.java =================================================================== --- jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/compiler/ValidatorGenerator.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/compiler/ValidatorGenerator.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -3,14 +3,11 @@ import jaxx.compiler.CompiledObject.ChildRef; import jaxx.reflect.ClassDescriptor; import jaxx.reflect.ClassDescriptorLoader; -import jaxx.runtime.JAXXValidator; -import jaxx.runtime.validator.BeanValidator; import jaxx.tags.validator.BeanValidatorHandler; import jaxx.tags.validator.BeanValidatorHandler.CompiledBeanValidator; import jaxx.types.TypeManager; import java.util.List; -import java.lang.*; /** @author chemit */ public class ValidatorGenerator implements Generator { @@ -19,11 +16,6 @@ "java.util.List<String>", "validatorIds", "new ArrayList<String>()" ); - protected static final JavaMethod GET_VALIDATOR_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "BeanValidator<?>", "getValidator", - "return (BeanValidator) (validatorIds.contains(validatorId)?getObjectById(validatorId):null);", - new JavaArgument("String", "validatorId") - ); - @Override public void finalizeCompiler(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) { @@ -61,16 +53,19 @@ } @Override - public void prepareJavaFile(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) throws ClassNotFoundException { + public void prepareJavaFile(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) throws ClassNotFoundException { if (!BeanValidatorHandler.hasValidator(compiler)) { return; } + String validatorClass = compiler.getOptions().getValidatorFQN(); + javaFile.addImport(validatorClass); - javaFile.addImport(BeanValidator.class); + //TODO use the specific JAXXValidator interface (swing, gwt,...) + Class<?> validatorInterface = jaxx.runtime.JAXXValidator.class; if (javaFile.isSuperclassIsJAXXObject()) { ClassDescriptor superClass = ClassDescriptorLoader.getClassDescriptor(javaFile.getSuperClass()); - boolean parentIsValidator = ClassDescriptorLoader.getClassDescriptor(JAXXValidator.class).isAssignableFrom(superClass); + boolean parentIsValidator = ClassDescriptorLoader.getClassDescriptor(validatorInterface).isAssignableFrom(superClass); if (parentIsValidator) { // nothing to generate (use the parent directly) @@ -79,12 +74,14 @@ } // add JAXXValidator interface - javaFile.addInterface(JAXXCompiler.getCanonicalName(JAXXValidator.class)); + javaFile.addInterface(JAXXCompiler.getCanonicalName(validatorInterface)); // implements JAXXValidator javaFile.addField(VALIDATOR_IDS_FIELD); - javaFile.addMethod(GET_VALIDATOR_METHOD); + javaFile.addMethod(JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, validatorClass + "<?>", "getValidator", + "return (" + validatorClass + ") (validatorIds.contains(validatorId) ? getObjectById(validatorId) : null);", + new JavaArgument("String", "validatorId") + )); } - } Modified: jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java =================================================================== --- jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -11,9 +11,8 @@ import jaxx.introspection.JAXXPropertyDescriptor; import jaxx.reflect.ClassDescriptor; import jaxx.reflect.ClassDescriptorLoader; -import jaxx.runtime.validator.BeanValidator; -import jaxx.runtime.validator.BeanValidator.Scope; -import jaxx.runtime.validator.Util; +import jaxx.runtime.validator.ValidationUtil; +import jaxx.runtime.validator.swing.SwingValidator; import jaxx.runtime.validator.ui.AbstractBeanValidatorUI; import jaxx.tags.DefaultObjectHandler; import jaxx.types.TypeManager; @@ -32,7 +31,7 @@ public class BeanValidatorHandler extends DefaultObjectHandler { - public static final String TAG = BeanValidator.class.getSimpleName(); + public static final String TAG = "BeanValidator"; public static final String BEAN_ATTRIBUTE = "bean"; public static final String BEAN_CLASS_ATTRIBUTE = "beanClass"; public static final String BEAN_INITIALIZER_ATTRIBUTE = "beanInitializer"; @@ -54,7 +53,7 @@ public static final String CONTEXT_NAME_ATTRIBUTE = "contextName"; - public static final String SCOPE_ATTRIBUTE = "scope"; + //public static final String SCOPE_ATTRIBUTE = "scope"; public static final String PARENT_VALIDATOR_ATTRIBUTE = "parentValidator"; @@ -67,7 +66,7 @@ public BeanValidatorHandler(ClassDescriptor beanClass) { super(beanClass); - ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, BeanValidator.class); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, SwingValidator.class); } @Override @@ -116,13 +115,13 @@ error = info.addBean(tag, this, compiler); } - if (!error) { + /*if (!error) { error = info.addContextName(this, compiler); - } + }*/ - if (!error) { + /*if (!error) { error = info.addScope(this, compiler); - } + }*/ if (!error) { error = info.addParentValidator(tag, this, compiler); @@ -171,7 +170,7 @@ protected JAXXBeanInfo beanDescriptor; protected String errorTableModel; protected String errorTable; - protected Scope scope; + //protected Scope scope; protected String parentValidator; public CompiledBeanValidator(String id, ClassDescriptor objectClass, JAXXCompiler compiler) { @@ -269,12 +268,12 @@ return; } - if (SCOPE_ATTRIBUTE.equals(property)) { + /*if (SCOPE_ATTRIBUTE.equals(property)) { if (value != null && !value.trim().isEmpty()) { scope = (Scope) TypeManager.convertFromString(value.trim(), Scope.class); } return; - } + }*/ if (PARENT_VALIDATOR_ATTRIBUTE.equals(property)) { if (value != null && !value.trim().isEmpty()) { @@ -314,9 +313,9 @@ return contextName; } - public Scope getScope() { + /*public Scope getScope() { return scope; - } + }*/ public String getParentValidator() { return parentValidator; @@ -431,21 +430,21 @@ } - protected boolean addContextName(BeanValidatorHandler handler, JAXXCompiler compiler) { + /*protected boolean addContextName(BeanValidatorHandler handler, JAXXCompiler compiler) { if (contextName != null) { String code = handler.getSetPropertyCode(getJavaCode(), CONTEXT_NAME_ATTRIBUTE, TypeManager.getJavaCode(contextName), compiler); appendAdditionCode(code); } return false; - } + }*/ - protected boolean addScope(BeanValidatorHandler handler, JAXXCompiler compiler) { + /*protected boolean addScope(BeanValidatorHandler handler, JAXXCompiler compiler) { if (scope != null) { String code = handler.getSetPropertyCode(getJavaCode(), SCOPE_ATTRIBUTE, TypeManager.getJavaCode(scope), compiler); appendAdditionCode(code); } return false; - } + }*/ protected boolean addParentValidator(Element tag, BeanValidatorHandler handler, JAXXCompiler compiler) { if (parentValidator != null) { @@ -483,11 +482,10 @@ } } - String code = Util.class.getName() + ".registerErrorListMouseListener(" + errorList + ");"; + String code = ValidationUtil.class.getName() + ".registerErrorListMouseListener(" + errorList + ");"; appendAdditionCode(code); return false; - } protected boolean addErrorTable(Element tag, JAXXCompiler compiler) { @@ -504,11 +502,10 @@ } } - String code = Util.class.getName() + ".registerErrorTableMouseListener(" + errorTable + ");"; + String code = ValidationUtil.class.getName() + ".registerErrorTableMouseListener(" + errorTable + ");"; appendAdditionCode(code); return false; - } protected boolean addBean(Element tag, BeanValidatorHandler handler, JAXXCompiler compiler) { @@ -567,10 +564,10 @@ appendAdditionCode(code); } - // add generic type to validator - String beanClassName = beanInfo.getJAXXBeanDescriptor().getClassDescriptor().getName(); - setConstructorParams(beanClassName + ".class"); + // contextName must be in constructor to able to init validator with his correct contextName + setConstructorParams(beanClassName + ".class, " + TypeManager.getJavaCode(contextName)); + // add generic type to validator setGenericTypes(new String[]{beanClassName}); if (getAutoField()) { @@ -624,7 +621,6 @@ }*/ String keyCode = TypeManager.getJavaCode(propertyName); appendAdditionCode(getJavaCode() + ".setFieldRepresentation(" + keyCode + ", " + component + ");"); - } } Modified: jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ExcludeFieldValidatorHandler.java =================================================================== --- jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ExcludeFieldValidatorHandler.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ExcludeFieldValidatorHandler.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -7,7 +7,7 @@ import jaxx.CompilerException; import jaxx.compiler.JAXXCompiler; import jaxx.reflect.ClassDescriptorLoader; -import jaxx.runtime.validator.BeanValidator; +import jaxx.runtime.validator.swing.SwingValidator; import jaxx.tags.TagHandler; import jaxx.tags.validator.BeanValidatorHandler.CompiledBeanValidator; import org.apache.commons.logging.Log; @@ -37,7 +37,7 @@ log.debug(tag); } - if (!ClassDescriptorLoader.getClassDescriptor(BeanValidator.class).isAssignableFrom(compiler.getOpenComponent().getObjectClass())) { + if (!ClassDescriptorLoader.getClassDescriptor(SwingValidator.class).isAssignableFrom(compiler.getOpenComponent().getObjectClass())) { compiler.reportError(TAG + " tag may only appear within " + BeanValidatorHandler.TAG + " tag but was " + tag); return; } Modified: jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java =================================================================== --- jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -7,7 +7,7 @@ import jaxx.CompilerException; import jaxx.compiler.JAXXCompiler; import jaxx.reflect.ClassDescriptorLoader; -import jaxx.runtime.validator.BeanValidator; +import jaxx.runtime.validator.swing.SwingValidator; import jaxx.tags.TagHandler; import jaxx.tags.validator.BeanValidatorHandler.CompiledBeanValidator; import org.apache.commons.logging.Log; @@ -37,7 +37,7 @@ log.info(tag); } - if (!ClassDescriptorLoader.getClassDescriptor(BeanValidator.class).isAssignableFrom(compiler.getOpenComponent().getObjectClass())) { + if (!ClassDescriptorLoader.getClassDescriptor(SwingValidator.class).isAssignableFrom(compiler.getOpenComponent().getObjectClass())) { compiler.reportError(TAG + " tag may only appear within " + BeanValidatorHandler.TAG + " tag but was " + tag); return; } Modified: jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ValidatorInitializer.java =================================================================== --- jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ValidatorInitializer.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ValidatorInitializer.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -6,19 +6,16 @@ import jaxx.compiler.JAXXCompiler; import jaxx.reflect.ClassDescriptorLoader; -import jaxx.runtime.validator.BeanValidator; +import jaxx.runtime.validator.swing.SwingValidator; import jaxx.tags.TagManager; -import jaxx.types.BeanValidatorScopeConverter; -import jaxx.types.TypeManager; public class ValidatorInitializer implements jaxx.spi.Initializer { @Override public void initialize() { - TypeManager.registerTypeConverter(BeanValidator.Scope.class, new BeanValidatorScopeConverter()); - - TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(BeanValidator.class), BeanValidatorHandler.class); + TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, BeanValidatorHandler.TAG, new BeanValidatorHandler(ClassDescriptorLoader.getClassDescriptor(SwingValidator.class))); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(SwingValidator.class), BeanValidatorHandler.class); TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, FieldValidatorHandler.TAG, new FieldValidatorHandler()); TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, ExcludeFieldValidatorHandler.TAG, new FieldValidatorHandler()); } Deleted: jaxx/trunk/jaxx-compiler-validator/src/test/java/jaxx/junit/BeanValidatorScopeConverterTest.java =================================================================== --- jaxx/trunk/jaxx-compiler-validator/src/test/java/jaxx/junit/BeanValidatorScopeConverterTest.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-compiler-validator/src/test/java/jaxx/junit/BeanValidatorScopeConverterTest.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,46 +0,0 @@ -package jaxx.junit; - -import jaxx.runtime.validator.BeanValidator; -import jaxx.runtime.validator.BeanValidator.Scope; -import jaxx.types.BeanValidatorScopeConverter; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -public class BeanValidatorScopeConverterTest { - - BeanValidatorScopeConverter converter; - Scope value; - String strValue; - - @Before - public void before() { - converter = new BeanValidatorScopeConverter(); - } - - @Test - public void testConvertFromString() { - value = (Scope) converter.convertFromString("ERROR", Scope.class); - Assert.assertEquals(value, Scope.ERROR); - - value = (Scope) converter.convertFromString("WARNING", Scope.class); - Assert.assertEquals(value, Scope.WARNING); - } - - @Test - public void testGetJavaCode() { - value = Scope.ERROR; - strValue = converter.getJavaCode(value); - Assert.assertEquals(BeanValidator.class.getName() + "." + Scope.class.getSimpleName() + "." + value.name(), strValue); - - value = Scope.WARNING; - strValue = converter.getJavaCode(value); - Assert.assertEquals(BeanValidator.class.getName() + "." + Scope.class.getSimpleName() + "." + value.name(), strValue); - } - - @Test(expected = IllegalArgumentException.class) - public void testConvertFromStringError() { - converter.convertFromString("FAKE", Scope.class); - } - -} \ No newline at end of file Modified: jaxx/trunk/jaxx-example/changelog.txt =================================================================== --- jaxx/trunk/jaxx-example/changelog.txt 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-example/changelog.txt 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,4 +1,6 @@ 1.1 chemit 200901?? + * 20090202 [chemit] - no more scope attribute on validator + - fix I18NTableCellRenderer (must have tip inside) * 20090122 [chemit] - refactor poms (sibling dependencies, pluginsManagment,...) - rename i18n bundles according artifactId Modified: jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx =================================================================== --- jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx 2009-02-03 01:38:07 UTC (rev 1194) @@ -7,8 +7,8 @@ <Identity id='identity'/> <!-- errors model --> - <jaxx.runtime.validator.BeanValidatorErrorListModel id='errors' - onContentsChanged='ok.setEnabled(errors.isEmpty())'/> + <jaxx.runtime.validator.swing.SwingValidatorErrorListModel id='errors' + onContentsChanged='ok.setEnabled(errors.isEmpty())'/> <!-- validators --> <BeanValidator id='validator' bean='model1' uiClass="jaxx.runtime.validator.ui.ImageValidationUI"> @@ -16,7 +16,7 @@ <field name="text2"/> <field name="ratio"/> </BeanValidator> - <BeanValidator id='validator2' bean='model2' uiClass="jaxx.runtime.validator.ui.IconValidationUI" scope='WARNING'> + <BeanValidator id='validator2' bean='model2' uiClass="jaxx.runtime.validator.ui.IconValidationUI"> <field name="text" component="_text"/> <field name="text2" component="_text2"/> <field name="ratio" component="_ratio"/> Modified: jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx =================================================================== --- jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx 2009-02-03 01:38:07 UTC (rev 1194) @@ -7,8 +7,8 @@ <Identity id='identity'/> <!-- errors model --> - <jaxx.runtime.validator.BeanValidatorErrorTableModel id='errors2' - onTableChanged='ok.setEnabled(errors2.getRowCount()==0)'/> + <jaxx.runtime.validator.swing.SwingValidatorErrorTableModel id='errors2' + onTableChanged='ok.setEnabled(errors2.getRowCount()==0)'/> <!-- validators --> <BeanValidator id='validator' bean='model1' uiClass="jaxx.runtime.validator.ui.ImageValidationUI"> @@ -16,7 +16,7 @@ <field name="text2"/> <field name="ratio"/> </BeanValidator> - <BeanValidator id='validator2' bean='model2' uiClass="jaxx.runtime.validator.ui.IconValidationUI" scope='WARNING'> + <BeanValidator id='validator2' bean='model2' uiClass="jaxx.runtime.validator.ui.IconValidationUI"> <field name="text" component="_text"/> <field name="text2" component="_text2"/> <field name="ratio" component="_ratio"/> @@ -32,8 +32,8 @@ static boolean wasinit=false; -errorTable.setDefaultRenderer(Object.class, new jaxx.runtime.validator.ErrorTableRenderer()); -Utils.setI18nTableHeaderRenderer(errorTable, n_("validator.scope"), n_("validator.field"), n_("validator.message")); +errorTable.setDefaultRenderer(Object.class, new jaxx.runtime.validator.swing.SwingValidatorErrorTableRenderer()); +Utils.setI18nTableHeaderRenderer(errorTable, n_("validator.scope"), n_("validator.scope.tip"), n_("validator.field"), n_("validator.field.tip"), n_("validator.message"), n_("validator.message.tip")); public void setVisible(boolean value) { if (!wasinit) { Utils.fixTableColumnWidth(errorTable, 0, 20); Modified: jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-en_GB.properties =================================================================== --- jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-en_GB.properties 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-en_GB.properties 2009-02-03 01:38:07 UTC (rev 1194) @@ -95,6 +95,9 @@ ttt= valid= validator.field=Champ +validator.field.tip= validator.message=Message +validator.message.tip= validator.scope=... +validator.scope.tip= x= Modified: jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-fr_FR.properties =================================================================== --- jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-fr_FR.properties 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-fr_FR.properties 2009-02-03 01:38:07 UTC (rev 1194) @@ -95,6 +95,9 @@ ttt= valid= validator.field=Champ +validator.field.tip= validator.message=Message +validator.message.tip= validator.scope=... +validator.scope.tip= x= Modified: jaxx/trunk/jaxx-runtime-validator/changelog.txt =================================================================== --- jaxx/trunk/jaxx-runtime-validator/changelog.txt 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-runtime-validator/changelog.txt 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,4 +1,6 @@ 1.1 chemit 200901?? + * 20090202 [chemit] - rename Util to ValidationUtil + - refactor validator mecanism to extract validation from swing * 20090122 [chemit] - refactor poms (sibling dependencies, pluginsManagment,...) * 20090120 [chemit] - improve validators tests (one test by validator with a common AbstractValidatorTest super class) - add a CollectionFieldExpressionValidator to validate a collection of a bean Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/JAXXValidator.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/JAXXValidator.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/JAXXValidator.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,6 +1,6 @@ package jaxx.runtime; -import jaxx.runtime.validator.BeanValidator; +import jaxx.runtime.validator.SimpleBeanValidator; import java.util.List; @@ -17,7 +17,7 @@ * @param validatorId validator id * @return the associated validator, or <code>null</code> if not find */ - BeanValidator<?> getValidator(String validatorId); + SimpleBeanValidator<?> getValidator(String validatorId); /** @return the list of ids of all registred validator */ List<String> getValidatorIds(); Deleted: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,660 +0,0 @@ -/* *##% - * Copyright (C) 2002-2008 Code Lutin, Benjamin Poussin - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * 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 Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - *##%*/ - -package jaxx.runtime.validator; - - -import com.opensymphony.xwork2.ActionContext; -import com.opensymphony.xwork2.ValidationAware; -import com.opensymphony.xwork2.ValidationAwareSupport; -import com.opensymphony.xwork2.config.Configuration; -import com.opensymphony.xwork2.config.ConfigurationManager; -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.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; -import java.lang.reflect.Constructor; -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/> - * Permet d'ajouter facilement le support de la validation des champs d'un - * bean et de le relier a une interface graphique. - * Utilise xwork pour la validation et JXLayer pour la visualisation. - * <p/> - * <p/> - * Le mieux pour son integration dans Jaxx est de faire de la generation pour - * force la compilation du code suivant: - * <p/> - * <pre> - * myValidor.getBean().get<field>(); - * </pre> - * <p/> - * et ceci pour chaque field ajoute a la map fieldRepresentation. De cette - * facon meme si le champs field est en texte on a une verification de son - * existance a la compilation. - * <p/> - * <p/> - * La representation en tag pourrait etre - * <pre> - * <validator id="myValidator" beanClass="{Personne.class}" errorList="$list"> - * <field name="name" component="$name"/> - * <field name="firstName" component="$firstName"/> - * <field name="birthDate" component="$birthDate"/> - * </validator> - * <validator beanClass="{Personne.class}" autoField="true" errorList="$list"> - * <fieldRepresentation name="name" component="$lastName"/> - * </validator> - * </pre> - * <p/> - * dans le premier exemple on fait un mapping explicite des champs, mais on voit - * que le nom du composant graphique est le meme que celui du champs. Pour eviter - * de longue saisie, il est possible d'utiliser le flag <b>autoField</b> - * qui pour chaque champs du ayant une methode get du bean recherche un composant - * avec cet Id. Il est aussi possible de surcharge un champs explicitement - * comme ici name, dans le cas ou le composant qui porterait ce nom serait - * utilise pour autre chose. - * <p/> - * <p/> - * Il faut un handler particulier pour ce composant car les attributs - * <b>beanClass</b> et <b>autoField</b> ne sont present que dans le XML jaxx et - * servent a la generation. Il faut aussi prendre en compte les elements - * fieldRepresentation fils du tag validator. - * <p/> - * <p/> - * Voici ce que pourrait etre le code genere par jaxx - * <pre> - * // declaration du bean - * BeanValidator<beanClass> $myValidator; - * // init du bean - * protected void createMyValidator() { - * $myValidator = new BeanValidator<beanClass>(); - * // genere seulement si autoField = true - * for (Method m : beanClass.getMethod()) { - * if (m.getName().startsWith("get")) { - * String fieldName = m.getName().substring(3).toLowerCase(); - * $myValidator.setFieldRepresentation(fieldName, $objectMap.get(fieldName)); - * } - * } - * // pour chaque tag fieldRepresentation - * myValidator.setFieldRepresentation("name", $lastName); - * // si beanClass est specifie et n'est pas Object, on force l'acces au champs - * // pour validation a la compilation - * $myValidator.getBean().getName(); - * $objectMap.put("myValidator", $myValidator); - * } - * </pre> - * - * @author poussin - * @author chemit - * @version 1.0 - * <p/> - * Last update: $Date$ - * by : chemit - */ -public class BeanValidator<T> { - - /** - * Pour definir le niveau de validation. - * <p/> - * Par défaut, le validateur est supposé géré des erreurs, mais on peut aussi l'utiliser - * pour consigner des warnings sur le bean surveiller. - */ - public enum Scope { - ERROR, - WARNING - } - - static public final String BEAN_PROERTY = "bean"; - - private static final String CONTEXT_NAME_PROPERTY = "contextName"; - - static public final String VALID_PROERTY = "valid"; - - static public final String CHANGED_PROERTY = "changed"; - - /** to use log facility, just put in your code: log.info(\"...\"); */ - static private final Log log = LogFactory.getLog(BeanValidator.class); - - /** Constant name of the default ui renderer to be used. */ - static private final Class<? extends AbstractBeanValidatorUI> DEFAULT_UI_CLASS = IconValidationUI.class; - - /** delgate property change support */ - protected PropertyChangeSupport pcs; - - protected ValidationAwareSupport validationSupport; - - protected DelegatingValidatorContext validationContext; - - protected transient ActionValidatorManager validator; - - /** indique si le bean a ete modifie depuis son arrivee */ - protected boolean changed = false; - - /** state of the validator */ - protected boolean valid; - - /** la classe du bean à surveiller */ - protected final Class<T> beanClass; - - /** le bean a surveiller */ - protected T bean = null; - - /** l'objet qui recoit les notifications de modification du bean */ - protected PropertyChangeListener l; - - /** permet de faire le lien en un champs du bean et l'objet qui permet de l'editer */ - protected Map<String, JComponent> fieldRepresentation; - - /** Object servant a contenir la liste des erreurs */ - protected BeanValidatorErrorListModel errorListModel; - - /** Object servant a contenir la liste des erreurs */ - protected BeanValidatorErrorTableModel errorTableModel; - - /** ui renderer class */ - protected Class<? extends AbstractBeanValidatorUI> uiClass; - - /** validator context */ - protected ActionContext context; - - /** map of conversion errors detected by this validator */ - protected Map<String, String> conversionErrors; - - /** the validation named context */ - protected String contextName; - - /** the scope of the validator */ - protected Scope scope = Scope.ERROR; - - /** to chain to a prent validator */ - protected BeanValidator<?> parentValidator; - - public BeanValidator(Class<T> beanClass) { - this.beanClass = beanClass; - pcs = new PropertyChangeSupport(this); - validationSupport = new ValidationAwareSupport(); - validationContext = new DelegatingValidatorContext(validationSupport); - fieldRepresentation = new HashMap<String, JComponent>(); - conversionErrors = new TreeMap<String, String>(); - l = new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent evt) { - validate(); - setValid(!hasErrors()); - setChanged(true); - } - }; - } - - 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); - } - - public BeanValidatorErrorListModel getErrorListModel() { - return errorListModel; - } - - public BeanValidatorErrorTableModel getErrorTableModel() { - return errorTableModel; - } - - public JComponent getFieldRepresentation(String fieldname) { - return fieldRepresentation.get(fieldname); - } - - public Scope getScope() { - return scope; - } - - public Class<T> getBeanClass() { - return beanClass; - } - - public BeanValidator<?> getParentValidator() { - return parentValidator; - } - - public String getContextName() { - return contextName; - } - - /** - * 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 T getBean() { - return bean; - } - - public Class<? extends AbstractBeanValidatorUI> getUiClass() { - return uiClass; - } - - public Map getFieldErrors() { - return validationContext.getFieldErrors(); - } - - public Collection getActionErrors() { - return validationContext.getActionErrors(); - } - - public Collection getActionMessages() { - return validationContext.getActionMessages(); - } - - public Map<String, String> getConversionErrors() { - return conversionErrors; - } - - public void setErrorListModel(BeanValidatorErrorListModel errorListModel) { - this.errorListModel = errorListModel; - if (errorListModel != null) { - // register the validator in the model list - errorListModel.registerValidator(this); - } - } - - public void setErrorTableModel(BeanValidatorErrorTableModel errorTableModel) { - this.errorTableModel = errorTableModel; - if (errorTableModel != null) { - // register the validator in the model table - errorTableModel.registerValidator(this); - } - } - - /** - * Permet d'indiquer le composant graphique responsable de l'affichage - * d'un attribut du bean - * - * @param fieldname the field name in the bean - * @param c the editor component for the field - */ - public void setFieldRepresentation(String fieldname, JComponent c) { - fieldRepresentation.put(fieldname, c); - //todo we do not want at this moment to add something in ui, since ui is perharps not useable - //todo prefer to use the method installUIs - //JComponent old = fieldRepresentation.put(fieldname, c); - //setErrorRepresentation(fieldname, old, c, uiClass); - } - - public void setFieldRepresentation(Map<String, JComponent> fieldRepresentation) { - for (Map.Entry<String, JComponent> e : fieldRepresentation.entrySet()) { - setFieldRepresentation(e.getKey(), e.getValue()); - } - } - - /** - * 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) { - boolean oldChanged = this.changed; - this.changed = changed; - // force the property to be propagated - pcs.firePropertyChange(CHANGED_PROERTY, null, changed); - //pcs.firePropertyChange(CHANGED_PROERTY, oldChanged, changed); - } - - public void setValid(boolean valid) { - boolean oldValid = this.valid; - this.valid = valid; - // force the property to be propagated - pcs.firePropertyChange(VALID_PROERTY, null, valid); - //if (oldValid != valid) { - // pcs.firePropertyChange(VALID_PROERTY, oldValid, valid); - //} - } - - public void setBean(T bean) { - T oldBean = this.bean; - if (log.isDebugEnabled()) { - log.debug(this + " : " + bean); - } - // clean conversions of previous bean - conversionErrors.clear(); - if (oldBean != null) { - try { - Method method = this.bean.getClass().getMethod("removePropertyChangeListener", PropertyChangeListener.class); - method.invoke(oldBean, l); - } catch (Exception eee) { - log.info("Can't register as listener", eee); - } - } - this.bean = bean; - if (bean != null) { - try { - Method method = this.bean.getClass().getMethod("addPropertyChangeListener", PropertyChangeListener.class); - method.invoke(bean, l); - } catch (Exception eee) { - log.info("Can't register as listener", eee); - } - validate(); - } else { - // must remove all errors from this validator on errorListModel - validationSupport.clearErrorsAndMessages(); - addErrors(); - } - setValid(!hasErrors()); - setChanged(false); - pcs.firePropertyChange(BEAN_PROERTY, oldBean, bean); - } - - public void setContextName(String contextName) { - String oldValidationContextName = this.contextName; - this.contextName = contextName; - pcs.firePropertyChange(CONTEXT_NAME_PROPERTY, oldValidationContextName, contextName); - } - - public void setUiClass(Class<? extends AbstractBeanValidatorUI> uiClass) { - this.uiClass = uiClass; - } - - public void setScope(Scope scope) { - this.scope = scope; - } - - public void setParentValidator(BeanValidator<?> parentValidator) { - this.parentValidator = parentValidator; - } - - /** @return <code>true</code> if errors are detected, <code>false</code> otherwise */ - public boolean hasErrors() { - //todo should also detecte actionErrors ? - return scope == Scope.ERROR && (validationContext.hasFieldErrors() || !conversionErrors.isEmpty()); - //return validationContext.hasFieldErrors() || validationContext.hasActionErrors(); - } - - public boolean hasWarnings() { - return scope == Scope.WARNING && (validationContext.hasFieldErrors() || !conversionErrors.isEmpty()); - } - - /** install ui on required components */ - public void installUIs() { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - if (uiClass == null) { - // use the default one - uiClass = DEFAULT_UI_CLASS; - } - for (String fieldname : fieldRepresentation.keySet()) { - try { - setErrorRepresentation(fieldname, null, fieldRepresentation.get(fieldname), uiClass); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - }); - - } - - /** - * 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 (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 (checkState() || 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 - 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 - * 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} - */ - public 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 (checkState()) { - return; - } - - try { - - validationSupport.clearErrorsAndMessages(); - - getValidator().validate(bean, contextName, validationContext); - - // add the registred conversion errors - transfertConversionErrorsToFieldErrors(); - - 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()); - } - // add errors - addErrors(); - - for (String fieldname : fieldRepresentation.keySet()) { - JComponent c = fieldRepresentation.get(fieldname); - //todo: a supprimer mais actuellemnt le layer ne se repaint pas bien, cela n'est pas normal - if (c.getParent() != null) { - c.getParent().repaint(); - } - } - if (parentValidator != null) { - // chain validation - parentValidator.l.propertyChange(null); - } - } catch (ValidationException eee) { - log.warn("Error during validation", eee); - } - } - - @Override - public String toString() { - return super.toString() + "<beanClass:" + beanClass + ", contextName:" + contextName + ">"; - } - - /** - * Test if a fieldName is valid for the validator - * - * @param fieldName the name of the field to test - * @return <code>true</code> if field is valid, <code>false</code> otherwise. - */ - public boolean isValid(String fieldName) { - if (!isValid()) { - for (Object o : getFieldErrors().keySet()) { - if (fieldName.equals(o)) { - return false; - } - } - } - return true; - } - - /** @return <code>true</code> if validation is not active , <code>false</code> otherwise. */ - protected boolean checkState() { - return bean == null || (getErrorListModel() == null && getErrorTableModel() == null) || fieldRepresentation.size() == 0; - } - - protected ActionValidatorManager getValidator() { - if (validator == null) { - ConfigurationManager confManager = new ConfigurationManager(); - Configuration conf = confManager.getConfiguration(); - - ValueStackFactory vsf = conf.getContainer().getInstance( - ValueStackFactory.class); - ValueStack vs = vsf.createValueStack(); - context = new ActionContext(vs.getContext()); - ActionContext.setContext(context); - - validator = conf.getContainer().getInstance( - ActionValidatorManager.class, "no-annotations"); - } - //TC - 20081024 : since context is in a ThreadLocal variable, we must do the check - if (ActionContext.getContext() == null) { - ActionContext.setContext(context); - } - return validator; - } - - protected void setErrorRepresentation(String fieldname, JComponent old, JComponent c, Class<? extends AbstractBeanValidatorUI> uiClass) throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { - if (old != c) { - if (old != null) { - // suppression du jxlayer sous l'ancien composant - Container container = old.getParent(); - if (container instanceof JXLayer) { - JXLayer<?> jx = (JXLayer<?>) container; - jx.setUI(null); - } - } - if (c != null) { - // ajout du jxlayer sous ce composant - Container container = c.getParent(); - if (container instanceof JXLayer) { - Constructor<? extends AbstractBeanValidatorUI> cons = uiClass.getConstructor(String.class, String.class, Scope.class, ValidationAware.class); - AbstractBeanValidatorUI ui = cons.newInstance(fieldname, c.getName(), scope, validationSupport); - ui.setEnabled(true); - JXLayer<JComponent> jx = (JXLayer<JComponent>) container; - jx.setUI(ui); - } - } - } - } - - /** - * 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 void addErrors() { - if (errorListModel != null) { - errorListModel.addErrors(this); - } - if (errorTableModel != null) { - errorTableModel.addErrors(this); - } - } - -} Deleted: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorError.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorError.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorError.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,89 +0,0 @@ -package jaxx.runtime.validator; - -import org.codelutin.i18n.I18n; - -import javax.swing.JComponent; - -import jaxx.runtime.validator.BeanValidator.Scope; - -/** - * The model of an error. - * - * @author chemit - */ -public class BeanValidatorError<T> { - - protected BeanValidator<T> validator; - - protected String fieldName; - - protected String error; - - protected JComponent component; - - public BeanValidator<T> getValidator() { - return validator; - } - - public String getFieldName() { - return fieldName; - } - - public String getError() { - return error; - } - - public JComponent getComponent() { - return component; - } - - public void setValidator(BeanValidator<T> validator) { - this.validator = validator; - } - - public void setFieldName(String fieldName) { - this.fieldName = fieldName; - } - - public void setError(String error) { - this.error = error; - } - - public void setComponent(JComponent component) { - this.component = component; - } - - public Scope getScope() { - return validator.getScope(); - } - - @Override - public String toString() { - return component.getName() + " : " + I18n._(error); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof BeanValidatorError)) { - return false; - } - - BeanValidatorError that = (BeanValidatorError) o; - - return component.equals(that.component) && error.equals(that.error) && fieldName.equals(that.fieldName) && validator.equals(that.validator); - - } - - @Override - public int hashCode() { - int result; - result = validator.hashCode(); - result = 31 * result + fieldName.hashCode(); - result = 31 * result + error.hashCode(); - result = 31 * result + component.hashCode(); - return result; - } -} Deleted: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorListModel.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorListModel.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorListModel.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,139 +0,0 @@ -package jaxx.runtime.validator; - -import javax.swing.DefaultListModel; -import javax.swing.JComponent; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; - -/** - * The model of the list of errors - * - * @author chemit - */ -public class BeanValidatorErrorListModel extends DefaultListModel { - private static final long serialVersionUID = 1L; - - /** list of registred validators */ - protected transient List<BeanValidator<?>> validators; - - /** comporator of errors */ - protected transient Comparator<BeanValidatorError> comparator; - - public BeanValidatorErrorListModel() { - validators = new ArrayList<BeanValidator<?>>(); - } - - public void registerValidator(BeanValidator<?> validator) { - if (validators.contains(validator)) { - throw new IllegalArgumentException("the validator " + validator + " is already registred in " + this); - } - validators.add(validator); - } - - public <T> void addErrors(BeanValidator<T> validator) { - if (!validators.contains(validator)) { - throw new IllegalArgumentException("the validator " + validator + " is not registred in " + this); - } - - // new errors for the given validator - List<BeanValidatorError> newErrors = new ArrayList<BeanValidatorError>(); - // old errors for the given validator - List<BeanValidatorError> oldErrors = new ArrayList<BeanValidatorError>(); - // old errors for other validators - List<BeanValidatorError> oldOtherErrors = new ArrayList<BeanValidatorError>(); - - // split old errors from other validators - splitOldErrors(validator, oldErrors, oldOtherErrors); - - // fill new errors - fillNewErrors(validator, newErrors); - - // check if something has changed for the given validator - if (hasChanged(oldErrors, newErrors)) { - - // reinject other errors - newErrors.addAll(oldOtherErrors); - - // sort errors - Collections.sort(newErrors, getComparator()); - - // clean errors in model - clear(); - - // reinject in list model, all the errors - for (BeanValidatorError error : newErrors) { - addElement(error); - } - - // notify thaht the model has changed - fireContentsChanged(this, 0, getSize() - 1); - } - } - - protected boolean hasChanged(List<BeanValidatorError> oldErrors, List<BeanValidatorError> newErrors) { - if (oldErrors.size() != newErrors.size()) { - return true; - } - for (BeanValidatorError oldError : oldErrors) { - if (!newErrors.contains(oldError)) { - return true; - } - } - return false; - } - - protected <T> void fillNewErrors(BeanValidator<T> validator, List<BeanValidatorError> newErrors) { - if (validator.hasErrors()) { - // inject this validator errors - for (Object o : validator.getFieldErrors().entrySet()) { - 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()) { - String error1 = (String) errorString; - error = new BeanValidatorError<T>(); - error.setComponent(component); - error.setValidator(validator); - error.setError(error1); - error.setFieldName(field); - newErrors.add(error); - } - } - } - //todo should also do actionErrors - } - } - - protected <T> void splitOldErrors(BeanValidator<T> validator, List<BeanValidatorError> oldErrors, List<BeanValidatorError> oldOtherErrors) { - Enumeration enumeration = elements(); - - while (enumeration.hasMoreElements()) { - Object o = enumeration.nextElement(); - BeanValidatorError<?> error = (BeanValidatorError) o; - if (!error.getValidator().equals(validator)) { - // error from another validator, keep it - oldOtherErrors.add(error); - } else { - oldErrors.add(error); - } - } - } - - protected Comparator<BeanValidatorError> getComparator() { - if (comparator == null) { - comparator = new Comparator<BeanValidatorError>() { - public int compare(BeanValidatorError o1, BeanValidatorError o2) { - return o1.toString().compareTo(o2.toString()); - } - }; - } - return comparator; - } - -} Deleted: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorTableModel.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorTableModel.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorTableModel.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,161 +0,0 @@ -package jaxx.runtime.validator; - -import javax.swing.JComponent; -import javax.swing.table.DefaultTableModel; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Vector; - -/** - * The model of the list of errors - * - * @author chemit - */ -public class BeanValidatorErrorTableModel extends DefaultTableModel { - - private static final long serialVersionUID = 1L; - - public static final String[] columnNames = {"validator.scope", "validator.field", "validator.message"}; - - /** list of registred validators */ - protected transient List<BeanValidator<?>> validators; - - /** comporator of errors */ - protected transient Comparator<BeanValidatorError> comparator; - - public BeanValidatorErrorTableModel() { - super(columnNames, 0); - validators = new ArrayList<BeanValidator<?>>(); - } - - public int getErrorColumn() { - return findColumn(BeanValidatorErrorTableModel.columnNames[2]); - } - - @Override - public boolean isCellEditable(int row, int column) { - // cells are never editable in this model - return false; - } - - public void registerValidator(BeanValidator<?> validator) { - if (validators.contains(validator)) { - throw new IllegalArgumentException("the validator " + validator + " is already registred in " + this); - } - validators.add(validator); - } - - public <T> void addErrors(BeanValidator<T> validator) { - if (!validators.contains(validator)) { - throw new IllegalArgumentException("the validator " + validator + " is not registred in " + this); - } - - // new errors for the given validator - List<BeanValidatorError> newErrors = new ArrayList<BeanValidatorError>(); - // old errors for the given validator - List<BeanValidatorError> oldErrors = new ArrayList<BeanValidatorError>(); - // old errors for other validators - List<BeanValidatorError> oldOtherErrors = new ArrayList<BeanValidatorError>(); - - // split old errors from other validators - splitOldErrors(validator, oldErrors, oldOtherErrors); - - // fill new errors - fillNewErrors(validator, newErrors); - - // check if something has changed for the given validator - if (hasChanged(oldErrors, newErrors)) { - - // reinject other errors - newErrors.addAll(oldOtherErrors); - - // sort errors - Collections.sort(newErrors, getComparator()); - - // clean errors in model - getDataVector().clear(); - // reinject in list model, all the errors - for (BeanValidatorError error : newErrors) { - addRow(new Object[]{error.getScope(), error.getFieldName(), error}); - } - - // notify thaht the model has changed - fireTableDataChanged(); - } - } - - protected boolean hasChanged(List<BeanValidatorError> oldErrors, List<BeanValidatorError> newErrors) { - if (oldErrors.size() != newErrors.size()) { - return true; - } - for (BeanValidatorError oldError : oldErrors) { - if (!newErrors.contains(oldError)) { - return true; - } - } - return false; - } - - protected <T> void fillNewErrors(BeanValidator<T> validator, List<BeanValidatorError> newErrors) { - if (validator.hasErrors() || validator.hasWarnings()) { - // inject this validator errors - for (Object o : validator.getFieldErrors().entrySet()) { - 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()) { - String error1 = (String) errorString; - error = new BeanValidatorError<T>(); - error.setComponent(component); - error.setValidator(validator); - error.setError(error1); - error.setFieldName(field); - newErrors.add(error); - } - } - } - //todo should also do actionErrors - } - } - - protected <T> void splitOldErrors(BeanValidator<T> validator, List<BeanValidatorError> oldErrors, List<BeanValidatorError> oldOtherErrors) { - - int col = getErrorColumn(); - for (Object o : super.getDataVector()) { - Vector row = (Vector) o; - BeanValidatorError<?> error = (BeanValidatorError<?>) row.get(col); - if (!error.getValidator().equals(validator)) { - // error from another validator, keep it - oldOtherErrors.add(error); - } else { - oldErrors.add(error); - } - } - } - - protected Comparator<BeanValidatorError> getComparator() { - if (comparator == null) { - comparator = new Comparator<BeanValidatorError>() { - public int compare(BeanValidatorError o1, BeanValidatorError o2) { - // first sort on scope - int scope = o1.getScope().ordinal() - o2.getScope().ordinal(); - if (scope != 0) { - return scope; - } - int field = o1.getFieldName().compareTo(o2.getFieldName()); - if (field != 0) { - return field; - } - return o1.getError().compareTo(o2.getError()); - } - }; - } - return comparator; - } - -} \ No newline at end of file Deleted: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorListMouseListener.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorListMouseListener.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorListMouseListener.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,61 +0,0 @@ -package jaxx.runtime.validator; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import javax.swing.JComponent; -import javax.swing.JList; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; - -/** - * A mouse listener to put on a {@link JList} with a {@link BeanValidatorErrorListModel} as a model. - * <p/> - * When a double click occurs, find the selected error in model and then focus to the associated component of error. - * - * @author chemit - */ -public class ErrorListMouseListener extends MouseAdapter { - - /** to use log facility, just put in your code: log.info(\"...\"); */ - static private Log log = LogFactory.getLog(ErrorListMouseListener.class); - - @Override - public void mouseClicked(MouseEvent e) { - super.mouseClicked(e); - if (e.getClickCount() == 2) { - - BeanValidatorError<?> entry = getSelectedError(e); - if (entry == null) { - // no entry found - return; - } - JComponent component = entry.getComponent(); - if (component != null) { - component.requestFocus(); - } - } - } - - - protected BeanValidatorError<?> getSelectedError(MouseEvent e) { - JList list = (JList) e.getSource(); - if (!(list.getModel() instanceof BeanValidatorErrorListModel)) { - log.warn("model must be a " + BeanValidatorErrorListModel.class + ", but was " + list.getModel()); - return null; - } - - BeanValidatorErrorListModel model = (BeanValidatorErrorListModel) list.getModel(); - int index = list.getSelectionModel().getMinSelectionIndex(); - if (index == -1) { - // nothing is selected - return null; - } - BeanValidatorError<?> entry = (BeanValidatorError) model.getElementAt(index); - if (log.isDebugEnabled()) { - log.debug("selected index: " + index + " : error: " + entry); - } - return entry; - } - -} Deleted: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableMouseListener.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableMouseListener.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableMouseListener.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,92 +0,0 @@ -package jaxx.runtime.validator; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import javax.swing.JComponent; -import javax.swing.JTable; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; - -/** - * A mouse listener to put on a {@link javax.swing.JList} with a {@link jaxx.runtime.validator.BeanValidatorErrorListModel} as a model. - * <p/> - * When a double click occurs, find the selected error in model and then focus to the associated component of error. - * - * @author chemit - */ -public class ErrorTableMouseListener extends MouseAdapter { - - /** to use log facility, just put in your code: log.info(\"...\"); */ - private static Log log = LogFactory.getLog(ErrorTableMouseListener.class); - - public static final String HIGHLIGHT_ERROR_PROPERTY = "highlightError"; - - /** delgate property change support */ - protected PropertyChangeSupport pcs; - - public ErrorTableMouseListener() { - pcs = new PropertyChangeSupport(this); - } - - @Override - public void mouseClicked(MouseEvent e) { - super.mouseClicked(e); - if (e.getClickCount() == 2) { - - BeanValidatorError<?> entry = getSelectedError(e); - if (entry == null) { - // no entry found - return; - } - JComponent component = entry.getComponent(); - if (component != null) { - pcs.firePropertyChange(HIGHLIGHT_ERROR_PROPERTY, null, entry); - if (component.isVisible()) { - component.requestFocus(); - } - } - } - } - - - protected BeanValidatorError<?> getSelectedError(MouseEvent e) { - JTable table = (JTable) e.getSource(); - if (!(table.getModel() instanceof BeanValidatorErrorTableModel)) { - log.warn("model must be a " + BeanValidatorErrorTableModel.class + ", but was " + table.getModel()); - return null; - } - - BeanValidatorErrorTableModel model = (BeanValidatorErrorTableModel) table.getModel(); - int index = table.getSelectionModel().getMinSelectionIndex(); - if (index == -1) { - // nothing is selected - return null; - } - int col = model.getErrorColumn(); - BeanValidatorError<?> entry = (BeanValidatorError) model.getValueAt(index, col); - if (log.isDebugEnabled()) { - log.debug("selected index: " + index + " : error: " + entry); - } - return entry; - } - - 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); - } - -} \ No newline at end of file Deleted: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableRenderer.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableRenderer.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableRenderer.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,68 +0,0 @@ -package jaxx.runtime.validator; - -import jaxx.runtime.validator.BeanValidator.Scope; -import static org.codelutin.i18n.I18n._; - -import javax.swing.ImageIcon; -import javax.swing.JLabel; -import javax.swing.JTable; -import javax.swing.table.DefaultTableCellRenderer; -import java.awt.Component; -import java.util.ArrayList; -import java.util.List; -import java.util.StringTokenizer; - -/** @author chemit */ -public class ErrorTableRenderer extends DefaultTableCellRenderer { - - ImageIcon errorIcon; - ImageIcon warningIcon; - - public ErrorTableRenderer() { - errorIcon = jaxx.runtime.Util.createImageIcon("error.png"); - warningIcon = jaxx.runtime.Util.createImageIcon("warning.png"); - } - - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - JLabel rendererComponent = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - - ImageIcon icon = null; - String text = null; - if (value instanceof Scope) { - - Scope scope = (Scope) value; - switch (scope) { - case ERROR: - icon = errorIcon; - break; - case WARNING: - icon = warningIcon; - break; - } - } else if (value instanceof BeanValidatorError) { - String error = ((BeanValidatorError) value).getError(); - if (error.indexOf("##") == -1) { - 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()); - } - } else { - // keep text rendered - text = rendererComponent.getText(); - } - rendererComponent.setText(text); - rendererComponent.setIcon(icon); - return rendererComponent; - } - - @Override - protected void setValue(Object value) { - super.setValue(value); - } -} Added: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/SimpleBeanValidator.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/SimpleBeanValidator.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/SimpleBeanValidator.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -0,0 +1,450 @@ +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.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 com.opensymphony.xwork2.validator.ValidatorScope; +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 java.beans.Introspector; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +/** @author chemit */ +public class SimpleBeanValidator<B> { + + /** + * Pour definir le niveau de validation. + * <p/> + * Par défaut, le validateur est supposé géré des erreurs, mais on peut aussi l'utiliser + * pour consigner des warnings sur le bean surveiller. + */ + public enum Scope { + ERROR, + WARNING + } + + public enum State { + VALID, + CONVERSION_ERROR, + FAILED + } + + /** 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"; + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static protected final Log log = LogFactory.getLog(SimpleBeanValidator.class); + + /** 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 SimpleBeanValidator<?> parentValidator; + + /** state to indicate that validator has changed since the last time bean was setted */ + protected boolean changed = false; + + /** state of the validator (is true if no errors of error scope is found) */ + protected boolean valid; + + /** bean to be watched */ + protected B bean = null; + + /** list of fields watched by this validator */ + protected List<ValidatorField<B>> fields; + + /** map of conversion errors detected by this validator */ + protected Map<String, String> conversionErrors; + + /** delgate property change support */ + protected PropertyChangeSupport pcs; + + /** listener that listens on bean modification */ + protected PropertyChangeListener l; + + protected ValidationAwareSupport validationSupport; + protected DelegatingValidatorContext validationContext; + protected transient ActionValidatorManager validator; + protected ActionContext context; + + public SimpleBeanValidator(Class<B> beanClass, String contextName) { + this.beanClass = beanClass; + this.contextName = contextName; + pcs = new PropertyChangeSupport(this); + validationSupport = new ValidationAwareSupport(); + validationContext = new DelegatingValidatorContext(validationSupport); + + // init context + ConfigurationManager confManager = new ConfigurationManager(); + Configuration conf = confManager.getConfiguration(); + + ValueStackFactory vsf = conf.getContainer().getInstance( + ValueStackFactory.class); + ValueStack vs = vsf.createValueStack(); + context = new ActionContext(vs.getContext()); + ActionContext.setContext(context); + + // init validator + validator = conf.getContainer().getInstance(ActionValidatorManager.class, "no-annotations"); + initFields(); + + conversionErrors = new TreeMap<String, String>(); + + l = new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + validate(); + setValid(!hasErrors()); + setChanged(true); + } + }; + } + + protected void initFields() { + // init fields from detected fieldValidator in XWorks framework + fields = new ArrayList<ValidatorField<B>>(); + for (Validator v : validator.getValidators(beanClass, contextName)) { + // we only work on FieldValidator at the moment + if (v instanceof FieldValidator) { + FieldValidator fieldValidator = (FieldValidator) v; + String fName = fieldValidator.getFieldName(); + ValidatorScope fScope = fieldValidator.getValidatorScope(); + ValidatorField<B> field = new ValidatorField<B>(beanClass, fName, fScope); + if (!fields.contains(field)) { + fields.add(field); + } + } + } + + fields = Collections.unmodifiableList(fields); + } + + public Class<B> getBeanClass() { + return beanClass; + } + + public SimpleBeanValidator<?> getParentValidator() { + return parentValidator; + } + + public String getContextName() { + return contextName; + } + + public List<ValidatorField<B>> getFields() { + return fields; + } + + public ValidatorField<B> getField(String fieldName) { + for (ValidatorField<B> field : fields) { + if (fieldName.equals(field.getName())) { + return field; + } + } + return null; + } + + /** + * 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; + } + + /** + * 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 { + Method method = this.bean.getClass().getMethod("removePropertyChangeListener", PropertyChangeListener.class); + method.invoke(oldBean, l); + } catch (Exception eee) { + log.info("Can't register as listener", eee); + } + } + this.bean = bean; + if (bean == null) { + // must remove all errors from this validator on errorListModel + validationSupport.clearErrorsAndMessages(); + //errors.clear(); + } else { + try { + Method method = this.bean.getClass().getMethod("addPropertyChangeListener", PropertyChangeListener.class); + method.invoke(bean, l); + } catch (Exception eee) { + log.info("Can't register as listener", eee); + } + validate(); + } + setChanged(false); + setValid(!hasErrors()); + pcs.firePropertyChange(BEAN_PROERTY, oldBean, bean); + } + + //FIXME At the moment we do not allow to change contextName, but we should be able to do it + public void setContextName(String contextName) { + String oldValidationContextName = this.contextName; + this.contextName = contextName; + // changing contextName could change fields definition + // so dettach bean, must rebuild the fields + setBean(null); + initFields(); + //pcs.firePropertyChange(CONTEXT_NAME_PROPERTY, oldValidationContextName, contextName); + } + + public void setParentValidator(SimpleBeanValidator<?> parentValidator) { + this.parentValidator = parentValidator; + } + + /** @return <code>true</code> if errors are detected, <code>false</code> otherwise */ + public boolean hasErrors() { + for (ValidatorField<B> field : fields) { + if (field.hasErrors()) { + return true; + } + } + return false; + } + + public boolean hasWarnings() { + for (ValidatorField<B> field : fields) { + if (field.hasWarnings()) { + return true; + } + } + return false; + } + + public boolean isValid(String fieldName) { + ValidatorField<B> field = getField(fieldName); + if (field == null) { + throw new IllegalArgumentException("could not find a validator field " + fieldName); + } + return field.isValid(); + } + + /** + * 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 (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 + 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 + * 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} + */ + public 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; + } + + try { + + validationSupport.clearErrorsAndMessages(); + + //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); + + // add the registred conversion errors + transfertConversionErrorsToFieldErrors(); + + 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()); + } + + // dispatch in each field the new errors + dispatchErrorsToFields(); + + if (parentValidator != null) { + // chained validation + parentValidator.l.propertyChange(null); + } + } catch (ValidationException eee) { + log.warn("Error during validation", eee); + } + } + + @Override + public String toString() { + return super.toString() + "<beanClass:" + beanClass + ", contextName:" + contextName + ">"; + } + + 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()); + } + + /** + * 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 = validationContext.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); + } + + /** synchronize the errors found in this validator to each field. */ + protected void dispatchErrorsToFields() { + + Map map = validationContext.getFieldErrors(); + for (ValidatorField<B> field : fields) { + String fieldName = field.getName(); + boolean detectedErrors = map.containsKey(fieldName); + field.addErrors(this, detectedErrors ? (List) map.get(fieldName) : null); + } + } + +} Deleted: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/Util.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/Util.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/Util.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,158 +0,0 @@ -package jaxx.runtime.validator; - -import jaxx.runtime.JAXXObject; -import jaxx.runtime.JAXXValidator; - -import javax.swing.JList; -import javax.swing.JTable; -import java.awt.event.MouseListener; -import java.util.List; -import java.util.ArrayList; -import java.beans.BeanInfo; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.beans.IntrospectionException; -import java.lang.reflect.InvocationTargetException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** @author chemit */ -public class Util { - - /** to use log facility, just put in your code: log.info(\"...\"); */ - static private final Log log = LogFactory.getLog(Util.class); - - public static void registerErrorListMouseListener(JList list) { - if (list == null) { - return; - } - for (MouseListener listener : list.getMouseListeners()) { - if (listener instanceof ErrorListMouseListener) { - // already have a such listener - log.info("already registered a such MouseListener : " + listener); - return; - } - } - list.addMouseListener(new ErrorListMouseListener()); - } - - public static void registerErrorTableMouseListener(JTable table) { - if (table == null) { - return; - } - for (MouseListener listener : table.getMouseListeners()) { - if (listener instanceof ErrorTableMouseListener) { - // already have a such listener - log.info("already registered a such MouseListener : " + listener); - return; - } - } - table.addMouseListener(new ErrorTableMouseListener()); - } - - public static ErrorTableMouseListener getErrorTableMouseListener(JTable table) { - if (table != null) { - for (MouseListener listener : table.getMouseListeners()) { - if (listener instanceof ErrorTableMouseListener) { - return (ErrorTableMouseListener) listener; - } - } - } - return null; - } - - /** - * 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 (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); - } - } else { - //fixme : conversion failed, we should be able to notify ui that values has changed ? - // otherwise, bean value has not changed,... - } - } -} Copied: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidationUtil.java (from rev 1173, jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/Util.java) =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidationUtil.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidationUtil.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -0,0 +1,167 @@ +package jaxx.runtime.validator; + +import jaxx.runtime.JAXXObject; +import jaxx.runtime.JAXXValidator; +import jaxx.runtime.validator.swing.SwingValidatorErrorListMouseListener; +import jaxx.runtime.validator.swing.SwingValidatorErrorTableMouseListener; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.JList; +import javax.swing.JTable; +import java.awt.event.MouseListener; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +/** + * The helper class for validation module. + * + * @author chemit + */ +public class ValidationUtil { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(ValidationUtil.class); + + protected ValidationUtil() { + // no instance + } + + public static void registerErrorListMouseListener(JList list) { + if (list == null) { + return; + } + for (MouseListener listener : list.getMouseListeners()) { + if (listener instanceof SwingValidatorErrorListMouseListener) { + // already have a such listener + log.info("already registered a such MouseListener : " + listener); + return; + } + } + list.addMouseListener(new SwingValidatorErrorListMouseListener()); + } + + public static void registerErrorTableMouseListener(JTable table) { + if (table == null) { + return; + } + for (MouseListener listener : table.getMouseListeners()) { + if (listener instanceof SwingValidatorErrorTableMouseListener) { + // already have a such listener + log.info("already registered a such MouseListener : " + listener); + return; + } + } + table.addMouseListener(new SwingValidatorErrorTableMouseListener()); + } + + public static SwingValidatorErrorTableMouseListener getErrorTableMouseListener(JTable table) { + if (table != null) { + for (MouseListener listener : table.getMouseListeners()) { + if (listener instanceof SwingValidatorErrorTableMouseListener) { + return (SwingValidatorErrorTableMouseListener) listener; + } + } + } + return null; + } + + /** + * 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) { + SimpleBeanValidator 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) { + SimpleBeanValidator 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(SimpleBeanValidator<?> 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); + } + } else { + //fixme : conversion failed, we should be able to notify ui that values has changed ? + // otherwise, bean value has not changed,... + } + } +} Added: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorEvent.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorEvent.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorEvent.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -0,0 +1,45 @@ +package jaxx.runtime.validator; + +import com.opensymphony.xwork2.validator.ValidatorScope; + +import java.util.Set; + +/** + * The definition of an event on {@link ValidatorErrorListener} + * to be fired by a {@link SimpleBeanValidator}. + * + * @author chemit + */ +public class ValidatorErrorEvent { + + /** the source of the event */ + SimpleBeanValidator source; + + /** the field impacted by the validator */ + ValidatorField<?> field; + + public ValidatorErrorEvent(SimpleBeanValidator source, ValidatorField<?> field) { + this.source = source; + this.field = field; + } + + public SimpleBeanValidator getSource() { + return source; + } + + public String getFieldName() { + return field.getName(); + } + + public Set<String> getErrors() { + return field.getErrors(); + } + + public ValidatorScope getScope() { + return field.getScope(); + } + + public ValidatorField getField() { + return field; + } +} Added: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorListener.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorListener.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorListener.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -0,0 +1,24 @@ +package jaxx.runtime.validator; + +/** + * The listener contract to be used on {@link SimpleBeanValidator] + * + * @author chemit + */ +public interface ValidatorErrorListener extends java.util.EventListener { + /** + * Invoked when a validator detects a error on a field. + * + * @param event the event + */ + void onNewError(ValidatorErrorEvent event); + + /** + * Invoked when a validator detetcs that a previously error is + * no more exisitng. + * + * @param event the event + */ + void onResolvedError(ValidatorErrorEvent event); + +} Added: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorField.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorField.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorField.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -0,0 +1,182 @@ +package jaxx.runtime.validator; + +import com.opensymphony.xwork2.validator.ValidatorScope; +import static org.codelutin.i18n.I18n._; + +import javax.swing.event.EventListenerList; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.StringTokenizer; + +/** + * Definition of a field to be handled in a {@link SimpleBeanValidator]. + * <p/> + * <p/> + * A such class is only registred in {@link SimpleBeanValidator} when the field of the bean + * was found in validator xml configuration file for a {@link com.opensymphony.xwork2.validator.FieldValidator} only. + * <p/> + * This class use properties {@link #beanClass}, {@link #name} to define + * his naturel order. + * + * @author chemit + * @param <B> the type of the bean handled by the validator and this field of validation. + */ +public class ValidatorField<B> { + + /** the class of bean */ + protected final Class<B> beanClass; + + /** name of field in bean */ + protected String name; + + /** the scope of the field */ + protected ValidatorScope scope; + + /** the list of error for this field */ + protected Set<String> errors; + + /** A list of event listeners for this validators */ + protected EventListenerList listenerList = new EventListenerList(); + + public ValidatorField(Class<B> beanClass, String name, ValidatorScope scope) { + this.beanClass = beanClass; + this.name = name; + this.scope = scope; + this.errors = new HashSet<String>(); + } + + public String getName() { + return name; + } + + public ValidatorScope getScope() { + return scope; + } + + public Class<B> getBeanClass() { + return beanClass; + } + + public Set<String> getErrors() { + return errors; + } + + public void setName(String name) { + this.name = name; + } + + public void setScope(ValidatorScope scope) { + this.scope = scope; + } + + /** + * @return <code>true</code> if this field is valid (says is in error + * scope and has errors), <code>false</code> otherwise. + */ + public boolean isValid() { + return hasErrors(); + } + + public boolean hasErrors() { + return scope == ValidatorScope.ERROR && !errors.isEmpty(); + } + + public boolean hasWarnings() { + return scope == ValidatorScope.WARNING && !errors.isEmpty(); + } + + public void addErrors(SimpleBeanValidator<B> validator, List errors) { + boolean hasPreviousError = !this.errors.isEmpty(); + + // reset errors for this field + this.errors.clear(); + + if (errors == null) { + // no error to assign to this field + if (hasPreviousError) { + // there were previously errors, but any longer + // so fire a resolvedErrorEvent for this field + fireResolvedError(validator); + } + return; + } + + for (Object error : errors) { + this.errors.add(error.toString()); + } + // fire a newErrorEvent for this field + fireNewError(validator); + } + + public String getI18nError(String error) { + String text; + if (error.indexOf("##") == -1) { + 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; + } + + public void addValidatorErrorListener(ValidatorErrorListener listener) { + listenerList.add(ValidatorErrorListener.class, listener); + } + + public void removeValidatorErrorListener(ValidatorErrorListener listener) { + listenerList.remove(ValidatorErrorListener.class, listener); + } + + protected void fireNewError(SimpleBeanValidator<B> validator) { + ValidatorErrorEvent evt = new ValidatorErrorEvent(validator, this); + for (ValidatorErrorListener listener : listenerList.getListeners(ValidatorErrorListener.class)) { + listener.onNewError(evt); + } + } + + protected void fireResolvedError(SimpleBeanValidator<B> validator) { + ValidatorErrorEvent evt = new ValidatorErrorEvent(validator, this); + for (ValidatorErrorListener listener : listenerList.getListeners(ValidatorErrorListener.class)) { + listener.onResolvedError(evt); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ValidatorField)) { + return false; + } + + ValidatorField that = (ValidatorField) 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(", scope:").append(scope); + sb.append(", errors:").append(errors); + sb.append('>'); + return sb.toString(); + } +} Added: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -0,0 +1,175 @@ +package jaxx.runtime.validator.swing; + +import jaxx.runtime.validator.SimpleBeanValidator; +import jaxx.runtime.validator.ValidatorField; +import jaxx.runtime.validator.ui.AbstractBeanValidatorUI; +import jaxx.runtime.validator.ui.IconValidationUI; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jdesktop.jxlayer.JXLayer; + +import javax.swing.JComponent; +import javax.swing.SwingUtilities; +import java.awt.Container; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +/** + * La surcharge de {@link jaxx.runtime.validator.SimpleBeanValidator} pour les ui swing + * + * @author chemit + */ +public class SwingValidator<B> extends SimpleBeanValidator<B> { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(SwingValidator.class); + + static private final Class<? extends AbstractBeanValidatorUI> DEFAULT_UI_CLASS = IconValidationUI.class; + + /** permet de faire le lien en un champs du bean et l'objet qui permet de l'editer */ + protected Map<String, JComponent> fieldRepresentation; + + /** Object servant a contenir la liste des erreurs */ + protected SwingValidatorErrorListModel errorListModel; + + /** Object servant a contenir la liste des erreurs */ + protected SwingValidatorErrorTableModel errorTableModel; + + /** ui renderer class */ + protected Class<? extends AbstractBeanValidatorUI> uiClass; + + + public SwingValidator(Class<B> beanClass, String contextName) { + super(beanClass, contextName); + fieldRepresentation = new HashMap<String, JComponent>(); + } + + public JComponent getFieldRepresentation(String fieldname) { + return fieldRepresentation.get(fieldname); + } + + public Class<? extends AbstractBeanValidatorUI> getUiClass() { + return uiClass; + } + + public void setErrorListModel(SwingValidatorErrorListModel errorListModel) { + this.errorListModel = errorListModel; + if (errorListModel != null) { + // register the validator in the model list + errorListModel.registerValidator(this); + } + } + + public void setErrorTableModel(SwingValidatorErrorTableModel errorTableModel) { + this.errorTableModel = errorTableModel; + if (errorTableModel != null) { + // register the validator in the model table + errorTableModel.registerValidator(this); + } + } + + public void setUiClass(Class<? extends AbstractBeanValidatorUI> uiClass) { + this.uiClass = uiClass; + } + + @Override + public void setContextName(String contextName) { + super.setContextName(contextName); + // must reinstall ui + installUIs(); + } + + /** + * Permet d'indiquer le composant graphique responsable de l'affichage + * d'un attribut du bean + * + * @param fieldname the field name in the bean + * @param c the editor component for the field + */ + public void setFieldRepresentation(String fieldname, JComponent c) { + ValidatorField<B> field = getField(fieldname); + if (field == null) { + // no field registred in the validator + log.warn("the field '" + fieldname + "' is not defined in validator (no rules on it)"); + return; + } + fieldRepresentation.put(fieldname, c); + } + + public void setFieldRepresentation(Map<String, JComponent> fieldRepresentation) { + for (Map.Entry<String, JComponent> e : fieldRepresentation.entrySet()) { + setFieldRepresentation(e.getKey(), e.getValue()); + } + } + + @Override + public SwingValidator<?> getParentValidator() { + return (SwingValidator<?>) super.getParentValidator(); + } + + public void setParentValidator(SwingValidator<?> parentValidator) { + super.setParentValidator(parentValidator); + } + + /** install ui on required components */ + public void installUIs() { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (uiClass == null) { + // use the default one + uiClass = DEFAULT_UI_CLASS; + } + for (Entry<String, JComponent> entry : fieldRepresentation.entrySet()) { + try { + setErrorRepresentation(entry.getKey(), null, entry.getValue(), uiClass); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + }); + } + + protected void setErrorRepresentation(String fieldname, JComponent old, JComponent c, Class<? extends AbstractBeanValidatorUI> uiClass) + throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { + if (old == c) { + // same component, nothing to do + return; + } + ValidatorField<B> field = getField(fieldname); + + if (field == null) { + // this case should not appear since fieldName has already been check in method addFieldRepresentation + return; + } + if (old != null) { + // suppression du jxlayer sous l'ancien composant + Container container = old.getParent(); + if (container instanceof JXLayer) { + JXLayer<?> jx = (JXLayer<?>) container; + Object ui = jx.getUI(); + if (ui != null && ui instanceof AbstractBeanValidatorUI) { + field.removeValidatorErrorListener((AbstractBeanValidatorUI) ui); + } + jx.setUI(null); + } + } + if (c != null) { + // ajout du jxlayer sous ce composant + Container container = c.getParent(); + if (container instanceof JXLayer) { + Constructor<? extends AbstractBeanValidatorUI> cons = uiClass.getConstructor(ValidatorField.class); + AbstractBeanValidatorUI ui = cons.newInstance(field); + ui.setEnabled(true); + JXLayer<JComponent> jx = (JXLayer<JComponent>) container; + field.addValidatorErrorListener(ui); + jx.setUI(ui); + } + } + } + + +} Copied: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListModel.java (from rev 1173, jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorListModel.java) =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListModel.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListModel.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -0,0 +1,117 @@ +package jaxx.runtime.validator.swing; + +import jaxx.runtime.validator.SimpleBeanValidator; +import jaxx.runtime.validator.ValidatorErrorEvent; +import jaxx.runtime.validator.ValidatorErrorListener; +import jaxx.runtime.validator.ValidatorField; + +import javax.swing.DefaultListModel; +import javax.swing.JComponent; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Set; + +/** + * The model of the list of errors + * + * @author chemit + */ +public class SwingValidatorErrorListModel extends DefaultListModel implements ValidatorErrorListener { + + private static final long serialVersionUID = 1L; + + /** list of registred validators */ + protected transient List<SimpleBeanValidator<?>> validators; + + + public SwingValidatorErrorListModel() { + validators = new ArrayList<SimpleBeanValidator<?>>(); + } + + public void registerValidator(SimpleBeanValidator<?> validator) { + if (validators.contains(validator)) { + throw new IllegalArgumentException("the validator " + validator + " is already registred in " + this); + } + validators.add(validator); + // the model listen on each field of the validator + for (ValidatorField<?> field : validator.getFields()) { + field.addValidatorErrorListener(this); + } + } + + + /** + * Invoked when a validator detects a error on a field. + * + * @param event the event + */ + @Override + public void onNewError(ValidatorErrorEvent event) { + ValidatorField field = event.getField(); + SwingValidator validator = (SwingValidator) event.getSource(); + Set<String> errors = event.getErrors(); + + // must remove all previously error for this field and validator + List<SwingValidatorErrorModel> newErrors = new ArrayList<SwingValidatorErrorModel>(); + JComponent editor = validator.getFieldRepresentation(field.getName()); + Enumeration enumeration = elements(); + while (enumeration.hasMoreElements()) { + SwingValidatorErrorModel error = (SwingValidatorErrorModel) enumeration.nextElement(); + if (error.getValidator() == validator && error.getField() == field) { + // this error can be skipped + continue; + } + newErrors.add(error); + } + // add new errors + for (String error : errors) { + newErrors.add(new SwingValidatorErrorModel(validator, field, error, editor)); + } + java.util.Collections.sort(newErrors); + + // clean model and reinject new errors + removeAllElements(); + + // reinject in list model, all the errors + for (SwingValidatorErrorModel error : newErrors) { + addElement(error); + } + //FIXME, this is not performant, prefer use a isValueAdjusting property on SwingValidator + // notify that the model has changed + } + + /** + * Invoked when a validator detetcs that a previously error is + * no more exisitng. + * + * @param event the event + */ + @Override + public void onResolvedError(ValidatorErrorEvent event) { + SwingValidator validator = (SwingValidator) event.getSource(); + ValidatorField field = event.getField(); + // must remove all previously error for this field + + boolean somethingChange = false; + Enumeration enumeration = elements(); + List<SwingValidatorErrorModel> newList = new ArrayList<SwingValidatorErrorModel>(); + while (enumeration.hasMoreElements()) { + SwingValidatorErrorModel error = (SwingValidatorErrorModel) enumeration.nextElement(); + if (error.getValidator() == validator && error.getField() == field) { + // this error can be skipped + somethingChange = true; + } else { + newList.add(error); + } + } + // clean model and reinject new errors + removeAllElements(); + + if (somethingChange) { + for (SwingValidatorErrorModel errorModel : newList) { + addElement(errorModel); + } + } + } +} \ No newline at end of file Property changes on: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListModel.java ___________________________________________________________________ Name: svn:mergeinfo + Added: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListMouseListener.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListMouseListener.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListMouseListener.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -0,0 +1,61 @@ +package jaxx.runtime.validator.swing; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.JComponent; +import javax.swing.JList; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/** + * A mouse listener to put on a {@link javax.swing.JList} with a {@link SwingValidatorErrorListModel} as a model. + * <p/> + * When a double click occurs, find the selected error in model and then focus to the associated component of error. + * + * @author chemit + */ +public class SwingValidatorErrorListMouseListener extends MouseAdapter { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(SwingValidatorErrorListMouseListener.class); + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (e.getClickCount() == 2) { + + SwingValidatorErrorModel entry = getSelectedError(e); + if (entry == null) { + // no entry found + return; + } + JComponent component = entry.getEditor(); + if (component != null) { + component.requestFocus(); + } + } + } + + + protected SwingValidatorErrorModel getSelectedError(MouseEvent e) { + JList list = (JList) e.getSource(); + if (!(list.getModel() instanceof SwingValidatorErrorListModel)) { + log.warn("model must be a " + SwingValidatorErrorListModel.class + ", but was " + list.getModel()); + return null; + } + + SwingValidatorErrorListModel model = (SwingValidatorErrorListModel) list.getModel(); + int index = list.getSelectionModel().getMinSelectionIndex(); + if (index == -1) { + // nothing is selected + return null; + } + SwingValidatorErrorModel entry = (SwingValidatorErrorModel) model.getElementAt(index); + if (log.isDebugEnabled()) { + log.debug("selected index: " + index + " : error: " + entry); + } + return entry; + } + +} \ No newline at end of file Added: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorModel.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorModel.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorModel.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -0,0 +1,55 @@ +package jaxx.runtime.validator.swing; + +import jaxx.runtime.validator.ValidatorField; + +import javax.swing.JComponent; + +/** @author chemit */ +public class SwingValidatorErrorModel implements Comparable<SwingValidatorErrorModel> { + protected SwingValidator validator; + protected ValidatorField field; + protected String error; + protected JComponent editor; + + public SwingValidatorErrorModel(SwingValidator validator, ValidatorField field, String error, JComponent editor) { + this.field = field; + this.validator = validator; + this.error = error; + this.editor = editor; + } + + public JComponent getEditor() { + return editor; + } + + public SwingValidator getValidator() { + return validator; + } + + public ValidatorField getField() { + return field; + } + + public String getError() { + return error; + } + + @Override + public int compareTo(SwingValidatorErrorModel o) { + int result = field.getScope().compareTo(o.field.getScope()); + if (result != 0) { + return result; + } + result = field.getName().compareTo(o.field.getName()); + if (result != 0) { + return result; + } + result = error.compareTo(o.error); + return result; + } + + @Override + public String toString() { + return editor.getName() + " : " + field.getI18nError(error); + } +} Copied: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableModel.java (from rev 1173, jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorTableModel.java) =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableModel.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableModel.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -0,0 +1,129 @@ +package jaxx.runtime.validator.swing; + +import jaxx.runtime.validator.ValidatorErrorEvent; +import jaxx.runtime.validator.ValidatorErrorListener; +import jaxx.runtime.validator.ValidatorField; + +import javax.swing.JComponent; +import javax.swing.table.DefaultTableModel; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.Vector; + +/** + * The model of the list of errors + * + * @author chemit + */ +public class SwingValidatorErrorTableModel extends DefaultTableModel implements ValidatorErrorListener { + + private static final long serialVersionUID = 1L; + + public static final String[] columnNames = {"validator.scope", "validator.field", "validator.message"}; + + /** list of registred validators */ + protected transient List<SwingValidator<?>> validators; + + /** comporator of errors */ + protected transient Comparator<SwingValidatorErrorModel> comparator; + + public SwingValidatorErrorTableModel() { + super(columnNames, 0); + validators = new ArrayList<SwingValidator<?>>(); + } + + public int getErrorColumn() { + return findColumn(columnNames[2]); + } + + @Override + public boolean isCellEditable(int row, int column) { + // cells are never editable in this model + return false; + } + + public void registerValidator(SwingValidator<?> validator) { + if (validators.contains(validator)) { + throw new IllegalArgumentException("the validator " + validator + " is already registred in " + this); + } + validators.add(validator); + // the model listen on each field of the validator + for (ValidatorField<?> field : validator.getFields()) { + field.addValidatorErrorListener(this); + } + } + + /** + * Invoked when a validator detects a error on a field. + * + * @param event the event + */ + @Override + public void onNewError(ValidatorErrorEvent event) { + ValidatorField field = event.getField(); + SwingValidator validator = (SwingValidator) event.getSource(); + Set<String> errors = event.getErrors(); + // must remove all previously error for this field and validator + int errorColumn = getErrorColumn(); + + List<SwingValidatorErrorModel> newErrors = new ArrayList<SwingValidatorErrorModel>(); + JComponent editor = validator.getFieldRepresentation(field.getName()); + for (Object o : getDataVector()) { + Vector row = (Vector) o; + SwingValidatorErrorModel error = (SwingValidatorErrorModel) row.get(errorColumn); + if (error.getValidator() == validator && error.getField() == field) { + // this error can be skipped + continue; + } + newErrors.add(error); + } + // add new errors + for (String error : errors) { + newErrors.add(new SwingValidatorErrorModel(validator, field, error, editor)); + } + java.util.Collections.sort(newErrors); + + // clean table model and reinject new errors + getDataVector().clear(); + // reinject in list model, all the errors + for (SwingValidatorErrorModel error : newErrors) { + addRow(new Object[]{error.getField().getScope(), error.getField().getName(), error}); + } + //FIXME, this is not performant, prefer use a isValueAdjusting property on SwingValidator + // notify that the model has changed + fireTableDataChanged(); + } + + /** + * Invoked when a validator detetcs that a previously error is + * no more exisitng. + * + * @param event the event + */ + @Override + public void onResolvedError(ValidatorErrorEvent event) { + SwingValidator validator = (SwingValidator) event.getSource(); + ValidatorField field = event.getField(); + // must remove all previously error for this field + int errorColumn = getErrorColumn(); + boolean somethingChange = false; + for (Iterator it = getDataVector().iterator(); it.hasNext();) { + Object o = it.next(); + Vector row = (Vector) o; + SwingValidatorErrorModel error = (SwingValidatorErrorModel) row.get(errorColumn); + if (error.getValidator() == validator && error.getField() == field) { + // this error can be skipped + it.remove(); + somethingChange = true; + } + } + if (somethingChange) { + // notify that the model has changed + fireTableDataChanged(); + } + } + +} \ No newline at end of file Property changes on: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableModel.java ___________________________________________________________________ Name: svn:mergeinfo + Added: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableMouseListener.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableMouseListener.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableMouseListener.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -0,0 +1,92 @@ +package jaxx.runtime.validator.swing; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.JComponent; +import javax.swing.JTable; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; + +/** + * A mouse listener to put on a {@link javax.swing.JList} with a {@link SwingValidatorErrorTableModel} as a model. + * <p/> + * When a double click occurs, find the selected error in model and then focus to the associated component of error. + * + * @author chemit + */ +public class SwingValidatorErrorTableMouseListener extends MouseAdapter { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + private static Log log = LogFactory.getLog(SwingValidatorErrorTableMouseListener.class); + + public static final String HIGHLIGHT_ERROR_PROPERTY = "highlightError"; + + /** delgate property change support */ + protected PropertyChangeSupport pcs; + + public SwingValidatorErrorTableMouseListener() { + pcs = new PropertyChangeSupport(this); + } + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (e.getClickCount() == 2) { + + SwingValidatorErrorModel entry = getSelectedError(e); + if (entry == null) { + // no entry found + return; + } + JComponent component = entry.getEditor(); + if (component != null) { + pcs.firePropertyChange(HIGHLIGHT_ERROR_PROPERTY, null, entry); + if (component.isVisible()) { + component.requestFocus(); + } + } + } + } + + + protected SwingValidatorErrorModel getSelectedError(MouseEvent e) { + JTable table = (JTable) e.getSource(); + if (!(table.getModel() instanceof SwingValidatorErrorTableModel)) { + log.warn("model must be a " + SwingValidatorErrorTableModel.class + ", but was " + table.getModel()); + return null; + } + + SwingValidatorErrorTableModel model = (SwingValidatorErrorTableModel) table.getModel(); + int index = table.getSelectionModel().getMinSelectionIndex(); + if (index == -1) { + // nothing is selected + return null; + } + int col = model.getErrorColumn(); + SwingValidatorErrorModel entry = (SwingValidatorErrorModel) model.getValueAt(index, col); + if (log.isDebugEnabled()) { + log.debug("selected index: " + index + " : error: " + entry); + } + return entry; + } + + 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); + } + +} \ No newline at end of file Added: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableRenderer.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableRenderer.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableRenderer.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -0,0 +1,55 @@ +package jaxx.runtime.validator.swing; + +import com.opensymphony.xwork2.validator.ValidatorScope; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.table.DefaultTableCellRenderer; +import java.awt.Component; + +/** @author chemit */ +public class SwingValidatorErrorTableRenderer extends DefaultTableCellRenderer { + + ImageIcon errorIcon; + ImageIcon warningIcon; + + public SwingValidatorErrorTableRenderer() { + errorIcon = jaxx.runtime.Util.createImageIcon("error.png"); + warningIcon = jaxx.runtime.Util.createImageIcon("warning.png"); + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + JLabel rendererComponent = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + + ImageIcon icon = null; + String text = null; + if (value instanceof ValidatorScope) { + + ValidatorScope scope = (ValidatorScope) value; + switch (scope) { + case ERROR: + icon = errorIcon; + break; + case WARNING: + icon = warningIcon; + break; + } + } else if (value instanceof SwingValidatorErrorModel) { + SwingValidatorErrorModel model = (SwingValidatorErrorModel) value; + String error = model.getError(); + text = model.getField().getI18nError(error); + } else { + // keep text rendered + text = rendererComponent.getText(); + } + rendererComponent.setText(text); + rendererComponent.setIcon(icon); + return rendererComponent; + } + + @Override + protected void setValue(Object value) { + super.setValue(value); + } +} \ No newline at end of file Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/AbstractBeanValidatorUI.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/AbstractBeanValidatorUI.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/AbstractBeanValidatorUI.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,7 +1,8 @@ package jaxx.runtime.validator.ui; -import com.opensymphony.xwork2.ValidationAware; -import jaxx.runtime.validator.BeanValidator.Scope; +import jaxx.runtime.validator.ValidatorErrorEvent; +import jaxx.runtime.validator.ValidatorErrorListener; +import jaxx.runtime.validator.ValidatorField; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jdesktop.jxlayer.plaf.AbstractLayerUI; @@ -11,28 +12,38 @@ * * @author chemit */ -public abstract class AbstractBeanValidatorUI extends AbstractLayerUI<javax.swing.JComponent> { +public abstract class AbstractBeanValidatorUI extends AbstractLayerUI<javax.swing.JComponent> implements ValidatorErrorListener { /** to use log facility, just put in your code: log.info(\"...\"); */ - protected static Log log = LogFactory.getLog(AbstractBeanValidatorUI.class); + private static final Log log = LogFactory.getLog(AbstractBeanValidatorUI.class); - /** scope */ - protected Scope scope; + /** the field to render */ + protected ValidatorField field; - /** bean field */ - protected String field; + public AbstractBeanValidatorUI(ValidatorField field) { + this.field = field; + if (log.isInfoEnabled()) { + log.info("install " + this + "<field:" + field + ">"); + } + } - /** component id */ - protected String componentId; + @Override + public void onNewError(ValidatorErrorEvent event) { + dispatchValidatorErrorEvent(event); + } - /** validation context */ - protected ValidationAware validationContext; + @Override + public void onResolvedError(ValidatorErrorEvent event) { + dispatchValidatorErrorEvent(event); + } - public AbstractBeanValidatorUI(String field, String componentId, Scope scope, ValidationAware validationContext) { - this.componentId = componentId; - this.field = field; - this.scope = scope; - this.validationContext = validationContext; - log.info("install " + this + "<field:" + field + ", componentId:" + componentId + ">"); + protected void dispatchValidatorErrorEvent(ValidatorErrorEvent event) { + // check if event occurs to this field + if (!field.equals(event.getField())) { + return; + } + // repaint the layer + setDirty(true); } + } Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/IconValidationUI.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/IconValidationUI.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/IconValidationUI.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,7 +1,6 @@ package jaxx.runtime.validator.ui; -import com.opensymphony.xwork2.ValidationAware; -import jaxx.runtime.validator.BeanValidator.Scope; +import jaxx.runtime.validator.ValidatorField; import org.jdesktop.jxlayer.JXLayer; import javax.swing.BorderFactory; @@ -15,25 +14,11 @@ public class IconValidationUI extends AbstractBeanValidatorUI { // The icon to be shown at the layer's corner - protected BufferedImage invalidIcon; + protected static BufferedImage errorIcon; + protected static BufferedImage warningIcon; - protected Color hightlight; - - public IconValidationUI(String field, String componentId, Scope scope, ValidationAware validationContext) { - super(field, componentId, scope, validationContext); - int width = 7; - int height = 8; - hightlight = scope == Scope.ERROR ? Color.RED : Color.YELLOW; - invalidIcon = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - Graphics2D g2 = (Graphics2D) invalidIcon.getGraphics(); - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); - g2.setColor(hightlight); - g2.fillRect(0, 0, width, height); - g2.setColor(Color.WHITE); - g2.drawLine(0, 0, width, height); - g2.drawLine(0, height, width, 0); - g2.dispose(); + public IconValidationUI(ValidatorField field) { + super(field); } @Override @@ -52,8 +37,47 @@ protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) { super.paintLayer(g2, l); // There is no need to take insets into account for this painter - if (validationContext.getFieldErrors().containsKey(field)) { - g2.drawImage(invalidIcon, l.getWidth() - invalidIcon.getWidth() - 1, 0, null); + switch (field.getScope()) { + case ERROR: + if (field.hasErrors()) { + g2.drawImage(getErrorIcon(), l.getWidth() - errorIcon.getWidth() - 1, 0, null); + } + break; + case WARNING: + if (field.hasWarnings()) { + g2.drawImage(getWarningIcon(), l.getWidth() - warningIcon.getWidth() - 1, 0, null); + } + break; } } + + protected static BufferedImage getErrorIcon() { + if (errorIcon == null) { + errorIcon = prepareIcon(Color.RED); + } + return errorIcon; + } + + protected static BufferedImage getWarningIcon() { + if (warningIcon == null) { + warningIcon = prepareIcon(Color.YELLOW); + } + return warningIcon; + } + + protected static BufferedImage prepareIcon(Color color) { + int width = 7; + int height = 8; + BufferedImage icon = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + Graphics2D g2 = (Graphics2D) icon.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); + g2.setColor(color); + g2.fillRect(0, 0, width, height); + g2.setColor(Color.WHITE); + g2.drawLine(0, 0, width, height); + g2.drawLine(0, height, width, 0); + g2.dispose(); + return icon; + } } Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/ImageValidationUI.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/ImageValidationUI.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/ImageValidationUI.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,13 +1,11 @@ package jaxx.runtime.validator.ui; -import com.opensymphony.xwork2.ValidationAware; -import jaxx.runtime.validator.BeanValidator.Scope; +import jaxx.runtime.validator.ValidatorField; import org.jdesktop.jxlayer.JXLayer; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JComponent; -import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; @@ -15,34 +13,21 @@ /** @author chemit */ public class ImageValidationUI extends AbstractBeanValidatorUI { - // The icon to be shown at the layer's corner - protected BufferedImage invalidIcon; + protected static BufferedImage errorIcon; + protected static BufferedImage warningIcon; - protected Color hightlight; + public ImageValidationUI(ValidatorField field) { + super(field); + } - public ImageValidationUI(String field, String componentId, Scope scope, ValidationAware validationContext) { - super(field, componentId, scope, validationContext); - - hightlight = scope == Scope.ERROR ? Color.RED : Color.YELLOW; - ImageIcon image = null; - switch (scope) { - - case ERROR: - image = jaxx.runtime.Util.createImageIcon("error.png"); - break; - case WARNING: - image = jaxx.runtime.Util.createImageIcon("warning.png"); - break; - } - //int width = 7; - //int height = 8; - invalidIcon = new BufferedImage(image.getIconWidth(), image.getIconHeight(), BufferedImage.TYPE_INT_ARGB); - - Graphics2D g2 = (Graphics2D) invalidIcon.getGraphics(); + protected static BufferedImage prepareIcon(ImageIcon image) { + BufferedImage icon = new BufferedImage(image.getIconWidth(), image.getIconHeight(), BufferedImage.TYPE_INT_ARGB); + Graphics2D g2 = (Graphics2D) icon.getGraphics(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); g2.drawImage(image.getImage(), 0, 0, null); g2.dispose(); + return icon; } @Override @@ -60,9 +45,31 @@ @Override protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) { super.paintLayer(g2, l); - // There is no need to take insets into account for this painter - if (validationContext.getFieldErrors().containsKey(field)) { - g2.drawImage(invalidIcon, l.getWidth() - invalidIcon.getWidth() - 1, 0, null); + switch (field.getScope()) { + case ERROR: + if (field.hasErrors()) { + g2.drawImage(getErrorIcon(), l.getWidth() - errorIcon.getWidth() - 1, 0, null); + } + break; + case WARNING: + if (field.hasWarnings()) { + g2.drawImage(getWarningIcon(), l.getWidth() - warningIcon.getWidth() - 1, 0, null); + } + break; } } + + protected static BufferedImage getErrorIcon() { + if (errorIcon == null) { + errorIcon = prepareIcon(jaxx.runtime.Util.createImageIcon("error.png")); + } + return errorIcon; + } + + protected static BufferedImage getWarningIcon() { + if (warningIcon == null) { + warningIcon = prepareIcon(jaxx.runtime.Util.createImageIcon("warning.png")); + } + return warningIcon; + } } \ No newline at end of file Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/TranslucentValidationUI.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/TranslucentValidationUI.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/TranslucentValidationUI.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,7 +1,6 @@ package jaxx.runtime.validator.ui; -import com.opensymphony.xwork2.ValidationAware; -import jaxx.runtime.validator.BeanValidator.Scope; +import jaxx.runtime.validator.ValidatorField; import org.jdesktop.jxlayer.JXLayer; import javax.swing.JComponent; @@ -14,11 +13,13 @@ /** @author chemit */ public class TranslucentValidationUI extends AbstractBeanValidatorUI { - protected Color hightlight; + protected Color errorHightlight; + protected Color warningHightlight; - public TranslucentValidationUI(String field, String componentId, Scope scope, ValidationAware validationContext) { - super(field, componentId, scope, validationContext); - hightlight = scope == Scope.ERROR ? Color.RED : Color.YELLOW; + public TranslucentValidationUI(ValidatorField field) { + super(field); + errorHightlight = Color.RED; + warningHightlight = Color.YELLOW; } @Override @@ -37,8 +38,23 @@ view.getWidth() - insets.left - insets.right, view.getHeight() - insets.top - insets.bottom)); - g2.setColor(!validationContext.getFieldErrors().containsKey(field) ? - Color.GREEN : Color.RED); + switch (field.getScope()) { + + case ERROR: + if (field.hasErrors()) { + g2.setColor(errorHightlight); + } else { + g2.setColor(Color.WHITE); + } + break; + case WARNING: + if (field.hasErrors()) { + g2.setColor(warningHightlight); + } else { + g2.setColor(Color.WHITE); + } + break; + } g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .2f)); g2.fillRect(0, 0, l.getWidth(), l.getHeight()); } Modified: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractValidatorTest.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractValidatorTest.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractValidatorTest.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,8 +1,7 @@ package jaxx.runtime.validator.field; -import jaxx.runtime.validator.BeanValidator; -import jaxx.runtime.validator.BeanValidatorError; -import jaxx.runtime.validator.BeanValidatorErrorListModel; +import jaxx.runtime.validator.SimpleBeanValidator; +import jaxx.runtime.validator.ValidatorField; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.After; @@ -10,22 +9,32 @@ import org.junit.Before; import org.junit.BeforeClass; -import javax.swing.JLabel; import java.io.File; -import java.util.Enumeration; -/** @author chemit */ +/** + * Abstract class to test a specific validator. + * <p/> + * To implements a test on a new validator, just extends this class + * and implements the method {@link #testValidator()}. + * + * @author chemit + */ public abstract class AbstractValidatorTest extends Assert { /** to use log facility, just put in your code: log.info(\"...\"); */ static private final Log log = LogFactory.getLog(AbstractValidatorTest.class); - protected ValidatorBean bean; + static protected SimpleBeanValidator<ValidatorBean> validator; - static protected BeanValidator<ValidatorBean> validator; - static protected BeanValidatorErrorListModel errors; static protected File basedir; + protected ValidatorBean bean; + + /** + * the moethod to implements testing the given validator on the given bean. + * + * @throws Exception if any error ? + */ public abstract void testValidator() throws Exception; @BeforeClass @@ -36,14 +45,7 @@ b = new File("").getAbsolutePath(); } basedir = new File(b); - validator = new BeanValidator<ValidatorBean>(ValidatorBean.class); - validator.setErrorListModel(errors = new BeanValidatorErrorListModel()); - JLabel label = new JLabel(); - validator.setFieldRepresentation("existingFile", label); - validator.setFieldRepresentation("existingDirectory", label); - validator.setFieldRepresentation("notExistingFile", label); - validator.setFieldRepresentation("notExistingDirectory", label); - validator.setFieldRepresentation("entries", label); + validator = new SimpleBeanValidator<ValidatorBean>(ValidatorBean.class, null); } @Before @@ -57,11 +59,11 @@ validator.setBean(null); } - protected void assertFieldInError(String s, String error, boolean required) { - Enumeration<?> myErrors = errors.elements(); - while (myErrors.hasMoreElements()) { - BeanValidatorError o = (BeanValidatorError) myErrors.nextElement(); - if (o.getFieldName().equals(s) && o.getError().equals(error)) { + protected void assertFieldInError(String fieldName, String error, boolean required) { + ValidatorField<ValidatorBean> field = validator.getField(fieldName); + + for (String o : field.getErrors()) { + if (o.equals(error)) { assertTrue(required); return; } Modified: jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/field/ValidatorBean-validation.xml =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/field/ValidatorBean-validation.xml 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/field/ValidatorBean-validation.xml 2009-02-03 01:38:07 UTC (rev 1194) @@ -4,7 +4,7 @@ <validators> <field name="existingFile"> - <field-validator type="requiredFile" short-circuit="true"> + <field-validator type="requiredFile" short-circuit="true" validatorScope="ERROR"> <message>existingFile.required</message> </field-validator> <field-validator type="existingFile" short-circuit="true"> Modified: jaxx/trunk/maven-jaxx-plugin/changelog.txt =================================================================== --- jaxx/trunk/maven-jaxx-plugin/changelog.txt 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/maven-jaxx-plugin/changelog.txt 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,4 +1,5 @@ 1.1 chemit 200901?? + * 20090202 [chemit] - introduce a property validatorClass to specify the validator implementation * 20090124 [chemit] - introduce a flag useUIManagerForIcon to retreave icons from UIManager - clean mojo getter and setter (not used here) * 20090123 [chemit] - add tests for icon improvment Modified: jaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java =================================================================== --- jaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -74,6 +74,13 @@ protected String compilerFQN; /** + * Le compilateur à utiliser (par défaut celui de Swing) + * + * @parameter expression="${jaxx.validatorFQN}" default-value="jaxx.runtime.validator.swing.SwingValidator" + */ + protected String validatorFQN; + + /** * Repertoire de destination des fichiers java a generer. * * @parameter expression="${jaxx.outJava}" default-value="${basedir}/target/generated-sources/java" @@ -227,7 +234,7 @@ * If not given, will use the one defined in validator * * @parameter expression="${jaxx.defaultErrorUIFQN}" - * @see jaxx.runtime.validator.BeanValidator#DEFAULT_UI_CLASS + * @see jaxx.runtime.validator.swing.SwingValidator#DEFAULT_UI_CLASS */ protected String defaultErrorUIFQN; /** @@ -263,6 +270,9 @@ compilerClass = (Class<? extends JAXXCompiler>) Class.forName(compilerFQN); + // check the validator class is correct + Class.forName(validatorFQN); + if (defaultErrorUIFQN != null && !defaultErrorUIFQN.trim().isEmpty()) { defaultErrorUIClass = Class.forName(defaultErrorUIFQN); } @@ -344,6 +354,7 @@ result.setJavacOpts(javaOpts); } result.setCompilerClass(compilerClass); + result.setValidatorFQN(validatorFQN); result.setKeepJavaFiles(true); result.setOptimize(optimize); result.setJavacTargetDirectory(outClass); Modified: jaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/JaxxBaseTest.java =================================================================== --- jaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/JaxxBaseTest.java 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/JaxxBaseTest.java 2009-02-03 01:38:07 UTC (rev 1194) @@ -33,6 +33,7 @@ mojo = (JaxxGeneratorMojo) lookupMojo("generate", pomFile); mojo.jaxxContextImplementorClass = DefaultJAXXContext.class.getName(); mojo.compilerFQN = jaxx.compiler.SwingCompiler.class.getName(); + mojo.validatorFQN = jaxx.runtime.validator.swing.SwingValidator.class.getName(); assertNotNull(mojo); } Modified: jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/errors/DuplicatedErrorListModel.jaxx =================================================================== --- jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/errors/DuplicatedErrorListModel.jaxx 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/errors/DuplicatedErrorListModel.jaxx 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,4 +1,4 @@ <Application> - <jaxx.runtime.validator.BeanValidatorErrorListModel id='errors'/> + <jaxx.runtime.validator.swing.SwingValidatorErrorListModel id='errors'/> <BeanValidator beanClass='testcases.validator.errors.Model' errorListModel='errors' errorListModel='fake'/> </Application> Modified: jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/errors/DuplicatedErrorTableModel.jaxx =================================================================== --- jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/errors/DuplicatedErrorTableModel.jaxx 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/errors/DuplicatedErrorTableModel.jaxx 2009-02-03 01:38:07 UTC (rev 1194) @@ -1,4 +1,4 @@ <Application> - <jaxx.runtime.validator.BeanValidatorErrorListModel id='errors'/> + <jaxx.runtime.validator.swing.SwingValidatorErrorListModel id='errors'/> <BeanValidator beanClass='testcases.validator.errors.Model' errorTableModel='errors' errorTableModel='fake'/> </Application> Modified: jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/Validation.jaxx =================================================================== --- jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/Validation.jaxx 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/Validation.jaxx 2009-02-03 01:38:07 UTC (rev 1194) @@ -6,24 +6,23 @@ <Identity id='identity'/> <!-- errors model --> - <jaxx.runtime.validator.BeanValidatorErrorListModel id='errors' - onContentsChanged='ok.setEnabled(errors.size()==0)'/> + <jaxx.runtime.validator.swing.SwingValidatorErrorListModel id='errors' + onContentsChanged='ok.setEnabled(errors.size()==0)'/> <!-- validators --> - <BeanValidator id='validator' bean='model' errorListModel='errors' scope='ERROR'> + <BeanValidator id='validator' bean='model' errorListModel='errors'> <field name="text"/> <field name="text2"/> <field name="ratio"/> </BeanValidator> <BeanValidator id='validator2' bean='model2' errorListModel='errors' - uiClass="jaxx.runtime.validator.ui.IconValidationUI" scope="WARNING"> + uiClass="jaxx.runtime.validator.ui.IconValidationUI"> <field name="text" component="_text"/> <field name="text2" component="_text2"/> <field name="ratio" component="_ratio"/> </BeanValidator> <BeanValidator id='validator3' autoField='true' bean='identity' errorListModel='errors' - uiClass="jaxx.runtime.validator.ui.TranslucentValidationUI" - scope='ERROR'> + uiClass="jaxx.runtime.validator.ui.TranslucentValidationUI"> <field name="email" component="email2"/> </BeanValidator> Modified: jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/ValidationBeanClass.jaxx =================================================================== --- jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/ValidationBeanClass.jaxx 2009-02-03 01:27:22 UTC (rev 1193) +++ jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/ValidationBeanClass.jaxx 2009-02-03 01:38:07 UTC (rev 1194) @@ -4,11 +4,10 @@ <Identity id='identity'/> <!-- errors model --> - <jaxx.runtime.validator.BeanValidatorErrorListModel id='errors'/> + <jaxx.runtime.validator.swing.SwingValidatorErrorListModel id='errors'/> <!-- validators --> - <BeanValidator id='validator3' autoField='true' beanClass='testcases.validator.ok.Identity' errorListModel='errors' - scope='ERROR'> + <BeanValidator id='validator3' autoField='true' beanClass='testcases.validator.ok.Identity' errorListModel='errors'> <field name="email" component="email2"/> </BeanValidator> @@ -23,8 +22,8 @@ <JLabel text='FirstName:'/> </cell> <cell weightx='1'> - <JTextField id='firstName' text='{identity.getFirstName()}' - onKeyReleased='identity.setFirstName(firstName.getText())'/> + <JTextField id='firstName' text='{identity.getFirstName()}' + onKeyReleased='identity.setFirstName(firstName.getText())'/> </cell> </row> <row> @@ -32,8 +31,8 @@ <JLabel text='LastName:'/> </cell> <cell weightx='1'> - <JTextField id='lastName' text='{identity.getLastName()}' - onKeyReleased='identity.setLastName(lastName.getText())'/> + <JTextField id='lastName' text='{identity.getLastName()}' + onKeyReleased='identity.setLastName(lastName.getText())'/> </cell> </row> <row> @@ -41,8 +40,8 @@ <JLabel text='Email:'/> </cell> <cell weightx='1'> - <JTextField id='email2' text='{identity.getEmail()}' - onKeyReleased='identity.setEmail(email2.getText())'/> + <JTextField id='email2' text='{identity.getEmail()}' + onKeyReleased='identity.setEmail(email2.getText())'/> </cell> </row> @@ -51,8 +50,8 @@ <JLabel text='Age:'/> </cell> <cell> - <JSlider id='age' minimum='0' maximum='100' value='{identity.getAge()}' - onStateChanged='identity.setAge(age.getValue())'/> + <JSlider id='age' minimum='0' maximum='100' value='{identity.getAge()}' + onStateChanged='identity.setAge(age.getValue())'/> </cell> </row> </Table> @@ -60,8 +59,8 @@ </cell> <cell weightx='1' weighty='1' insets='6, 3, 0, 0'> <JPanel border='{BorderFactory.createTitledBorder("Identity Model")}' - layout='{new GridLayout()}' width='250' height='120'> - <Table anchor='west' fill='both'> + layout='{new GridLayout()}' width='250' height='120'> + <Table anchor='west' fill='both'> <row> <cell> <JLabel text='FirstName:'/> @@ -78,8 +77,8 @@ <JLabel text='{identity.getLastName()}'/> </cell> </row> - <row> - <cell> + <row> + <cell> <JLabel text='Email:'/> </cell> <cell weightx='1'> @@ -101,12 +100,13 @@ </row> <row> <cell columns='2' fill="both"> - <JPanel border='{BorderFactory.createTitledBorder("Errors")}' layout='{new GridLayout()}' height='200' width='500'> + <JPanel border='{BorderFactory.createTitledBorder("Errors")}' layout='{new GridLayout()}' height='200' + width='500'> <JScrollPane> <JList model='{errors}'/> </JScrollPane> </JPanel> </cell> - </row> + </row> </Table> </Application>