[Buix-commits] r1275 - in jaxx/trunk: jaxx-compiler-api jaxx-compiler-api/src/main/java/jaxx/compiler jaxx-compiler-validator jaxx-compiler-validator/src/main/java/jaxx/compiler jaxx-compiler-validator/src/main/java/jaxx/tags/validator jaxx-example jaxx-example/src/main/java/jaxx/demo jaxx-example/src/main/resources/i18n jaxx-runtime-swing jaxx-runtime-validator jaxx-runtime-validator/src/main/java/jaxx/runtime jaxx-runtime-validator/src/main/java/jaxx/runtime/validator jaxx-runtime-validator/src/test/java/
Author: tchemit Date: 2009-03-21 16:13:18 +0000 (Sat, 21 Mar 2009) New Revision: 1275 Added: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/SwingValidatorUtil.java jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessage.java jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListRenderer.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/BeanValidatorUtil.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/BeanValidatorMessage.java Removed: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/SwingValidationUtil.java jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageModel.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator2.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidationUtil.java Modified: jaxx/trunk/jaxx-compiler-api/changelog.txt jaxx/trunk/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompilerLaunchor.java jaxx/trunk/jaxx-compiler-validator/changelog.txt jaxx/trunk/jaxx-compiler-validator/pom.xml 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-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-swing/changelog.txt jaxx/trunk/jaxx-runtime-validator-swing/changelog.txt jaxx/trunk/jaxx-runtime-validator-swing/pom.xml jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListModel.java jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListMouseListener.java jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableModel.java jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableMouseListener.java jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableRenderer.java 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/BeanValidatorEvent.java jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorField.java jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/BeanValidatorTest.java jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractFieldValidatorTest.java jaxx/trunk/maven-jaxx-plugin/changelog.txt jaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java Log: validator refactor end Modified: jaxx/trunk/jaxx-compiler-api/changelog.txt =================================================================== --- jaxx/trunk/jaxx-compiler-api/changelog.txt 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-compiler-api/changelog.txt 2009-03-21 16:13:18 UTC (rev 1275) @@ -1,4 +1,5 @@ -1.3 chemit 20090320 +1.3 chemit 20090321 + * 20090321 [chemit] - add compilerCount in launchro to known how mush files where generated * 20090313 [chemit] - can now use geneticType on javaBean object - add an extra method $afterCompleteSetup method to be included if find in script at last statement of $completeSetup method Modified: jaxx/trunk/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompilerLaunchor.java =================================================================== --- jaxx/trunk/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompilerLaunchor.java 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompilerLaunchor.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -141,6 +141,7 @@ protected LifeCycle currentPass; protected int errorCount; protected int warningCount; + protected int compilerCount; protected JAXXProfile profiler; protected JAXXCompilerLaunchor(File[] files, String[] classNames, CompilerOptions options) { @@ -233,6 +234,7 @@ */ public synchronized boolean compile() { //reset(); // just to be safe... + compilerCount = 0; jaxxFiles.addAll(Arrays.asList(files)); jaxxFileClassNames.addAll(Arrays.asList(classNames)); try { @@ -375,6 +377,7 @@ e.printStackTrace(); return false; } finally { + compilerCount = compilers.size(); //TC - 20081018 only reset when no error was detected if (options.isResetAfterCompile() && errorCount == 0) { reset(); @@ -382,6 +385,10 @@ } } + public int getCompilerCount() { + return compilerCount; + } + protected JAXXCompiler getCompiler(String className, String message) { JAXXCompiler compiler = compilers.get(className); if (compiler == null) { @@ -441,5 +448,4 @@ System.out.println(); System.out.println("See http://www.jaxxframework.org/ for full documentation."); } - } Modified: jaxx/trunk/jaxx-compiler-validator/changelog.txt =================================================================== --- jaxx/trunk/jaxx-compiler-validator/changelog.txt 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-compiler-validator/changelog.txt 2009-03-21 16:13:18 UTC (rev 1275) @@ -1,4 +1,4 @@ -1.3 chemit 20090320 +1.3 chemit 20090321 1.1 chemit 20090220 * 20090202 [chemit] - refactor validators (this module will soon disappear to jaxx-compiler-swing-validator) Modified: jaxx/trunk/jaxx-compiler-validator/pom.xml =================================================================== --- jaxx/trunk/jaxx-compiler-validator/pom.xml 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-compiler-validator/pom.xml 2009-03-21 16:13:18 UTC (rev 1275) @@ -28,6 +28,12 @@ <dependency> <groupId>${project.groupId}</groupId> + <artifactId>jaxx-runtime-swing</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> <artifactId>jaxx-runtime-validator-swing</artifactId> <version>${project.version}</version> </dependency> 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-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/compiler/ValidatorGenerator.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -34,7 +34,7 @@ boolean found = BeanValidatorHandler.isComponentUsedByValidator(compiler, child.getChild().getId()); if (found) { // box the child component in a JxLayer - child.setChildJavaCode("jaxx.runtime.SwingUtil.boxComponentWithJxLayer(" + javaCode + ")"); + child.setChildJavaCode(jaxx.runtime.SwingUtil.class.getName()+".boxComponentWithJxLayer(" + javaCode + ")"); } } } @@ -45,7 +45,8 @@ compiler.appendLateInitializer(JAXXCompiler.getLineSeparator()); compiler.appendLateInitializer("getValidator(" + id + ").installUIs();"); compiler.appendLateInitializer(JAXXCompiler.getLineSeparator()); - compiler.appendLateInitializer("getValidator(" + id + ").validate();"); + compiler.appendLateInitializer("getValidator(" + id + ").reloadBean();"); + //compiler.appendLateInitializer("getValidator(" + id + ").validate();"); compiler.appendLateInitializer(JAXXCompiler.getLineSeparator()); } compiler.appendLateInitializer("validatorIds = java.util.Collections.unmodifiableList(validatorIds);"); 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-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -11,7 +11,7 @@ import jaxx.introspection.JAXXPropertyDescriptor; import jaxx.reflect.ClassDescriptor; import jaxx.reflect.ClassDescriptorLoader; -import jaxx.runtime.validator.SwingValidationUtil; +import jaxx.runtime.SwingValidatorUtil; import jaxx.runtime.validator.swing.SwingValidator; import jaxx.runtime.validator.swing.ui.AbstractBeanValidatorUI; import jaxx.tags.DefaultObjectHandler; @@ -35,33 +35,23 @@ public static final String BEAN_ATTRIBUTE = "bean"; public static final String BEAN_CLASS_ATTRIBUTE = "beanClass"; public static final String BEAN_INITIALIZER_ATTRIBUTE = "beanInitializer"; - public static final String ERROR_LIST_MODEL_ATTRIBUTE = "errorListModel"; public static final String ERROR_TABLE_MODEL_ATTRIBUTE = "errorTableModel"; public static final String ERROR_LIST_ATTRIBUTE = "errorList"; public static final String ERROR_TABLE_ATTRIBUTE = "errorTable"; - public static final String ERROR_LIST_MODEL_DEFAULT = "errors"; public static final String ERROR_TABLE_MODEL_DEFAULT = "errors2"; - public static final String ERROR_LIST_DEFAULT = "errorList"; public static final String ERROR_TABLE_DEFAULT = "errorTable"; - public static final String AUTOFIELD_ATTRIBUTE = "autoField"; public static final String UI_CLASS_ATTRIBUTE = "uiClass"; public static final String STRICT_MODE_ATTRIBUTE = "strictMode"; - public static final String CONTEXT_NAME_ATTRIBUTE = "contextName"; - //public static final String SCOPE_ATTRIBUTE = "scope"; - public static final String PARENT_VALIDATOR_ATTRIBUTE = "parentValidator"; - /** to use log facility, just put in your code: log.info(\"...\"); */ static Log log = LogFactory.getLog(BeanValidatorHandler.class); - protected static Map<JAXXCompiler, List<CompiledBeanValidator>> validators = new HashMap<JAXXCompiler, List<CompiledBeanValidator>>(); - protected static Map<JAXXCompiler, List<String>> validatedComponents = new HashMap<JAXXCompiler, List<String>>(); public BeanValidatorHandler(ClassDescriptor beanClass) { @@ -116,11 +106,11 @@ } /*if (!error) { - error = info.addContextName(this, compiler); + error = info.addContextName(this, compiler); }*/ /*if (!error) { - error = info.addScope(this, compiler); + error = info.addScope(this, compiler); }*/ if (!error) { @@ -317,13 +307,13 @@ //TC-20090111 beanClass is mandatory // get the real bean class name (from bean or beanClass) /*if (beanClass != null) { - beanClassName = beanClass; + beanClassName = beanClass; } else { - beanClassName = compiler.getSymbolTable().getClassTagIds().get(bean); - if (beanClassName == null) { - compiler.reportError("could not find class of the bean '" + bean + "'"); - return null; - } + beanClassName = compiler.getSymbolTable().getClassTagIds().get(bean); + if (beanClassName == null) { + compiler.reportError("could not find class of the bean '" + bean + "'"); + return null; + } }*/ ClassDescriptor beanClassDescriptor = ClassDescriptorLoader.getClassDescriptor(beanClass); beanDescriptor = DefaultObjectHandler.getJAXXBeanInfo(beanClassDescriptor); @@ -419,21 +409,20 @@ } /*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; + 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) { - if (scope != null) { - String code = handler.getSetPropertyCode(getJavaCode(), SCOPE_ATTRIBUTE, TypeManager.getJavaCode(scope), compiler); - appendAdditionCode(code); - } - return false; + 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) { String initializer; @@ -470,7 +459,7 @@ } } - String code = SwingValidationUtil.class.getName() + ".registerErrorListMouseListener(" + errorList + ");"; + String code = SwingValidatorUtil.class.getName() + ".registerErrorListMouseListener(" + errorList + ");"; appendAdditionCode(code); return false; @@ -490,7 +479,7 @@ } } - String code = SwingValidationUtil.class.getName() + ".registerErrorTableMouseListener(" + errorTable + ");"; + String code = SwingValidatorUtil.class.getName() + ".registerErrorTableMouseListener(" + errorTable + ");"; appendAdditionCode(code); return false; @@ -541,7 +530,7 @@ } /*if (beanInitializer != null) { - compiler.reportWarning("tag '" + tag + "' found a 'bean' and a 'beanInitializer' attributes, 'beanInitializer' is skipped"); + compiler.reportWarning("tag '" + tag + "' found a 'bean' and a 'beanInitializer' attributes, 'beanInitializer' is skipped"); }*/ beanInitializer = bean; } @@ -603,9 +592,9 @@ continue; } /*if (compiler.isComponentUsedByValidator(component)) { - // component is already used by another validator - compiler.reportError("component '" + component + "' is already used by another validator."); - continue; + // component is already used by another validator + compiler.reportError("component '" + component + "' is already used by another validator."); + continue; }*/ String keyCode = TypeManager.getJavaCode(propertyName); appendAdditionCode(getJavaCode() + ".setFieldRepresentation(" + keyCode + ", " + component + ");"); Modified: jaxx/trunk/jaxx-example/changelog.txt =================================================================== --- jaxx/trunk/jaxx-example/changelog.txt 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-example/changelog.txt 2009-03-21 16:13:18 UTC (rev 1275) @@ -1,4 +1,4 @@ -1.3 chemit 20090320 +1.3 chemit 20090321 * 20090319 [chemit] - refactor Validator : now can deal with scopes, improve design * 20090313 [chemit] - improve demo Modified: jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx =================================================================== --- jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx 2009-03-21 16:13:18 UTC (rev 1275) @@ -1,15 +1,10 @@ <DemoPanel> <style source="Validation.css"/> -<script> -void $afterCompleteSetup() { - validator.setBean(null); - validator2.setBean(null); - validator3.setBean(null); - validator.setBean(model1); - validator2.setBean(model2); - validator3.setBean(identity); -} +<script><![CDATA[ +import static org.codelutin.i18n.I18n.n_; +void $afterCompleteSetup() { +}]]> </script> <!-- models --> <Model id='model1'/> @@ -48,6 +43,7 @@ </cell> <cell weightx='1'> <JTextField id='text' text='{model1.getText()}' + _validatorLabel='{n_("form.text")}' onKeyReleased='model1.setText(text.getText())'/> </cell> </row> @@ -57,6 +53,7 @@ </cell> <cell weightx='1'> <JTextField id='text2' text='{model1.getText2()}' + _validatorLabel='{n_("form.text2")}' onKeyReleased='model1.setText2(text2.getText())'/> </cell> </row> @@ -66,7 +63,9 @@ <JLabel text='Ratio:'/> </cell> <cell> - <JSlider id='ratio' minimum='0' maximum='100' value='{model1.getRatio()}' + <JSlider id='ratio' minimum='0' maximum='100' + value='{model1.getRatio()}' + _validatorLabel='{n_("form.ratio")}' onStateChanged='model1.setRatio(ratio.getValue())'/> </cell> </row> @@ -117,6 +116,7 @@ </cell> <cell weightx='1'> <JTextField id='_text' text='{model2.getText()}' + _validatorLabel='{n_("form2.text")}' onKeyReleased='model2.setText(_text.getText())'/> </cell> </row> @@ -126,6 +126,7 @@ </cell> <cell weightx='1'> <JTextField id='_text2' text='{model2.getText2()}' + _validatorLabel='{n_("form2.text2")}' onKeyReleased='model2.setText2(_text2.getText())'/> </cell> </row> @@ -135,7 +136,9 @@ <JLabel text='Ratio:'/> </cell> <cell> - <JSlider id='_ratio' minimum='0' maximum='100' value='{model2.getRatio()}' + <JSlider id='_ratio' minimum='0' maximum='100' + value='{model2.getRatio()}' + _validatorLabel='{n_("form2.ratio")}' onStateChanged='model2.setRatio(_ratio.getValue())'/> </cell> </row> @@ -296,10 +299,11 @@ </row> <row> <cell columns='2' fill="both"> - <JPanel border='{BorderFactory.createTitledBorder("Errors")}' layout='{new GridLayout()}' height='200' + <JPanel border='{BorderFactory.createTitledBorder("Messages")}' layout='{new GridLayout()}' height='200' width='500'> <JScrollPane> - <JList id='errorList' model='{errors}'/> + <JList id='errorList' model='{errors}' + cellRenderer='{new jaxx.runtime.validator.swing.SwingValidatorMessageListRenderer()}'/> </JScrollPane> </JPanel> </cell> Modified: jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx =================================================================== --- jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx 2009-03-21 16:13:18 UTC (rev 1275) @@ -32,15 +32,9 @@ void $afterCompleteSetup() { errorTable.setDefaultRenderer(Object.class, new jaxx.runtime.validator.swing.SwingValidatorMessageTableRenderer()); + errorTable.getRowSorter().setSortKeys(java.util.Arrays.asList(new RowSorter.SortKey(0, SortOrder.ASCENDING))); SwingUtil.setI18nTableHeaderRenderer(errorTable, n_("validator.scope"), n_("validator.scope.tip"), n_("validator.field"), n_("validator.field.tip"), n_("validator.message"), n_("validator.message.tip")); SwingUtil.fixTableColumnWidth(errorTable, 0, 25); - - validator.setBean(null); - validator2.setBean(null); - validator3.setBean(null); - validator.setBean(model1); - validator2.setBean(model2); - validator3.setBean(identity); } ]]></script> @@ -56,7 +50,9 @@ </cell> <cell weightx='1'> <JTextField id='text' text='{model1.getText()}' - onKeyReleased='model1.setText(text.getText())'/> + onKeyReleased='model1.setText(text.getText())' + _validatorLabel='{n_("form.text")}' + /> </cell> </row> <row> @@ -65,7 +61,9 @@ </cell> <cell weightx='1'> <JTextField id='text2' text='{model1.getText2()}' - onKeyReleased='model1.setText2(text2.getText())'/> + onKeyReleased='model1.setText2(text2.getText())' + _validatorLabel='{n_("form.text2")}' + /> </cell> </row> @@ -74,7 +72,9 @@ <JLabel text='Ratio:'/> </cell> <cell> - <JSlider id='ratio' minimum='0' maximum='100' value='{model1.getRatio()}' + <JSlider id='ratio' minimum='0' maximum='100' + value='{model1.getRatio()}' + _validatorLabel='{n_("form.ratio")}' onStateChanged='model1.setRatio(ratio.getValue())'/> </cell> </row> @@ -125,6 +125,7 @@ </cell> <cell weightx='1'> <JTextField id='_text' text='{model2.getText()}' + _validatorLabel='{n_("form2.text")}' onKeyReleased='model2.setText(_text.getText())'/> </cell> </row> @@ -134,6 +135,7 @@ </cell> <cell weightx='1'> <JTextField id='_text2' text='{model2.getText2()}' + _validatorLabel='{n_("form2.text2")}' onKeyReleased='model2.setText2(_text2.getText())'/> </cell> </row> @@ -143,7 +145,9 @@ <JLabel text='Ratio:'/> </cell> <cell> - <JSlider id='_ratio' minimum='0' maximum='100' value='{model2.getRatio()}' + <JSlider id='_ratio' minimum='0' maximum='100' + value='{model2.getRatio()}' + _validatorLabel='{n_("form2.ratio")}' onStateChanged='model2.setRatio(_ratio.getValue())'/> </cell> </row> @@ -304,10 +308,10 @@ </row> <row> <cell columns='2' fill="both"> - <JPanel border='{BorderFactory.createTitledBorder("Errors")}' layout='{new GridLayout()}' height='200' + <JPanel border='{BorderFactory.createTitledBorder("Messages")}' layout='{new GridLayout()}' height='200' width='500'> <JScrollPane columnHeaderView='{errorTable.getTableHeader()}'> - <JTable id='errorTable' model='{errors2}' rowSelectionAllowed='true' + <JTable id='errorTable' model='{errors2}' rowSelectionAllowed='true' autoCreateRowSorter='true' autoResizeMode='2' cellSelectionEnabled='false' selectionMode='0'/> </JScrollPane> </JPanel> 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-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-en_GB.properties 2009-03-21 16:13:18 UTC (rev 1275) @@ -99,6 +99,12 @@ edit2= edit3= emptyNode=< empty node > +form.ratio=Form \: ratio +form.text=Form \: text +form.text2=Form \: text2 +form2.ratio=Form2 \: ratio +form2.text=Form2 \: text +form2.text2=Form2 \: text2 no\ layer= valid= validator.field=Champ 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-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-fr_FR.properties 2009-03-21 16:13:18 UTC (rev 1275) @@ -99,6 +99,12 @@ edit2= edit3= emptyNode=< empty node > +form.ratio=Form \: ratio +form.text=Form \: text +form.text2=Form \: text2 +form2.ratio=Form2 \: ratio +form2.text=Form2 \: text +form2.text2=Form2 \: text2 no\ layer= valid= validator.field=Champ Modified: jaxx/trunk/jaxx-runtime-swing/changelog.txt =================================================================== --- jaxx/trunk/jaxx-runtime-swing/changelog.txt 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-swing/changelog.txt 2009-03-21 16:13:18 UTC (rev 1275) @@ -1,4 +1,4 @@ -1.3 chemit 20090320 +1.3 chemit 20090321 * 20090318 [chemit] - introduce the BlockingLayerUI2 class (should be merge with BlockingLayerUI) * 20090318 [chemit] - introduce the CardLayout2Ext class * 20090312 [chemit] - add some usefull code from ObServe (load Nimbus L&F, load ui configuration) Modified: jaxx/trunk/jaxx-runtime-validator/changelog.txt =================================================================== --- jaxx/trunk/jaxx-runtime-validator/changelog.txt 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator/changelog.txt 2009-03-21 16:13:18 UTC (rev 1275) @@ -1,5 +1,6 @@ -1.3 chemit 20090320 - * 20090319 [chemit] - refactor Validator : now can deal with scopes, improve design +1.3 chemit 20090321 + * 20090320 [chemit] - rename and move ValidationUtil to jaxx.runtime.BeanValidatorUtil + * 20090319 [chemit] - refactor Validator : now can deal with scopes, improve design 1.1 chemit 20090220 * 20090203 [chemit] - move swing specific code to jaxx-runtime-validator-swing module Added: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/BeanValidatorUtil.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/BeanValidatorUtil.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/BeanValidatorUtil.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -0,0 +1,152 @@ +package jaxx.runtime; + +import jaxx.runtime.validator.*; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.beans.BeanInfo; +import java.beans.EventSetDescriptor; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +/** + * The helper class for validation module. + * + * @author chemit + */ +public class BeanValidatorUtil { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(BeanValidatorUtil.class); + + protected BeanValidatorUtil() { + // no instance + } + + /** + * Convinient method to attach a bean to all validators of an JAXXObject. + * <p/> + * It is possible to exclude some validator to be treated. + * + * @param ui the ui containing the validatros to treate + * @param bean the bean to attach in validators (can be null) + * @param excludeIds the list of validator id to exclude + */ + @SuppressWarnings({"unchecked"}) + public static void setValidatorBean(JAXXObject ui, Object bean, String... excludeIds) { + if (!JAXXValidator.class.isAssignableFrom(ui.getClass())) { + return; + } + JAXXValidator jaxxValidator = (JAXXValidator) ui; + List<String> validatorIds = jaxxValidator.getValidatorIds(); + if (excludeIds.length > 0) { + validatorIds = new ArrayList<String>(validatorIds); + for (String excludeId : excludeIds) { + validatorIds.remove(excludeId); + } + } + for (String validatorId : validatorIds) { + BeanValidator beanValidator = jaxxValidator.getValidator(validatorId); + if (bean == null || beanValidator.getBeanClass().isAssignableFrom(bean.getClass())) { + // touch validator, only if fits the bean type (or bean is null) + beanValidator.setBean(bean); + } + } + } + + /** + * Convinient method to set the changed property to all validators of an JAXXObject. + * <p/> + * It is possible to exclude some validator to be treated. + * + * @param ui the ui containing the validatros to treate + * @param newValue the new value to set in changed validator property + * @param excludeIds the list of validator id to exclude + */ + @SuppressWarnings({"unchecked"}) + public static void setValidatorChanged(JAXXObject ui, boolean newValue, String... excludeIds) { + if (!JAXXValidator.class.isAssignableFrom(ui.getClass())) { + return; + } + JAXXValidator jaxxValidator = (JAXXValidator) ui; + List<String> validatorIds = jaxxValidator.getValidatorIds(); + if (excludeIds.length > 0) { + validatorIds = new ArrayList<String>(validatorIds); + for (String excludeId : excludeIds) { + validatorIds.remove(excludeId); + } + } + for (String validatorId : validatorIds) { + BeanValidator beanValidator = jaxxValidator.getValidator(validatorId); + beanValidator.setChanged(newValue); + } + } + + /** + * Convert a value to a given type and then if was succesffull try to set it in the bean manage by the validator. + * + * @param validator validator to be involved + * @param fieldName the name of the bean property + * @param value the actual value to convert + * @param valueClass the type of the conversion + */ + public static void convert(BeanValidator<?> validator, String fieldName, String value, Class<?> valueClass) { + + Object result = validator.convert(fieldName, value, valueClass); + if (result != null) { + try { + BeanInfo info = Introspector.getBeanInfo(validator.getBean().getClass()); + + for (PropertyDescriptor descriptor : info.getPropertyDescriptors()) { + if (fieldName.equals(descriptor.getName()) && descriptor.getWriteMethod() != null) { + + descriptor.getWriteMethod().invoke(validator.getBean(), result); + break; + } + } + } catch (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,... + } + } + + public static EventSetDescriptor getPropertyChangeListenerDescriptor(Class beanClass) { + try { + // check that the bean is listenable, otherwise, can't use + // the validator on it + BeanInfo infos = Introspector.getBeanInfo(beanClass); + EventSetDescriptor[] events = infos.getEventSetDescriptors(); + for (EventSetDescriptor event : events) { + if ("propertyChange".equals(event.getName())) { + + if (event.getAddListenerMethod() == null) { + // no property event listener, so can not use the validator + throw new IllegalStateException("no addPropertyChangeListener method found for " + beanClass); + } + if (event.getRemoveListenerMethod() == null) { + // no property event listener, so can not use the validator + throw new IllegalStateException("no removePropertyChangeListener method found for " + beanClass); + } + return event; + } + } + + // no property event listener, so can not use the validator + throw new IllegalStateException("no PropertyChangeListener access method found for " + beanClass); + } catch (IntrospectionException ex) { + throw new IllegalStateException("could not acquire PropertyChangeListener bean info for " + beanClass + " for reason " + ex.getMessage(), ex); + } + } + +} 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-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/JAXXValidator.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -2,7 +2,7 @@ import java.util.List; -import jaxx.runtime.validator.BeanValidator2; +import jaxx.runtime.validator.BeanValidator; /** * The contract of a validator-able object. @@ -17,7 +17,7 @@ * @param validatorId validator id * @return the associated validator, or <code>null</code> if not find */ - BeanValidator2<?> getValidator(String validatorId); + BeanValidator<?> getValidator(String validatorId); /** @return the list of ids of all registred validator */ List<String> getValidatorIds(); Copied: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java (from rev 1273, jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator2.java) =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -0,0 +1,459 @@ +package jaxx.runtime.validator; + +import jaxx.runtime.BeanValidatorUtil; +import java.beans.EventSetDescriptor; +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.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; +import javax.swing.event.EventListenerList; + +/** + * + * A customized validator for a given bean. + * + * <b>Note:</b> The bean must be listenable on properyChange events (means + * must have public addPropertychangeListener and removePropertyChangeListener methods). + * + * @param <B> type of the bean to validate. + * + * @author chemit + */ +public class BeanValidator<B> { + + /** la nom de la propriété bean */ + static public final String BEAN_PROERTY = "bean"; + /** la nom de la propriété contextName */ + static public final String CONTEXT_NAME_PROPERTY = "contextName"; + /** la nom de l'état valid */ + static public final String VALID_PROERTY = "valid"; + /** la nom de l'état changed */ + static public final String CHANGED_PROERTY = "changed"; + /** to use log facility, just put in your code: log.info(\"...\"); */ + static protected final Log log = LogFactory.getLog(BeanValidator.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 BeanValidator<?> 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 = true; + /** bean to be watched */ + protected B bean = null; + /** to add and remove PropertyChangeListener on watched beans */ + protected EventSetDescriptor beanEventDescriptor; + /** list of fields watched by this validator */ + protected Set<BeanValidatorField<B>> fields; + /** map of conversion errors detected by this validator */ + protected Map<String, String> conversionErrors; + /** xworks scope validator **/ + protected EnumMap<BeanValidatorScope, XWorkBeanValidator<B>> validators; + /** listener that listens on bean modification */ + protected PropertyChangeListener l; + /** delegate property change support */ + protected PropertyChangeSupport pcs; + /** A list of event listeners for this validators */ + protected EventListenerList listenerList = new EventListenerList(); + + public BeanValidator(Class<B> beanClass, String contextName) { + this.beanClass = beanClass; + this.pcs = new PropertyChangeSupport(this); + this.conversionErrors = new TreeMap<String, String>(); + this.validators = new EnumMap<BeanValidatorScope, XWorkBeanValidator<B>>(BeanValidatorScope.class); + + setContextName(contextName); + + l = new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + validate(); + setValid(!hasErrors()); + setChanged(true); + } + }; + } + + public Class<B> getBeanClass() { + return beanClass; + } + + public BeanValidator<?> getParentValidator() { + return parentValidator; + } + + public String getContextName() { + return contextName; + } + + public Set<BeanValidatorField<B>> getFields() { + return fields; + } + + /** + * Retourne vrai si l'objet bean a ete modifie depuis le dernier + * {@link #setBean} + * + * @return <code>true</code> if bean was modify since last {@link #setBean(Object)} invocation + */ + public boolean isChanged() { + return changed; + } + + public boolean isValid() { + return valid; + } + + public B getBean() { + return bean; + } + + public BeanValidatorField<B> getField(String fieldName) { + for (BeanValidatorField<B> field : fields) { + if (fieldName.equals(field.getName())) { + return field; + } + } + return null; + } + + public boolean hasErrors() { + for (BeanValidatorField<B> field : fields) { + if (field.hasErrors()) { + return true; + } + } + return false; + } + + public boolean hasWarnings() { + for (BeanValidatorField<B> field : fields) { + if (field.hasWarnings()) { + return true; + } + } + return false; + } + + public boolean hasInfos() { + for (BeanValidatorField<B> field : fields) { + if (field.hasInfos()) { + return true; + } + } + return false; + } + + /** + * Test a the validator contains the field given his name + * + * @param fieldName the name of the searched field + * @return <code>true</code> if validator contaisn this field, <code>false</code> otherwise + */ + public boolean containsField(String fieldName) { + BeanValidatorField<B> field = getField(fieldName); + return field != null; + } + + public boolean isValid(String fieldName) { + BeanValidatorField<B> field = getField(fieldName); + if (field == null) { + throw new IllegalArgumentException("could not find a validator field " + fieldName); + } + return field.isValid(); + } + + /** + * Permet de force la remise a false de l'etat de changement du bean + * + * @param changed flag to force reset of property {@link #changed} + */ + public void setChanged(boolean changed) { + this.changed = changed; + // force the property to be fired (never pass the older value) + pcs.firePropertyChange(CHANGED_PROERTY, null, changed); + } + + public void setValid(boolean valid) { + this.valid = valid; + // force the property to be fired (never pass the older value) + pcs.firePropertyChange(VALID_PROERTY, null, valid); + } + + public void setBean(B bean) { + B oldBean = this.bean; + if (log.isDebugEnabled()) { + log.debug(this + " : " + bean); + } + + // clean conversions of previous bean + conversionErrors.clear(); + + if (oldBean != null) { + try { + getBeanEventDescriptor(oldBean).getRemoveListenerMethod().invoke(oldBean, l); + } catch (Exception eee) { + log.info("Can't register as listener for bean " + beanClass + " for reason " + eee.getMessage(), eee); + } + } + this.bean = bean; + + if (bean == null) { + + // remove all messages for all fields of the validator + + for (BeanValidatorField<B> f : fields) { + + f.updateMessages(this, null, null); + } + + } else { + try { + getBeanEventDescriptor(bean).getAddListenerMethod().invoke(bean, l); + } catch (Exception eee) { + log.info("Can't register as listener for bean " + beanClass + " for reason " + eee.getMessage(), eee); + } + validate(); + } + setChanged(false); + setValid(!hasErrors()); + pcs.firePropertyChange(BEAN_PROERTY, oldBean, bean); + } + + 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 + if (bean != null) { + setBean(null); + } + // rebuild the fields + initFields(); + pcs.firePropertyChange(CONTEXT_NAME_PROPERTY, oldValidationContextName, contextName); + } + + public void setParentValidator(BeanValidator<?> parentValidator) { + this.parentValidator = parentValidator; + } + + /** + * Convert a value. + * <p/> + * If an error occurs, then add an error in validator. + * + * @param <T> the type of conversion + * @param fieldName the name of the bean property + * @param value the value to convert + * @param valueClass the type of converted value + * @return the converted value, or null if conversion was not ok + */ + @SuppressWarnings({"unchecked"}) + public <T> T convert(String fieldName, String value, Class<T> valueClass) { + if (fieldName == null) { + throw new IllegalArgumentException("fieldName can not be null"); + } + if (valueClass == null) { + throw new IllegalArgumentException("valueClass can not be null"); + } + + // on ne convertit pas si il y a un bean et que le resultat de la validation + // pourra etre affiche quelque part + if (!canValidate() || value == null) { + return null; + } + + // remove the previous conversion error for the field + conversionErrors.remove(fieldName); + + T result; + try { + Converter converter = ConverterUtil.getConverter(valueClass); + if (converter == null) { + throw new RuntimeException("could not find converter for the type " + valueClass); + } + result = (T) converter.convert(valueClass, value); + /* Why this test ? if (result != null && !value.equals(result.toString())) { + conversionErrors.put(fieldName, "error.convertor." + Introspector.decapitalize(valueClass.getSimpleName())); + result = null; + validate(); + }*/ + } catch (ConversionException e) { + // get + 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; + } + + for (BeanValidatorScope scope : validators.keySet()) { + + XWorkBeanValidator<B> validator = validators.get(scope); + + Map<String, List<String>> newMessages = validator.validate(bean); + + if (scope == BeanValidatorScope.ERROR) { + // treate conversion errors + // reinject them + for (Entry<String, String> entry : conversionErrors.entrySet()) { + // remove from validation, errors occurs on this field + List<String> errors = newMessages.get(entry.getKey()); + String conversionError = entry.getValue(); + if (errors != null) { + errors.clear(); + errors.add(conversionError); + } else { + errors = java.util.Collections.singletonList(conversionError); + // add the concrete conversion error + newMessages.put(entry.getKey(), errors); + } + } + } + + // for each field, update his list of messages + for (BeanValidatorField<B> field : fields) { + List<String> messagesForField = newMessages.get(field.getName()); + if (field.getScopes().contains(scope)) { + field.updateMessages(this, scope, messagesForField); + } + } + } + + if (parentValidator != null) { + // chained validation + parentValidator.l.propertyChange(null); + } + + } + + @Override + public String toString() { + return super.toString() + "<beanClass:" + beanClass + ", contextName:" + contextName + ">"; + } + + public void addBeanValidatorListener(BeanValidatorListener listener) { + listenerList.add(BeanValidatorListener.class, listener); + } + + public void removeBeanValidatorListener(BeanValidatorListener listener) { + listenerList.remove(BeanValidatorListener.class, listener); + } + + public BeanValidatorListener[] getBeanValidatorListeners() { + return listenerList.getListeners(BeanValidatorListener.class); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + pcs.addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { + pcs.addPropertyChangeListener(propertyName, listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + pcs.removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { + pcs.removePropertyChangeListener(propertyName, listener); + } + + /** @return <code>true</code> if validation is enabled, <code>false</code> otherwise. */ + protected boolean canValidate() { + return !(bean == null || fields.isEmpty()); + } + + protected void fireFieldChanged(BeanValidatorField<B> field, BeanValidatorScope scope, String[] toAdd, String[] toDelete) { + + BeanValidatorEvent evt = new BeanValidatorEvent(this, field, scope, toAdd, toDelete); + + for (BeanValidatorListener listener : listenerList.getListeners(BeanValidatorListener.class)) { + listener.onFieldChanged(evt); + } + } + + protected synchronized void initFields() { + + Set<String> detectedFieldNames = new java.util.HashSet<String>(); + EnumMap<BeanValidatorScope, Set<String>> tmp = new EnumMap<BeanValidatorScope, Set<String>>(BeanValidatorScope.class); + Set<BeanValidatorField<B>> detectedFields = new java.util.HashSet<BeanValidatorField<B>>(); + + validators.clear(); + + for (BeanValidatorScope scope : BeanValidatorScope.values()) { + String scopeContext = (contextName == null ? "" : contextName + "-") + scope.name().toLowerCase(); + + XWorkBeanValidator<B> newValidator = new XWorkBeanValidator<B>(beanClass, scopeContext, false); + Set<String> fieldNames = newValidator.getFieldNames(); + if (log.isDebugEnabled()) { + log.debug("detected validators for scope " + scopeContext + " : " + fieldNames); + } + if (!fieldNames.isEmpty()) { + // fields detected in this validator, keep it + validators.put(scope, newValidator); + detectedFieldNames.addAll(fieldNames); + tmp.put(scope, fieldNames); + } + } + + List<BeanValidatorScope> scopes = new ArrayList<BeanValidatorScope>(); + for (String fieldName : detectedFieldNames) { + scopes.clear(); + // detect scopes for the field + for (BeanValidatorScope scope : BeanValidatorScope.values()) { + if (tmp.containsKey(scope) && tmp.get(scope).contains(fieldName)) { + scopes.add(scope); + } + } + BeanValidatorField<B> f = new BeanValidatorField<B>(beanClass, fieldName, scopes); + detectedFields.add(f); + } + tmp.clear(); + detectedFieldNames.clear(); + + this.fields = java.util.Collections.unmodifiableSet(detectedFields); + } + + protected EventSetDescriptor getBeanEventDescriptor(B bean) { + if (beanEventDescriptor == null) { + // check that the bean is listenable, otherwise, can't use the validator on it + this.beanEventDescriptor = BeanValidatorUtil.getPropertyChangeListenerDescriptor(bean.getClass()); + } + return beanEventDescriptor; + } +} Property changes on: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java ___________________________________________________________________ Name: svn:mergeinfo + Deleted: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator2.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator2.java 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator2.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -1,458 +0,0 @@ -package jaxx.runtime.validator; - -import java.beans.EventSetDescriptor; -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.util.ArrayList; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeMap; -import javax.swing.event.EventListenerList; - -/** - * - * A customized validator for a given bean. - * - * <b>Note:</b> The bean must be listenable on properyChange events (means - * must have public addPropertychangeListener and removePropertyChangeListener methods). - * - * @param <B> type of the bean to validate. - * - * @author chemit - */ -public class BeanValidator2<B> { - - /** la nom de la propriété bean */ - static public final String BEAN_PROERTY = "bean"; - /** la nom de la propriété contextName */ - static public final String CONTEXT_NAME_PROPERTY = "contextName"; - /** la nom de l'état valid */ - static public final String VALID_PROERTY = "valid"; - /** la nom de l'état changed */ - static public final String CHANGED_PROERTY = "changed"; - /** to use log facility, just put in your code: log.info(\"...\"); */ - static protected final Log log = LogFactory.getLog(BeanValidator2.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 BeanValidator2<?> 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 = true; - /** bean to be watched */ - protected B bean = null; - /** to add and remove PropertyChangeListener on watched beans */ - protected EventSetDescriptor beanEventDescriptor; - /** list of fields watched by this validator */ - protected Set<BeanValidatorField<B>> fields; - /** map of conversion errors detected by this validator */ - protected Map<String, String> conversionErrors; - /** xworks scope validator **/ - protected EnumMap<BeanValidatorScope, XWorkBeanValidator<B>> validators; - /** listener that listens on bean modification */ - protected PropertyChangeListener l; - /** delegate property change support */ - protected PropertyChangeSupport pcs; - /** A list of event listeners for this validators */ - protected EventListenerList listenerList = new EventListenerList(); - - public BeanValidator2(Class<B> beanClass, String contextName) { - this.beanClass = beanClass; - this.pcs = new PropertyChangeSupport(this); - this.conversionErrors = new TreeMap<String, String>(); - this.validators = new EnumMap<BeanValidatorScope, XWorkBeanValidator<B>>(BeanValidatorScope.class); - - setContextName(contextName); - - l = new PropertyChangeListener() { - - @Override - public void propertyChange(PropertyChangeEvent evt) { - validate(); - setValid(!hasErrors()); - setChanged(true); - } - }; - } - - public Class<B> getBeanClass() { - return beanClass; - } - - public BeanValidator2<?> getParentValidator() { - return parentValidator; - } - - public String getContextName() { - return contextName; - } - - public Set<BeanValidatorField<B>> getFields() { - return fields; - } - - /** - * Retourne vrai si l'objet bean a ete modifie depuis le dernier - * {@link #setBean} - * - * @return <code>true</code> if bean was modify since last {@link #setBean(Object)} invocation - */ - public boolean isChanged() { - return changed; - } - - public boolean isValid() { - return valid; - } - - public B getBean() { - return bean; - } - - public BeanValidatorField<B> getField(String fieldName) { - for (BeanValidatorField<B> field : fields) { - if (fieldName.equals(field.getName())) { - return field; - } - } - return null; - } - - public boolean hasErrors() { - for (BeanValidatorField<B> field : fields) { - if (field.hasErrors()) { - return true; - } - } - return false; - } - - public boolean hasWarnings() { - for (BeanValidatorField<B> field : fields) { - if (field.hasWarnings()) { - return true; - } - } - return false; - } - - public boolean hasInfos() { - for (BeanValidatorField<B> field : fields) { - if (field.hasInfos()) { - return true; - } - } - return false; - } - - /** - * Test a the validator contains the field given his name - * - * @param fieldName the name of the searched field - * @return <code>true</code> if validator contaisn this field, <code>false</code> otherwise - */ - public boolean containsField(String fieldName) { - BeanValidatorField<B> field = getField(fieldName); - return field != null; - } - - public boolean isValid(String fieldName) { - BeanValidatorField<B> field = getField(fieldName); - if (field == null) { - throw new IllegalArgumentException("could not find a validator field " + fieldName); - } - return field.isValid(); - } - - /** - * Permet de force la remise a false de l'etat de changement du bean - * - * @param changed flag to force reset of property {@link #changed} - */ - public void setChanged(boolean changed) { - this.changed = changed; - // force the property to be fired (never pass the older value) - pcs.firePropertyChange(CHANGED_PROERTY, null, changed); - } - - public void setValid(boolean valid) { - this.valid = valid; - // force the property to be fired (never pass the older value) - pcs.firePropertyChange(VALID_PROERTY, null, valid); - } - - public void setBean(B bean) { - B oldBean = this.bean; - if (log.isDebugEnabled()) { - log.debug(this + " : " + bean); - } - - // clean conversions of previous bean - conversionErrors.clear(); - - if (oldBean != null) { - try { - getBeanEventDescriptor(oldBean).getRemoveListenerMethod().invoke(oldBean, l); - } catch (Exception eee) { - log.info("Can't register as listener for bean " + beanClass + " for reason " + eee.getMessage(), eee); - } - } - this.bean = bean; - - if (bean == null) { - - // remove all messages for all fields of the validator - - for (BeanValidatorField<B> f : fields) { - - f.updateMessages(this, null, null); - } - - } else { - try { - getBeanEventDescriptor(bean).getAddListenerMethod().invoke(bean, l); - } catch (Exception eee) { - log.info("Can't register as listener for bean " + beanClass + " for reason " + eee.getMessage(), eee); - } - validate(); - } - setChanged(false); - setValid(!hasErrors()); - pcs.firePropertyChange(BEAN_PROERTY, oldBean, bean); - } - - 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 - if (bean != null) { - setBean(null); - } - // rebuild the fields - initFields(); - pcs.firePropertyChange(CONTEXT_NAME_PROPERTY, oldValidationContextName, contextName); - } - - public void setParentValidator(BeanValidator2<?> parentValidator) { - this.parentValidator = parentValidator; - } - - /** - * Convert a value. - * <p/> - * If an error occurs, then add an error in validator. - * - * @param <T> the type of conversion - * @param fieldName the name of the bean property - * @param value the value to convert - * @param valueClass the type of converted value - * @return the converted value, or null if conversion was not ok - */ - @SuppressWarnings({"unchecked"}) - public <T> T convert(String fieldName, String value, Class<T> valueClass) { - if (fieldName == null) { - throw new IllegalArgumentException("fieldName can not be null"); - } - if (valueClass == null) { - throw new IllegalArgumentException("valueClass can not be null"); - } - - // on ne convertit pas si il y a un bean et que le resultat de la validation - // pourra etre affiche quelque part - if (!canValidate() || value == null) { - return null; - } - - // remove the previous conversion error for the field - conversionErrors.remove(fieldName); - - T result; - try { - Converter converter = ConverterUtil.getConverter(valueClass); - if (converter == null) { - throw new RuntimeException("could not find converter for the type " + valueClass); - } - result = (T) converter.convert(valueClass, value); - /* Why this test ? if (result != null && !value.equals(result.toString())) { - conversionErrors.put(fieldName, "error.convertor." + Introspector.decapitalize(valueClass.getSimpleName())); - result = null; - validate(); - }*/ - } catch (ConversionException e) { - // get - 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; - } - - for (BeanValidatorScope scope : validators.keySet()) { - - XWorkBeanValidator<B> validator = validators.get(scope); - - Map<String, List<String>> newMessages = validator.validate(bean); - - if (scope == BeanValidatorScope.ERROR) { - // treate conversion errors - // reinject them - for (Entry<String, String> entry : conversionErrors.entrySet()) { - // remove from validation, errors occurs on this field - List<String> errors = newMessages.get(entry.getKey()); - String conversionError = entry.getValue(); - if (errors != null) { - errors.clear(); - errors.add(conversionError); - } else { - errors = java.util.Collections.singletonList(conversionError); - // add the concrete conversion error - newMessages.put(entry.getKey(), errors); - } - } - } - - // for each field, update his list of messages - for (BeanValidatorField<B> field : fields) { - List<String> messagesForField = newMessages.get(field.getName()); - if (field.getScopes().contains(scope)) { - field.updateMessages(this, scope, messagesForField); - } - } - } - - if (parentValidator != null) { - // chained validation - parentValidator.l.propertyChange(null); - } - - } - - @Override - public String toString() { - return super.toString() + "<beanClass:" + beanClass + ", contextName:" + contextName + ">"; - } - - public void addBeanValidatorListener(BeanValidatorListener listener) { - listenerList.add(BeanValidatorListener.class, listener); - } - - public void removeBeanValidatorListener(BeanValidatorListener listener) { - listenerList.remove(BeanValidatorListener.class, listener); - } - - public BeanValidatorListener[] getBeanValidatorListeners() { - return listenerList.getListeners(BeanValidatorListener.class); - } - - public void addPropertyChangeListener(PropertyChangeListener listener) { - pcs.addPropertyChangeListener(listener); - } - - public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - pcs.addPropertyChangeListener(propertyName, listener); - } - - public void removePropertyChangeListener(PropertyChangeListener listener) { - pcs.removePropertyChangeListener(listener); - } - - public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - pcs.removePropertyChangeListener(propertyName, listener); - } - - /** @return <code>true</code> if validation is enabled, <code>false</code> otherwise. */ - protected boolean canValidate() { - return !(bean == null || fields.isEmpty()); - } - - protected void fireFieldChanged(BeanValidatorField<B> field, BeanValidatorScope scope, String[] toAdd, String[] toDelete) { - - BeanValidatorEvent evt = new BeanValidatorEvent(this, field, scope, toAdd, toDelete); - - for (BeanValidatorListener listener : listenerList.getListeners(BeanValidatorListener.class)) { - listener.onFieldChanged(evt); - } - } - - protected synchronized void initFields() { - - Set<String> detectedFieldNames = new java.util.HashSet<String>(); - EnumMap<BeanValidatorScope, Set<String>> tmp = new EnumMap<BeanValidatorScope, Set<String>>(BeanValidatorScope.class); - Set<BeanValidatorField<B>> detectedFields = new java.util.HashSet<BeanValidatorField<B>>(); - - validators.clear(); - - for (BeanValidatorScope scope : BeanValidatorScope.values()) { - String scopeContext = (contextName == null ? "" : contextName + "-") + scope.name().toLowerCase(); - - XWorkBeanValidator<B> newValidator = new XWorkBeanValidator<B>(beanClass, scopeContext, false); - Set<String> fieldNames = newValidator.getFieldNames(); - if (log.isDebugEnabled()) { - log.debug("detected validators for scope " + scopeContext + " : " + fieldNames); - } - if (!fieldNames.isEmpty()) { - // fields detected in this validator, keep it - validators.put(scope, newValidator); - detectedFieldNames.addAll(fieldNames); - tmp.put(scope, fieldNames); - } - } - - List<BeanValidatorScope> scopes = new ArrayList<BeanValidatorScope>(); - for (String fieldName : detectedFieldNames) { - scopes.clear(); - // detect scopes for the field - for (BeanValidatorScope scope : BeanValidatorScope.values()) { - if (tmp.containsKey(scope) && tmp.get(scope).contains(fieldName)) { - scopes.add(scope); - } - } - BeanValidatorField<B> f = new BeanValidatorField<B>(beanClass, fieldName, scopes); - detectedFields.add(f); - } - tmp.clear(); - detectedFieldNames.clear(); - - this.fields = java.util.Collections.unmodifiableSet(detectedFields); - } - - protected EventSetDescriptor getBeanEventDescriptor(B bean) { - if (beanEventDescriptor == null) { - // check that the bean is listenable, otherwise, can't use the validator on it - this.beanEventDescriptor = ValidationUtil.getPropertyChangeListenerDescriptor(bean.getClass()); - } - return beanEventDescriptor; - } -} Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorEvent.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorEvent.java 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorEvent.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -17,7 +17,7 @@ String[] messagestoAdd; String[] messagestoDelete; - public BeanValidatorEvent(BeanValidator2 source, BeanValidatorField<?> field, BeanValidatorScope scope, String[] toAdd, String[] toDelete) { + public BeanValidatorEvent(BeanValidator source, BeanValidatorField<?> field, BeanValidatorScope scope, String[] toAdd, String[] toDelete) { super(source); this.field = field; this.scope = scope; @@ -26,8 +26,8 @@ } @Override - public BeanValidator2 getSource() { - return (BeanValidator2) super.getSource(); + public BeanValidator getSource() { + return (BeanValidator) super.getSource(); } public String getFieldName() { Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorField.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorField.java 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorField.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -107,7 +107,7 @@ return messages.get(scope); } - public void updateMessages(BeanValidator2<B> validator, BeanValidatorScope scope, List<String> messages) { + public void updateMessages(BeanValidator<B> validator, BeanValidatorScope scope, List<String> messages) { if (scope == null) { @@ -220,7 +220,7 @@ return sb.toString(); } - protected void clearMessages(BeanValidatorScope scope, BeanValidator2<B> validator) { + protected void clearMessages(BeanValidatorScope scope, BeanValidator<B> validator) { // remove all messages Set<String> toDelete = getMessages(scope); Added: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorMessage.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorMessage.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorMessage.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -0,0 +1,72 @@ +package jaxx.runtime.validator; + +/** + * The object to box a validation message. + * + * @param <E> type of message (use for override {@link #compareTo(E)} method. + * + * @author chemit + * @since 1.3 + */ +public class BeanValidatorMessage<E extends BeanValidatorMessage> implements Comparable<E> { + + /** + * the validator that produce the message + */ + protected BeanValidator validator; + /** + * the field thatproduce the message + */ + protected BeanValidatorField field; + /** + * the label of the message (to be displayed somewhere) + */ + protected String message; + /** + * the scope of the message + */ + protected BeanValidatorScope scope; + + public BeanValidatorMessage(BeanValidator validator, BeanValidatorField field, String message, BeanValidatorScope scope) { + this.field = field; + this.validator = validator; + this.message = message; + this.scope = scope; + } + + public BeanValidator getValidator() { + return validator; + } + + public BeanValidatorField getField() { + return field; + } + + public BeanValidatorScope getScope() { + return scope; + } + + public String getMessage() { + return message; + } + + @Override + public int compareTo(E o) { + // sort on scope + int result = getScope().compareTo(o.getScope()); + if (result == 0) { + // sort on field name + result = field.getName().compareTo(o.field.getName()); + if (result == 0) { + // sort on message + result = message.compareTo(o.message); + } + } + return result; + } + + @Override + public String toString() { + return scope + " - " + field.getI18nError(message); + } +} Deleted: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidationUtil.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidationUtil.java 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidationUtil.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -1,153 +0,0 @@ -package jaxx.runtime.validator; - -import jaxx.runtime.JAXXObject; -import jaxx.runtime.JAXXValidator; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.beans.BeanInfo; -import java.beans.EventSetDescriptor; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.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 - } - - /** - * 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) { - BeanValidator2 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) { - BeanValidator2 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(BeanValidator2<?> 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,... - } - } - - static EventSetDescriptor getPropertyChangeListenerDescriptor(Class beanClass) { - try { - // check that the bean is listenable, otherwise, can't use - // the validator on it - BeanInfo infos = Introspector.getBeanInfo(beanClass); - EventSetDescriptor[] events = infos.getEventSetDescriptors(); - for (EventSetDescriptor event : events) { - if ("propertyChange".equals(event.getName())) { - - if (event.getAddListenerMethod() == null) { - // no property event listener, so can not use the validator - throw new IllegalStateException("no addPropertyChangeListener method found for " + beanClass); - } - if (event.getRemoveListenerMethod() == null) { - // no property event listener, so can not use the validator - throw new IllegalStateException("no removePropertyChangeListener method found for " + beanClass); - } - return event; - } - } - - // no property event listener, so can not use the validator - throw new IllegalStateException("no PropertyChangeListener access method found for " + beanClass); - } catch (IntrospectionException ex) { - throw new IllegalStateException("could not acquire PropertyChangeListener bean info for " + beanClass + " for reason " + ex.getMessage(), ex); - } - } - -} Modified: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/BeanValidatorTest.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/BeanValidatorTest.java 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/BeanValidatorTest.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -15,8 +15,8 @@ public class BeanValidatorTest { /** to use log facility, just put in your code: log.info(\"...\"); */ - static protected final Log log = LogFactory.getLog(BeanValidator2.class); - protected BeanValidator2<SimpleBean> validator; + static protected final Log log = LogFactory.getLog(BeanValidator.class); + protected BeanValidator<SimpleBean> validator; protected SimpleBean bean; BeanValidatorListenerImpl errorListener; BeanValidatorListenerImpl warningListener; @@ -25,7 +25,7 @@ @Before public void setUp() { bean = new SimpleBean(); - validator = new BeanValidator2<SimpleBean>(SimpleBean.class, null); + validator = new BeanValidator<SimpleBean>(SimpleBean.class, null); validator.addBeanValidatorListener(errorListener = new BeanValidatorListenerImpl(BeanValidatorScope.ERROR)); validator.addBeanValidatorListener(warningListener = new BeanValidatorListenerImpl(BeanValidatorScope.WARNING)); validator.addBeanValidatorListener(infoListener = new BeanValidatorListenerImpl(BeanValidatorScope.INFO)); Modified: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractFieldValidatorTest.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractFieldValidatorTest.java 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractFieldValidatorTest.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -1,7 +1,7 @@ package jaxx.runtime.validator.field; import java.io.File; -import jaxx.runtime.validator.BeanValidator2; +import jaxx.runtime.validator.BeanValidator; import jaxx.runtime.validator.BeanValidatorField; import jaxx.runtime.validator.ValidatorBean; import org.apache.commons.logging.Log; @@ -23,7 +23,7 @@ /** to use log facility, just put in your code: log.info(\"...\"); */ static private final Log log = LogFactory.getLog(AbstractFieldValidatorTest.class); - static protected BeanValidator2<ValidatorBean> validator; + static protected BeanValidator<ValidatorBean> validator; static protected File basedir; protected ValidatorBean bean; @@ -53,7 +53,7 @@ b = new File("").getAbsolutePath(); } basedir = new File(b); - validator = new BeanValidator2<ValidatorBean>(ValidatorBean.class, null); + validator = new BeanValidator<ValidatorBean>(ValidatorBean.class, null); } protected void assertFieldInError(String fieldName, String error, boolean required) { Modified: jaxx/trunk/jaxx-runtime-validator-swing/changelog.txt =================================================================== --- jaxx/trunk/jaxx-runtime-validator-swing/changelog.txt 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator-swing/changelog.txt 2009-03-21 16:13:18 UTC (rev 1275) @@ -1,4 +1,5 @@ -1.3 chemit 20090320 +1.3 chemit 20090321 + * 20090320 [chemit] - rename and move SwingValidationUtil to jaxx.runtime.SwingValidatorUtil * 20090319 [chemit] - refactor Validator : now can deal with scopes, improve design 1.1 chemit 20090220 Modified: jaxx/trunk/jaxx-runtime-validator-swing/pom.xml =================================================================== --- jaxx/trunk/jaxx-runtime-validator-swing/pom.xml 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator-swing/pom.xml 2009-03-21 16:13:18 UTC (rev 1275) @@ -25,6 +25,11 @@ <artifactId>jaxx-runtime-validator</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>jaxx-runtime-swing</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> Added: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/SwingValidatorUtil.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/SwingValidatorUtil.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/SwingValidatorUtil.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -0,0 +1,175 @@ +package jaxx.runtime; + +import jaxx.runtime.validator.*; +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 javax.swing.ImageIcon; +import javax.swing.JComponent; +import jaxx.runtime.validator.swing.SwingValidatorMessageTableMouseListener; +import jaxx.runtime.validator.swing.SwingValidatorMessageListMouseListener; +import jaxx.runtime.validator.swing.SwingValidatorMessage; +import org.codelutin.i18n.I18n; + +/** + * The helper class for validation module. + * + * @author chemit + */ +public class SwingValidatorUtil extends BeanValidatorUtil { + + static ImageIcon errorIcon; + static ImageIcon warningIcon; + static ImageIcon infoIcon; + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(SwingValidatorUtil.class); + + public static ImageIcon getErrorIcon() { + if (errorIcon == null) { + errorIcon = jaxx.runtime.Util.createImageIcon("error.png"); + } + return errorIcon; + } + + public static ImageIcon getInfoIcon() { + if (infoIcon == null) { + infoIcon = jaxx.runtime.Util.createImageIcon("info.png"); + } + return infoIcon; + } + + public static ImageIcon getWarningIcon() { + if (warningIcon == null) { + warningIcon = jaxx.runtime.Util.createImageIcon("warning.png"); + } + return warningIcon; + } + + protected SwingValidatorUtil() { + // no instance + } + + /** + * Register for a given validator list ui a validator mouse listener. + * + * Note: there is only one listener registred for a given list model, so + * invoking this method tiwce or more will have no effect. + * + * @param list the validation ui list + * @return the listener instanciate or found + * @see SwingValidatorMessageListMouseListener + */ + public static SwingValidatorMessageListMouseListener registerErrorListMouseListener(JList list) { + SwingValidatorMessageListMouseListener listener = getErrorListMouseListener(list); + + if (listener != null) { + return listener; + } + listener = new SwingValidatorMessageListMouseListener(); + if (log.isDebugEnabled()) { + log.debug(listener.toString()); + } + list.addMouseListener(listener); + return listener; + } + + /** + * Register for a given validator table ui a validator mouse listener + * + * Note: there is onlt one listener registred for a givne table model, so + * invokin this method twice or more will have no effect. + * + * @param table the validator table ui + * @return the listener instanciate or found + * @see SwingValidatorMessageTableMouseListener + */ + public static SwingValidatorMessageTableMouseListener registerErrorTableMouseListener(JTable table) { + SwingValidatorMessageTableMouseListener listener = getErrorTableMouseListener(table); + + if (listener != null) { + return listener; + } + listener = new SwingValidatorMessageTableMouseListener(); + if (log.isDebugEnabled()) { + log.debug(listener.toString()); + } + table.addMouseListener(listener); + return listener; + } + + /** + * @param list the validator list ui + * @return the validator list mouse listener, or <code>null</code> if not found + * @see SwingValidatorMessageListMouseListener + */ + public static SwingValidatorMessageListMouseListener getErrorListMouseListener(JList list) { + if (list != null) { + for (MouseListener listener : list.getMouseListeners()) { + if (listener instanceof SwingValidatorMessageTableMouseListener) { + return (SwingValidatorMessageListMouseListener) listener; + } + } + } + return null; + } + + /** + * @param table the validator table ui + * @return the validator table mouse listener, or <code>null</code> if not found + * @see SwingValidatorMessageTableMouseListener + */ + public static SwingValidatorMessageTableMouseListener getErrorTableMouseListener(JTable table) { + if (table != null) { + for (MouseListener listener : table.getMouseListeners()) { + if (listener instanceof SwingValidatorMessageTableMouseListener) { + return (SwingValidatorMessageTableMouseListener) listener; + } + } + } + return null; + } + + public static String getMessage(SwingValidatorMessage model) { + String text = model.getMessage(); + if (model.getField()!=null) { + text = model.getField().getI18nError(text); + } + return text; + } + + public static String getFieldName(SwingValidatorMessage model, String value) { + String text = null; + JComponent editor = model.getEditor(); + if (editor != null) { + String l = (String) editor.getClientProperty("validatorLabel"); + if (l != null) { + text = I18n._(l); + } else { + // TODO should try the text + } + } + if (text == null) { + text = value; + } + return text; + } + + public static ImageIcon getIcon(BeanValidatorScope scope) { + ImageIcon icon = null; + switch (scope) { + case ERROR: + icon = getErrorIcon(); + break; + case WARNING: + icon = getWarningIcon(); + break; + case INFO: + icon = getInfoIcon(); + break; + } + return icon; + } +} \ No newline at end of file Deleted: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/SwingValidationUtil.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/SwingValidationUtil.java 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/SwingValidationUtil.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -1,65 +0,0 @@ -package jaxx.runtime.validator; - - -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 jaxx.runtime.validator.swing.SwingValidatorMessageTableMouseListener; -import jaxx.runtime.validator.swing.SwingValidatorMessageListMouseListener; - -/** - * The helper class for validation module. - * - * @author chemit - */ -public class SwingValidationUtil extends ValidationUtil { - - /** to use log facility, just put in your code: log.info(\"...\"); */ - static private final Log log = LogFactory.getLog(SwingValidationUtil.class); - - protected SwingValidationUtil() { - // no instance - } - - public static void registerErrorListMouseListener(JList list) { - if (list == null) { - return; - } - for (MouseListener listener : list.getMouseListeners()) { - if (listener instanceof SwingValidatorMessageListMouseListener) { - // already have a such listener - log.info("already registered a such MouseListener : " + listener); - return; - } - } - list.addMouseListener(new SwingValidatorMessageListMouseListener()); - } - - public static void registerErrorTableMouseListener(JTable table) { - if (table == null) { - return; - } - for (MouseListener listener : table.getMouseListeners()) { - if (listener instanceof SwingValidatorMessageTableMouseListener) { - // already have a such listener - log.info("already registered a such MouseListener : " + listener); - return; - } - } - table.addMouseListener(new SwingValidatorMessageTableMouseListener()); - } - - public SwingValidatorMessageTableMouseListener getErrorTableMouseListener(JTable table) { - if (table != null) { - for (MouseListener listener : table.getMouseListeners()) { - if (listener instanceof SwingValidatorMessageTableMouseListener) { - return (SwingValidatorMessageTableMouseListener) listener; - } - } - } - return null; - } -} \ No newline at end of file Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -1,6 +1,5 @@ package jaxx.runtime.validator.swing; - import jaxx.runtime.validator.swing.ui.AbstractBeanValidatorUI; import jaxx.runtime.validator.swing.ui.IconValidationUI; import org.apache.commons.logging.Log; @@ -15,10 +14,9 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; -import jaxx.runtime.validator.BeanValidator2; +import jaxx.runtime.validator.BeanValidator; import jaxx.runtime.validator.BeanValidatorField; - /** * La surcharge de {@link jaxx.runtime.validator.BeanValidator} pour les ui swing * <p/> @@ -96,31 +94,40 @@ * @author chemit * @version 1.0 */ -public class SwingValidator<B> extends BeanValidator2<B> { +public class SwingValidator<B> extends BeanValidator<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 SwingValidatorMessageListModel errorListModel; - /** Object servant a contenir la liste des erreurs */ protected SwingValidatorMessageTableModel errorTableModel; - /** ui renderer class */ protected Class<? extends AbstractBeanValidatorUI> uiClass; - public SwingValidator(Class<B> beanClass, String contextName) { super(beanClass, contextName); fieldRepresentation = new HashMap<String, JComponent>(); } + /** + * To reload a bean in the validator. + * + * This method is used to reload ui, since some editors + * could not exist when validator is init, so some messages + * should not be attached to an editor. + */ + public void reloadBean() { + B b = getBean(); + if (b != null) { + setBean(null); + setBean(b); + } + } + public JComponent getFieldRepresentation(String fieldname) { return fieldRepresentation.get(fieldname); } @@ -154,27 +161,27 @@ /*Map<ValidatorField<B>, List<ValidatorErrorListener>> oldListeners = new HashMap<ValidatorField<B>, List<ValidatorErrorListener>>(); for (ValidatorField<B> field : fields) { - ValidatorErrorListener[] listeners = field.getValidatorErrorListeners(); - List<ValidatorErrorListener> toReinject = new ArrayList<ValidatorErrorListener>(); - for (ValidatorErrorListener listener : listeners) { - if (listener instanceof AbstractBeanValidatorUI) { - // this listener will be reinject via installUIs method - continue; - } - toReinject.add(listener); - } - oldListeners.put(field, toReinject); + ValidatorErrorListener[] listeners = field.getValidatorErrorListeners(); + List<ValidatorErrorListener> toReinject = new ArrayList<ValidatorErrorListener>(); + for (ValidatorErrorListener listener : listeners) { + if (listener instanceof AbstractBeanValidatorUI) { + // this listener will be reinject via installUIs method + continue; + } + toReinject.add(listener); + } + oldListeners.put(field, toReinject); }*/ super.setContextName(contextName); // must reinstall ui installUIs(); // reinject none ui listeners /*for (Entry<ValidatorField<B>, List<ValidatorErrorListener>> entry : oldListeners.entrySet()) { - ValidatorField<B> field = getField(entry.getKey().getName()); - for (ValidatorErrorListener listener : entry.getValue()) { - field.addValidatorErrorListener(listener); - } + ValidatorField<B> field = getField(entry.getKey().getName()); + for (ValidatorErrorListener listener : entry.getValue()) { + field.addValidatorErrorListener(listener); } + } oldListeners.clear();*/ } @@ -213,6 +220,7 @@ /** install ui on required components */ public void installUIs() { SwingUtilities.invokeLater(new Runnable() { + @Override public void run() { if (uiClass == null) { @@ -249,9 +257,9 @@ JXLayer<?> jx = (JXLayer<?>) container; Object ui = jx.getUI(); if (ui != null && ui instanceof AbstractBeanValidatorUI) { - removeBeanValidatorListener((AbstractBeanValidatorUI)ui); + removeBeanValidatorListener((AbstractBeanValidatorUI) ui); } - + jx.setUI(null); } } @@ -268,6 +276,4 @@ } } } - - } Copied: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessage.java (from rev 1274, jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageModel.java) =================================================================== --- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessage.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessage.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -0,0 +1,66 @@ +package jaxx.runtime.validator.swing; + +import javax.swing.JComponent; +import jaxx.runtime.validator.BeanValidatorField; +import jaxx.runtime.validator.BeanValidatorMessage; +import jaxx.runtime.validator.BeanValidatorScope; + +/** + * The object to box a validation message within an u. + * + * @author chemit + * @since 1.3 + * @see BeanValidatorMessage + */ +public class SwingValidatorMessage extends BeanValidatorMessage<SwingValidatorMessage> { + + /** + * the optional field's editor + */ + protected JComponent editor; + protected String fieldName; + + public SwingValidatorMessage(SwingValidator validator, BeanValidatorField field, String message, BeanValidatorScope scope, JComponent editor) { + super(validator, field, message, scope); + this.fieldName = field.getName(); + this.editor = editor; + } + + public SwingValidatorMessage(SwingValidator validator, String fieldName, String message, BeanValidatorScope scope, JComponent editor) { + super(validator, null, message, scope); + this.fieldName = fieldName; + this.editor = editor; + } + + public JComponent getEditor() { + return editor; + } + + public String getFieldName() { + return fieldName; + } + + @Override + public int compareTo(SwingValidatorMessage o) { + // sort on scope + int result = getScope().compareTo(o.getScope()); + if (result == 0) { + // sort on field name + result = fieldName.compareTo(o.getFieldName()); + if (result == 0) { + // sort on message + result = message.compareTo(o.getMessage()); + } + } + return result; + } + + @Override + public String toString() { + String s = scope + " - " + (field == null ? message : field.getI18nError(message)); + if (editor == null) { + return s; + } + return editor.getName() + " : " + s; + } +} Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListModel.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListModel.java 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListModel.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -2,13 +2,10 @@ import jaxx.runtime.validator.BeanValidatorEvent; -import javax.swing.DefaultListModel; import javax.swing.JComponent; import java.util.ArrayList; -import java.util.Enumeration; import java.util.List; import jaxx.runtime.validator.BeanValidatorField; -import jaxx.runtime.validator.BeanValidatorListener; import jaxx.runtime.validator.BeanValidatorScope; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -18,18 +15,27 @@ * * @author chemit */ -public class SwingValidatorMessageListModel extends DefaultListModel implements BeanValidatorListener { +public class SwingValidatorMessageListModel + extends javax.swing.AbstractListModel + implements jaxx.runtime.validator.BeanValidatorListener { + private static final long serialVersionUID = 1L; /** to use log facility, just put in your code: log.info(\"...\"); */ private static Log log = LogFactory.getLog(SwingValidatorMessageListModel.class); - private static final long serialVersionUID = 1L; /** list of registred validators */ protected transient List<SwingValidator<?>> validators; + /** list of messages actual displayed */ + protected List<SwingValidatorMessage> data; public SwingValidatorMessageListModel() { validators = new ArrayList<SwingValidator<?>>(); + data = new java.util.ArrayList<SwingValidatorMessage>(); } + public boolean isEmpty() { + return getSize() == 0; + } + public void registerValidator(SwingValidator<?> validator) { if (validators.contains(validator)) { throw new IllegalArgumentException("the validator " + validator + " is already registred in " + this); @@ -39,97 +45,90 @@ } @Override + public int getSize() { + return data.size(); + } + + @Override + public Object getElementAt(int index) { + ensureRowIndex(index); + return data.get(index); + } + + @Override public void onFieldChanged(BeanValidatorEvent event) { String[] toDelete = event.getMessagesToDelete(); String[] toAdd = event.getMessagesToAdd(); - BeanValidatorScope scope = event.getScope(); - SwingValidator validator = (SwingValidator) event.getSource(); BeanValidatorField field = event.getField(); + BeanValidatorScope scope = event.getScope(); + boolean mustAdd = toAdd != null && toAdd.length > 0; + boolean mustDel = toDelete != null && toDelete.length > 0; if (log.isTraceEnabled()) { log.trace("----------------------------------------------------------"); - log.trace(field + " - (" + getSize() + ") toAdd " + (toAdd == null ? null : toAdd.length)); - log.trace(field + " - (" + getSize() + ") toDelete " + (toDelete == null ? null : toDelete.length)); + log.trace(field + " - (" + getSize() + ") toAdd " + mustAdd); + log.trace(field + " - (" + getSize() + ") toDelete " + mustDel); } - if ((toAdd == null || toAdd.length == 0) && (toDelete == null || toDelete.length == 0)) { - // no data to add nor remove, so nothing to do - return; - } + SwingValidator validator = (SwingValidator) event.getSource(); - if (toAdd == null || toAdd.length == 0) { + if (mustDel) { - if (log.isTraceEnabled()) { - log.trace(field + " - toDelete : just delete some datas!"); - } + // removes datas and notify if no messages to add + removeMessages(validator, field, scope, !mustAdd, toDelete); + } - // no add, no need to resort the datas, can direclty delete - // messages we do not want any longer + if (mustAdd) { - // delete some messages for the given field and given scope - List<String> ids = new java.util.ArrayList<String>(java.util.Arrays.asList(toDelete)); - List<Integer> indexs = new java.util.ArrayList<Integer>(toDelete.length); + // add new messages, sort datas and notify + addMessages(validator, field, scope, true, toAdd); + } + } - Enumeration enumeration = elements(); - int index = 0; - while (enumeration.hasMoreElements()) { - SwingValidatorMessageModel error = (SwingValidatorMessageModel) enumeration.nextElement(); + protected void ensureRowIndex(int index) throws ArrayIndexOutOfBoundsException { + if (index < -1 || index >= getSize()) { + throw new ArrayIndexOutOfBoundsException("the rowIndex was " + index + ", but should be int [0," + (getSize() - 1) + "]"); + } + } - if (error.getValidator() == validator && error.getField() == field && ids.contains(error.getMessage())) { - indexs.add(index); - } - index++; - } + protected void addMessages(SwingValidator validator, BeanValidatorField field, BeanValidatorScope scope, boolean sort, String... messages) { - java.util.Collections.reverse(indexs); - - for (Integer i : indexs) { - removeElementAt(i); + JComponent editor = validator.getFieldRepresentation(field.getName()); + // add new errors + for (String error : messages) { + SwingValidatorMessage row = new SwingValidatorMessage(validator, field, error, scope, editor); + data.add(row); + if (!sort) { + fireIntervalAdded(this, data.size() - 1, data.size() - 1); } - - return; } - if (log.isTraceEnabled()) { - log.trace(field + " - add and delete !"); - } + if (sort) { - List<SwingValidatorMessageModel> newMessages = new ArrayList<SwingValidatorMessageModel>(); + // resort datas + java.util.Collections.sort(data); + // notify + fireContentsChanged(this, 0, getSize() - 1); + } + } + protected void removeMessages(SwingValidator validator, BeanValidatorField field, BeanValidatorScope scope, boolean notify, String... messages) { - // obtain all messages not to delete + List<String> messagesToDel = new java.util.ArrayList<String>(java.util.Arrays.asList(messages)); - List<String> ids = new java.util.ArrayList<String>(java.util.Arrays.asList(toDelete)); + // do it in reverse mode (only one pass in that way since index + // will stay coherent while removing them) - Enumeration enumeration = elements(); - while (enumeration.hasMoreElements()) { - SwingValidatorMessageModel error = (SwingValidatorMessageModel) enumeration.nextElement(); - - if (error.getValidator() != validator || error.getField() != field || !ids.contains(error.getMessage())) { - // keep this row - newMessages.add(error); + for (int i = getSize() - 1; i > -1; i--) { + SwingValidatorMessage error = data.get(i); + if (error.getValidator() == validator && error.getScope() == scope && error.getField() == field && messagesToDel.contains(error.getMessage())) { + // remove the message + data.remove(i); + if (notify) { + fireIntervalRemoved(this, i, i); + } } } - - if (toAdd != null && toAdd.length > 0) { - JComponent editor = validator.getFieldRepresentation(field.getName()); - // add new messages - for (String error : toAdd) { - newMessages.add(new SwingValidatorMessageModel(validator, field, error, editor)); - } - } - - // sort datas - - java.util.Collections.sort(newMessages); - - // clean model and reinject new errors - removeAllElements(); - - // reinject in list model, all the errors - for (SwingValidatorMessageModel error : newMessages) { - addElement(error); - } - } + } } Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListMouseListener.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListMouseListener.java 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListMouseListener.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -25,7 +25,7 @@ super.mouseClicked(e); if (e.getClickCount() == 2) { - SwingValidatorMessageModel entry = getSelectedError(e); + SwingValidatorMessage entry = getSelectedMessage(e); if (entry == null) { // no entry found return; @@ -37,8 +37,7 @@ } } - - protected SwingValidatorMessageModel getSelectedError(MouseEvent e) { + protected SwingValidatorMessage getSelectedMessage(MouseEvent e) { JList list = (JList) e.getSource(); if (!(list.getModel() instanceof SwingValidatorMessageListModel)) { log.warn("model must be a " + SwingValidatorMessageListModel.class + ", but was " + list.getModel()); @@ -51,7 +50,7 @@ // nothing is selected return null; } - SwingValidatorMessageModel entry = (SwingValidatorMessageModel) model.getElementAt(index); + SwingValidatorMessage entry = (SwingValidatorMessage) model.getElementAt(index); if (log.isDebugEnabled()) { log.debug("selected index: " + index + " : error: " + entry); } Added: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListRenderer.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListRenderer.java (rev 0) +++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListRenderer.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -0,0 +1,80 @@ +package jaxx.runtime.validator.swing; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JList; +import java.awt.Component; +import javax.swing.DefaultListCellRenderer; +import jaxx.runtime.validator.BeanValidatorScope; +import jaxx.runtime.SwingValidatorUtil; + +/** + * A simple render of a table of validator's messages, says a table that use + * a {@link SwingValidatorMessageTableModel} model. + * + * @author chemit + * @since 1.3 + * @see SwingValidatorMessageTableModel + */ +public class SwingValidatorMessageListRenderer extends DefaultListCellRenderer { + + private static final long serialVersionUID = 1L; + protected String format = "%1$-20s - %2$s"; + + public SwingValidatorMessageListRenderer() { + } + + public SwingValidatorMessageListRenderer(String format) { + this.format = format; + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + + JLabel rendererComponent = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + + SwingValidatorMessage model = (SwingValidatorMessage) value; + + // scope + ImageIcon icon = SwingValidatorUtil.getIcon(model.getScope()); + + // field name + String fieldName = getFieldName(list, model.getField().getName(), index); + + // message + String message = getMessage(model); + + // text to display + String text = String.format(format, fieldName, message); + + rendererComponent.setText(text); + rendererComponent.setIcon(icon); + + return rendererComponent; + } + + public ImageIcon getIcon(BeanValidatorScope scope) { + ImageIcon icon = SwingValidatorUtil.getIcon(scope); + return icon; + } + + public String getMessage(SwingValidatorMessage model) { + String text = SwingValidatorUtil.getMessage(model); + return text; + } + + public String getFieldName(JList list, String value, int row) { + SwingValidatorMessageListModel tableModel = (SwingValidatorMessageListModel) list.getModel(); + SwingValidatorMessage model = (SwingValidatorMessage) tableModel.getElementAt(row); + String fieldName = SwingValidatorUtil.getFieldName(model, value); + return fieldName; + } +} \ No newline at end of file Deleted: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageModel.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageModel.java 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageModel.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -1,75 +0,0 @@ -package jaxx.runtime.validator.swing; - -import javax.swing.JComponent; -import jaxx.runtime.validator.BeanValidatorField; - -/** - * The object to box a validation message within an u. - * - * @author chemit - * @since 1.3 - */ -public class SwingValidatorMessageModel implements Comparable<SwingValidatorMessageModel> { - - /** - * the validator that produce the message - */ - protected SwingValidator validator; - /** - * the field thatproduce the message - */ - protected BeanValidatorField field; - /** - * the label of the message (to be displayed somewhere) - */ - protected String message; - /** - * the optional field's editor - */ - protected JComponent editor; - - public SwingValidatorMessageModel(SwingValidator validator, BeanValidatorField field, String message, JComponent editor) { - this.field = field; - this.validator = validator; - this.message = message; - this.editor = editor; - } - - public JComponent getEditor() { - return editor; - } - - public SwingValidator getValidator() { - return validator; - } - - public BeanValidatorField getField() { - return field; - } - - public String getMessage() { - return message; - } - - @Override - public int compareTo(SwingValidatorMessageModel 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 = message.compareTo(o.message); - return result; - } - - @Override - public String toString() { - if (editor == null) { - return field.getI18nError(message); - } - return editor.getName() + " : " + field.getI18nError(message); - } -} Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableModel.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableModel.java 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableModel.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -3,156 +3,317 @@ import jaxx.runtime.validator.BeanValidatorEvent; import javax.swing.JComponent; -import javax.swing.table.DefaultTableModel; import java.util.ArrayList; -import java.util.Comparator; -import java.util.Enumeration; import java.util.List; -import java.util.Vector; import jaxx.runtime.validator.BeanValidatorField; -import jaxx.runtime.validator.BeanValidatorListener; +import jaxx.runtime.validator.BeanValidatorScope; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** - * The model of the list of errors + * The model of the table of errors. * + * The model listens validators messages and update his internal model from it. + * * @author chemit + * @since 1.3 */ -public class SwingValidatorMessageTableModel extends DefaultTableModel implements BeanValidatorListener { +public class SwingValidatorMessageTableModel + extends javax.swing.table.AbstractTableModel + implements jaxx.runtime.validator.BeanValidatorListener { + private static final long serialVersionUID = 1L; /** to use log facility, just put in your code: log.info(\"...\"); */ private static Log log = LogFactory.getLog(SwingValidatorMessageTableMouseListener.class); - private static final long serialVersionUID = 1L; public static final String[] columnNames = {"validator.scope", "validator.field", "validator.message"}; + public static final Class<?>[] columnClasses = {BeanValidatorScope.class, String.class, String.class}; /** list of registred validators */ protected transient List<SwingValidator<?>> validators; - /** comporator of errors */ - protected transient Comparator<SwingValidatorMessageModel> comparator; + /** list of messages actual displayed */ + protected List<SwingValidatorMessage> data; public SwingValidatorMessageTableModel() { - super(columnNames, 0); + super(); validators = new ArrayList<SwingValidator<?>>(); + data = new java.util.ArrayList<SwingValidatorMessage>(); } - public int getErrorColumn() { - return findColumn(columnNames[2]); + /** + * Register a validator for this model. + * + * + * Note: a validator can not be register twice in the same model. + * + * @param validator the validator to register + */ + public void registerValidator(SwingValidator<?> validator) { + if (validators.contains(validator)) { + throw new IllegalArgumentException("the validator " + validator + " is already registred in " + this); + } + validators.add(validator); + validator.addBeanValidatorListener(this); } + public void addMessages(SwingValidator validator, String fieldName, BeanValidatorScope scope, String... messages) { + addMessages(validator, fieldName, scope, true, messages); + } + + public void addMessages(JComponent editor, String fieldName, BeanValidatorScope scope, String... messages) { + addMessages(editor, fieldName, scope, true, messages); + } + + public void addMessages(SwingValidator validator, BeanValidatorField field, BeanValidatorScope scope, String... messages) { + addMessages(validator, field, scope, true, messages); + } + + public void removeMessages(JComponent editor, BeanValidatorScope scope) { + + // do it in reverse mode (only one pass in that way since index + // will stay coherent while removing them) + + for (int i = getRowCount() - 1; i > -1; i--) { + SwingValidatorMessage error = data.get(i); + if (error.getEditor() == editor && (scope == null || error.getScope() == scope)) { + // remove the message + data.remove(i); + fireTableRowsDeleted(i, i); + } + } + } + + public void removeMessages(SwingValidator validator, String fieldName, BeanValidatorScope scope, String... messages) { + removeMessages(validator, fieldName, scope, true, messages); + } + + public void removeMessages(JComponent editor, String fieldName, BeanValidatorScope scope) { + removeMessages(editor, fieldName, scope, true); + } + + public void removeMessages(SwingValidator validator, BeanValidatorField field, BeanValidatorScope scope, String... messages) { + removeMessages(validator, field, scope, true, messages); + } + + /** + * Obtain the message for a given row. + * + * @param rowIndex the row index + * @return the message for the given row index + */ + public SwingValidatorMessage getRow(int rowIndex) { + ensureRowIndex(rowIndex); + return data.get(rowIndex); + } + @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); - validator.addBeanValidatorListener(this); + @Override + public Class<?> getColumnClass(int columnIndex) { + ensureColumnIndex(columnIndex); + return columnClasses[columnIndex]; } @Override + public String getColumnName(int column) { + ensureColumnIndex(column); + return columnNames[column]; + } + + @Override public void onFieldChanged(BeanValidatorEvent event) { String[] toDelete = event.getMessagesToDelete(); String[] toAdd = event.getMessagesToAdd(); BeanValidatorField field = event.getField(); + BeanValidatorScope scope = event.getScope(); + boolean mustAdd = toAdd != null && toAdd.length > 0; + boolean mustDel = toDelete != null && toDelete.length > 0; if (log.isTraceEnabled()) { log.trace("----------------------------------------------------------"); - log.trace(field + " - (" + getRowCount() + ") toAdd " + (toAdd == null ? null : toAdd.length)); - log.trace(field + " - (" + getRowCount() + ") toDelete " + (toDelete == null ? null : toDelete.length)); + log.trace(field + " - (" + getRowCount() + ") toAdd " + mustAdd); + log.trace(field + " - (" + getRowCount() + ") toDelete " + mustDel); } - if ((toAdd == null || toAdd.length == 0) && (toDelete == null || toDelete.length == 0)) { - // no data to add nor remove, so nothing to do - return; - } SwingValidator validator = (SwingValidator) event.getSource(); + if (mustDel) { - int errorColumn = getErrorColumn(); + // removes datas and notify if no messages to add + removeMessages(validator, field, scope, !mustAdd, toDelete); + } - if (toAdd == null || toAdd.length == 0) { + if (mustAdd) { + // add new messages, sort datas and notify + addMessages(validator, field, scope, true, toAdd); + } + } - if (log.isTraceEnabled()) { - log.trace(field + " - toDelete : just delete some datas!"); - } + @Override + public int getRowCount() { + return data.size(); + } - // no add, no need to resort the datas, can direclty delete - // messages we do not want any longer + @Override + public int getColumnCount() { + return columnNames.length; + } - // delete some messages for the given field and given scope - List<String> ids = new java.util.ArrayList<String>(java.util.Arrays.asList(toDelete)); - List<Integer> indexs = new java.util.ArrayList<Integer>(toDelete.length); + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + ensureColumnIndex(columnIndex); + ensureRowIndex(rowIndex); - Enumeration enumeration = getDataVector().elements(); + SwingValidatorMessage row = data.get(rowIndex); + if (columnIndex == 0) { + // the icon + return row.getScope(); + } + if (columnIndex == 1) { + // the field + return row.getFieldName(); + } + if (columnIndex == 2) { + // the message + return row.getMessage(); + } - int index = 0; - while (enumeration.hasMoreElements()) { - Vector row = (Vector) enumeration.nextElement(); - SwingValidatorMessageModel error = (SwingValidatorMessageModel) row.get(errorColumn); - if (error.getValidator() == validator && error.getField() == field && ids.contains(error.getMessage())) { - // remo the message - indexs.add(index); - } - index++; - } - java.util.Collections.reverse(indexs); + // should never come here + return null; + } - for (Integer i : indexs) { - removeRow(i); + protected void ensureRowIndex(int rowIndex) throws ArrayIndexOutOfBoundsException { + if (rowIndex < -1 || rowIndex >= getRowCount()) { + throw new ArrayIndexOutOfBoundsException("the rowIndex was " + rowIndex + ", but should be int [0," + (getRowCount() - 1) + "]"); + } + } + + protected void ensureColumnIndex(int index) throws ArrayIndexOutOfBoundsException { + if (index < -1 || index >= getColumnCount()) { + throw new ArrayIndexOutOfBoundsException("the columnIndex was " + index + ", but should be int [0," + (getColumnCount() - 1) + "]"); + } + } + + protected void addMessages(SwingValidator validator, BeanValidatorField field, BeanValidatorScope scope, boolean sort, String... messages) { + + JComponent editor = validator == null ? null : validator.getFieldRepresentation(field.getName()); + // add new errors + for (String error : messages) { + SwingValidatorMessage row = new SwingValidatorMessage(validator, field, error, scope, editor); + data.add(row); + if (!sort) { + fireTableRowsInserted(data.size() - 1, data.size() - 1); } + } - return; + if (sort) { + + // resort datas + java.util.Collections.sort(data); + + // notify + fireTableDataChanged(); } + } - if (log.isTraceEnabled()) { - log.trace(field + " - add and delete !"); + protected void addMessages(SwingValidator validator, String fieldName, BeanValidatorScope scope, boolean sort, String... messages) { + + JComponent editor = validator == null ? null : validator.getFieldRepresentation(fieldName); + // add new errors + for (String error : messages) { + SwingValidatorMessage row = new SwingValidatorMessage(validator, fieldName, error, scope, editor); + data.add(row); + if (!sort) { + fireTableRowsInserted(data.size() - 1, data.size() - 1); + } } - // rebuild all the data (since we are some adding data and we ensure - // an order on datas) + if (sort) { - List<SwingValidatorMessageModel> newMessages = new ArrayList<SwingValidatorMessageModel>(); + // resort datas + java.util.Collections.sort(data); - // delete some messages for the given field and given scope - List<String> ids = new java.util.ArrayList<String>(java.util.Arrays.asList(toDelete)); + // notify + fireTableDataChanged(); + } + } - Enumeration enumeration = getDataVector().elements(); + protected void addMessages(JComponent editor, String fieldName, BeanValidatorScope scope, boolean sort, String... messages) { - while (enumeration.hasMoreElements()) { - Vector row = (Vector) enumeration.nextElement(); - SwingValidatorMessageModel error = (SwingValidatorMessageModel) row.get(errorColumn); - if (error.getValidator() != validator || error.getField() != field || !ids.contains(error.getMessage())) { - // keep this row - newMessages.add(error); + // add new errors + for (String error : messages) { + SwingValidatorMessage row = new SwingValidatorMessage(null, fieldName, error, scope, editor); + data.add(row); + if (!sort) { + fireTableRowsInserted(data.size() - 1, data.size() - 1); } } - if (toAdd != null && toAdd.length > 0) { - JComponent editor = validator.getFieldRepresentation(field.getName()); - // add new errors - for (String error : toAdd) { - SwingValidatorMessageModel errorModel = new SwingValidatorMessageModel(validator, field, error, editor); - newMessages.add(errorModel); + if (sort) { + + // resort datas + java.util.Collections.sort(data); + + // notify + fireTableDataChanged(); + } + } + + protected void removeMessages(SwingValidator validator, BeanValidatorField field, BeanValidatorScope scope, boolean notify, String... messages) { + + List<String> messagesToDel = new java.util.ArrayList<String>(java.util.Arrays.asList(messages)); + + // do it in reverse mode (only one pass in that way since index + // will stay coherent while removing them) + + for (int i = getRowCount() - 1; i > -1; i--) { + SwingValidatorMessage error = data.get(i); + if (error.getValidator() == validator && error.getScope() == scope && error.getFieldName().equals(field.getName()) && messagesToDel.contains(error.getMessage())) { + // remove the message + data.remove(i); + if (notify) { + fireTableRowsDeleted(i, i); + } } } + } - // sort datas + protected void removeMessages(SwingValidator validator, String fieldName, BeanValidatorScope scope, boolean notify, String... messages) { - java.util.Collections.sort(newMessages); + List<String> messagesToDel = new java.util.ArrayList<String>(java.util.Arrays.asList(messages)); - // clean table model and reinject new messages - getDataVector().clear(); + // do it in reverse mode (only one pass in that way since index + // will stay coherent while removing them) - // reinject in list model, all the errors - for (SwingValidatorMessageModel error : newMessages) { - addRow(new Object[]{error.getField().getScope(), error.getField().getName(), error}); + for (int i = getRowCount() - 1; i > -1; i--) { + SwingValidatorMessage error = data.get(i); + if (error.getValidator() == validator && error.getScope() == scope && error.getFieldName().equals(fieldName) && messagesToDel.contains(error.getMessage())) { + // remove the message + data.remove(i); + if (notify) { + fireTableRowsDeleted(i, i); + } + } } + } - fireTableDataChanged(); + protected void removeMessages(JComponent editor, String fieldName, BeanValidatorScope scope, boolean notify) { + + // do it in reverse mode (only one pass in that way since index + // will stay coherent while removing them) + + for (int i = getRowCount() - 1; i > -1; i--) { + SwingValidatorMessage error = data.get(i); + if (error.getEditor() == editor && (scope==null || error.getScope() == scope) && error.getFieldName().equals(fieldName)) { + // remove the message + data.remove(i); + if (notify) { + fireTableRowsDeleted(i, i); + } + } + } } } \ No newline at end of file Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableMouseListener.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableMouseListener.java 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableMouseListener.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -36,7 +36,7 @@ super.mouseClicked(e); if (e.getClickCount() == 2) { - SwingValidatorMessageModel entry = getSelectedError(e); + SwingValidatorMessage entry = getSelectedMessage(e); if (entry == null) { // no entry found return; @@ -52,7 +52,7 @@ } - protected SwingValidatorMessageModel getSelectedError(MouseEvent e) { + protected SwingValidatorMessage getSelectedMessage(MouseEvent e) { JTable table = (JTable) e.getSource(); if (!(table.getModel() instanceof SwingValidatorMessageTableModel)) { log.warn("model must be a " + SwingValidatorMessageTableModel.class + ", but was " + table.getModel()); @@ -65,8 +65,10 @@ // nothing is selected return null; } - int col = model.getErrorColumn(); - SwingValidatorMessageModel entry = (SwingValidatorMessageModel) model.getValueAt(index, col); + if (table.getRowSorter() != null) { + index = table.getRowSorter().convertRowIndexToModel(index); + } + SwingValidatorMessage entry = model.getRow(index); if (log.isDebugEnabled()) { log.debug("selected index: " + index + " : error: " + entry); } Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableRenderer.java =================================================================== --- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableRenderer.java 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableRenderer.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -6,56 +6,70 @@ import javax.swing.table.DefaultTableCellRenderer; import java.awt.Component; import jaxx.runtime.validator.BeanValidatorScope; +import jaxx.runtime.SwingValidatorUtil; -/** @author chemit */ +/** + * A simple render of a table of validator's messages, says a table that use + * a {@link SwingValidatorMessageTableModel} model. + * + * @author chemit + * @since 1.3 + * @see SwingValidatorMessageTableModel + */ public class SwingValidatorMessageTableRenderer extends DefaultTableCellRenderer { private static final long serialVersionUID = 1L; - ImageIcon errorIcon; - ImageIcon warningIcon; - ImageIcon infoIcon; - public SwingValidatorMessageTableRenderer() { - errorIcon = jaxx.runtime.Util.createImageIcon("error.png"); - warningIcon = jaxx.runtime.Util.createImageIcon("warning.png"); - infoIcon = jaxx.runtime.Util.createImageIcon("info.png"); - } - @Override 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 BeanValidatorScope) { - BeanValidatorScope scope = (BeanValidatorScope) value; - switch (scope) { - case ERROR: - icon = errorIcon; - break; - case WARNING: - icon = warningIcon; - break; - case INFO: - icon = infoIcon; - break; - } - } else if (value instanceof SwingValidatorMessageModel) { - SwingValidatorMessageModel model = (SwingValidatorMessageModel) value; - String error = model.getMessage(); - text = model.getField().getI18nError(error); - } else { - // keep text rendered - text = rendererComponent.getText(); + column = table.convertColumnIndexToModel(column); + if (table.getRowSorter() != null) { + row = table.getRowSorter().convertRowIndexToModel(row); } + + switch (column) { + case 0: + // scope + icon = SwingValidatorUtil.getIcon((BeanValidatorScope) value); + break; + + case 1: + // field name + text = getFieldName(table, (String) value, row); + break; + + case 2: + // message + text = getMessage(table, (String) value, row); + break; + } + rendererComponent.setText(text); rendererComponent.setIcon(icon); return rendererComponent; } - @Override - protected void setValue(Object value) { - super.setValue(value); + public ImageIcon getIcon(BeanValidatorScope scope) { + ImageIcon icon = SwingValidatorUtil.getIcon(scope); + return icon; } + + public String getMessage(JTable table, String value, int row) { + SwingValidatorMessageTableModel tableModel = (SwingValidatorMessageTableModel) table.getModel(); + SwingValidatorMessage model = tableModel.getRow(row); + String text = SwingValidatorUtil.getMessage(model); + return text; + } + + public String getFieldName(JTable table, String value, int row) { + SwingValidatorMessageTableModel tableModel = (SwingValidatorMessageTableModel) table.getModel(); + SwingValidatorMessage model = tableModel.getRow(row); + String fieldName = SwingValidatorUtil.getFieldName(model, value); + return fieldName; + } } \ No newline at end of file Modified: jaxx/trunk/maven-jaxx-plugin/changelog.txt =================================================================== --- jaxx/trunk/maven-jaxx-plugin/changelog.txt 2009-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/maven-jaxx-plugin/changelog.txt 2009-03-21 16:13:18 UTC (rev 1275) @@ -1,4 +1,4 @@ -1.3 chemit 20090320 +1.3 chemit 20090321 * 20090301 [chemit] - add a profile mode (-Djaxx.profile) 1.2 letelier 2009022? 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-03-21 08:22:03 UTC (rev 1274) +++ jaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java 2009-03-21 16:13:18 UTC (rev 1275) @@ -281,6 +281,7 @@ protected ClassLoader cl; private Class<? extends JAXXCompiler> compilerClass; + @SuppressWarnings("unchecked") protected void init() throws ClassNotFoundException, MalformedURLException { if (project != null && ("pom".equals(project.getPackaging()) || "site".equals(project.getPackaging()))) { @@ -353,7 +354,7 @@ } } else { if (verbose) { - getLog().info("jaxx - will generate file [" + file + "]."); + getLog().info("jaxx - detect modify file [" + file + "]."); } listFiles.add(file); } @@ -430,7 +431,7 @@ } public void doAction() throws MojoExecutionException { - getLog().info("jaxx - will generate " + this.files.length + " jaxx file(s). "); + getLog().info("jaxx - detects " + this.files.length + " modify jaxx file(s). "); try { @@ -438,8 +439,10 @@ TagManager.reset(verbose); JAXXCompilerLaunchor launchor = JAXXCompilerLaunchor.newLaunchor(src, files, options); + boolean success = launchor.compile(); + getLog().info("jaxx - generate " + launchor.getCompilerCount() + " file(s). "); - if (!launchor.compile()) { + if (!success) { throw new MojoExecutionException("Aborting due to errors reported by jaxxc"); }
participants (1)
-
tchemit@users.labs.libre-entreprise.org