Buix-commits
Threads by month
- ----- 2026 -----
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- 1440 discussions
21 Mar '09
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");
}
1
0
21 Mar '09
Author: tchemit
Date: 2009-03-21 08:22:03 +0000 (Sat, 21 Mar 2009)
New Revision: 1274
Added:
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/SwingValidatorMessageModel.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/src/test/resources/jaxx/runtime/validator/ValidatorBean-error-validation.xml
Removed:
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListModel.java
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListMouseListener.java
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorModel.java
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableModel.java
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableMouseListener.java
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableRenderer.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/ValidatorErrorEvent.java
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorListener.java
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorField.java
jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/ValidatorBean-validation.xml
Modified:
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-runtime-validator-swing/src/main/java/jaxx/runtime/validator/SwingValidationUtil.java
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorListener.java
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidationUtil.java
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractFieldValidatorTest.java
jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/errors/DuplicatedErrorListModel.jaxx
jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/errors/DuplicatedErrorTableModel.jaxx
jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/Validation.jaxx
jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/ValidationBeanClass.jaxx
Log:
remplacement des classes swingValidatorError* en SwingValidatorMessage*
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-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx 2009-03-21 08:22:03 UTC (rev 1274)
@@ -17,7 +17,7 @@
<Identity id='identity'/>
<!-- errors model -->
- <jaxx.runtime.validator.swing.SwingValidatorErrorListModel id='errors'
+ <jaxx.runtime.validator.swing.SwingValidatorMessageListModel id='errors'
onContentsChanged='ok.setEnabled(errors.isEmpty())'/>
<!-- validators -->
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-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx 2009-03-21 08:22:03 UTC (rev 1274)
@@ -7,7 +7,7 @@
<Identity id='identity'/>
<!-- errors model -->
- <jaxx.runtime.validator.swing.SwingValidatorErrorTableModel id='errors2'
+ <jaxx.runtime.validator.swing.SwingValidatorMessageTableModel id='errors2'
onTableChanged='ok.setEnabled(errors2.getRowCount()==0)'/>
<!-- validators -->
@@ -31,7 +31,7 @@
import jaxx.runtime.SwingUtil;
void $afterCompleteSetup() {
- errorTable.setDefaultRenderer(Object.class, new jaxx.runtime.validator.swing.SwingValidatorErrorTableRenderer());
+ errorTable.setDefaultRenderer(Object.class, new jaxx.runtime.validator.swing.SwingValidatorMessageTableRenderer());
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);
Deleted: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java 2009-03-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -1,476 +0,0 @@
-package jaxx.runtime.validator;
-
-import com.opensymphony.xwork2.ActionContext;
-import com.opensymphony.xwork2.ValidationAwareSupport;
-import com.opensymphony.xwork2.config.Configuration;
-import com.opensymphony.xwork2.config.ConfigurationManager;
-import com.opensymphony.xwork2.util.ValueStack;
-import com.opensymphony.xwork2.util.ValueStackFactory;
-import com.opensymphony.xwork2.validator.ActionValidatorManager;
-import com.opensymphony.xwork2.validator.DelegatingValidatorContext;
-import com.opensymphony.xwork2.validator.FieldValidator;
-import com.opensymphony.xwork2.validator.ValidationException;
-import com.opensymphony.xwork2.validator.Validator;
-import com.opensymphony.xwork2.validator.ValidatorScope;
-import 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.Collections;
-import java.util.EnumMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeMap;
-
-/**
- *
- * 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
- */
-@Deprecated
-public class BeanValidator<B> {
-
- /** la nom de la propriété bean */
- static public final String BEAN_PROERTY = "bean";
-
- /** la nom de la propriété contextName */
- static public final String CONTEXT_NAME_PROPERTY = "contextName";
-
- /** la nom de l'état valid */
- static public final String VALID_PROERTY = "valid";
-
- /** la nom de l'état changed */
- static public final String CHANGED_PROERTY = "changed";
-
- /** 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;
-
- /**
- * map of fields by scope
- * TODO use this and remove fields property and xworks patch :)
- */
- protected EnumMap<ValidatorScope, List<ValidatorField<B>>> fieldsByScope;
-
- /** list of fields watched by this validator */
- protected List<ValidatorField<B>> fields;
-
- /** map of conversion errors detected by this validator */
- protected Map<String, String> conversionErrors;
-
- /** delgate property change support */
- protected PropertyChangeSupport pcs;
-
- /** listener that listens on bean modification */
- protected PropertyChangeListener l;
-
- protected ValidationAwareSupport validationSupport;
- protected DelegatingValidatorContext validationContext;
- protected transient ActionValidatorManager validator;
- protected ActionContext context;
-
- protected EventSetDescriptor beanEventDescriptor;
-
- public BeanValidator(Class<B> beanClass, String contextName) {
- // check that the bean is listenable, otherwise, can't use the validator on it
- beanEventDescriptor = ValidationUtil.getPropertyChangeListenerDescriptor(beanClass);
-
- this.beanClass = beanClass;
- this.contextName = contextName;
- pcs = new PropertyChangeSupport(this);
- validationSupport = new ValidationAwareSupport();
- validationContext = new DelegatingValidatorContext(validationSupport);
-
- // init context
- ConfigurationManager confManager = new ConfigurationManager();
- Configuration conf = confManager.getConfiguration();
-
- ValueStackFactory vsf = conf.getContainer().getInstance(
- ValueStackFactory.class);
- ValueStack vs = vsf.createValueStack();
- context = new ActionContext(vs.getContext());
- ActionContext.setContext(context);
-
- // init validator
- validator = conf.getContainer().getInstance(ActionValidatorManager.class, "no-annotations");
- initFields();
-
- conversionErrors = new TreeMap<String, String>();
-
- l = new PropertyChangeListener() {
- @Override
- public void propertyChange(PropertyChangeEvent evt) {
- validate();
- setValid(!hasErrors());
- setChanged(true);
- }
- };
- }
-
- protected void initFields() {
- // init fields from detected fieldValidator in XWorks framework
- fields = new ArrayList<ValidatorField<B>>();
- for (Validator v : validator.getValidators(beanClass, contextName)) {
- // we only work on FieldValidator at the moment
- if (v instanceof FieldValidator) {
- FieldValidator fieldValidator = (FieldValidator) v;
- String fName = fieldValidator.getFieldName();
- ValidatorScope fScope = fieldValidator.getValidatorScope();
- ValidatorField<B> field = new ValidatorField<B>(beanClass, fName, fScope);
- if (!fields.contains(field)) {
- fields.add(field);
- }
- }
- }
-
- fields = Collections.unmodifiableList(fields);
- }
-
- public Class<B> getBeanClass() {
- return beanClass;
- }
-
- public BeanValidator<?> getParentValidator() {
- return parentValidator;
- }
-
- public String getContextName() {
- return contextName;
- }
-
- public List<ValidatorField<B>> getFields() {
- return fields;
- }
-
- public ValidatorField<B> getField(String fieldName) {
- for (ValidatorField<B> field : fields) {
- if (fieldName.equals(field.getName())) {
- return field;
- }
- }
- return null;
- }
-
- /**
- * Retourne vrai si l'objet bean a ete modifie depuis le dernier
- * {@link #setBean}
- *
- * @return <code>true</code> if bean was modify since last {@link #setBean(Object)} invocation
- */
- public boolean isChanged() {
- return changed;
- }
-
- public boolean isValid() {
- return valid;
- }
-
- public B getBean() {
- return bean;
- }
-
- /**
- * Permet de force la remise a false de l'etat de changement du bean
- *
- * @param changed flag to force reset of property {@link #changed}
- */
- public void setChanged(boolean changed) {
- this.changed = changed;
- // force the property to be fired (never pass the older value)
- pcs.firePropertyChange(CHANGED_PROERTY, null, changed);
- }
-
- public void setValid(boolean valid) {
- this.valid = valid;
- // force the property to be fired (never pass the older value)
- pcs.firePropertyChange(VALID_PROERTY, null, valid);
- }
-
- public void setBean(B bean) {
- B oldBean = this.bean;
- if (log.isDebugEnabled()) {
- log.debug(this + " : " + bean);
- }
- // clean conversions of previous bean
- conversionErrors.clear();
-
- if (oldBean != null) {
- try {
- beanEventDescriptor.getRemoveListenerMethod().invoke(oldBean, l);
- //Method method = this.bean.getClass().getMethod("removePropertyChangeListener", PropertyChangeListener.class);
- //method.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) {
- // must remove all errors from this validator on errorListModel
- validationSupport.clearErrorsAndMessages();
-
- // dispatch in each field the new errors
- dispatchErrorsToFields();
- } else {
- try {
- beanEventDescriptor.getAddListenerMethod().invoke(bean, l);
- //Method method = this.bean.getClass().getMethod("addPropertyChangeListener", PropertyChangeListener.class);
- //method.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);
- }
-
- //FIXME At the moment we do not allow to change contextName, but we should be able to do it
- public void setContextName(String contextName) {
- String oldValidationContextName = this.contextName;
- this.contextName = contextName;
- // changing contextName could change fields definition
- // so dettach bean, must rebuild the fields
- setBean(null);
- initFields();
- pcs.firePropertyChange(CONTEXT_NAME_PROPERTY, oldValidationContextName, contextName);
- }
-
- public void setParentValidator(BeanValidator<?> parentValidator) {
- this.parentValidator = parentValidator;
- }
-
- /** @return <code>true</code> if errors are detected, <code>false</code> otherwise */
- public boolean hasErrors() {
- for (ValidatorField<B> field : fields) {
- if (field.hasErrors()) {
- return true;
- }
- }
- return false;
- }
-
- public boolean hasWarnings() {
- for (ValidatorField<B> field : fields) {
- if (field.hasWarnings()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * 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) {
- ValidatorField<B> field = getField(fieldName);
- return field != null;
- }
-
- public boolean isValid(String fieldName) {
- ValidatorField<B> field = getField(fieldName);
- if (field == null) {
- throw new IllegalArgumentException("could not find a validator field " + fieldName);
- }
- return field.isValid();
- }
-
- /**
- * Convert a value.
- * <p/>
- * If an error occurs, then add an error in validator.
- *
- * @param <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;
- }
-
- try {
-
- validationSupport.clearErrorsAndMessages();
-
- //TC - 20081024 : since context is in a ThreadLocal variable, we must do the check
- if (ActionContext.getContext() == null) {
- ActionContext.setContext(context);
- }
-
- validator.validate(bean, contextName, validationContext);
-
- // add the registred conversion errors
- transfertConversionErrorsToFieldErrors();
-
- if (log.isTraceEnabled()) {
- log.trace("Action errors: " + validationContext.getActionErrors());
- log.trace("Action messages: " + validationContext.getActionMessages());
- log.trace("Field errors: " + validationContext.getFieldErrors());
- }
-
- if (log.isDebugEnabled()) {
- log.debug(this + " : " + validationContext.getFieldErrors());
- }
-
- // dispatch in each field the new errors
- dispatchErrorsToFields();
-
- if (parentValidator != null) {
- // chained validation
- parentValidator.l.propertyChange(null);
- }
- } catch (ValidationException eee) {
- log.warn("Error during validation", eee);
- }
- }
-
- @Override
- public String toString() {
- return super.toString() + "<beanClass:" + beanClass + ", contextName:" + contextName + ">";
- }
-
- public void addPropertyChangeListener(PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(listener);
- }
-
- public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(propertyName, listener);
- }
-
- public void removePropertyChangeListener(PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(listener);
- }
-
- public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(propertyName, listener);
- }
-
- /** @return <code>true</code> if validation is enabled, <code>false</code> otherwise. */
- protected boolean canValidate() {
- return !(bean == null || fields.isEmpty());
- }
-
- /**
- * Transfer the registred conversion errors to fieldErrors.
- * <p/>
- * The previously filed errors of a given field where a conversion error occurs will be removed.
- */
- @SuppressWarnings({"unchecked"})
- protected void transfertConversionErrorsToFieldErrors() {
- Map map = validationContext.getFieldErrors();
- for (Entry<String, String> entry : conversionErrors.entrySet()) {
- // remove from validation, errors occurs on this field
- List errors = (List) map.get(entry.getKey());
- if (errors != null) {
- errors.clear();
- errors.add(entry.getValue());
- } else {
- errors = Collections.singletonList(entry.getValue());
- }
- // add the concrete conversion error
- map.put(entry.getKey(), errors);
- }
- validationContext.setFieldErrors(map);
- }
-
- /** synchronize the errors found in this validator to each field. */
- protected void dispatchErrorsToFields() {
-
- Map map = validationContext.getFieldErrors();
- for (ValidatorField<B> field : fields) {
- String fieldName = field.getName();
- boolean detectedErrors = map.containsKey(fieldName);
- field.addErrors(this, detectedErrors ? (List) map.get(fieldName) : null);
- }
- }
-
-}
Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorListener.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorListener.java 2009-03-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorListener.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -14,19 +14,4 @@
* @param event the event
*/
void onFieldChanged(BeanValidatorEvent event);
-
- /**
- * Invoked when a validator detects a new message on a field.
- *
- * @param event the event
- */
- //void onNewMessages(BeanValidatorEvent event);
-
- /**
- * Invoked when a validator detetcs that a previously message is
- * no more exisitng.
- *
- * @param event the event
- */
- //void onResolvedMessages(BeanValidatorEvent event);
}
Modified: 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-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidationUtil.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -95,7 +95,7 @@
* @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) {
+ public static void convert(BeanValidator2<?> validator, String fieldName, String value, Class<?> valueClass) {
Object result = validator.convert(fieldName, value, valueClass);
if (result != null) {
Deleted: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorEvent.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorEvent.java 2009-03-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorEvent.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -1,46 +0,0 @@
-package jaxx.runtime.validator;
-
-import com.opensymphony.xwork2.validator.ValidatorScope;
-
-import java.util.Set;
-
-/**
- * The definition of an event on {@link ValidatorErrorListener}
- * to be fired by a {@link BeanValidator}.
- *
- * @author chemit
- */
-@Deprecated
-public class ValidatorErrorEvent {
-
- /** the source of the event */
- BeanValidator source;
-
- /** the field impacted by the validator */
- ValidatorField<?> field;
-
- public ValidatorErrorEvent(BeanValidator source, ValidatorField<?> field) {
- this.source = source;
- this.field = field;
- }
-
- public BeanValidator getSource() {
- return source;
- }
-
- public String getFieldName() {
- return field.getName();
- }
-
- public Set<String> getErrors() {
- return field.getErrors();
- }
-
- public ValidatorScope getScope() {
- return field.getScope();
- }
-
- public ValidatorField getField() {
- return field;
- }
-}
Deleted: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorListener.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorListener.java 2009-03-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorListener.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -1,25 +0,0 @@
-package jaxx.runtime.validator;
-
-/**
- * The listener contract to be used on {@link BeanValidator]
- *
- * @author chemit
- */
-@Deprecated
-public interface ValidatorErrorListener extends java.util.EventListener {
- /**
- * Invoked when a validator detects a error on a field.
- *
- * @param event the event
- */
- void onNewError(ValidatorErrorEvent event);
-
- /**
- * Invoked when a validator detetcs that a previously error is
- * no more exisitng.
- *
- * @param event the event
- */
- void onResolvedError(ValidatorErrorEvent event);
-
-}
Deleted: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorField.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorField.java 2009-03-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorField.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -1,187 +0,0 @@
-package jaxx.runtime.validator;
-
-import com.opensymphony.xwork2.validator.ValidatorScope;
-import static org.codelutin.i18n.I18n._;
-
-import javax.swing.event.EventListenerList;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-/**
- * Definition of a field to be handled in a {@link BeanValidator].
- * <p/>
- * <p/>
- * A such class is only registred in {@link BeanValidator } when the field of the bean
- * was found in validator xml configuration file for a {@link com.opensymphony.xwork2.validator.FieldValidator} only.
- * <p/>
- * This class use properties {@link #beanClass}, {@link #name} to define
- * his naturel order.
- *
- * @author chemit
- * @param <B> the type of the bean handled by the validator and this field of validation.
- */
-@Deprecated
-public class ValidatorField<B> {
-
- /** the class of bean */
- protected final Class<B> beanClass;
-
- /** name of field in bean */
- protected String name;
-
- /** the scope of the field */
- protected ValidatorScope scope;
-
- /** the list of error for this field */
- protected Set<String> errors;
-
- /** A list of event listeners for this validators */
- protected EventListenerList listenerList = new EventListenerList();
-
- public ValidatorField(Class<B> beanClass, String name, ValidatorScope scope) {
- this.beanClass = beanClass;
- this.name = name;
- this.scope = scope;
- this.errors = new HashSet<String>();
- }
-
- public String getName() {
- return name;
- }
-
- public ValidatorScope getScope() {
- return scope;
- }
-
- public Class<B> getBeanClass() {
- return beanClass;
- }
-
- public Set<String> getErrors() {
- return errors;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public void setScope(ValidatorScope scope) {
- this.scope = scope;
- }
-
- /**
- * @return <code>true</code> if this field is valid (says is in error
- * scope and has errors), <code>false</code> otherwise.
- */
- public boolean isValid() {
- return hasErrors();
- }
-
- public boolean hasErrors() {
- return scope == ValidatorScope.ERROR && !errors.isEmpty();
- }
-
- public boolean hasWarnings() {
- return scope == ValidatorScope.WARNING && !errors.isEmpty();
- }
-
- public void addErrors(BeanValidator<B> validator, List errors) {
- boolean hasPreviousError = !this.errors.isEmpty();
-
- // reset errors for this field
- this.errors.clear();
-
- if (errors == null) {
- // no error to assign to this field
- if (hasPreviousError) {
- // there were previously errors, but any longer
- // so fire a resolvedErrorEvent for this field
- fireResolvedError(validator);
- }
- return;
- }
-
- for (Object error : errors) {
- this.errors.add(error.toString());
- }
- // fire a newErrorEvent for this field
- fireNewError(validator);
- }
-
- public String getI18nError(String error) {
- String text;
- if (error.indexOf("##") == -1) {
- text = _(error);
- } else {
- StringTokenizer stk = new StringTokenizer(error, "##");
- String errorName = stk.nextToken();
- List<String> args = new ArrayList<String>();
- while (stk.hasMoreTokens()) {
- args.add(stk.nextToken());
- }
- text = _(errorName, args.toArray());
- }
- return text;
- }
-
- public void addValidatorErrorListener(ValidatorErrorListener listener) {
- listenerList.add(ValidatorErrorListener.class, listener);
- }
-
- public void removeValidatorErrorListener(ValidatorErrorListener listener) {
- listenerList.remove(ValidatorErrorListener.class, listener);
- }
-
- public ValidatorErrorListener[] getValidatorErrorListeners() {
- return listenerList.getListeners(ValidatorErrorListener.class);
- }
-
- protected void fireNewError(BeanValidator<B> validator) {
- ValidatorErrorEvent evt = new ValidatorErrorEvent(validator, this);
- for (ValidatorErrorListener listener : listenerList.getListeners(ValidatorErrorListener.class)) {
- listener.onNewError(evt);
- }
- }
-
- protected void fireResolvedError(BeanValidator<B> validator) {
- ValidatorErrorEvent evt = new ValidatorErrorEvent(validator, this);
- for (ValidatorErrorListener listener : listenerList.getListeners(ValidatorErrorListener.class)) {
- listener.onResolvedError(evt);
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof ValidatorField)) {
- return false;
- }
-
- ValidatorField that = (ValidatorField) o;
- return beanClass.equals(that.beanClass) && name.equals(that.name);
- }
-
- @Override
- public int hashCode() {
- int result = beanClass.hashCode();
- result = 31 * result + name.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("<").append(super.toString());
- sb.append(" beanClass:").append(beanClass);
- sb.append(", name:").append(name);
- sb.append(", scope:").append(scope);
- sb.append(", errors:").append(errors);
- sb.append('>');
- return sb.toString();
- }
-}
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-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractFieldValidatorTest.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -1,9 +1,9 @@
package jaxx.runtime.validator.field;
import java.io.File;
-import jaxx.runtime.validator.BeanValidator;
+import jaxx.runtime.validator.BeanValidator2;
+import jaxx.runtime.validator.BeanValidatorField;
import jaxx.runtime.validator.ValidatorBean;
-import jaxx.runtime.validator.ValidatorField;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
@@ -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 BeanValidator<ValidatorBean> validator;
+ static protected BeanValidator2<ValidatorBean> validator;
static protected File basedir;
protected ValidatorBean bean;
@@ -53,16 +53,17 @@
b = new File("").getAbsolutePath();
}
basedir = new File(b);
- validator = new BeanValidator<ValidatorBean>(ValidatorBean.class, null);
+ validator = new BeanValidator2<ValidatorBean>(ValidatorBean.class, null);
}
protected void assertFieldInError(String fieldName, String error, boolean required) {
- ValidatorField<ValidatorBean> field = validator.getField(fieldName);
-
- for (String o : field.getErrors()) {
- if (o.equals(error)) {
- assertTrue(required);
- return;
+ BeanValidatorField<ValidatorBean> field = validator.getField(fieldName);
+ if (field !=null && field.getErrors() != null) {
+ for (String o : field.getErrors()) {
+ if (o.equals(error)) {
+ assertTrue(required);
+ return;
+ }
}
}
// error was not found
Copied: jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/ValidatorBean-error-validation.xml (from rev 1273, jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/ValidatorBean-validation.xml)
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/ValidatorBean-error-validation.xml (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/ValidatorBean-error-validation.xml 2009-03-21 08:22:03 UTC (rev 1274)
@@ -0,0 +1,95 @@
+<!DOCTYPE validators PUBLIC
+ "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+
+ <field name="stringValue">
+ <field-validator type="requiredstring" short-circuit="true">
+ <message>stringValue.required</message>
+ </field-validator>
+ </field>
+
+ <field name="existingFile">
+ <field-validator type="requiredFile" short-circuit="true">
+ <message>existingFile.required</message>
+ </field-validator>
+ <field-validator type="existingFile" short-circuit="true">
+ <message>existingFile.not.exist</message>
+ </field-validator>
+ </field>
+
+ <field name="notExistingFile">
+ <field-validator type="requiredFile" short-circuit="true">
+ <message>notExistingFile.required</message>
+ </field-validator>
+ <field-validator type="notExistingFile" short-circuit="true">
+ <message>notExistingFile.exist</message>
+ </field-validator>
+ </field>
+
+ <field name="existingDirectory">
+ <field-validator type="requiredFile" short-circuit="true">
+ <message>existingDirectory.required</message>
+ </field-validator>
+
+ <field-validator type="existingDirectory" short-circuit="true">
+ <message>existingDirectory.not.exist</message>
+ </field-validator>
+ </field>
+
+ <field name="notExistingDirectory">
+ <field-validator type="requiredFile" short-circuit="true">
+ <message>notExistingDirectory.required</message>
+ </field-validator>
+
+ <field-validator type="notExistingDirectory" short-circuit="true">
+ <message>notExistingDirectory.exist</message>
+ </field-validator>
+ </field>
+
+ <field name="entries">
+ <field-validator type="collectionFieldExpression">
+ <param name="mode">AT_LEAST_ONE</param>
+ <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]></param>
+ <message>collectionFieldExpression.atLeastOne</message>
+ </field-validator>
+ <field-validator type="collectionFieldExpression">
+ <param name="mode">EXACTLY_ONE</param>
+ <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]></param>
+ <message>collectionFieldExpression.exactlyOne</message>
+ </field-validator>
+ <field-validator type="collectionFieldExpression">
+ <param name="mode">ALL</param>
+ <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]></param>
+ <message>collectionFieldExpression.all</message>
+ </field-validator>
+ <field-validator type="collectionFieldExpression">
+ <param name="mode">NONE</param>
+ <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]></param>
+ <message>collectionFieldExpression.none</message>
+ </field-validator>
+
+ <field-validator type="collectionUniqueKey">
+ <param name="keys">intValue</param>
+ <message>collectionUniqueKey.one.failed</message>
+ </field-validator>
+ <field-validator type="collectionUniqueKey">
+ <param name="keys">stringValue</param>
+ <message>collectionUniqueKey.two.failed</message>
+ </field-validator>
+ <field-validator type="collectionUniqueKey">
+ <param name="keys">intValue,stringValue</param>
+ <message>collectionUniqueKey.three.failed</message>
+ </field-validator>
+ <field-validator type="collectionUniqueKey">
+ <param name="keys">intValue,stringValue,stringValue2</param>
+ <message>collectionUniqueKey.four.failed</message>
+ </field-validator>
+ <field-validator type="collectionUniqueKey">
+ <param name="keys">stringValue</param>
+ <param name="againstProperty">entry</param>
+ <message>collectionUniqueKey.five.failed</message>
+ </field-validator>
+ </field>
+
+</validators>
\ No newline at end of file
Deleted: jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/ValidatorBean-validation.xml
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/ValidatorBean-validation.xml 2009-03-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/ValidatorBean-validation.xml 2009-03-21 08:22:03 UTC (rev 1274)
@@ -1,95 +0,0 @@
-<!DOCTYPE validators PUBLIC
- "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
- "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-<validators>
-
- <field name="stringValue">
- <field-validator type="requiredstring" short-circuit="true">
- <message>stringValue.required</message>
- </field-validator>
- </field>
-
- <field name="existingFile">
- <field-validator type="requiredFile" short-circuit="true" validatorScope="ERROR">
- <message>existingFile.required</message>
- </field-validator>
- <field-validator type="existingFile" short-circuit="true">
- <message>existingFile.not.exist</message>
- </field-validator>
- </field>
-
- <field name="notExistingFile">
- <field-validator type="requiredFile" short-circuit="true">
- <message>notExistingFile.required</message>
- </field-validator>
- <field-validator type="notExistingFile" short-circuit="true">
- <message>notExistingFile.exist</message>
- </field-validator>
- </field>
-
- <field name="existingDirectory">
- <field-validator type="requiredFile" short-circuit="true">
- <message>existingDirectory.required</message>
- </field-validator>
-
- <field-validator type="existingDirectory" short-circuit="true">
- <message>existingDirectory.not.exist</message>
- </field-validator>
- </field>
-
- <field name="notExistingDirectory">
- <field-validator type="requiredFile" short-circuit="true">
- <message>notExistingDirectory.required</message>
- </field-validator>
-
- <field-validator type="notExistingDirectory" short-circuit="true">
- <message>notExistingDirectory.exist</message>
- </field-validator>
- </field>
-
- <field name="entries">
- <field-validator type="collectionFieldExpression">
- <param name="mode">AT_LEAST_ONE</param>
- <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]></param>
- <message>collectionFieldExpression.atLeastOne</message>
- </field-validator>
- <field-validator type="collectionFieldExpression">
- <param name="mode">EXACTLY_ONE</param>
- <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]></param>
- <message>collectionFieldExpression.exactlyOne</message>
- </field-validator>
- <field-validator type="collectionFieldExpression">
- <param name="mode">ALL</param>
- <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]></param>
- <message>collectionFieldExpression.all</message>
- </field-validator>
- <field-validator type="collectionFieldExpression">
- <param name="mode">NONE</param>
- <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]></param>
- <message>collectionFieldExpression.none</message>
- </field-validator>
-
- <field-validator type="collectionUniqueKey">
- <param name="keys">intValue</param>
- <message>collectionUniqueKey.one.failed</message>
- </field-validator>
- <field-validator type="collectionUniqueKey">
- <param name="keys">stringValue</param>
- <message>collectionUniqueKey.two.failed</message>
- </field-validator>
- <field-validator type="collectionUniqueKey">
- <param name="keys">intValue,stringValue</param>
- <message>collectionUniqueKey.three.failed</message>
- </field-validator>
- <field-validator type="collectionUniqueKey">
- <param name="keys">intValue,stringValue,stringValue2</param>
- <message>collectionUniqueKey.four.failed</message>
- </field-validator>
- <field-validator type="collectionUniqueKey">
- <param name="keys">stringValue</param>
- <param name="againstProperty">entry</param>
- <message>collectionUniqueKey.five.failed</message>
- </field-validator>
- </field>
-
-</validators>
\ No newline at end of file
Modified: 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-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/SwingValidationUtil.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -1,13 +1,14 @@
package jaxx.runtime.validator;
-import jaxx.runtime.validator.swing.SwingValidatorErrorListMouseListener;
-import jaxx.runtime.validator.swing.SwingValidatorErrorTableMouseListener;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.swing.JList;
import javax.swing.JTable;
import java.awt.event.MouseListener;
+import jaxx.runtime.validator.swing.SwingValidatorMessageTableMouseListener;
+import jaxx.runtime.validator.swing.SwingValidatorMessageListMouseListener;
/**
* The helper class for validation module.
@@ -28,13 +29,13 @@
return;
}
for (MouseListener listener : list.getMouseListeners()) {
- if (listener instanceof SwingValidatorErrorListMouseListener) {
+ if (listener instanceof SwingValidatorMessageListMouseListener) {
// already have a such listener
log.info("already registered a such MouseListener : " + listener);
return;
}
}
- list.addMouseListener(new SwingValidatorErrorListMouseListener());
+ list.addMouseListener(new SwingValidatorMessageListMouseListener());
}
public static void registerErrorTableMouseListener(JTable table) {
@@ -42,20 +43,20 @@
return;
}
for (MouseListener listener : table.getMouseListeners()) {
- if (listener instanceof SwingValidatorErrorTableMouseListener) {
+ if (listener instanceof SwingValidatorMessageTableMouseListener) {
// already have a such listener
log.info("already registered a such MouseListener : " + listener);
return;
}
}
- table.addMouseListener(new SwingValidatorErrorTableMouseListener());
+ table.addMouseListener(new SwingValidatorMessageTableMouseListener());
}
- public static SwingValidatorErrorTableMouseListener getErrorTableMouseListener(JTable table) {
+ public SwingValidatorMessageTableMouseListener getErrorTableMouseListener(JTable table) {
if (table != null) {
for (MouseListener listener : table.getMouseListeners()) {
- if (listener instanceof SwingValidatorErrorTableMouseListener) {
- return (SwingValidatorErrorTableMouseListener) listener;
+ if (listener instanceof SwingValidatorMessageTableMouseListener) {
+ return (SwingValidatorMessageTableMouseListener) listener;
}
}
}
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-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -107,10 +107,10 @@
protected Map<String, JComponent> fieldRepresentation;
/** Object servant a contenir la liste des erreurs */
- protected SwingValidatorErrorListModel errorListModel;
+ protected SwingValidatorMessageListModel errorListModel;
/** Object servant a contenir la liste des erreurs */
- protected SwingValidatorErrorTableModel errorTableModel;
+ protected SwingValidatorMessageTableModel errorTableModel;
/** ui renderer class */
protected Class<? extends AbstractBeanValidatorUI> uiClass;
@@ -129,7 +129,7 @@
return uiClass;
}
- public void setErrorListModel(SwingValidatorErrorListModel errorListModel) {
+ public void setErrorListModel(SwingValidatorMessageListModel errorListModel) {
this.errorListModel = errorListModel;
if (errorListModel != null) {
// register the validator in the model list
@@ -137,7 +137,7 @@
}
}
- public void setErrorTableModel(SwingValidatorErrorTableModel errorTableModel) {
+ public void setErrorTableModel(SwingValidatorMessageTableModel errorTableModel) {
this.errorTableModel = errorTableModel;
if (errorTableModel != null) {
// register the validator in the model table
@@ -221,7 +221,7 @@
}
for (Entry<String, JComponent> entry : fieldRepresentation.entrySet()) {
try {
- setErrorRepresentation(entry.getKey(), null, entry.getValue(), uiClass);
+ setMessageRepresentation(entry.getKey(), null, entry.getValue(), uiClass);
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -230,7 +230,7 @@
});
}
- protected void setErrorRepresentation(String fieldname, JComponent old, JComponent c, Class<? extends AbstractBeanValidatorUI> uiClass)
+ protected void setMessageRepresentation(String fieldname, JComponent old, JComponent c, Class<? extends AbstractBeanValidatorUI> uiClass)
throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException {
if (old == c) {
// same component, nothing to do
@@ -250,7 +250,6 @@
Object ui = jx.getUI();
if (ui != null && ui instanceof AbstractBeanValidatorUI) {
removeBeanValidatorListener((AbstractBeanValidatorUI)ui);
- //field.removeValidatorErrorListener((AbstractBeanValidatorUI) ui);
}
jx.setUI(null);
@@ -265,7 +264,6 @@
ui.setEnabled(true);
JXLayer<JComponent> jx = (JXLayer<JComponent>) container;
addBeanValidatorListener(ui);
- //field.addValidatorErrorListener(ui);
jx.setUI(ui);
}
}
Deleted: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListModel.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListModel.java 2009-03-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListModel.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -1,231 +0,0 @@
-package jaxx.runtime.validator.swing;
-
-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;
-
-/**
- * The model of the list of errors
- *
- * @author chemit
- */
-public class SwingValidatorErrorListModel extends DefaultListModel implements BeanValidatorListener {
-
- /** to use log facility, just put in your code: log.info(\"...\"); */
- private static Log log = LogFactory.getLog(SwingValidatorErrorListModel.class);
- private static final long serialVersionUID = 1L;
- /** list of registred validators */
- protected transient List<SwingValidator<?>> validators;
-
- public SwingValidatorErrorListModel() {
- validators = new ArrayList<SwingValidator<?>>();
- }
-
- 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);
- // the model listen on each field of the validator
- /*for (ValidatorField<?> field : validator.getFields()) {
- field.addValidatorErrorListener(this);
- }*/
- }
-
- @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();
-
- 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));
- }
-
- if ((toAdd == null || toAdd.length == 0) && (toDelete == null || toDelete.length == 0)) {
- // no data to add nor remove, so nothing to do
- return;
- }
-
- if (toAdd == null || toAdd.length == 0) {
-
- if (log.isTraceEnabled()) {
- log.trace(field + " - toDelete : just delete some datas!");
- }
-
- // no add, no need to resort the datas, can direclty delete
- // messages we do not want any longer
-
- // 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);
-
- Enumeration enumeration = elements();
- int index = 0;
- while (enumeration.hasMoreElements()) {
- SwingValidatorErrorModel error = (SwingValidatorErrorModel) enumeration.nextElement();
-
- if (error.getValidator() == validator && error.getField() == field && ids.contains(error.getError())) {
- indexs.add(index);
- }
- index++;
- }
-
- java.util.Collections.reverse(indexs);
-
- for (Integer i : indexs) {
- removeElementAt(i);
- }
-
- return;
- }
-
- if (log.isTraceEnabled()) {
- log.trace(field + " - add and delete !");
- }
-
- List<SwingValidatorErrorModel> newMessages = new ArrayList<SwingValidatorErrorModel>();
-
-
-
- // obtain all messages not to delete
-
- List<String> ids = new java.util.ArrayList<String>(java.util.Arrays.asList(toDelete));
-
- Enumeration enumeration = elements();
- while (enumeration.hasMoreElements()) {
- SwingValidatorErrorModel error = (SwingValidatorErrorModel) enumeration.nextElement();
-
- if (error.getValidator() != validator || error.getField() != field || !ids.contains(error.getError())) {
- // keep this row
- newMessages.add(error);
- }
- }
-
- if (toAdd != null && toAdd.length > 0) {
- JComponent editor = validator.getFieldRepresentation(field.getName());
- // add new messages
- for (String error : toAdd) {
- newMessages.add(new SwingValidatorErrorModel(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 (SwingValidatorErrorModel error : newMessages) {
- addElement(error);
- }
-
- /*
- List<SwingValidatorErrorModel> newErrors = new ArrayList<SwingValidatorErrorModel>();
-
- JComponent editor = validator.getFieldRepresentation(field.getName());
- // add new errors
- for (String error : toAdd) {
- newErrors.add(new SwingValidatorErrorModel(validator, field, error, editor));
- }
-
-
- java.util.Collections.sort(newErrors);
-
- // clean model and reinject new errors
- removeAllElements();
-
- // reinject in list model, all the errors
- for (SwingValidatorErrorModel error : newErrors) {
- addElement(error);
- }*/
- }
- /**
- * Invoked when a validator detects a error on a field.
- *
- * @param event the event
- */
- /*@Override
- public void onNewError(ValidatorErrorEvent event) {
- ValidatorField field = event.getField();
- SwingValidator validator = (SwingValidator) event.getSource();
- Set<String> errors = event.getErrors();
-
- // must remove all previously error for this field and validator
- List<SwingValidatorErrorModel> newErrors = new ArrayList<SwingValidatorErrorModel>();
- JComponent editor = validator.getFieldRepresentation(field.getName());
- Enumeration enumeration = elements();
- while (enumeration.hasMoreElements()) {
- SwingValidatorErrorModel error = (SwingValidatorErrorModel) enumeration.nextElement();
- if (error.getValidator() == validator && error.getField() == field) {
- // this error can be skipped
- continue;
- }
- newErrors.add(error);
- }
- // add new errors
- for (String error : errors) {
- newErrors.add(new SwingValidatorErrorModel(validator, field, error, editor));
- }
- java.util.Collections.sort(newErrors);
-
- // clean model and reinject new errors
- removeAllElements();
-
- // reinject in list model, all the errors
- for (SwingValidatorErrorModel error : newErrors) {
- addElement(error);
- }
- //FIXME, this is not performant, prefer use a isValueAdjusting property on SwingValidator
- // notify that the model has changed
- }*/
- /**
- * Invoked when a validator detetcs that a previously error is
- * no more exisitng.
- *
- * @param event the event
- */
- /*@Override
- public void onResolvedError(ValidatorErrorEvent event) {
- SwingValidator validator = (SwingValidator) event.getSource();
- ValidatorField field = event.getField();
- // must remove all previously error for this field
-
- boolean somethingChange = false;
- Enumeration enumeration = elements();
- List<SwingValidatorErrorModel> newList = new ArrayList<SwingValidatorErrorModel>();
- while (enumeration.hasMoreElements()) {
- SwingValidatorErrorModel error = (SwingValidatorErrorModel) enumeration.nextElement();
- if (error.getValidator() == validator && error.getField() == field) {
- // this error can be skipped
- somethingChange = true;
- } else {
- newList.add(error);
- }
- }
- // clean model and reinject new errors
- removeAllElements();
-
- if (somethingChange) {
- for (SwingValidatorErrorModel errorModel : newList) {
- addElement(errorModel);
- }
- }
- }*/
-}
Deleted: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListMouseListener.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListMouseListener.java 2009-03-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListMouseListener.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -1,61 +0,0 @@
-package jaxx.runtime.validator.swing;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import javax.swing.JComponent;
-import javax.swing.JList;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-
-/**
- * A mouse listener to put on a {@link javax.swing.JList} with a {@link SwingValidatorErrorListModel} as a model.
- * <p/>
- * When a double click occurs, find the selected error in model and then focus to the associated component of error.
- *
- * @author chemit
- */
-public class SwingValidatorErrorListMouseListener extends MouseAdapter {
-
- /** to use log facility, just put in your code: log.info(\"...\"); */
- static private Log log = LogFactory.getLog(SwingValidatorErrorListMouseListener.class);
-
- @Override
- public void mouseClicked(MouseEvent e) {
- super.mouseClicked(e);
- if (e.getClickCount() == 2) {
-
- SwingValidatorErrorModel entry = getSelectedError(e);
- if (entry == null) {
- // no entry found
- return;
- }
- JComponent component = entry.getEditor();
- if (component != null) {
- component.requestFocus();
- }
- }
- }
-
-
- protected SwingValidatorErrorModel getSelectedError(MouseEvent e) {
- JList list = (JList) e.getSource();
- if (!(list.getModel() instanceof SwingValidatorErrorListModel)) {
- log.warn("model must be a " + SwingValidatorErrorListModel.class + ", but was " + list.getModel());
- return null;
- }
-
- SwingValidatorErrorListModel model = (SwingValidatorErrorListModel) list.getModel();
- int index = list.getSelectionModel().getMinSelectionIndex();
- if (index == -1) {
- // nothing is selected
- return null;
- }
- SwingValidatorErrorModel entry = (SwingValidatorErrorModel) model.getElementAt(index);
- if (log.isDebugEnabled()) {
- log.debug("selected index: " + index + " : error: " + entry);
- }
- return entry;
- }
-
-}
\ No newline at end of file
Deleted: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorModel.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorModel.java 2009-03-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorModel.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -1,58 +0,0 @@
-package jaxx.runtime.validator.swing;
-
-
-import javax.swing.JComponent;
-import jaxx.runtime.validator.BeanValidatorField;
-
-/** @author chemit */
-public class SwingValidatorErrorModel implements Comparable<SwingValidatorErrorModel> {
- protected SwingValidator validator;
- protected BeanValidatorField field;
- protected String error;
- protected JComponent editor;
-
- public SwingValidatorErrorModel(SwingValidator validator, BeanValidatorField field, String error, JComponent editor) {
- this.field = field;
- this.validator = validator;
- this.error = error;
- this.editor = editor;
- }
-
- public JComponent getEditor() {
- return editor;
- }
-
- public SwingValidator getValidator() {
- return validator;
- }
-
- public BeanValidatorField getField() {
- return field;
- }
-
- public String getError() {
- return error;
- }
-
- @Override
- public int compareTo(SwingValidatorErrorModel o) {
- int result = field.getScope().compareTo(o.field.getScope());
- if (result != 0) {
- return result;
- }
- result = field.getName().compareTo(o.field.getName());
- if (result != 0) {
- return result;
- }
- result = error.compareTo(o.error);
- return result;
- }
-
- @Override
- public String toString() {
- if (editor == null) {
- return field.getI18nError(error);
- }
- return editor.getName() + " : " + field.getI18nError(error);
- }
-}
Deleted: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableModel.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableModel.java 2009-03-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableModel.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -1,158 +0,0 @@
-package jaxx.runtime.validator.swing;
-
-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 org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * The model of the list of errors
- *
- * @author chemit
- */
-public class SwingValidatorErrorTableModel extends DefaultTableModel implements BeanValidatorListener {
-
- /** to use log facility, just put in your code: log.info(\"...\"); */
- private static Log log = LogFactory.getLog(SwingValidatorErrorTableMouseListener.class);
- private static final long serialVersionUID = 1L;
- public static final String[] columnNames = {"validator.scope", "validator.field", "validator.message"};
- /** list of registred validators */
- protected transient List<SwingValidator<?>> validators;
- /** comporator of errors */
- protected transient Comparator<SwingValidatorErrorModel> comparator;
-
- public SwingValidatorErrorTableModel() {
- super(columnNames, 0);
- validators = new ArrayList<SwingValidator<?>>();
- }
-
- public int getErrorColumn() {
- return findColumn(columnNames[2]);
- }
-
- @Override
- public boolean isCellEditable(int row, int column) {
- // cells are never editable in this model
- return false;
- }
-
- public void registerValidator(SwingValidator<?> validator) {
- if (validators.contains(validator)) {
- throw new IllegalArgumentException("the validator " + validator + " is already registred in " + this);
- }
- validators.add(validator);
- validator.addBeanValidatorListener(this);
- }
-
- @Override
- public void onFieldChanged(BeanValidatorEvent event) {
- String[] toDelete = event.getMessagesToDelete();
- String[] toAdd = event.getMessagesToAdd();
- BeanValidatorField field = event.getField();
-
- 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));
- }
- 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();
-
-
- int errorColumn = getErrorColumn();
-
- if (toAdd == null || toAdd.length == 0) {
-
-
- if (log.isTraceEnabled()) {
- log.trace(field + " - toDelete : just delete some datas!");
- }
-
- // no add, no need to resort the datas, can direclty delete
- // messages we do not want any longer
-
- // 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);
-
- Enumeration enumeration = getDataVector().elements();
-
- int index = 0;
- while (enumeration.hasMoreElements()) {
- Vector row = (Vector) enumeration.nextElement();
- SwingValidatorErrorModel error = (SwingValidatorErrorModel) row.get(errorColumn);
- if (error.getValidator() == validator && error.getField() == field && ids.contains(error.getError())) {
- // remo the message
- indexs.add(index);
- }
- index++;
- }
- java.util.Collections.reverse(indexs);
-
- for (Integer i : indexs) {
- removeRow(i);
- }
-
- return;
- }
-
- if (log.isTraceEnabled()) {
- log.trace(field + " - add and delete !");
- }
-
- // rebuild all the data (since we are some adding data and we ensure
- // an order on datas)
-
- List<SwingValidatorErrorModel> newMessages = new ArrayList<SwingValidatorErrorModel>();
-
- // delete some messages for the given field and given scope
- List<String> ids = new java.util.ArrayList<String>(java.util.Arrays.asList(toDelete));
-
- Enumeration enumeration = getDataVector().elements();
-
- while (enumeration.hasMoreElements()) {
- Vector row = (Vector) enumeration.nextElement();
- SwingValidatorErrorModel error = (SwingValidatorErrorModel) row.get(errorColumn);
- if (error.getValidator() != validator || error.getField() != field || !ids.contains(error.getError())) {
- // keep this row
- newMessages.add(error);
- }
- }
-
- if (toAdd != null && toAdd.length > 0) {
- JComponent editor = validator.getFieldRepresentation(field.getName());
- // add new errors
- for (String error : toAdd) {
- SwingValidatorErrorModel errorModel = new SwingValidatorErrorModel(validator, field, error, editor);
- newMessages.add(errorModel);
- }
- }
-
- // sort datas
-
- java.util.Collections.sort(newMessages);
-
- // clean table model and reinject new messages
- getDataVector().clear();
-
- // reinject in list model, all the errors
- for (SwingValidatorErrorModel error : newMessages) {
- addRow(new Object[]{error.getField().getScope(), error.getField().getName(), error});
- }
-
- fireTableDataChanged();
- }
-}
\ No newline at end of file
Deleted: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableMouseListener.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableMouseListener.java 2009-03-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableMouseListener.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -1,92 +0,0 @@
-package jaxx.runtime.validator.swing;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import javax.swing.JComponent;
-import javax.swing.JTable;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-
-/**
- * A mouse listener to put on a {@link javax.swing.JList} with a {@link SwingValidatorErrorTableModel} as a model.
- * <p/>
- * When a double click occurs, find the selected error in model and then focus to the associated component of error.
- *
- * @author chemit
- */
-public class SwingValidatorErrorTableMouseListener extends MouseAdapter {
-
- /** to use log facility, just put in your code: log.info(\"...\"); */
- private static Log log = LogFactory.getLog(SwingValidatorErrorTableMouseListener.class);
-
- public static final String HIGHLIGHT_ERROR_PROPERTY = "highlightError";
-
- /** delgate property change support */
- protected PropertyChangeSupport pcs;
-
- public SwingValidatorErrorTableMouseListener() {
- pcs = new PropertyChangeSupport(this);
- }
-
- @Override
- public void mouseClicked(MouseEvent e) {
- super.mouseClicked(e);
- if (e.getClickCount() == 2) {
-
- SwingValidatorErrorModel entry = getSelectedError(e);
- if (entry == null) {
- // no entry found
- return;
- }
- JComponent component = entry.getEditor();
- if (component != null) {
- pcs.firePropertyChange(HIGHLIGHT_ERROR_PROPERTY, null, entry);
- if (component.isVisible()) {
- component.requestFocus();
- }
- }
- }
- }
-
-
- protected SwingValidatorErrorModel getSelectedError(MouseEvent e) {
- JTable table = (JTable) e.getSource();
- if (!(table.getModel() instanceof SwingValidatorErrorTableModel)) {
- log.warn("model must be a " + SwingValidatorErrorTableModel.class + ", but was " + table.getModel());
- return null;
- }
-
- SwingValidatorErrorTableModel model = (SwingValidatorErrorTableModel) table.getModel();
- int index = table.getSelectionModel().getMinSelectionIndex();
- if (index == -1) {
- // nothing is selected
- return null;
- }
- int col = model.getErrorColumn();
- SwingValidatorErrorModel entry = (SwingValidatorErrorModel) model.getValueAt(index, col);
- if (log.isDebugEnabled()) {
- log.debug("selected index: " + index + " : error: " + entry);
- }
- return entry;
- }
-
- public void addPropertyChangeListener(PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(listener);
- }
-
- public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(propertyName, listener);
- }
-
- public void removePropertyChangeListener(PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(listener);
- }
-
- public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(propertyName, listener);
- }
-
-}
\ No newline at end of file
Deleted: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableRenderer.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableRenderer.java 2009-03-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableRenderer.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -1,61 +0,0 @@
-package jaxx.runtime.validator.swing;
-
-import javax.swing.ImageIcon;
-import javax.swing.JLabel;
-import javax.swing.JTable;
-import javax.swing.table.DefaultTableCellRenderer;
-import java.awt.Component;
-import jaxx.runtime.validator.BeanValidatorScope;
-
-/** @author chemit */
-public class SwingValidatorErrorTableRenderer extends DefaultTableCellRenderer {
-
- private static final long serialVersionUID = 1L;
- ImageIcon errorIcon;
- ImageIcon warningIcon;
- ImageIcon infoIcon;
-
- public SwingValidatorErrorTableRenderer() {
- 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 SwingValidatorErrorModel) {
- SwingValidatorErrorModel model = (SwingValidatorErrorModel) value;
- String error = model.getError();
- text = model.getField().getI18nError(error);
- } else {
- // keep text rendered
- text = rendererComponent.getText();
- }
- rendererComponent.setText(text);
- rendererComponent.setIcon(icon);
- return rendererComponent;
- }
-
- @Override
- protected void setValue(Object value) {
- super.setValue(value);
- }
-}
\ No newline at end of file
Copied: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListModel.java (from rev 1273, jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListModel.java)
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListModel.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListModel.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -0,0 +1,135 @@
+package jaxx.runtime.validator.swing;
+
+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;
+
+/**
+ * The model of the list of validation's messages
+ *
+ * @author chemit
+ */
+public class SwingValidatorMessageListModel extends DefaultListModel implements BeanValidatorListener {
+
+ /** 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;
+
+ public SwingValidatorMessageListModel() {
+ validators = new ArrayList<SwingValidator<?>>();
+ }
+
+ 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 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();
+
+ 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));
+ }
+
+ if ((toAdd == null || toAdd.length == 0) && (toDelete == null || toDelete.length == 0)) {
+ // no data to add nor remove, so nothing to do
+ return;
+ }
+
+ if (toAdd == null || toAdd.length == 0) {
+
+ if (log.isTraceEnabled()) {
+ log.trace(field + " - toDelete : just delete some datas!");
+ }
+
+ // no add, no need to resort the datas, can direclty delete
+ // messages we do not want any longer
+
+ // 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);
+
+ Enumeration enumeration = elements();
+ int index = 0;
+ while (enumeration.hasMoreElements()) {
+ SwingValidatorMessageModel error = (SwingValidatorMessageModel) enumeration.nextElement();
+
+ if (error.getValidator() == validator && error.getField() == field && ids.contains(error.getMessage())) {
+ indexs.add(index);
+ }
+ index++;
+ }
+
+ java.util.Collections.reverse(indexs);
+
+ for (Integer i : indexs) {
+ removeElementAt(i);
+ }
+
+ return;
+ }
+
+ if (log.isTraceEnabled()) {
+ log.trace(field + " - add and delete !");
+ }
+
+ List<SwingValidatorMessageModel> newMessages = new ArrayList<SwingValidatorMessageModel>();
+
+
+
+ // obtain all messages not to delete
+
+ List<String> ids = new java.util.ArrayList<String>(java.util.Arrays.asList(toDelete));
+
+ 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);
+ }
+ }
+
+ 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);
+ }
+ }
+}
Copied: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListMouseListener.java (from rev 1273, jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListMouseListener.java)
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListMouseListener.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListMouseListener.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -0,0 +1,61 @@
+package jaxx.runtime.validator.swing;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.swing.JComponent;
+import javax.swing.JList;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+/**
+ * A mouse listener to put on a {@link javax.swing.JList} with a {@link SwingValidatorMessageListModel} as a model.
+ * <p/>
+ * When a double click occurs, find the selected error in model and then focus to the associated component of error.
+ *
+ * @author chemit
+ */
+public class SwingValidatorMessageListMouseListener extends MouseAdapter {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(SwingValidatorMessageListMouseListener.class);
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ super.mouseClicked(e);
+ if (e.getClickCount() == 2) {
+
+ SwingValidatorMessageModel entry = getSelectedError(e);
+ if (entry == null) {
+ // no entry found
+ return;
+ }
+ JComponent component = entry.getEditor();
+ if (component != null) {
+ component.requestFocus();
+ }
+ }
+ }
+
+
+ protected SwingValidatorMessageModel getSelectedError(MouseEvent e) {
+ JList list = (JList) e.getSource();
+ if (!(list.getModel() instanceof SwingValidatorMessageListModel)) {
+ log.warn("model must be a " + SwingValidatorMessageListModel.class + ", but was " + list.getModel());
+ return null;
+ }
+
+ SwingValidatorMessageListModel model = (SwingValidatorMessageListModel) list.getModel();
+ int index = list.getSelectionModel().getMinSelectionIndex();
+ if (index == -1) {
+ // nothing is selected
+ return null;
+ }
+ SwingValidatorMessageModel entry = (SwingValidatorMessageModel) model.getElementAt(index);
+ if (log.isDebugEnabled()) {
+ log.debug("selected index: " + index + " : error: " + entry);
+ }
+ return entry;
+ }
+
+}
\ No newline at end of file
Property changes on: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListMouseListener.java
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageModel.java (from rev 1273, jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorModel.java)
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageModel.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageModel.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -0,0 +1,75 @@
+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);
+ }
+}
Property changes on: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageModel.java
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableModel.java (from rev 1273, jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableModel.java)
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableModel.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableModel.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -0,0 +1,158 @@
+package jaxx.runtime.validator.swing;
+
+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 org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * The model of the list of errors
+ *
+ * @author chemit
+ */
+public class SwingValidatorMessageTableModel extends DefaultTableModel implements BeanValidatorListener {
+
+ /** 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"};
+ /** list of registred validators */
+ protected transient List<SwingValidator<?>> validators;
+ /** comporator of errors */
+ protected transient Comparator<SwingValidatorMessageModel> comparator;
+
+ public SwingValidatorMessageTableModel() {
+ super(columnNames, 0);
+ validators = new ArrayList<SwingValidator<?>>();
+ }
+
+ public int getErrorColumn() {
+ return findColumn(columnNames[2]);
+ }
+
+ @Override
+ public boolean isCellEditable(int row, int column) {
+ // cells are never editable in this model
+ return false;
+ }
+
+ public void registerValidator(SwingValidator<?> validator) {
+ if (validators.contains(validator)) {
+ throw new IllegalArgumentException("the validator " + validator + " is already registred in " + this);
+ }
+ validators.add(validator);
+ validator.addBeanValidatorListener(this);
+ }
+
+ @Override
+ public void onFieldChanged(BeanValidatorEvent event) {
+ String[] toDelete = event.getMessagesToDelete();
+ String[] toAdd = event.getMessagesToAdd();
+ BeanValidatorField field = event.getField();
+
+ 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));
+ }
+ 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();
+
+
+ int errorColumn = getErrorColumn();
+
+ if (toAdd == null || toAdd.length == 0) {
+
+
+ if (log.isTraceEnabled()) {
+ log.trace(field + " - toDelete : just delete some datas!");
+ }
+
+ // no add, no need to resort the datas, can direclty delete
+ // messages we do not want any longer
+
+ // 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);
+
+ Enumeration enumeration = getDataVector().elements();
+
+ 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);
+
+ for (Integer i : indexs) {
+ removeRow(i);
+ }
+
+ return;
+ }
+
+ if (log.isTraceEnabled()) {
+ log.trace(field + " - add and delete !");
+ }
+
+ // rebuild all the data (since we are some adding data and we ensure
+ // an order on datas)
+
+ List<SwingValidatorMessageModel> newMessages = new ArrayList<SwingValidatorMessageModel>();
+
+ // delete some messages for the given field and given scope
+ List<String> ids = new java.util.ArrayList<String>(java.util.Arrays.asList(toDelete));
+
+ Enumeration enumeration = getDataVector().elements();
+
+ 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);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ // sort datas
+
+ java.util.Collections.sort(newMessages);
+
+ // clean table model and reinject new messages
+ getDataVector().clear();
+
+ // reinject in list model, all the errors
+ for (SwingValidatorMessageModel error : newMessages) {
+ addRow(new Object[]{error.getField().getScope(), error.getField().getName(), error});
+ }
+
+ fireTableDataChanged();
+ }
+}
\ No newline at end of file
Copied: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableMouseListener.java (from rev 1273, jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableMouseListener.java)
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableMouseListener.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableMouseListener.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -0,0 +1,92 @@
+package jaxx.runtime.validator.swing;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.swing.JComponent;
+import javax.swing.JTable;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+/**
+ * A mouse listener to put on a {@link javax.swing.JList} with a {@link SwingValidatorMessageTableModel} as a model.
+ * <p/>
+ * When a double click occurs, find the selected error in model and then focus to the associated component of error.
+ *
+ * @author chemit
+ */
+public class SwingValidatorMessageTableMouseListener extends MouseAdapter {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ private static Log log = LogFactory.getLog(SwingValidatorMessageTableMouseListener.class);
+
+ public static final String HIGHLIGHT_ERROR_PROPERTY = "highlightError";
+
+ /** delgate property change support */
+ protected PropertyChangeSupport pcs;
+
+ public SwingValidatorMessageTableMouseListener() {
+ pcs = new PropertyChangeSupport(this);
+ }
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ super.mouseClicked(e);
+ if (e.getClickCount() == 2) {
+
+ SwingValidatorMessageModel entry = getSelectedError(e);
+ if (entry == null) {
+ // no entry found
+ return;
+ }
+ JComponent component = entry.getEditor();
+ if (component != null) {
+ pcs.firePropertyChange(HIGHLIGHT_ERROR_PROPERTY, null, entry);
+ if (component.isVisible()) {
+ component.requestFocus();
+ }
+ }
+ }
+ }
+
+
+ protected SwingValidatorMessageModel getSelectedError(MouseEvent e) {
+ JTable table = (JTable) e.getSource();
+ if (!(table.getModel() instanceof SwingValidatorMessageTableModel)) {
+ log.warn("model must be a " + SwingValidatorMessageTableModel.class + ", but was " + table.getModel());
+ return null;
+ }
+
+ SwingValidatorMessageTableModel model = (SwingValidatorMessageTableModel) table.getModel();
+ int index = table.getSelectionModel().getMinSelectionIndex();
+ if (index == -1) {
+ // nothing is selected
+ return null;
+ }
+ int col = model.getErrorColumn();
+ SwingValidatorMessageModel entry = (SwingValidatorMessageModel) model.getValueAt(index, col);
+ if (log.isDebugEnabled()) {
+ log.debug("selected index: " + index + " : error: " + entry);
+ }
+ return entry;
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ pcs.addPropertyChangeListener(listener);
+ }
+
+ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ pcs.addPropertyChangeListener(propertyName, listener);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ pcs.removePropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ pcs.removePropertyChangeListener(propertyName, listener);
+ }
+
+}
\ No newline at end of file
Property changes on: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableMouseListener.java
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableRenderer.java (from rev 1273, jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableRenderer.java)
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableRenderer.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableRenderer.java 2009-03-21 08:22:03 UTC (rev 1274)
@@ -0,0 +1,61 @@
+package jaxx.runtime.validator.swing;
+
+import javax.swing.ImageIcon;
+import javax.swing.JLabel;
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableCellRenderer;
+import java.awt.Component;
+import jaxx.runtime.validator.BeanValidatorScope;
+
+/** @author chemit */
+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();
+ }
+ rendererComponent.setText(text);
+ rendererComponent.setIcon(icon);
+ return rendererComponent;
+ }
+
+ @Override
+ protected void setValue(Object value) {
+ super.setValue(value);
+ }
+}
\ No newline at end of file
Property changes on: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableRenderer.java
___________________________________________________________________
Name: svn:mergeinfo
+
Modified: jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/errors/DuplicatedErrorListModel.jaxx
===================================================================
--- jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/errors/DuplicatedErrorListModel.jaxx 2009-03-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/errors/DuplicatedErrorListModel.jaxx 2009-03-21 08:22:03 UTC (rev 1274)
@@ -1,4 +1,4 @@
<Application>
- <jaxx.runtime.validator.swing.SwingValidatorErrorListModel id='errors'/>
+ <jaxx.runtime.validator.swing.SwingValidatorMessageListModel id='errors'/>
<BeanValidator beanClass='testcases.validator.errors.Model' errorListModel='errors' errorListModel='fake'/>
</Application>
Modified: jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/errors/DuplicatedErrorTableModel.jaxx
===================================================================
--- jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/errors/DuplicatedErrorTableModel.jaxx 2009-03-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/errors/DuplicatedErrorTableModel.jaxx 2009-03-21 08:22:03 UTC (rev 1274)
@@ -1,4 +1,4 @@
<Application>
- <jaxx.runtime.validator.swing.SwingValidatorErrorListModel id='errors'/>
+ <jaxx.runtime.validator.swing.SwingValidatorMessageListModel id='errors'/>
<BeanValidator beanClass='testcases.validator.errors.Model' errorTableModel='errors' errorTableModel='fake'/>
</Application>
Modified: jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/Validation.jaxx
===================================================================
--- jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/Validation.jaxx 2009-03-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/Validation.jaxx 2009-03-21 08:22:03 UTC (rev 1274)
@@ -6,7 +6,7 @@
<Identity id='identity'/>
<!-- errors model -->
- <jaxx.runtime.validator.swing.SwingValidatorErrorListModel id='errors'
+ <jaxx.runtime.validator.swing.SwingValidatorMessageListModel id='errors'
onContentsChanged='ok.setEnabled(errors.size()==0)'/>
<!-- validators -->
Modified: jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/ValidationBeanClass.jaxx
===================================================================
--- jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/ValidationBeanClass.jaxx 2009-03-20 13:02:18 UTC (rev 1273)
+++ jaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/ValidationBeanClass.jaxx 2009-03-21 08:22:03 UTC (rev 1274)
@@ -4,7 +4,7 @@
<Identity id='identity'/>
<!-- errors model -->
- <jaxx.runtime.validator.swing.SwingValidatorErrorListModel id='errors'/>
+ <jaxx.runtime.validator.swing.SwingValidatorMessageListModel id='errors'/>
<!-- validators -->
<BeanValidator id='validator3' autoField='true' beanClass='testcases.validator.ok.Identity' errorListModel='errors'>
1
0
r1273 - in jaxx/trunk: . jaxx-compiler-api jaxx-compiler-swing jaxx-compiler-validator jaxx-example jaxx-runtime-api jaxx-runtime-swing jaxx-runtime-validator jaxx-runtime-validator-swing jaxx-swing-action jaxx-util maven-jaxx-plugin
by tchemit@users.labs.libre-entreprise.org 20 Mar '09
by tchemit@users.labs.libre-entreprise.org 20 Mar '09
20 Mar '09
Author: tchemit
Date: 2009-03-20 13:02:18 +0000 (Fri, 20 Mar 2009)
New Revision: 1273
Modified:
jaxx/trunk/changelog.txt
jaxx/trunk/jaxx-compiler-api/changelog.txt
jaxx/trunk/jaxx-compiler-swing/changelog.txt
jaxx/trunk/jaxx-compiler-validator/changelog.txt
jaxx/trunk/jaxx-example/changelog.txt
jaxx/trunk/jaxx-runtime-api/changelog.txt
jaxx/trunk/jaxx-runtime-swing/changelog.txt
jaxx/trunk/jaxx-runtime-validator-swing/changelog.txt
jaxx/trunk/jaxx-runtime-validator/changelog.txt
jaxx/trunk/jaxx-swing-action/changelog.txt
jaxx/trunk/jaxx-util/changelog.txt
jaxx/trunk/maven-jaxx-plugin/changelog.txt
Log:
release 1.3
Modified: jaxx/trunk/changelog.txt
===================================================================
--- jaxx/trunk/changelog.txt 2009-03-19 22:47:05 UTC (rev 1272)
+++ jaxx/trunk/changelog.txt 2009-03-20 13:02:18 UTC (rev 1273)
@@ -1,5 +1,6 @@
-1.3
+1.3 chemit 20090320
* 20090313 [chemit] - use i18n 0.10
+
1.2 ??? 2009????
* 20090223 [chemit] - move sources from jaxx-util to jaxx-swing-action module
- delete jaxx-util module
Modified: jaxx/trunk/jaxx-compiler-api/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-compiler-api/changelog.txt 2009-03-19 22:47:05 UTC (rev 1272)
+++ jaxx/trunk/jaxx-compiler-api/changelog.txt 2009-03-20 13:02:18 UTC (rev 1273)
@@ -1,4 +1,4 @@
-1.3 ??? 200902??
+1.3 chemit 20090320
* 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-swing/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-compiler-swing/changelog.txt 2009-03-19 22:47:05 UTC (rev 1272)
+++ jaxx/trunk/jaxx-compiler-swing/changelog.txt 2009-03-20 13:02:18 UTC (rev 1273)
@@ -1,3 +1,5 @@
+1.3 chemit 20090320
+
1.1 chemit 20090220
* 20090122 [chemit] - refactor poms (sibling dependencies, pluginsManagment,...)
Modified: jaxx/trunk/jaxx-compiler-validator/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-compiler-validator/changelog.txt 2009-03-19 22:47:05 UTC (rev 1272)
+++ jaxx/trunk/jaxx-compiler-validator/changelog.txt 2009-03-20 13:02:18 UTC (rev 1273)
@@ -1,3 +1,5 @@
+1.3 chemit 20090320
+
1.1 chemit 20090220
* 20090202 [chemit] - refactor validators (this module will soon disappear to jaxx-compiler-swing-validator)
* 20090122 [chemit] - refactor poms (sibling dependencies, pluginsManagment,...)
Modified: jaxx/trunk/jaxx-example/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-example/changelog.txt 2009-03-19 22:47:05 UTC (rev 1272)
+++ jaxx/trunk/jaxx-example/changelog.txt 2009-03-20 13:02:18 UTC (rev 1273)
@@ -1,4 +1,4 @@
-1.3
+1.3 chemit 20090320
* 20090319 [chemit] - refactor Validator : now can deal with scopes, improve design
* 20090313 [chemit] - improve demo
Modified: jaxx/trunk/jaxx-runtime-api/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-runtime-api/changelog.txt 2009-03-19 22:47:05 UTC (rev 1272)
+++ jaxx/trunk/jaxx-runtime-api/changelog.txt 2009-03-20 13:02:18 UTC (rev 1273)
@@ -1,4 +1,4 @@
-1.3 ??? 200903??
+1.3 chemit 20090320
* 20090302 [chemit] - add pcs in ApplicationContext
- add method in Util to filter JAXX property changed listeners
Modified: jaxx/trunk/jaxx-runtime-swing/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/changelog.txt 2009-03-19 22:47:05 UTC (rev 1272)
+++ jaxx/trunk/jaxx-runtime-swing/changelog.txt 2009-03-20 13:02:18 UTC (rev 1273)
@@ -1,4 +1,4 @@
-1.3 ?? 200903??
+1.3 chemit 20090320
* 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-19 22:47:05 UTC (rev 1272)
+++ jaxx/trunk/jaxx-runtime-validator/changelog.txt 2009-03-20 13:02:18 UTC (rev 1273)
@@ -1,4 +1,4 @@
-1.3 ??? 200903??
+1.3 chemit 20090320
* 20090319 [chemit] - refactor Validator : now can deal with scopes, improve design
1.1 chemit 20090220
Modified: jaxx/trunk/jaxx-runtime-validator-swing/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/changelog.txt 2009-03-19 22:47:05 UTC (rev 1272)
+++ jaxx/trunk/jaxx-runtime-validator-swing/changelog.txt 2009-03-20 13:02:18 UTC (rev 1273)
@@ -1,4 +1,4 @@
-1.3 ??? 200903??
+1.3 chemit 20090320
* 20090319 [chemit] - refactor Validator : now can deal with scopes, improve design
1.1 chemit 20090220
Modified: jaxx/trunk/jaxx-swing-action/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-swing-action/changelog.txt 2009-03-19 22:47:05 UTC (rev 1272)
+++ jaxx/trunk/jaxx-swing-action/changelog.txt 2009-03-20 13:02:18 UTC (rev 1273)
@@ -1,3 +1,5 @@
+1.3 chemit 20090320
+
1.1 chemit 20090220
* 20090122 [chemit] - refactor poms (sibling dependencies, pluginsManagment,...)
- rename i18n bundles according artifactId
Modified: jaxx/trunk/jaxx-util/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-util/changelog.txt 2009-03-19 22:47:05 UTC (rev 1272)
+++ jaxx/trunk/jaxx-util/changelog.txt 2009-03-20 13:02:18 UTC (rev 1273)
@@ -1,3 +1,5 @@
+1.3 chemit 20090320
+
1.1 chemit 20090220
* 20090122 [chemit] - refactor poms (sibling dependencies, pluginsManagment,...)
- rename i18n bundles according artifactId
Modified: jaxx/trunk/maven-jaxx-plugin/changelog.txt
===================================================================
--- jaxx/trunk/maven-jaxx-plugin/changelog.txt 2009-03-19 22:47:05 UTC (rev 1272)
+++ jaxx/trunk/maven-jaxx-plugin/changelog.txt 2009-03-20 13:02:18 UTC (rev 1273)
@@ -1,4 +1,4 @@
-1.3 ??? 200903??
+1.3 chemit 20090320
* 20090301 [chemit] - add a profile mode (-Djaxx.profile)
1.2 letelier 2009022?
1
0
19 Mar '09
Author: tchemit
Date: 2009-03-19 22:47:05 +0000 (Thu, 19 Mar 2009)
New Revision: 1272
Added:
jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-error-validation.xml
jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-info-validation.xml
jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-warning-validation.xml
jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-error-validation.xml
jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-info-validation.xml
jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-warning-validation.xml
jaxx/trunk/jaxx-runtime-validator-swing/src/main/resources/icons/info.png
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator2.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/main/java/jaxx/runtime/validator/BeanValidatorListener.java
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorScope.java
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/XWorkBeanValidator.java
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/SimpleBean.java
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/XWorkBeanValidatorTest.java
jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/SimpleBean-error-validation.xml
jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/SimpleBean-info-validation.xml
jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/SimpleBean-simple-validation.xml
jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/SimpleBean-warning-validation.xml
Removed:
jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-validation.xml
jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-validation.xml
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorScope.java
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/AbstractValidatorTest.java
Modified:
jaxx/trunk/jaxx-example/changelog.txt
jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/JAXXDemo.jaxx
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-example/src/main/resources/log4j.properties
jaxx/trunk/jaxx-runtime-validator-swing/changelog.txt
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/SwingValidatorErrorListModel.java
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorModel.java
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableModel.java
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableRenderer.java
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/ui/AbstractBeanValidatorUI.java
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/ui/IconValidationUI.java
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/ui/ImageValidationUI.java
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/ui/TranslucentValidationUI.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/BeanValidator.java
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidationUtil.java
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorEvent.java
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorListener.java
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorField.java
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/CollectionFieldExpressionValidator.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/jaxx-runtime-validator/src/test/resources/log4j.properties
Log:
refactor validator, now can deal with scope : one file by scope
no more modification in xworls
improve listener design
TODO remove all classes and bump back the version of xworks
Modified: jaxx/trunk/jaxx-example/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-example/changelog.txt 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-example/changelog.txt 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,4 +1,5 @@
1.3
+ * 20090319 [chemit] - refactor Validator : now can deal with scopes, improve design
* 20090313 [chemit] - improve demo
1.1 chemit 20090220
Modified: jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/JAXXDemo.jaxx
===================================================================
--- jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/JAXXDemo.jaxx 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/JAXXDemo.jaxx 2009-03-19 22:47:05 UTC (rev 1272)
@@ -3,7 +3,8 @@
org.codelutin.i18n.I18n.init();
-void $afterCompleteSetup() {
+void $afterCompleteSetup() {
+ try { jaxx.runtime.SwingUtil.initNimbusLoookAndFeel(); } catch (Exception e) { log.error(e.getMessage(), e); }
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
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-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,6 +1,16 @@
<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>
<!-- models -->
<Model id='model1'/>
<Model id='model2'/>
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-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx 2009-03-19 22:47:05 UTC (rev 1272)
@@ -30,16 +30,17 @@
import static org.codelutin.i18n.I18n.n_;
import jaxx.runtime.SwingUtil;
-static boolean wasinit=false;
-
-errorTable.setDefaultRenderer(Object.class, new jaxx.runtime.validator.swing.SwingValidatorErrorTableRenderer());
-SwingUtil.setI18nTableHeaderRenderer(errorTable, n_("validator.scope"), n_("validator.scope.tip"), n_("validator.field"), n_("validator.field.tip"), n_("validator.message"), n_("validator.message.tip"));
-public void setVisible(boolean value) {
- if (!wasinit) {
- SwingUtil.fixTableColumnWidth(errorTable, 0, 20);
- wasinit=true;
- }
- super.setVisible(value);
+void $afterCompleteSetup() {
+ errorTable.setDefaultRenderer(Object.class, new jaxx.runtime.validator.swing.SwingValidatorErrorTableRenderer());
+ 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>
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-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-en_GB.properties 2009-03-19 22:47:05 UTC (rev 1272)
@@ -89,6 +89,7 @@
button\ B=
button\ C=
button\ C\ (full\ block)=
+button\ D\ (full\ block\ 2)=
button\ with\ layer=
cancel=
close=
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-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-fr_FR.properties 2009-03-19 22:47:05 UTC (rev 1272)
@@ -89,6 +89,7 @@
button\ B=
button\ C=
button\ C\ (full\ block)=
+button\ D\ (full\ block\ 2)=
button\ with\ layer=
cancel=
close=
Added: jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-error-validation.xml
===================================================================
--- jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-error-validation.xml (rev 0)
+++ jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-error-validation.xml 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,49 @@
+<!DOCTYPE validators PUBLIC
+ "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+ <field name="firstName">
+ <field-validator type="requiredstring" short-circuit="true">
+ <message>You must enter a firstName.</message>
+ </field-validator>
+ </field>
+ <field name="lastName">
+ <field-validator type="requiredstring" short-circuit="true">
+ <message>You must enter a lastName.</message>
+ </field-validator>
+ </field>
+
+ <field name="email">
+ <field-validator type="requiredstring" short-circuit="true">
+ <message>You must enter a value for email.</message>
+ </field-validator>
+ <field-validator type="email" short-circuit="true">
+ <message>Not a valid e-mail.</message>
+ </field-validator>
+ </field>
+
+ <field name="config">
+ <field-validator type="requiredFile" short-circuit="true">
+ <message>You must enter a value for config.</message>
+ </field-validator>
+ <field-validator type="existingFile" short-circuit="true">
+ <message>The configuration file ${config} does not exist.</message>
+ </field-validator>
+ </field>
+
+ <field name="dir">
+ <field-validator type="requiredFile" short-circuit="true">
+ <message>You must enter a value for dir.</message>
+ </field-validator>
+ <field-validator type="existingDirectory" short-circuit="true">
+ <message>The directory ${dir} does not exist.</message>
+ </field-validator>
+ </field>
+
+ <field name="age">
+ <field-validator type="int">
+ <param name="min">18</param>
+ <message>Your are too young (min ${min} )</message>
+ </field-validator>
+ </field>
+</validators>
\ No newline at end of file
Copied: jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-info-validation.xml (from rev 1250, jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-validation.xml)
===================================================================
--- jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-info-validation.xml (rev 0)
+++ jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-info-validation.xml 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,49 @@
+<!DOCTYPE validators PUBLIC
+ "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+ <!--field name="firstName">
+ <field-validator type="requiredstring" short-circuit="true">
+ <message>You must enter a firstName.</message>
+ </field-validator>
+ </field>
+ <field name="lastName">
+ <field-validator type="requiredstring" short-circuit="true">
+ <message>You must enter a lastName.</message>
+ </field-validator>
+ </field>
+
+ <field name="email">
+ <field-validator type="requiredstring" short-circuit="true">
+ <message>You must enter a value for email.</message>
+ </field-validator>
+ <field-validator type="email" short-circuit="true">
+ <message>Not a valid e-mail.</message>
+ </field-validator>
+ </field>
+
+ <field name="config">
+ <field-validator type="requiredFile" short-circuit="true">
+ <message>You must enter a value for config.</message>
+ </field-validator>
+ <field-validator type="existingFile" short-circuit="true">
+ <message>The configuration file ${config} does not exist.</message>
+ </field-validator>
+ </field>
+
+ <field name="dir">
+ <field-validator type="requiredFile" short-circuit="true">
+ <message>You must enter a value for dir.</message>
+ </field-validator>
+ <field-validator type="existingDirectory" short-circuit="true">
+ <message>The directory ${dir} does not exist.</message>
+ </field-validator>
+ </field-->
+
+ <field name="age">
+ <field-validator type="int">
+ <param name="min">25</param>
+ <message>You are still young ( old ${min} ) </message>
+ </field-validator>
+ </field>
+</validators>
\ No newline at end of file
Deleted: jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-validation.xml
===================================================================
--- jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-validation.xml 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-validation.xml 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,50 +0,0 @@
-<!DOCTYPE validators PUBLIC
- "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
- "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-<validators>
- <field name="firstName">
- <field-validator type="requiredstring" short-circuit="true">
- <message>You must enter a firstName.</message>
- </field-validator>
- </field>
- <field name="lastName">
- <field-validator type="requiredstring" short-circuit="true">
- <message>You must enter a lastName.</message>
- </field-validator>
- </field>
-
- <field name="email">
- <field-validator type="requiredstring" short-circuit="true">
- <message>You must enter a value for email.</message>
- </field-validator>
- <field-validator type="email" short-circuit="true">
- <message>Not a valid e-mail.</message>
- </field-validator>
- </field>
-
- <field name="config">
- <field-validator type="requiredFile" short-circuit="true">
- <message>You must enter a value for config.</message>
- </field-validator>
- <field-validator type="existingFile" short-circuit="true">
- <message>The configuration file ${config} does not exist.</message>
- </field-validator>
- </field>
-
- <field name="dir">
- <field-validator type="requiredFile" short-circuit="true">
- <message>You must enter a value for dir.</message>
- </field-validator>
- <field-validator type="existingDirectory" short-circuit="true">
- <message>The directory ${dir} does not exist.</message>
- </field-validator>
- </field>
-
- <field name="age">
- <field-validator type="int">
- <param name="min">18</param>
- <param name="max">88</param>
- <message>Age needs to be between ${min} and ${max}</message>
- </field-validator>
- </field>
-</validators>
\ No newline at end of file
Added: jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-warning-validation.xml
===================================================================
--- jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-warning-validation.xml (rev 0)
+++ jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Identity-warning-validation.xml 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,49 @@
+<!DOCTYPE validators PUBLIC
+ "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+ <!--field name="firstName">
+ <field-validator type="requiredstring" short-circuit="true">
+ <message>You must enter a firstName.</message>
+ </field-validator>
+ </field>
+ <field name="lastName">
+ <field-validator type="requiredstring" short-circuit="true">
+ <message>You must enter a lastName.</message>
+ </field-validator>
+ </field>
+
+ <field name="email">
+ <field-validator type="requiredstring" short-circuit="true">
+ <message>You must enter a value for email.</message>
+ </field-validator>
+ <field-validator type="email" short-circuit="true">
+ <message>Not a valid e-mail.</message>
+ </field-validator>
+ </field>
+
+ <field name="config">
+ <field-validator type="requiredFile" short-circuit="true">
+ <message>You must enter a value for config.</message>
+ </field-validator>
+ <field-validator type="existingFile" short-circuit="true">
+ <message>The configuration file ${config} does not exist.</message>
+ </field-validator>
+ </field>
+
+ <field name="dir">
+ <field-validator type="requiredFile" short-circuit="true">
+ <message>You must enter a value for dir.</message>
+ </field-validator>
+ <field-validator type="existingDirectory" short-circuit="true">
+ <message>The directory ${dir} does not exist.</message>
+ </field-validator>
+ </field-->
+
+ <field name="age">
+ <field-validator type="int">
+ <param name="max">88</param>
+ <message>Info : Your are older than ${max} !</message>
+ </field-validator>
+ </field>
+</validators>
\ No newline at end of file
Copied: jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-error-validation.xml (from rev 1250, jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-validation.xml)
===================================================================
--- jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-error-validation.xml (rev 0)
+++ jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-error-validation.xml 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,35 @@
+<!DOCTYPE validators PUBLIC
+ "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+ <!-- Field Validators for email field -->
+ <field name="text">
+ <field-validator type="requiredstring" short-circuit="true">
+ <message>You must enter a value for text.</message>
+ </field-validator>
+ </field>
+
+ <field name="text2">
+ <field-validator type="requiredstring" short-circuit="true">
+ <message>You must enter a value for text2.</message>
+ </field-validator>
+ </field>
+
+ <field name="ratio">
+ <field-validator type="int">
+ <param name="min">20</param>
+ <param name="max">50</param>
+ <message>Ratio needs to be between ${min} and ${max}</message>
+ </field-validator>
+ </field>
+
+ <!-- Plain Validator 1 -->
+ <validator type="expression">
+ <param name="expression">text.startsWith("poussin")</param>
+ <message>Email not starts with poussin</message>
+ </validator>
+ <validator type="expression">
+ <param name="expression">text2.startsWith("chemit")</param>
+ <message>Email not starts with chemit</message>
+ </validator>
+</validators>
\ No newline at end of file
Property changes on: jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-error-validation.xml
___________________________________________________________________
Name: svn:mergeinfo
+
Added: jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-info-validation.xml
===================================================================
--- jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-info-validation.xml (rev 0)
+++ jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-info-validation.xml 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,13 @@
+<!DOCTYPE validators PUBLIC
+ "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+ <!-- Field Validators for email field -->
+ <field name="text">
+ <field-validator type="fieldexpression">
+ <param name="expression"><![CDATA[ text != null && text.length() > 10]]></param>
+ <message>Text should have more than 10 caracters</message>
+ </field-validator>
+ </field>
+
+</validators>
\ No newline at end of file
Deleted: jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-validation.xml
===================================================================
--- jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-validation.xml 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-validation.xml 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,41 +0,0 @@
-<!DOCTYPE validators PUBLIC
- "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
- "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-<validators>
- <!-- Field Validators for email field -->
- <field name="text">
- <field-validator type="requiredstring" short-circuit="true">
- <message>You must enter a value for text.</message>
- </field-validator>
- <field-validator type="email" short-circuit="true">
- <message>Not a valid e-mail for text.</message>
- </field-validator>
- </field>
-
- <field name="text2">
- <field-validator type="requiredstring" short-circuit="true">
- <message>You must enter a value for text2.</message>
- </field-validator>
- <field-validator type="email" short-circuit="true">
- <message>Not a valid e-mail for text2.</message>
- </field-validator>
- </field>
-
- <field name="ratio">
- <field-validator type="int">
- <param name="min">20</param>
- <param name="max">50</param>
- <message>Ratio needs to be between ${min} and ${max}</message>
- </field-validator>
- </field>
-
- <!-- Plain Validator 1 -->
- <validator type="expression">
- <param name="expression">text.startsWith("poussin")</param>
- <message>Email not starts with poussin</message>
- </validator>
- <validator type="expression">
- <param name="expression">text2.startsWith("chemit")</param>
- <message>Email not starts with chemit</message>
- </validator>
-</validators>
\ No newline at end of file
Added: jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-warning-validation.xml
===================================================================
--- jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-warning-validation.xml (rev 0)
+++ jaxx/trunk/jaxx-example/src/main/resources/jaxx/demo/Model-warning-validation.xml 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,18 @@
+<!DOCTYPE validators PUBLIC
+ "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+ <!-- Field Validators for email field -->
+ <field name="text">
+ <field-validator type="email" short-circuit="true">
+ <message>Not a valid e-mail for text.</message>
+ </field-validator>
+ </field>
+
+ <field name="text2">
+ <field-validator type="requiredstring" short-circuit="true">
+ <message>You must enter a value for text2.</message>
+ </field-validator>
+ </field>
+
+</validators>
\ No newline at end of file
Modified: jaxx/trunk/jaxx-example/src/main/resources/log4j.properties
===================================================================
--- jaxx/trunk/jaxx-example/src/main/resources/log4j.properties 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-example/src/main/resources/log4j.properties 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,9 +1,9 @@
# Global logging configuration
-log4j.rootLogger=INFO, stdout
+log4j.rootLogger=ERROR, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) %M - %m%n
-#log4j.logger.org.codelutin.jaxx=DEBUG
log4j.logger.examples=DEBUG
+log4j.logger.jaxx=INFO
Modified: jaxx/trunk/jaxx-runtime-validator/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/changelog.txt 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator/changelog.txt 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,3 +1,6 @@
+1.3 ??? 200903??
+ * 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
* 20090202 [chemit] - rename Util to ValidationUtil
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-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/JAXXValidator.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,8 +1,8 @@
package jaxx.runtime;
-import jaxx.runtime.validator.BeanValidator;
import java.util.List;
+import jaxx.runtime.validator.BeanValidator2;
/**
* 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
*/
- BeanValidator<?> getValidator(String validatorId);
+ BeanValidator2<?> getValidator(String validatorId);
/** @return the list of ids of all registred validator */
List<String> getValidatorIds();
Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -12,6 +12,7 @@
import com.opensymphony.xwork2.validator.ValidationException;
import com.opensymphony.xwork2.validator.Validator;
import com.opensymphony.xwork2.validator.ValidatorScope;
+import java.beans.EventSetDescriptor;
import org.apache.commons.beanutils.ConversionException;
import org.apache.commons.beanutils.Converter;
import org.apache.commons.logging.Log;
@@ -22,7 +23,6 @@
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
-import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap;
@@ -31,7 +31,18 @@
import java.util.Map.Entry;
import java.util.TreeMap;
-/** @author chemit */
+/**
+ *
+ * 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
+ */
+@Deprecated
public class BeanValidator<B> {
/** la nom de la propriété bean */
@@ -90,7 +101,12 @@
protected transient ActionValidatorManager validator;
protected ActionContext context;
+ protected EventSetDescriptor beanEventDescriptor;
+
public BeanValidator(Class<B> beanClass, String contextName) {
+ // check that the bean is listenable, otherwise, can't use the validator on it
+ beanEventDescriptor = ValidationUtil.getPropertyChangeListenerDescriptor(beanClass);
+
this.beanClass = beanClass;
this.contextName = contextName;
pcs = new PropertyChangeSupport(this);
@@ -114,6 +130,7 @@
conversionErrors = new TreeMap<String, String>();
l = new PropertyChangeListener() {
+ @Override
public void propertyChange(PropertyChangeEvent evt) {
validate();
setValid(!hasErrors());
@@ -209,15 +226,17 @@
// clean conversions of previous bean
conversionErrors.clear();
- if (oldBean != null) {
+ if (oldBean != null) {
try {
- Method method = this.bean.getClass().getMethod("removePropertyChangeListener", PropertyChangeListener.class);
- method.invoke(oldBean, l);
+ beanEventDescriptor.getRemoveListenerMethod().invoke(oldBean, l);
+ //Method method = this.bean.getClass().getMethod("removePropertyChangeListener", PropertyChangeListener.class);
+ //method.invoke(oldBean, l);
} catch (Exception eee) {
- log.info("Can't register as listener", eee);
+ log.info("Can't register as listener for bean "+beanClass+" for reason "+eee.getMessage(), eee);
}
}
this.bean = bean;
+
if (bean == null) {
// must remove all errors from this validator on errorListModel
validationSupport.clearErrorsAndMessages();
@@ -226,10 +245,11 @@
dispatchErrorsToFields();
} else {
try {
- Method method = this.bean.getClass().getMethod("addPropertyChangeListener", PropertyChangeListener.class);
- method.invoke(bean, l);
+ beanEventDescriptor.getAddListenerMethod().invoke(bean, l);
+ //Method method = this.bean.getClass().getMethod("addPropertyChangeListener", PropertyChangeListener.class);
+ //method.invoke(bean, l);
} catch (Exception eee) {
- log.info("Can't register as listener", eee);
+ log.info("Can't register as listener for bean "+beanClass+" for reason "+eee.getMessage(), eee);
}
validate();
}
@@ -296,6 +316,7 @@
* <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
Added: 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 (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator2.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,458 @@
+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;
+ }
+}
Added: 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 (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorEvent.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,52 @@
+package jaxx.runtime.validator;
+
+/**
+ * The definition of an event on {@link BeanValidatorListener}
+ * to be fired by a {@link BeanValidator}.
+ *
+ * @author chemit
+ * @since 1.3
+ */
+public class BeanValidatorEvent extends java.util.EventObject {
+
+ private static final long serialVersionUID = 1L;
+ /** the field impacted by the validator */
+ BeanValidatorField<?> field;
+ /** the scope impacted by the event */
+ BeanValidatorScope scope;
+ String[] messagestoAdd;
+ String[] messagestoDelete;
+
+ public BeanValidatorEvent(BeanValidator2 source, BeanValidatorField<?> field, BeanValidatorScope scope, String[] toAdd, String[] toDelete) {
+ super(source);
+ this.field = field;
+ this.scope = scope;
+ this.messagestoAdd = toAdd;
+ this.messagestoDelete = toDelete;
+ }
+
+ @Override
+ public BeanValidator2 getSource() {
+ return (BeanValidator2) super.getSource();
+ }
+
+ public String getFieldName() {
+ return field.getName();
+ }
+
+ public String[] getMessagesToAdd() {
+ return messagestoAdd;
+ }
+
+ public String[] getMessagesToDelete() {
+ return messagestoDelete;
+ }
+
+ public BeanValidatorScope getScope() {
+ return scope;
+ }
+
+ public BeanValidatorField getField() {
+ return field;
+ }
+}
Added: 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 (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorField.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,239 @@
+package jaxx.runtime.validator;
+
+import static org.codelutin.i18n.I18n._;
+
+import javax.swing.event.EventListenerList;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * Definition of a field to be handled in a {@link BeanValidator}.
+ * <p/>
+ * A such class is only registred in {@link BeanValidator } when the field of the bean
+ * was found in validator xml configuration file for a {@link com.opensymphony.xwork2.validator.FieldValidator} only.
+ * <p/>
+ * This class use properties {@link #beanClass}, {@link #name} to define
+ * his naturel order.
+ *
+ * @author chemit
+ * @param <B> the type of the bean handled by the validator and this field of validation.
+ * @since 1.3
+ */
+public class BeanValidatorField<B> {
+
+ /** the class of bean */
+ protected final Class<B> beanClass;
+ /** name of field in bean */
+ protected final String name;
+ protected EnumMap<BeanValidatorScope, Set<String>> messages;
+ /** A list of event listeners for this validators */
+ protected EventListenerList listenerList = new EventListenerList();
+
+ public BeanValidatorField(Class<B> beanClass, String name, List<BeanValidatorScope> scopes) {
+ this.beanClass = beanClass;
+ this.name = name;
+ messages = new EnumMap<BeanValidatorScope, Set<String>>(BeanValidatorScope.class);
+ for (BeanValidatorScope scope : scopes) {
+ messages.put(scope, new HashSet<String>());
+ }
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Class<B> getBeanClass() {
+ return beanClass;
+ }
+
+ /**
+ * @return <code>true</code> if this field is valid (says is in error
+ * scope and has errors), <code>false</code> otherwise.
+ */
+ public boolean isValid() {
+ return !hasErrors();
+ }
+
+ public BeanValidatorScope getScope() {
+ if (hasErrors()) {
+ return BeanValidatorScope.ERROR;
+ }
+ if (hasWarnings()) {
+ return BeanValidatorScope.WARNING;
+ }
+ if (hasInfos()) {
+ return BeanValidatorScope.INFO;
+ }
+ return null;
+ }
+
+ public Set<BeanValidatorScope> getScopes() {
+ return messages.keySet();
+ }
+
+ public boolean hasErrors() {
+ return hasMessages(BeanValidatorScope.ERROR);
+ }
+
+ public boolean hasWarnings() {
+ return hasMessages(BeanValidatorScope.WARNING);
+ }
+
+ public boolean hasInfos() {
+ return hasMessages(BeanValidatorScope.INFO);
+ }
+
+ public Set<String> getErrors() {
+ return getMessages(BeanValidatorScope.ERROR);
+ }
+
+ public Set<String> getWarnings() {
+ return getMessages(BeanValidatorScope.WARNING);
+ }
+
+ public Set<String> getInfos() {
+ return getMessages(BeanValidatorScope.INFO);
+ }
+
+ public boolean hasMessages(BeanValidatorScope scope) {
+ return messages.containsKey(scope) && !getMessages(scope).isEmpty();
+ }
+
+ public Set<String> getMessages(BeanValidatorScope scope) {
+ return messages.get(scope);
+ }
+
+ public void updateMessages(BeanValidator2<B> validator, BeanValidatorScope scope, List<String> messages) {
+
+ if (scope == null) {
+
+ // special case to reset all messages from all scopes
+
+ for (BeanValidatorScope s : getScopes()) {
+
+ clearMessages(s, validator);
+ }
+ return;
+ }
+
+ if (!this.messages.containsKey(scope)) {
+ throw new IllegalArgumentException("the scope " + scope + " was not registred for " + this);
+ }
+
+ if (messages == null || messages.isEmpty()) {
+
+ // no incoming message for this scope
+
+ clearMessages(scope, validator);
+ return;
+ }
+
+ // build the diff of messages (the one to delete, the one to add)
+
+ boolean hasChanged = false;
+
+ Set<String> currentMessages = getMessages(scope);
+
+ // detect messages to delete
+ Set<String> toDelete = new java.util.HashSet<String>(currentMessages);
+ toDelete.removeAll(messages);
+
+ if (!toDelete.isEmpty()) {
+ // apply delete
+ currentMessages.removeAll(toDelete);
+ hasChanged = true;
+ }
+
+ // detect messages to add
+ Set<String> toAdd = new java.util.HashSet<String>(messages);
+ toAdd.removeAll(currentMessages);
+
+ if (!toAdd.isEmpty()) {
+ // apply add
+ currentMessages.addAll(toAdd);
+ hasChanged = true;
+ }
+
+ if (hasChanged) {
+
+ // something has changed, fire notifications
+ String[] del = toDelete.toArray(new String[toDelete.size()]);
+ String[] add = toAdd.toArray(new String[toAdd.size()]);
+
+ validator.fireFieldChanged(this, scope, add, del);
+ }
+ toAdd.clear();
+ toDelete.clear();
+
+ }
+
+ public String getI18nError(String error) {
+ String text;
+ if (error.indexOf("##") == -1) {
+ text = _(error);
+ } else {
+ StringTokenizer stk = new StringTokenizer(error, "##");
+ String errorName = stk.nextToken();
+ List<String> args = new ArrayList<String>();
+ while (stk.hasMoreTokens()) {
+ args.add(stk.nextToken());
+ }
+ text = _(errorName, args.toArray());
+ }
+ return text;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof BeanValidatorField)) {
+ return false;
+ }
+
+ BeanValidatorField that = (BeanValidatorField) o;
+ return beanClass.equals(that.beanClass) && name.equals(that.name);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = beanClass.hashCode();
+ result = 31 * result + name.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("<").append(super.toString());
+ sb.append(" beanClass:").append(beanClass);
+ sb.append(", name:").append(name);
+ sb.append(", scopes:").append(messages == null ? "[]" : messages.keySet());
+ sb.append(", scope:").append(getScope());
+ //sb.append(", errors:").append(errors);
+ sb.append('>');
+ return sb.toString();
+ }
+
+ protected void clearMessages(BeanValidatorScope scope, BeanValidator2<B> validator) {
+ // remove all messages
+ Set<String> toDelete = getMessages(scope);
+
+ if (!toDelete.isEmpty()) {
+
+ // there is some messages to delete
+ String[] toDel = toDelete.toArray(new String[toDelete.size()]);
+
+ // apply deletion
+ toDelete.clear();
+
+ // fire
+ validator.fireFieldChanged(this, scope, null, toDel);
+ }
+ }
+}
Added: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorListener.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorListener.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorListener.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,32 @@
+package jaxx.runtime.validator;
+
+/**
+ * The listener contract to be used on {@link BeanValidator]
+ *
+ * @author chemit
+ * @since 1.3
+ */
+public interface BeanValidatorListener extends java.util.EventListener {
+
+ /**
+ * Invoked when a validator detects some changes on a field.
+ *
+ * @param event the event
+ */
+ void onFieldChanged(BeanValidatorEvent event);
+
+ /**
+ * Invoked when a validator detects a new message on a field.
+ *
+ * @param event the event
+ */
+ //void onNewMessages(BeanValidatorEvent event);
+
+ /**
+ * Invoked when a validator detetcs that a previously message is
+ * no more exisitng.
+ *
+ * @param event the event
+ */
+ //void onResolvedMessages(BeanValidatorEvent event);
+}
Copied: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorScope.java (from rev 1250, jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorScope.java)
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorScope.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorScope.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,34 @@
+package jaxx.runtime.validator;
+
+/**
+ * The differents levels of messages in validation process.
+ * <p/>
+ * The order of the enum defines the severity of validation.
+ * <p/>
+ * Always begin with error, then if no error found, try warning, then info...
+ *
+ * @author chemit
+ */
+public enum BeanValidatorScope {
+ /**
+ * the error scope level.
+ *
+ * When a message of a such scope is found on a validator, then the validator
+ * is invalid and modified.
+ */
+ ERROR,
+ /**
+ * the warning scope level.
+ *
+ * When a message of a such scope is found on a validator, then the validator
+ * is still valid but modified.
+ */
+ WARNING,
+ /**
+ * the information scope level.
+ *
+ * When a message of a sucg scope is found on a validator, then the
+ * validator is still valid and not modified.
+ */
+ INFO
+}
Property changes on: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorScope.java
___________________________________________________________________
Name: svn:mergeinfo
+
Modified: 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-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidationUtil.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -6,6 +6,7 @@
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;
@@ -50,7 +51,7 @@
}
}
for (String validatorId : validatorIds) {
- BeanValidator beanValidator = jaxxValidator.getValidator(validatorId);
+ 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);
@@ -81,7 +82,7 @@
}
}
for (String validatorId : validatorIds) {
- BeanValidator beanValidator = jaxxValidator.getValidator(validatorId);
+ BeanValidator2 beanValidator = jaxxValidator.getValidator(validatorId);
beanValidator.setChanged(newValue);
}
}
@@ -120,4 +121,33 @@
// 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/main/java/jaxx/runtime/validator/ValidatorErrorEvent.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorEvent.java 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorEvent.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -10,6 +10,7 @@
*
* @author chemit
*/
+@Deprecated
public class ValidatorErrorEvent {
/** the source of the event */
Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorListener.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorListener.java 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorErrorListener.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -5,6 +5,7 @@
*
* @author chemit
*/
+@Deprecated
public interface ValidatorErrorListener extends java.util.EventListener {
/**
* Invoked when a validator detects a error on a field.
Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorField.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorField.java 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorField.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -23,6 +23,7 @@
* @author chemit
* @param <B> the type of the bean handled by the validator and this field of validation.
*/
+@Deprecated
public class ValidatorField<B> {
/** the class of bean */
Deleted: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorScope.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorScope.java 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ValidatorScope.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,16 +0,0 @@
-package jaxx.runtime.validator;
-
-/**
- * The differents levels of validation.
- * <p/>
- * The order of the enum defines the severity of validation.
- * <p/>
- * Always begin with error, then if no error found, try warning, ...
- *
- * @author chemit
- */
-public enum ValidatorScope {
- ERROR,
- WARNING,
- INFO
-}
Added: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/XWorkBeanValidator.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/XWorkBeanValidator.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/XWorkBeanValidator.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,230 @@
+package jaxx.runtime.validator;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ValidationAwareSupport;
+import com.opensymphony.xwork2.config.Configuration;
+import com.opensymphony.xwork2.config.ConfigurationManager;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
+import com.opensymphony.xwork2.validator.ActionValidatorManager;
+import com.opensymphony.xwork2.validator.DelegatingValidatorContext;
+import com.opensymphony.xwork2.validator.FieldValidator;
+import com.opensymphony.xwork2.validator.ValidationException;
+import com.opensymphony.xwork2.validator.Validator;
+import java.util.Collection;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * A customized validator for a given bean.
+ *
+ * Use the method {@link #validate(java.lang.Object)} to obtain the messages
+ * detected by the validator for the given bean.
+ *
+ * @param <B> type of the bean to validate.
+ *
+ * @author chemit
+ * @since 1.3
+ */
+public class XWorkBeanValidator<B> {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ private static final Log log = LogFactory.getLog(XWorkBeanValidator.class);
+ private final static Map<String, List<String>> EMPTY_RESULT = Collections.unmodifiableMap(new HashMap<String, List<String>>());
+ /** the type of bean to validate */
+ protected final Class<B> beanClass;
+ /** the validation named context (can be null) */
+ protected String contextName;
+ /** the list of field names detected for this validator */
+ protected Set<String> fieldNames;
+ /** a flag to include or not the default context validators */
+ protected boolean includeDefaultContext;
+ // --
+ // XWorks fields
+ // --
+ protected ValidationAwareSupport validationSupport;
+ protected DelegatingValidatorContext validationContext;
+ protected transient ActionValidatorManager validator;
+ protected ActionContext context;
+
+ public XWorkBeanValidator(Class<B> beanClass, String contextName) {
+ this(beanClass, contextName, true);
+ }
+
+ public XWorkBeanValidator(Class<B> beanClass, String contextName, boolean includeDefaultContext) {
+
+ this.beanClass = beanClass;
+ this.includeDefaultContext = includeDefaultContext;
+ validationSupport = new ValidationAwareSupport();
+ validationContext = new DelegatingValidatorContext(validationSupport);
+
+ // init context
+ ConfigurationManager confManager = new ConfigurationManager();
+ Configuration conf = confManager.getConfiguration();
+
+ ValueStack vs = conf.getContainer().getInstance(ValueStackFactory.class).createValueStack();
+ context = new ActionContext(vs.getContext());
+ ActionContext.setContext(context);
+
+ // init validator
+ validator = conf.getContainer().getInstance(ActionValidatorManager.class, "no-annotations");
+
+ // init context
+ setContextName(contextName);
+ }
+
+ public boolean isIncludeDefaultContext() {
+ return includeDefaultContext;
+ }
+
+ public Class<B> getBeanClass() {
+ return beanClass;
+ }
+
+ public String getContextName() {
+ return contextName;
+ }
+
+ public Set<String> getFieldNames() {
+ return fieldNames;
+ }
+
+ /**
+ * Test a the validator contains the field given his name
+ *
+ * @param fieldName the name of the searched field
+ * @return <code>true</code> if validator contaisn this field, <code>false</code> otherwise
+ */
+ public boolean containsField(String fieldName) {
+ return fieldNames.contains(fieldName);
+ }
+
+ public void setIncludeDefaultContext(boolean includeDefaultContext) {
+ this.includeDefaultContext = includeDefaultContext;
+ if (contextName != null) {
+ // reload context
+ setContextName(contextName);
+ }
+ }
+
+ public void setContextName(String contextName) {
+ this.contextName = contextName;
+ // changing contextName may change fields definition
+ // so reload fields
+ initFields();
+ }
+
+ /**
+ * Valide le bean donné et retourne les messages produits.
+ *
+ * @param bean le bean a valider (il doit etre non null)
+ *
+ * @return le dictionnaire des messages produits par la validation indexées
+ * par le nom du champs du bean impacté.
+ */
+ public Map<String, List<String>> validate(B bean) {
+
+ if (bean == null) {
+ throw new NullPointerException("bean can not be null in method validate");
+ }
+
+ Map<String, List<String>> result = EMPTY_RESULT;
+
+ // on lance la validation uniquement si des champs sont a valider
+ if (!fieldNames.isEmpty()) {
+
+ try {
+
+ //TC - 20081024 : since context is in a ThreadLocal variable, we must do the check
+ if (ActionContext.getContext() == null) {
+ ActionContext.setContext(context);
+ }
+
+ validator.validate(bean, contextName, validationContext);
+
+ if (log.isTraceEnabled()) {
+ log.trace("Action errors: " + validationContext.getActionErrors());
+ log.trace("Action messages: " + validationContext.getActionMessages());
+ log.trace("Field errors: " + validationContext.getFieldErrors());
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug(this + " : " + validationContext.getFieldErrors());
+ }
+
+ if (validationContext.hasFieldErrors()) {
+ Map messages = validationContext.getFieldErrors();
+ result = new HashMap<String, List<String>>(messages.size());
+ for (Object fieldName : messages.keySet()) {
+ Collection c = (Collection) messages.get(fieldName);
+ List<String> mm = new java.util.ArrayList<String>(c.size());
+ for (Object message : c) {
+ mm.add(message + "");
+ }
+ result.put(fieldName + "", mm);
+ }
+ }
+
+ } catch (ValidationException eee) {
+ log.warn("Error during validation on " + beanClass + " for reason : " + eee.getMessage(), eee);
+
+ } finally {
+ // on nettoye toujours le validateur apres operation
+ validationSupport.clearErrorsAndMessages();
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + "<beanClass:" + beanClass + ", contextName:" + contextName + ">";
+ }
+
+ /**
+ * update the property {@link #fieldNames}, says search in XWorks
+ */
+ protected synchronized void initFields() {
+
+ if (fieldNames != null) {
+ fieldNames = null;
+ }
+
+ Set<String> detectedFieldNames = new java.util.HashSet<String>();
+
+ int skip = 0;
+ if (contextName != null && !includeDefaultContext) {
+ // count the number of validator to skip
+ for (Validator v : validator.getValidators(beanClass, null)) {
+ // we only work on FieldValidator at the moment
+ if (v instanceof FieldValidator) {
+ skip++;
+ }
+ }
+ }
+
+ for (Validator v : validator.getValidators(beanClass, contextName)) {
+ // we only work on FieldValidator at the moment
+ if (v instanceof FieldValidator) {
+ if (skip > 0) {
+ skip--;
+ continue;
+ }
+ FieldValidator fieldValidator = (FieldValidator) v;
+ log.debug("context " + contextName + " - field " + fieldValidator.getFieldName());
+ String fName = fieldValidator.getFieldName();
+ detectedFieldNames.add(fName);
+ }
+ }
+
+ fieldNames = Collections.unmodifiableSet(detectedFieldNames);
+ }
+}
Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/CollectionFieldExpressionValidator.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/CollectionFieldExpressionValidator.java 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/CollectionFieldExpressionValidator.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -12,8 +12,8 @@
*/
public class CollectionFieldExpressionValidator extends FieldExpressionValidator {
-
public enum Mode {
+
/** au moins une entrée de la collection doit etre valide */
AT_LEAST_ONE,
/** exactement une entrée dela collection doit être valide */
@@ -23,7 +23,6 @@
/** aucune valeur de la collection doivent etre valides */
NONE
}
-
/** le mode de validation sur la liste */
protected Mode mode;
@@ -35,10 +34,6 @@
this.mode = mode;
}
- public void setMode(String mode) {
- this.mode = Mode.valueOf(mode);
- }
-
@Override
public void validate(Object object) throws ValidationException {
if (mode == null) {
@@ -188,5 +183,4 @@
public String getValidatorType() {
return "collectionFieldExpression";
}
-
}
Deleted: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/AbstractValidatorTest.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/AbstractValidatorTest.java 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/AbstractValidatorTest.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,44 +0,0 @@
-package jaxx.runtime.validator;
-
-import org.junit.Assert;
-import org.junit.BeforeClass;
-
-import java.io.File;
-
-/**
- * Abstract class of this module.
- *
- * @author chemit
- */
-public abstract class AbstractValidatorTest extends Assert {
-
- static protected BeanValidator<ValidatorBean> validator;
-
- static protected File basedir;
-
- protected ValidatorBean bean;
-
- @BeforeClass
- public static void initValidator() throws Exception {
-
- String b = System.getenv("basedir");
- if (b == null) {
- b = new File("").getAbsolutePath();
- }
- basedir = new File(b);
- validator = new BeanValidator<ValidatorBean>(ValidatorBean.class, null);
- }
-
- protected void assertFieldInError(String fieldName, String error, boolean required) {
- ValidatorField<ValidatorBean> field = validator.getField(fieldName);
-
- for (String o : field.getErrors()) {
- if (o.equals(error)) {
- assertTrue(required);
- return;
- }
- }
- // error was not found
- assertFalse(required);
- }
-}
\ No newline at end of file
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-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/BeanValidatorTest.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,33 +1,198 @@
package jaxx.runtime.validator;
+import java.util.List;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
/**
- * Une classe pour tester {@link BeanValidator}
*
- * @author chemit
+ * @author tony
*/
-public class BeanValidatorTest extends AbstractValidatorTest {
+public class BeanValidatorTest {
- //TODO do other tests :)
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static protected final Log log = LogFactory.getLog(BeanValidator2.class);
+ protected BeanValidator2<SimpleBean> validator;
+ protected SimpleBean bean;
+ BeanValidatorListenerImpl errorListener;
+ BeanValidatorListenerImpl warningListener;
+ BeanValidatorListenerImpl infoListener;
+ @Before
+ public void setUp() {
+ bean = new SimpleBean();
+ validator = new BeanValidator2<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));
+ }
+
+ @After
+ public void tearDown() {
+ bean = null;
+ if (validator != null) {
+ validator.setBean(null);
+ validator = null;
+ }
+ }
+ private static final String STRING_VALUE_ERROR = "stringValue.error";
+ private static final String STRING_VALUE_WARNING = "stringValue.warning";
+ private static final String INT_VALUE_ERROR = "intValue.error";
+ private static final String INT_VALUE_INFO = "intValue.info";
+
@Test
- public void testSetBean() {
- bean = new ValidatorBean();
+ public void testValidate() {
- assertNull(bean.getStringValue());
+ assertMessages(errorListener);
+ assertMessages(warningListener);
+ assertMessages(infoListener);
- // no bean on validator
- assertNull(validator.getBean());
- assertTrue(validator.isValid());
+ log.info("-----------------------------------------------");
+ validator.setBean(bean);
- // add bean to validator
+ assertMessages(errorListener, STRING_VALUE_ERROR, INT_VALUE_ERROR);
+ assertMessages(warningListener, STRING_VALUE_WARNING);
+ assertMessages(infoListener, INT_VALUE_INFO);
+
+ log.info("-----------------------------------------------");
+ bean.setStringValue("one");
+
+ assertMessages(errorListener, INT_VALUE_ERROR);
+ assertMessages(warningListener, STRING_VALUE_WARNING);
+ assertMessages(infoListener, INT_VALUE_INFO);
+
+ log.info("-----------------------------------------------");
+ bean.setStringValue("oneone");
+
+ assertMessages(errorListener, INT_VALUE_ERROR);
+ assertMessages(warningListener);
+ assertMessages(infoListener, INT_VALUE_INFO);
+
+ log.info("-----------------------------------------------");
+ bean.setIntValue(1);
+
+ assertMessages(errorListener);
+ assertMessages(warningListener);
+ assertMessages(infoListener, INT_VALUE_INFO);
+
+ log.info("-----------------------------------------------");
+ bean.setIntValue(10);
+
+ assertMessages(errorListener);
+ assertMessages(warningListener);
+ assertMessages(infoListener);
+
+ log.info("-----------------------------------------------");
+
+ bean.setStringValue(null);
+ bean.setIntValue(0);
+
+ assertMessages(errorListener, STRING_VALUE_ERROR, INT_VALUE_ERROR);
+ assertMessages(warningListener, STRING_VALUE_WARNING);
+ assertMessages(infoListener, INT_VALUE_INFO);
+
+
+ log.info("-----------------------------------------------");
+ }
+
+ @Test
+ public void testConvert() {
+
+
+ assertMessages(errorListener);
+ assertMessages(warningListener);
+ assertMessages(infoListener);
+
+ log.info("-----------------------------------------------");
+
validator.setBean(bean);
- assertFieldInError("stringValue", "stringValue.required", true);
- validator.setBean(null);
- // validator is valid, no more errors should be in validator
- assertTrue(validator.isValid());
+ assertMessages(errorListener, STRING_VALUE_ERROR, INT_VALUE_ERROR);
+ assertMessages(warningListener, STRING_VALUE_WARNING);
+ assertMessages(infoListener, INT_VALUE_INFO);
+
+
+ log.info("-----------------------------------------------");
+
+ Object value = validator.convert("intValue", "abc", Class.class);
+
+ Assert.assertNull(value);
+
+ assertMessages(errorListener, STRING_VALUE_ERROR, "error.convertor.class");
+ assertMessages(warningListener, STRING_VALUE_WARNING);
+ assertMessages(infoListener, INT_VALUE_INFO);
+
+ log.info("-----------------------------------------------");
+ bean.setStringValue("one");
+
+ assertMessages(errorListener, "error.convertor.class");
+ assertMessages(warningListener, STRING_VALUE_WARNING);
+ assertMessages(infoListener, INT_VALUE_INFO);
+
+ log.info("-----------------------------------------------");
+
+ value = validator.convert("intValue", "3", Integer.class);
+
+ bean.setIntValue((Integer) value);
+
+ assertMessages(errorListener);
+ assertMessages(warningListener, STRING_VALUE_WARNING);
+ assertMessages(infoListener, INT_VALUE_INFO);
+
+ log.info("-----------------------------------------------");
+
+ bean.setIntValue(-1);
+ assertMessages(errorListener, INT_VALUE_ERROR);
+ assertMessages(warningListener, STRING_VALUE_WARNING);
+ assertMessages(infoListener, INT_VALUE_INFO);
+
+ log.info("-----------------------------------------------");
}
-}
+ void assertMessages(BeanValidatorListenerImpl listener, String... expected) {
+ List<String> actual = listener.getMessages();
+ Assert.assertEquals(" shoudl have " + java.util.Arrays.toString(expected) + " but had " + actual, expected.length, actual.size());
+ for (String m : expected) {
+ Assert.assertEquals("could not find " + m + " in " + actual, true, actual.contains(m));
+ }
+ }
+
+ class BeanValidatorListenerImpl implements BeanValidatorListener {
+
+ final BeanValidatorScope scope;
+
+ public BeanValidatorListenerImpl(BeanValidatorScope scope) {
+ this.scope = scope;
+ }
+ java.util.List<String> messages = new java.util.ArrayList<String>();
+
+ public List<String> getMessages() {
+ return messages;
+ }
+
+ @Override
+ public void onFieldChanged(BeanValidatorEvent event) {
+ if (scope != event.getScope()) {
+ return;
+ }
+ String[] messagesToDelete = event.getMessagesToDelete();
+ if (messagesToDelete != null && messagesToDelete.length > 0) {
+ log.info(event.getScope() + " messages to delete : " + java.util.Arrays.toString(messagesToDelete));
+ for (String m : messagesToDelete) {
+ messages.remove(m);
+ }
+ }
+ String[] messagesToAdd = event.getMessagesToAdd();
+ if (messagesToAdd != null && messagesToAdd.length > 0) {
+ log.info(event.getScope() + " messages to add : " + java.util.Arrays.toString(messagesToAdd));
+ for (String m : messagesToAdd) {
+ messages.add(m);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/SimpleBean.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/SimpleBean.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/SimpleBean.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,51 @@
+package jaxx.runtime.validator;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+public class SimpleBean {
+
+ protected int intValue;
+ protected String stringValue;
+ final PropertyChangeSupport p;
+
+ public SimpleBean() {
+ p = new PropertyChangeSupport(this);
+ }
+
+ public int getIntValue() {
+ return intValue;
+ }
+
+ public String getStringValue() {
+ return stringValue;
+ }
+
+ public void setStringValue(String stringValue) {
+ String old = this.stringValue;
+ this.stringValue = stringValue;
+ p.firePropertyChange("stringValue", old, stringValue);
+ }
+
+ public void setIntValue(int intValue) {
+ int old = this.intValue;
+ this.intValue = intValue;
+ p.firePropertyChange("intValue", old, intValue);
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ p.addPropertyChangeListener(listener);
+ }
+
+ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ p.addPropertyChangeListener(propertyName, listener);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ p.removePropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ p.removePropertyChangeListener(propertyName, listener);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/XWorkBeanValidatorTest.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/XWorkBeanValidatorTest.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/XWorkBeanValidatorTest.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,156 @@
+package jaxx.runtime.validator;
+
+import java.util.List;
+import java.util.Map;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ *
+ * @author tony
+ * @since 1.3
+ */
+public class XWorkBeanValidatorTest {
+
+ protected XWorkBeanValidator<SimpleBean> validator;
+ protected SimpleBean bean;
+ protected Map<String, List<String>> messages;
+
+ @Before
+ public void setUp() {
+ bean = new SimpleBean();
+ validator = new XWorkBeanValidator<SimpleBean>(SimpleBean.class, "simple");
+ }
+
+ @After
+ public void tearDown() {
+ bean = null;
+ messages = null;
+ }
+
+ @Test
+ public void testUnknownField() {
+ Assert.assertEquals(false, validator.containsField("fake_" + System.nanoTime()));
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testValidateNPE() {
+ validator.validate(null);
+ }
+
+ @Test
+ public void testValidate() {
+
+
+ messages = validator.validate(bean);
+
+ assertFieldInError("stringValue", "stringValue.null", true, messages);
+ assertFieldInError("intValue", "intValue.null", true, messages);
+
+ bean.setStringValue("notnull");
+ messages = validator.validate(bean);
+
+ assertFieldInError("stringValue", "stringValue.null", false, messages);
+ assertFieldInError("intValue", "intValue.null", true, messages);
+
+ bean.setIntValue(1);
+ messages = validator.validate(bean);
+
+ assertFieldInError("stringValue", "stringValue.null", false, messages);
+ assertFieldInError("intValue", "intValue.null", false, messages);
+
+ }
+
+ @Test
+ public void testSetContextName() {
+
+
+ String expected = "simple";
+
+ Assert.assertEquals(expected, validator.getContextName());
+ Assert.assertEquals(true, validator.containsField("stringValue"));
+ Assert.assertEquals(true, validator.containsField("intValue"));
+
+ validator.setContextName(expected = "error");
+
+ Assert.assertEquals(expected, validator.getContextName());
+ Assert.assertEquals(true, validator.containsField("stringValue"));
+ Assert.assertEquals(true, validator.containsField("intValue"));
+
+ validator.setContextName(expected = "warning");
+
+ Assert.assertEquals(expected, validator.getContextName());
+ Assert.assertEquals(true, validator.containsField("stringValue"));
+ Assert.assertEquals(false, validator.containsField("intValue"));
+
+ validator.setContextName(expected = "info");
+
+ Assert.assertEquals(expected, validator.getContextName());
+ Assert.assertEquals(false, validator.containsField("stringValue"));
+ Assert.assertEquals(true, validator.containsField("intValue"));
+
+ validator.setContextName(expected = "fake_" + System.nanoTime());
+
+ Assert.assertEquals(expected, validator.getContextName());
+ Assert.assertEquals(false, validator.containsField("stringValue"));
+ Assert.assertEquals(false, validator.containsField("intValue"));
+
+ }
+
+ @Test
+ public void testSetIncludeDefaultContext() {
+
+ validator.setIncludeDefaultContext(false);
+
+ String expected = "simple";
+
+ Assert.assertEquals(expected, validator.getContextName());
+ Assert.assertEquals(true, validator.containsField("stringValue"));
+ Assert.assertEquals(true, validator.containsField("intValue"));
+
+ validator.setContextName(expected = "error");
+
+ Assert.assertEquals(expected, validator.getContextName());
+ Assert.assertEquals(true, validator.containsField("stringValue"));
+ Assert.assertEquals(true, validator.containsField("intValue"));
+
+ validator.setContextName(expected = "warning");
+
+ Assert.assertEquals(expected, validator.getContextName());
+ Assert.assertEquals(true, validator.containsField("stringValue"));
+ Assert.assertEquals(false, validator.containsField("intValue"));
+
+ validator.setContextName(expected = "info");
+
+ Assert.assertEquals(expected, validator.getContextName());
+ Assert.assertEquals(false, validator.containsField("stringValue"));
+ Assert.assertEquals(true, validator.containsField("intValue"));
+
+ validator.setContextName(expected = "fake_" + System.nanoTime());
+
+ Assert.assertEquals(expected, validator.getContextName());
+ Assert.assertEquals(false, validator.containsField("stringValue"));
+ Assert.assertEquals(false, validator.containsField("intValue"));
+
+ }
+
+ protected void assertFieldInError(String fieldName, String error, boolean required, Map<String, List<String>> messages) {
+
+ Assert.assertEquals(true, validator.containsField(fieldName));
+ List<String> fieldMessages = messages.get(fieldName);
+ //Assert.assertEquals(true,validator.containsField(fieldName));
+ if (fieldMessages != null) {
+ for (String o : fieldMessages) {
+ if (o.equals(error)) {
+ Assert.assertTrue(required);
+ return;
+ }
+ }
+ }
+
+ // error was not found
+ Assert.assertFalse(required);
+ }
+}
\ No newline at end of file
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-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractFieldValidatorTest.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,11 +1,15 @@
package jaxx.runtime.validator.field;
-import jaxx.runtime.validator.AbstractValidatorTest;
+import java.io.File;
+import jaxx.runtime.validator.BeanValidator;
import jaxx.runtime.validator.ValidatorBean;
+import jaxx.runtime.validator.ValidatorField;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
+import org.junit.Assert;
import org.junit.Before;
+import org.junit.BeforeClass;
/**
* Abstract class to test a specific validator.
@@ -15,10 +19,13 @@
*
* @author chemit
*/
-public abstract class AbstractFieldValidatorTest extends AbstractValidatorTest {
+public abstract class AbstractFieldValidatorTest extends Assert {
/** to use log facility, just put in your code: log.info(\"...\"); */
static private final Log log = LogFactory.getLog(AbstractFieldValidatorTest.class);
+ static protected BeanValidator<ValidatorBean> validator;
+ static protected File basedir;
+ protected ValidatorBean bean;
/**
* the moethod to implements testing the given validator on the given bean.
@@ -29,7 +36,7 @@
@Before
public void setUp() throws Exception {
- log.info("start test " + getClass().getSimpleName());
+ log.debug("start test " + getClass().getSimpleName());
validator.setBean(bean = new ValidatorBean());
}
@@ -38,4 +45,27 @@
validator.setBean(null);
}
+ @BeforeClass
+ public static void initValidator() throws Exception {
+
+ String b = System.getenv("basedir");
+ if (b == null) {
+ b = new File("").getAbsolutePath();
+ }
+ basedir = new File(b);
+ validator = new BeanValidator<ValidatorBean>(ValidatorBean.class, null);
+ }
+
+ protected void assertFieldInError(String fieldName, String error, boolean required) {
+ ValidatorField<ValidatorBean> field = validator.getField(fieldName);
+
+ for (String o : field.getErrors()) {
+ if (o.equals(error)) {
+ assertTrue(required);
+ return;
+ }
+ }
+ // error was not found
+ assertFalse(required);
+ }
}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/SimpleBean-error-validation.xml
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/SimpleBean-error-validation.xml (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/SimpleBean-error-validation.xml 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,19 @@
+<!DOCTYPE validators PUBLIC
+ "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+
+ <field name="stringValue">
+ <field-validator type="requiredstring">
+ <message>stringValue.error</message>
+ </field-validator>
+ </field>
+
+ <field name="intValue">
+ <field-validator type="int">
+ <param name="min">1</param>
+ <message>intValue.error</message>
+ </field-validator>
+ </field>
+
+</validators>
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/SimpleBean-info-validation.xml
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/SimpleBean-info-validation.xml (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/SimpleBean-info-validation.xml 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,13 @@
+<!DOCTYPE validators PUBLIC
+ "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+
+ <field name="intValue">
+ <field-validator type="int">
+ <param name="min">10</param>
+ <message>intValue.info</message>
+ </field-validator>
+ </field>
+
+</validators>
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/SimpleBean-simple-validation.xml
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/SimpleBean-simple-validation.xml (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/SimpleBean-simple-validation.xml 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,19 @@
+<!DOCTYPE validators PUBLIC
+ "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+
+ <field name="stringValue">
+ <field-validator type="requiredstring">
+ <message>stringValue.null</message>
+ </field-validator>
+ </field>
+
+ <field name="intValue">
+ <field-validator type="int">
+ <param name="min">1</param>
+ <message>intValue.null</message>
+ </field-validator>
+ </field>
+
+</validators>
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/SimpleBean-warning-validation.xml
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/SimpleBean-warning-validation.xml (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/SimpleBean-warning-validation.xml 2009-03-19 22:47:05 UTC (rev 1272)
@@ -0,0 +1,13 @@
+<!DOCTYPE validators PUBLIC
+ "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+
+ <field name="stringValue">
+ <field-validator type="fieldexpression">
+ <param name="expression"><![CDATA[ stringValue != null && stringValue.length() > 5]]></param>
+ <message>stringValue.warning</message>
+ </field-validator>
+ </field>
+
+</validators>
\ No newline at end of file
Modified: jaxx/trunk/jaxx-runtime-validator/src/test/resources/log4j.properties
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/resources/log4j.properties 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/resources/log4j.properties 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,5 +1,5 @@
# Global logging configuration
-log4j.rootLogger=INFO, stdout
+log4j.rootLogger=ERROR, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
Modified: jaxx/trunk/jaxx-runtime-validator-swing/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/changelog.txt 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator-swing/changelog.txt 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,2 +1,5 @@
+1.3 ??? 200903??
+ * 20090319 [chemit] - refactor Validator : now can deal with scopes, improve design
+
1.1 chemit 20090220
* 20090203 [chemit] - introduce this module specific to swing
\ 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-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidator.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,8 +1,6 @@
package jaxx.runtime.validator.swing;
-import jaxx.runtime.validator.BeanValidator;
-import jaxx.runtime.validator.ValidatorErrorListener;
-import jaxx.runtime.validator.ValidatorField;
+
import jaxx.runtime.validator.swing.ui.AbstractBeanValidatorUI;
import jaxx.runtime.validator.swing.ui.IconValidationUI;
import org.apache.commons.logging.Log;
@@ -14,12 +12,13 @@
import java.awt.Container;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import jaxx.runtime.validator.BeanValidator2;
+import jaxx.runtime.validator.BeanValidatorField;
+
/**
* La surcharge de {@link jaxx.runtime.validator.BeanValidator} pour les ui swing
* <p/>
@@ -92,14 +91,12 @@
* }
* </pre>
*
+ * @param <B> le type de bean a valider
* @author poussin
* @author chemit
- * @version 1.0
- * <p/>
- * Last update: $Date: 3 févr. 2009 $
- * By : $Author: chatellier $
+ * @version 1.0
*/
-public class SwingValidator<B> extends BeanValidator<B> {
+public class SwingValidator<B> extends BeanValidator2<B> {
/** to use log facility, just put in your code: log.info(\"...\"); */
static private final Log log = LogFactory.getLog(SwingValidator.class);
@@ -154,9 +151,8 @@
@Override
public void setContextName(String contextName) {
- Map<ValidatorField<B>, List<ValidatorErrorListener>> oldListeners = new HashMap<ValidatorField<B>, List<ValidatorErrorListener>>();
+ /*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>();
@@ -168,18 +164,18 @@
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()) {
+ /*for (Entry<ValidatorField<B>, List<ValidatorErrorListener>> entry : oldListeners.entrySet()) {
ValidatorField<B> field = getField(entry.getKey().getName());
for (ValidatorErrorListener listener : entry.getValue()) {
field.addValidatorErrorListener(listener);
}
}
- oldListeners.clear();
+ oldListeners.clear();*/
}
/**
@@ -190,7 +186,7 @@
* @param c the editor component for the field
*/
public void setFieldRepresentation(String fieldname, JComponent c) {
- ValidatorField<B> field = getField(fieldname);
+ BeanValidatorField<B> field = getField(fieldname);
if (field == null) {
// no field registred in the validator
log.warn("the field '" + fieldname + "' is not defined in validator (no rules on it)");
@@ -240,7 +236,7 @@
// same component, nothing to do
return;
}
- ValidatorField<B> field = getField(fieldname);
+ BeanValidatorField<B> field = getField(fieldname);
if (field == null) {
// this case should not appear since fieldName has already been check in method addFieldRepresentation
@@ -253,8 +249,10 @@
JXLayer<?> jx = (JXLayer<?>) container;
Object ui = jx.getUI();
if (ui != null && ui instanceof AbstractBeanValidatorUI) {
- field.removeValidatorErrorListener((AbstractBeanValidatorUI) ui);
+ removeBeanValidatorListener((AbstractBeanValidatorUI)ui);
+ //field.removeValidatorErrorListener((AbstractBeanValidatorUI) ui);
}
+
jx.setUI(null);
}
}
@@ -262,11 +260,12 @@
// ajout du jxlayer sous ce composant
Container container = c.getParent();
if (container instanceof JXLayer) {
- Constructor<? extends AbstractBeanValidatorUI> cons = uiClass.getConstructor(ValidatorField.class);
+ Constructor<? extends AbstractBeanValidatorUI> cons = uiClass.getConstructor(BeanValidatorField.class);
AbstractBeanValidatorUI ui = cons.newInstance(field);
ui.setEnabled(true);
JXLayer<JComponent> jx = (JXLayer<JComponent>) container;
- field.addValidatorErrorListener(ui);
+ addBeanValidatorListener(ui);
+ //field.addValidatorErrorListener(ui);
jx.setUI(ui);
}
}
Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListModel.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListModel.java 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorListModel.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,73 +1,151 @@
package jaxx.runtime.validator.swing;
-import jaxx.runtime.validator.BeanValidator;
-import jaxx.runtime.validator.ValidatorErrorEvent;
-import jaxx.runtime.validator.ValidatorErrorListener;
-import jaxx.runtime.validator.ValidatorField;
+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 java.util.Set;
+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
*
* @author chemit
*/
-public class SwingValidatorErrorListModel extends DefaultListModel implements ValidatorErrorListener {
+public class SwingValidatorErrorListModel extends DefaultListModel implements BeanValidatorListener {
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ private static Log log = LogFactory.getLog(SwingValidatorErrorListModel.class);
private static final long serialVersionUID = 1L;
-
/** list of registred validators */
- protected transient List<BeanValidator<?>> validators;
+ protected transient List<SwingValidator<?>> validators;
-
public SwingValidatorErrorListModel() {
- validators = new ArrayList<BeanValidator<?>>();
+ validators = new ArrayList<SwingValidator<?>>();
}
- public void registerValidator(BeanValidator<?> validator) {
+ 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);
// the model listen on each field of the validator
- for (ValidatorField<?> field : validator.getFields()) {
- field.addValidatorErrorListener(this);
- }
+ /*for (ValidatorField<?> field : validator.getFields()) {
+ field.addValidatorErrorListener(this);
+ }*/
}
-
- /**
- * Invoked when a validator detects a error on a field.
- *
- * @param event the event
- */
@Override
- public void onNewError(ValidatorErrorEvent event) {
- ValidatorField field = event.getField();
+ public void onFieldChanged(BeanValidatorEvent event) {
+ String[] toDelete = event.getMessagesToDelete();
+ String[] toAdd = event.getMessagesToAdd();
+ BeanValidatorScope scope = event.getScope();
SwingValidator validator = (SwingValidator) event.getSource();
- Set<String> errors = event.getErrors();
+ BeanValidatorField field = event.getField();
- // must remove all previously error for this field and validator
- List<SwingValidatorErrorModel> newErrors = new ArrayList<SwingValidatorErrorModel>();
- JComponent editor = validator.getFieldRepresentation(field.getName());
+ 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));
+ }
+
+ if ((toAdd == null || toAdd.length == 0) && (toDelete == null || toDelete.length == 0)) {
+ // no data to add nor remove, so nothing to do
+ return;
+ }
+
+ if (toAdd == null || toAdd.length == 0) {
+
+ if (log.isTraceEnabled()) {
+ log.trace(field + " - toDelete : just delete some datas!");
+ }
+
+ // no add, no need to resort the datas, can direclty delete
+ // messages we do not want any longer
+
+ // 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);
+
+ Enumeration enumeration = elements();
+ int index = 0;
+ while (enumeration.hasMoreElements()) {
+ SwingValidatorErrorModel error = (SwingValidatorErrorModel) enumeration.nextElement();
+
+ if (error.getValidator() == validator && error.getField() == field && ids.contains(error.getError())) {
+ indexs.add(index);
+ }
+ index++;
+ }
+
+ java.util.Collections.reverse(indexs);
+
+ for (Integer i : indexs) {
+ removeElementAt(i);
+ }
+
+ return;
+ }
+
+ if (log.isTraceEnabled()) {
+ log.trace(field + " - add and delete !");
+ }
+
+ List<SwingValidatorErrorModel> newMessages = new ArrayList<SwingValidatorErrorModel>();
+
+
+
+ // obtain all messages not to delete
+
+ List<String> ids = new java.util.ArrayList<String>(java.util.Arrays.asList(toDelete));
+
Enumeration enumeration = elements();
while (enumeration.hasMoreElements()) {
SwingValidatorErrorModel error = (SwingValidatorErrorModel) enumeration.nextElement();
- if (error.getValidator() == validator && error.getField() == field) {
- // this error can be skipped
- continue;
+
+ if (error.getValidator() != validator || error.getField() != field || !ids.contains(error.getError())) {
+ // keep this row
+ newMessages.add(error);
}
- newErrors.add(error);
}
+
+ if (toAdd != null && toAdd.length > 0) {
+ JComponent editor = validator.getFieldRepresentation(field.getName());
+ // add new messages
+ for (String error : toAdd) {
+ newMessages.add(new SwingValidatorErrorModel(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 (SwingValidatorErrorModel error : newMessages) {
+ addElement(error);
+ }
+
+ /*
+ List<SwingValidatorErrorModel> newErrors = new ArrayList<SwingValidatorErrorModel>();
+
+ JComponent editor = validator.getFieldRepresentation(field.getName());
// add new errors
- for (String error : errors) {
- newErrors.add(new SwingValidatorErrorModel(validator, field, error, editor));
+ for (String error : toAdd) {
+ newErrors.add(new SwingValidatorErrorModel(validator, field, error, editor));
}
+
+
java.util.Collections.sort(newErrors);
// clean model and reinject new errors
@@ -75,43 +153,79 @@
// reinject in list model, all the errors
for (SwingValidatorErrorModel error : newErrors) {
- addElement(error);
- }
- //FIXME, this is not performant, prefer use a isValueAdjusting property on SwingValidator
- // notify that the model has changed
+ addElement(error);
+ }*/
}
+ /**
+ * Invoked when a validator detects a error on a field.
+ *
+ * @param event the event
+ */
+ /*@Override
+ public void onNewError(ValidatorErrorEvent event) {
+ ValidatorField field = event.getField();
+ SwingValidator validator = (SwingValidator) event.getSource();
+ Set<String> errors = event.getErrors();
+ // must remove all previously error for this field and validator
+ List<SwingValidatorErrorModel> newErrors = new ArrayList<SwingValidatorErrorModel>();
+ JComponent editor = validator.getFieldRepresentation(field.getName());
+ Enumeration enumeration = elements();
+ while (enumeration.hasMoreElements()) {
+ SwingValidatorErrorModel error = (SwingValidatorErrorModel) enumeration.nextElement();
+ if (error.getValidator() == validator && error.getField() == field) {
+ // this error can be skipped
+ continue;
+ }
+ newErrors.add(error);
+ }
+ // add new errors
+ for (String error : errors) {
+ newErrors.add(new SwingValidatorErrorModel(validator, field, error, editor));
+ }
+ java.util.Collections.sort(newErrors);
+
+ // clean model and reinject new errors
+ removeAllElements();
+
+ // reinject in list model, all the errors
+ for (SwingValidatorErrorModel error : newErrors) {
+ addElement(error);
+ }
+ //FIXME, this is not performant, prefer use a isValueAdjusting property on SwingValidator
+ // notify that the model has changed
+ }*/
/**
* Invoked when a validator detetcs that a previously error is
* no more exisitng.
*
* @param event the event
*/
- @Override
+ /*@Override
public void onResolvedError(ValidatorErrorEvent event) {
- SwingValidator validator = (SwingValidator) event.getSource();
- ValidatorField field = event.getField();
- // must remove all previously error for this field
+ SwingValidator validator = (SwingValidator) event.getSource();
+ ValidatorField field = event.getField();
+ // must remove all previously error for this field
- boolean somethingChange = false;
- Enumeration enumeration = elements();
- List<SwingValidatorErrorModel> newList = new ArrayList<SwingValidatorErrorModel>();
- while (enumeration.hasMoreElements()) {
- SwingValidatorErrorModel error = (SwingValidatorErrorModel) enumeration.nextElement();
- if (error.getValidator() == validator && error.getField() == field) {
- // this error can be skipped
- somethingChange = true;
- } else {
- newList.add(error);
- }
- }
- // clean model and reinject new errors
- removeAllElements();
+ boolean somethingChange = false;
+ Enumeration enumeration = elements();
+ List<SwingValidatorErrorModel> newList = new ArrayList<SwingValidatorErrorModel>();
+ while (enumeration.hasMoreElements()) {
+ SwingValidatorErrorModel error = (SwingValidatorErrorModel) enumeration.nextElement();
+ if (error.getValidator() == validator && error.getField() == field) {
+ // this error can be skipped
+ somethingChange = true;
+ } else {
+ newList.add(error);
+ }
+ }
+ // clean model and reinject new errors
+ removeAllElements();
- if (somethingChange) {
- for (SwingValidatorErrorModel errorModel : newList) {
- addElement(errorModel);
- }
- }
+ if (somethingChange) {
+ for (SwingValidatorErrorModel errorModel : newList) {
+ addElement(errorModel);
}
-}
\ No newline at end of file
+ }
+ }*/
+}
Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorModel.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorModel.java 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorModel.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,17 +1,17 @@
package jaxx.runtime.validator.swing;
-import jaxx.runtime.validator.ValidatorField;
import javax.swing.JComponent;
+import jaxx.runtime.validator.BeanValidatorField;
/** @author chemit */
public class SwingValidatorErrorModel implements Comparable<SwingValidatorErrorModel> {
protected SwingValidator validator;
- protected ValidatorField field;
+ protected BeanValidatorField field;
protected String error;
protected JComponent editor;
- public SwingValidatorErrorModel(SwingValidator validator, ValidatorField field, String error, JComponent editor) {
+ public SwingValidatorErrorModel(SwingValidator validator, BeanValidatorField field, String error, JComponent editor) {
this.field = field;
this.validator = validator;
this.error = error;
@@ -26,7 +26,7 @@
return validator;
}
- public ValidatorField getField() {
+ public BeanValidatorField getField() {
return field;
}
Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableModel.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableModel.java 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableModel.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,32 +1,32 @@
package jaxx.runtime.validator.swing;
-import jaxx.runtime.validator.ValidatorErrorEvent;
-import jaxx.runtime.validator.ValidatorErrorListener;
-import jaxx.runtime.validator.ValidatorField;
+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.Iterator;
+import java.util.Enumeration;
import java.util.List;
-import java.util.Set;
import java.util.Vector;
+import jaxx.runtime.validator.BeanValidatorField;
+import jaxx.runtime.validator.BeanValidatorListener;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
* The model of the list of errors
*
* @author chemit
*/
-public class SwingValidatorErrorTableModel extends DefaultTableModel implements ValidatorErrorListener {
+public class SwingValidatorErrorTableModel extends DefaultTableModel implements BeanValidatorListener {
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ private static Log log = LogFactory.getLog(SwingValidatorErrorTableMouseListener.class);
private static final long serialVersionUID = 1L;
-
public static final String[] columnNames = {"validator.scope", "validator.field", "validator.message"};
-
/** list of registred validators */
protected transient List<SwingValidator<?>> validators;
-
/** comporator of errors */
protected transient Comparator<SwingValidatorErrorModel> comparator;
@@ -50,80 +50,109 @@
throw new IllegalArgumentException("the validator " + validator + " is already registred in " + this);
}
validators.add(validator);
- // the model listen on each field of the validator
- for (ValidatorField<?> field : validator.getFields()) {
- field.addValidatorErrorListener(this);
- }
+ validator.addBeanValidatorListener(this);
}
- /**
- * Invoked when a validator detects a error on a field.
- *
- * @param event the event
- */
@Override
- public void onNewError(ValidatorErrorEvent event) {
- ValidatorField field = event.getField();
+ public void onFieldChanged(BeanValidatorEvent event) {
+ String[] toDelete = event.getMessagesToDelete();
+ String[] toAdd = event.getMessagesToAdd();
+ BeanValidatorField field = event.getField();
+
+ 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));
+ }
+ 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();
- Set<String> errors = event.getErrors();
- // must remove all previously error for this field and validator
+
+
int errorColumn = getErrorColumn();
- List<SwingValidatorErrorModel> newErrors = new ArrayList<SwingValidatorErrorModel>();
- JComponent editor = validator.getFieldRepresentation(field.getName());
- for (Object o : getDataVector()) {
- Vector row = (Vector) o;
+ if (toAdd == null || toAdd.length == 0) {
+
+
+ if (log.isTraceEnabled()) {
+ log.trace(field + " - toDelete : just delete some datas!");
+ }
+
+ // no add, no need to resort the datas, can direclty delete
+ // messages we do not want any longer
+
+ // 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);
+
+ Enumeration enumeration = getDataVector().elements();
+
+ int index = 0;
+ while (enumeration.hasMoreElements()) {
+ Vector row = (Vector) enumeration.nextElement();
+ SwingValidatorErrorModel error = (SwingValidatorErrorModel) row.get(errorColumn);
+ if (error.getValidator() == validator && error.getField() == field && ids.contains(error.getError())) {
+ // remo the message
+ indexs.add(index);
+ }
+ index++;
+ }
+ java.util.Collections.reverse(indexs);
+
+ for (Integer i : indexs) {
+ removeRow(i);
+ }
+
+ return;
+ }
+
+ if (log.isTraceEnabled()) {
+ log.trace(field + " - add and delete !");
+ }
+
+ // rebuild all the data (since we are some adding data and we ensure
+ // an order on datas)
+
+ List<SwingValidatorErrorModel> newMessages = new ArrayList<SwingValidatorErrorModel>();
+
+ // delete some messages for the given field and given scope
+ List<String> ids = new java.util.ArrayList<String>(java.util.Arrays.asList(toDelete));
+
+ Enumeration enumeration = getDataVector().elements();
+
+ while (enumeration.hasMoreElements()) {
+ Vector row = (Vector) enumeration.nextElement();
SwingValidatorErrorModel error = (SwingValidatorErrorModel) row.get(errorColumn);
- if (error.getValidator() == validator && error.getField() == field) {
- // this error can be skipped
- continue;
+ if (error.getValidator() != validator || error.getField() != field || !ids.contains(error.getError())) {
+ // keep this row
+ newMessages.add(error);
}
- newErrors.add(error);
}
- // add new errors
- for (String error : errors) {
- newErrors.add(new SwingValidatorErrorModel(validator, field, error, editor));
+
+ if (toAdd != null && toAdd.length > 0) {
+ JComponent editor = validator.getFieldRepresentation(field.getName());
+ // add new errors
+ for (String error : toAdd) {
+ SwingValidatorErrorModel errorModel = new SwingValidatorErrorModel(validator, field, error, editor);
+ newMessages.add(errorModel);
+ }
}
- java.util.Collections.sort(newErrors);
- // clean table model and reinject new errors
+ // sort datas
+
+ java.util.Collections.sort(newMessages);
+
+ // clean table model and reinject new messages
getDataVector().clear();
+
// reinject in list model, all the errors
- for (SwingValidatorErrorModel error : newErrors) {
+ for (SwingValidatorErrorModel error : newMessages) {
addRow(new Object[]{error.getField().getScope(), error.getField().getName(), error});
}
- //FIXME, this is not performant, prefer use a isValueAdjusting property on SwingValidator
- // notify that the model has changed
+
fireTableDataChanged();
}
-
- /**
- * Invoked when a validator detetcs that a previously error is
- * no more exisitng.
- *
- * @param event the event
- */
- @Override
- public void onResolvedError(ValidatorErrorEvent event) {
- SwingValidator validator = (SwingValidator) event.getSource();
- ValidatorField field = event.getField();
- // must remove all previously error for this field
- int errorColumn = getErrorColumn();
- boolean somethingChange = false;
- for (Iterator it = getDataVector().iterator(); it.hasNext();) {
- Object o = it.next();
- Vector row = (Vector) o;
- SwingValidatorErrorModel error = (SwingValidatorErrorModel) row.get(errorColumn);
- if (error.getValidator() == validator && error.getField() == field) {
- // this error can be skipped
- it.remove();
- somethingChange = true;
- }
- }
- if (somethingChange) {
- // notify that the model has changed
- fireTableDataChanged();
- }
- }
-
}
\ No newline at end of file
Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableRenderer.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableRenderer.java 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorErrorTableRenderer.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,32 +1,35 @@
package jaxx.runtime.validator.swing;
-import com.opensymphony.xwork2.validator.ValidatorScope;
-
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.Component;
+import jaxx.runtime.validator.BeanValidatorScope;
/** @author chemit */
public class SwingValidatorErrorTableRenderer extends DefaultTableCellRenderer {
+ private static final long serialVersionUID = 1L;
ImageIcon errorIcon;
ImageIcon warningIcon;
+ ImageIcon infoIcon;
public SwingValidatorErrorTableRenderer() {
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 ValidatorScope) {
+ if (value instanceof BeanValidatorScope) {
- ValidatorScope scope = (ValidatorScope) value;
+ BeanValidatorScope scope = (BeanValidatorScope) value;
switch (scope) {
case ERROR:
icon = errorIcon;
@@ -34,6 +37,9 @@
case WARNING:
icon = warningIcon;
break;
+ case INFO:
+ icon = infoIcon;
+ break;
}
} else if (value instanceof SwingValidatorErrorModel) {
SwingValidatorErrorModel model = (SwingValidatorErrorModel) value;
Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/ui/AbstractBeanValidatorUI.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/ui/AbstractBeanValidatorUI.java 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/ui/AbstractBeanValidatorUI.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,8 +1,8 @@
package jaxx.runtime.validator.swing.ui;
-import jaxx.runtime.validator.ValidatorErrorEvent;
-import jaxx.runtime.validator.ValidatorErrorListener;
-import jaxx.runtime.validator.ValidatorField;
+import jaxx.runtime.validator.BeanValidatorEvent;
+import jaxx.runtime.validator.BeanValidatorField;
+import jaxx.runtime.validator.BeanValidatorListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdesktop.jxlayer.plaf.AbstractLayerUI;
@@ -12,15 +12,14 @@
*
* @author chemit
*/
-public abstract class AbstractBeanValidatorUI extends AbstractLayerUI<javax.swing.JComponent> implements ValidatorErrorListener {
+public abstract class AbstractBeanValidatorUI extends AbstractLayerUI<javax.swing.JComponent> implements BeanValidatorListener {
/** to use log facility, just put in your code: log.info(\"...\"); */
private static final Log log = LogFactory.getLog(AbstractBeanValidatorUI.class);
-
/** the field to render */
- protected ValidatorField field;
+ protected BeanValidatorField field;
- public AbstractBeanValidatorUI(ValidatorField field) {
+ public AbstractBeanValidatorUI(BeanValidatorField field) {
this.field = field;
if (log.isDebugEnabled()) {
log.debug("install " + this + "<field:" + field + ">");
@@ -28,22 +27,11 @@
}
@Override
- public void onNewError(ValidatorErrorEvent event) {
- dispatchValidatorErrorEvent(event);
- }
-
- @Override
- public void onResolvedError(ValidatorErrorEvent event) {
- dispatchValidatorErrorEvent(event);
- }
-
- protected void dispatchValidatorErrorEvent(ValidatorErrorEvent event) {
- // check if event occurs to this field
- if (!field.equals(event.getField())) {
- return;
+ public void onFieldChanged(BeanValidatorEvent event) {
+ if (field.equals(event.getField())) {
+ // ask to repaint the layer
+ setDirty(true);
}
- // repaint the layer
- setDirty(true);
}
}
Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/ui/IconValidationUI.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/ui/IconValidationUI.java 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/ui/IconValidationUI.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,6 +1,5 @@
package jaxx.runtime.validator.swing.ui;
-import jaxx.runtime.validator.ValidatorField;
import org.jdesktop.jxlayer.JXLayer;
import javax.swing.BorderFactory;
@@ -9,6 +8,8 @@
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
+import jaxx.runtime.validator.BeanValidatorField;
+import jaxx.runtime.validator.BeanValidatorScope;
/** @author chemit */
public class IconValidationUI extends AbstractBeanValidatorUI {
@@ -16,9 +17,19 @@
// The icon to be shown at the layer's corner
protected static BufferedImage errorIcon;
protected static BufferedImage warningIcon;
+ protected static BufferedImage infoIcon;
- public IconValidationUI(ValidatorField field) {
+ public IconValidationUI(BeanValidatorField field) {
super(field);
+ if (errorIcon == null) {
+ errorIcon = prepareIcon(Color.RED);
+ }
+ if (warningIcon == null) {
+ warningIcon = prepareIcon(Color.ORANGE);
+ }
+ if (infoIcon == null) {
+ infoIcon = prepareIcon(Color.GREEN);
+ }
}
@Override
@@ -37,34 +48,26 @@
protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) {
super.paintLayer(g2, l);
// There is no need to take insets into account for this painter
- switch (field.getScope()) {
- case ERROR:
- if (field.hasErrors()) {
- g2.drawImage(getErrorIcon(), l.getWidth() - errorIcon.getWidth() - 1, 0, null);
- }
- break;
- case WARNING:
- if (field.hasWarnings()) {
- g2.drawImage(getWarningIcon(), l.getWidth() - warningIcon.getWidth() - 1, 0, null);
- }
- break;
+ BeanValidatorScope scope = field.getScope();
+ if (scope != null) {
+ BufferedImage icon = null;
+ switch (scope) {
+ case ERROR:
+ icon = errorIcon;
+ break;
+ case WARNING:
+ icon = warningIcon;
+ break;
+ case INFO:
+ icon = infoIcon;
+ break;
+ }
+ if (icon != null) {
+ g2.drawImage(icon, l.getWidth() - icon.getWidth() - 1, 0, null);
+ }
}
}
- protected static BufferedImage getErrorIcon() {
- if (errorIcon == null) {
- errorIcon = prepareIcon(Color.RED);
- }
- return errorIcon;
- }
-
- protected static BufferedImage getWarningIcon() {
- if (warningIcon == null) {
- warningIcon = prepareIcon(Color.YELLOW);
- }
- return warningIcon;
- }
-
protected static BufferedImage prepareIcon(Color color) {
int width = 7;
int height = 8;
Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/ui/ImageValidationUI.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/ui/ImageValidationUI.java 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/ui/ImageValidationUI.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,6 +1,5 @@
package jaxx.runtime.validator.swing.ui;
-import jaxx.runtime.validator.ValidatorField;
import org.jdesktop.jxlayer.JXLayer;
import javax.swing.BorderFactory;
@@ -9,15 +8,27 @@
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
+import jaxx.runtime.validator.BeanValidatorField;
+import jaxx.runtime.validator.BeanValidatorScope;
/** @author chemit */
public class ImageValidationUI extends AbstractBeanValidatorUI {
protected static BufferedImage errorIcon;
protected static BufferedImage warningIcon;
+ protected static BufferedImage infoIcon;
- public ImageValidationUI(ValidatorField field) {
+ public ImageValidationUI(BeanValidatorField field) {
super(field);
+ if (errorIcon == null) {
+ errorIcon = prepareIcon(jaxx.runtime.Util.createImageIcon("error.png"));
+ }
+ if (warningIcon == null) {
+ warningIcon = prepareIcon(jaxx.runtime.Util.createImageIcon("warning.png"));
+ }
+ if (infoIcon == null) {
+ infoIcon = prepareIcon(jaxx.runtime.Util.createImageIcon("info.png"));
+ }
}
protected static BufferedImage prepareIcon(ImageIcon image) {
@@ -45,31 +56,23 @@
@Override
protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) {
super.paintLayer(g2, l);
- switch (field.getScope()) {
- case ERROR:
- if (field.hasErrors()) {
- g2.drawImage(getErrorIcon(), l.getWidth() - errorIcon.getWidth() - 1, 0, null);
- }
- break;
- case WARNING:
- if (field.hasWarnings()) {
- g2.drawImage(getWarningIcon(), l.getWidth() - warningIcon.getWidth() - 1, 0, null);
- }
- break;
+ BeanValidatorScope scope = field.getScope();
+ if (scope != null) {
+ BufferedImage icon = null;
+ switch (scope) {
+ case ERROR:
+ icon = errorIcon;
+ break;
+ case WARNING:
+ icon = warningIcon;
+ break;
+ case INFO:
+ icon = infoIcon;
+ break;
+ }
+ if (icon != null) {
+ g2.drawImage(icon, l.getWidth() - icon.getWidth() - 1, 0, null);
+ }
}
}
-
- protected static BufferedImage getErrorIcon() {
- if (errorIcon == null) {
- errorIcon = prepareIcon(jaxx.runtime.Util.createImageIcon("error.png"));
- }
- return errorIcon;
- }
-
- protected static BufferedImage getWarningIcon() {
- if (warningIcon == null) {
- warningIcon = prepareIcon(jaxx.runtime.Util.createImageIcon("warning.png"));
- }
- return warningIcon;
- }
}
\ No newline at end of file
Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/ui/TranslucentValidationUI.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/ui/TranslucentValidationUI.java 2009-03-18 18:17:16 UTC (rev 1271)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/ui/TranslucentValidationUI.java 2009-03-19 22:47:05 UTC (rev 1272)
@@ -1,6 +1,6 @@
package jaxx.runtime.validator.swing.ui;
-import jaxx.runtime.validator.ValidatorField;
+import jaxx.runtime.validator.BeanValidatorScope;
import org.jdesktop.jxlayer.JXLayer;
import javax.swing.JComponent;
@@ -9,17 +9,20 @@
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
+import jaxx.runtime.validator.BeanValidatorField;
/** @author chemit */
public class TranslucentValidationUI extends AbstractBeanValidatorUI {
protected Color errorHightlight;
protected Color warningHightlight;
+ protected Color infoHightlight;
- public TranslucentValidationUI(ValidatorField field) {
+ public TranslucentValidationUI(BeanValidatorField field) {
super(field);
errorHightlight = Color.RED;
warningHightlight = Color.YELLOW;
+ infoHightlight = Color.GREEN;
}
@Override
@@ -38,23 +41,24 @@
view.getWidth() - insets.left - insets.right,
view.getHeight() - insets.top - insets.bottom));
- switch (field.getScope()) {
+ BeanValidatorScope scope = field.getScope();
- case ERROR:
- if (field.hasErrors()) {
+ if (scope == null) {
+ g2.setColor(Color.WHITE);
+ } else {
+ switch (scope) {
+ case ERROR:
g2.setColor(errorHightlight);
- } else {
- g2.setColor(Color.WHITE);
- }
- break;
- case WARNING:
- if (field.hasErrors()) {
+ break;
+ case WARNING:
g2.setColor(warningHightlight);
- } else {
- g2.setColor(Color.WHITE);
- }
- break;
+ break;
+ case INFO:
+ g2.setColor(infoHightlight);
+ break;
+ }
}
+
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .2f));
g2.fillRect(0, 0, l.getWidth(), l.getHeight());
}
Added: jaxx/trunk/jaxx-runtime-validator-swing/src/main/resources/icons/info.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-validator-swing/src/main/resources/icons/info.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
1
0
r1271 - in jaxx/trunk: jaxx-example/src/main/java/jaxx/demo jaxx-runtime-swing jaxx-runtime-swing/src/main/java/jaxx/runtime/swing
by tchemit@users.labs.libre-entreprise.org 18 Mar '09
by tchemit@users.labs.libre-entreprise.org 18 Mar '09
18 Mar '09
Author: tchemit
Date: 2009-03-18 18:17:16 +0000 (Wed, 18 Mar 2009)
New Revision: 1271
Added:
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/BlockingLayerUI2.java
Modified:
jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/BoxedDecoratorDemo.jaxx
jaxx/trunk/jaxx-runtime-swing/changelog.txt
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/BlockingLayerUI.java
Log:
introduce BlockingLayerUI2
Modified: jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/BoxedDecoratorDemo.jaxx
===================================================================
--- jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/BoxedDecoratorDemo.jaxx 2009-03-18 08:46:51 UTC (rev 1270)
+++ jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/BoxedDecoratorDemo.jaxx 2009-03-18 18:17:16 UTC (rev 1271)
@@ -11,22 +11,38 @@
accept(e, "from icon of layer");
}
}}' />
+ <jaxx.runtime.swing.BlockingLayerUI2 id='layerUI2'
+ blockIcon='{SwingUtil.createImageIcon("action-block.png")}'
+ acceptIcon='{SwingUtil.createImageIcon("action-accept.png")}'
+ acceptAction='{new AbstractAction() { private static final long serialVersionUID = 1L;
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ accept(e, "from icon of layer");
+ }
+ }}' />
<script><![CDATA[
import jaxx.runtime.SwingUtil;
void $afterCompleteSetup() {
for (JComponent boxed : SwingUtil.getLayeredComponents(this)) {
+ if (boxed == d) {
+ SwingUtil.getLayer(boxed).setUI(layerUI2);
+ continue;
+ }
+
jaxx.runtime.swing.BlockingLayerUI ui = layerUI.clone();
if ( boxed == c) {
ui.setBlock(true);
}
SwingUtil.getLayer(boxed).setUI(ui);
- //ui.setDirty(true);
}
}
public void setLayer(boolean active) {
for (JComponent boxed : SwingUtil.getLayeredComponents(this)) {
+ if (boxed == d) {
+ continue;
+ }
jaxx.runtime.swing.BlockingLayerUI ui = (jaxx.runtime.swing.BlockingLayerUI)SwingUtil.getLayer(boxed).getUI();
if ( boxed == c) {
ui.setBlock(active);
@@ -59,6 +75,8 @@
onActionPerformed='accept(event, "from button (no layer)")'/>
<JButton id='c' text='button C (full block)' decorator='boxed' _clickedText='"button C was clicked"'
onActionPerformed='accept(event, "from button (no layer)");'/>
+ <JButton id='d' text='button D (full block 2)' decorator='boxed' _clickedText='"button D was clicked"'
+ onActionPerformed='accept(event, "from button (no layer)");'/>
</JPanel>
</cell>
</row>
Modified: jaxx/trunk/jaxx-runtime-swing/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/changelog.txt 2009-03-18 08:46:51 UTC (rev 1270)
+++ jaxx/trunk/jaxx-runtime-swing/changelog.txt 2009-03-18 18:17:16 UTC (rev 1271)
@@ -1,4 +1,5 @@
1.3 ?? 200903??
+ * 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)
* 20090309 [chemit] - in BlockingLayerUI, add a new state 'block' to enable/disable blocking mode with a blockingColor
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/BlockingLayerUI.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/BlockingLayerUI.java 2009-03-18 08:46:51 UTC (rev 1270)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/BlockingLayerUI.java 2009-03-18 18:17:16 UTC (rev 1271)
@@ -4,9 +4,7 @@
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics2D;
-import java.awt.Insets;
import java.awt.Point;
-import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/BlockingLayerUI2.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/BlockingLayerUI2.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/BlockingLayerUI2.java 2009-03-18 18:17:16 UTC (rev 1271)
@@ -0,0 +1,206 @@
+package jaxx.runtime.swing;
+
+import java.awt.Component;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.RenderingHints;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.image.BufferedImage;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import javax.swing.JComponent;
+import org.jdesktop.jxlayer.JXLayer;
+
+/**
+ *
+ * A JXLayer ui implementation that permits to block a component but still
+ * allow an action when clicking everywhere on the layer.
+ *
+ * Moreover, an icon can be added on the right-top icon painted and changed
+ * when the mouse is over the layer.
+ *
+ * You can change the blocking and accepting icon.
+ *
+ * To hook an click on the layer's icon, you can :
+ *
+ * <ul><li>pass an Action via method {@link #setAcceptAction(Action)}</li>
+ * <li>override the method {@link #acceptEvent(java.awt.event.MouseEvent, org.jdesktop.jxlayer.JXLayer)}</li>
+ * </ul>
+ *
+ * @author tony
+ * @since 1.3
+ */
+public class BlockingLayerUI2 extends org.jdesktop.jxlayer.plaf.AbstractLayerUI<JComponent> {
+
+ public static final String CAN_CLICK_PROPERTY = "canClick";
+ public static final String ACCEPT_ICON_PROPERTY = "acceptIcon";
+ public static final String BLOCK_ICON_PROPERTY = "blockIcon";
+ private static final long serialVersionUID = 1L;
+ /**
+ * Action to be treated when click on icon
+ */
+ protected Action acceptAction;
+ /**
+ * Icon when you can not click
+ */
+ protected BufferedImage blockIcon;
+ /**
+ * Icon when you can click
+ */
+ protected BufferedImage acceptIcon;
+ /**
+ * Internal state to known when we can accept click
+ */
+ protected boolean canClick;
+
+ public void setAcceptAction(Action acceptAction) {
+ this.acceptAction = acceptAction;
+ }
+
+ public void setAcceptIcon(ImageIcon acceptIcon) {
+ this.acceptIcon = prepareIcon(acceptIcon);
+ firePropertyChange(ACCEPT_ICON_PROPERTY, null, acceptIcon);
+ setDirty(true);
+ }
+
+ public void setBlockIcon(ImageIcon blockIcon) {
+ this.blockIcon = prepareIcon(blockIcon);
+ firePropertyChange(BLOCK_ICON_PROPERTY, null, blockIcon);
+ setDirty(true);
+ }
+
+ public void setCanClick(boolean canClick) {
+ boolean oldvalue = this.canClick;
+ this.canClick = canClick;
+ firePropertyChange(CAN_CLICK_PROPERTY, oldvalue, canClick);
+ if (oldvalue != canClick) {
+ setDirty(true);
+ }
+ }
+
+ @Override
+ public void setDirty(boolean isDirty) {
+ super.setDirty(isDirty);
+ }
+
+ public void setBlockIcon(BufferedImage blockIcon) {
+ this.blockIcon = blockIcon;
+ }
+
+ public BufferedImage getBlockIcon() {
+ return blockIcon;
+ }
+
+ protected BufferedImage getAcceptIcon() {
+ return acceptIcon;
+ }
+
+ public boolean isCanClick() {
+ return canClick;
+ }
+
+ @Override
+ public BlockingLayerUI2 clone() {
+ BlockingLayerUI2 clone = new BlockingLayerUI2();
+ clone.acceptAction = acceptAction;
+ clone.acceptIcon = acceptIcon;
+ clone.blockIcon = blockIcon;
+ clone.setCanClick(false);
+ return clone;
+ }
+
+ @Override
+ protected void processKeyEvent(KeyEvent e, JXLayer<JComponent> l) {
+
+ e.consume();
+
+ }
+
+ @Override
+ protected void processMouseMotionEvent(MouseEvent e, JXLayer<JComponent> l) {
+
+ e.consume();
+
+ }
+
+ @Override
+ protected void processMouseEvent(MouseEvent e, JXLayer<JComponent> l) {
+ switch (e.getID()) {
+ case MouseEvent.MOUSE_ENTERED:
+ setCanClick(true);
+ break;
+ case MouseEvent.MOUSE_EXITED:
+ setCanClick(false);
+ break;
+ case MouseEvent.MOUSE_CLICKED:
+ if (canClick) {
+ acceptEvent(e, l);
+ }
+ break;
+ }
+ e.consume();
+ }
+
+ @Override
+ protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) {
+ super.paintLayer(g2, l);
+
+ // to be in sync with the view if the layer has a border
+ /*Insets layerInsets = l.getInsets();
+ g2.translate(layerInsets.left, layerInsets.top);
+
+ JComponent view = l.getView();
+ // To prevent painting on view's border
+ Insets insets = view.getInsets();
+ g2.clip(new Rectangle(insets.left, insets.top,
+ view.getWidth() - insets.left - insets.right,
+ view.getHeight() - insets.top - insets.bottom));
+ */
+
+ if (getCurrentIcon() != null) {
+ g2.drawImage(getCurrentIcon(), l.getWidth() - getCurrentIcon().getWidth() - 1, 0, null);
+ }
+ }
+
+ protected void acceptEvent(MouseEvent e, JXLayer<JComponent> l) {
+ if (acceptAction != null) {
+ acceptAction.putValue("layer", l);
+ Component source = l.getView();
+ acceptAction.actionPerformed(new ActionEvent(source, 0, "accept"));
+ }
+ }
+
+ protected BufferedImage getCurrentIcon() {
+ return canClick ? acceptIcon : blockIcon;
+ }
+
+ protected BufferedImage prepareIcon(ImageIcon image) {
+ BufferedImage icon = new BufferedImage(image.getIconWidth(), image.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g2 = (Graphics2D) icon.getGraphics();
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
+ g2.drawImage(image.getImage(), 0, 0, null);
+ g2.dispose();
+ return icon;
+ }
+
+ protected void updateCanClickState(JXLayer<JComponent> l, MouseEvent e) {
+ // udpate toolTipText
+ Point layerLocation = l.getView().getLocation();
+ Point mousePoint = e.getPoint();
+ BufferedImage currentIcon = getCurrentIcon();
+ if (currentIcon == null) {
+ setCanClick(false);
+ return;
+ }
+ int minX = (int) layerLocation.getX() + l.getWidth() - currentIcon.getWidth();
+ int maxX = (int) layerLocation.getX() + l.getWidth();
+ int minY = 0;
+ int maxY = currentIcon.getHeight();
+ boolean accept = minX <= mousePoint.getX() && mousePoint.getX() <= maxX;
+ accept &= minY <= mousePoint.getLocation().getY() && mousePoint.getLocation().getY() <= maxY;
+ setCanClick(accept);
+ }
+}
1
0
18 Mar '09
Author: tchemit
Date: 2009-03-18 08:46:51 +0000 (Wed, 18 Mar 2009)
New Revision: 1270
Modified:
jaxx/trunk/jaxx-runtime-swing/changelog.txt
Log:
introduce CardLayout2Ext + improve wizard framework
Modified: jaxx/trunk/jaxx-runtime-swing/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/changelog.txt 2009-03-18 08:45:58 UTC (rev 1269)
+++ jaxx/trunk/jaxx-runtime-swing/changelog.txt 2009-03-18 08:46:51 UTC (rev 1270)
@@ -1,4 +1,5 @@
1.3 ?? 200903??
+ * 20090318 [chemit] - introduce the CardLayout2Ext class
* 20090312 [chemit] - add some usefull code from ObServe (load Nimbus L&F, load ui configuration)
* 20090309 [chemit] - in BlockingLayerUI, add a new state 'block' to enable/disable blocking mode with a blockingColor
* 20090303 [chemit] - in BlockingLayerUI, add a new state 'useIcon' to enable/disable use of the action icon
1
0
r1269 - in jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing: . wizard
by tchemit@users.labs.libre-entreprise.org 18 Mar '09
by tchemit@users.labs.libre-entreprise.org 18 Mar '09
18 Mar '09
Author: tchemit
Date: 2009-03-18 08:45:58 +0000 (Wed, 18 Mar 2009)
New Revision: 1269
Added:
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/CardLayout2Ext.java
Modified:
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java
Log:
introduce CardLayout2Ext + improve wizard framework
Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/CardLayout2Ext.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/CardLayout2Ext.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/CardLayout2Ext.java 2009-03-18 08:45:58 UTC (rev 1269)
@@ -0,0 +1,99 @@
+package jaxx.runtime.swing;
+
+import java.awt.Container;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import jaxx.runtime.JAXXObject;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Une extension de {@link CardLayout2} pour pouvoir automatiquement afficher un
+ * contenu à partir de la propriété {@link #selected}.
+ *
+ * Ainsi, en changeant cette propriété via la méthode {@link #setSelected(String)},
+ * le contenu sera changé automatiquement, ce qui permet une utilisation direct
+ * dans jaxx sans à avoir à écrire d'écouteur.
+ *
+ * @author tony
+ * @since 1.3
+ * @see CardLayout2
+ */
+public class CardLayout2Ext extends CardLayout2 {
+
+ /** log */
+ static private Log log = LogFactory.getLog(CardLayout2.class);
+ private static final long serialVersionUID = 1L;
+ public static final String SELECTED_PROPERTY_NAME = "selected";
+ /**
+ * pour propager les changements dans le modèle vers l'ui
+ */
+ protected PropertyChangeSupport pcs;
+ /**
+ * le contenu sélectionné
+ */
+ protected String selected;
+ private String containerName;
+ private JAXXObject ui;
+ private Container container;
+
+ public CardLayout2Ext(JAXXObject ui, String containerName) {
+ pcs = new PropertyChangeSupport(this);
+ this.ui = ui;
+ this.containerName = containerName;
+ }
+
+ public String getSelected() {
+ return selected;
+ }
+
+ public String getPreviousSelected() {
+ int index = contexts.indexOf(selected);
+ if (index < 1) {
+ return null;
+ }
+ return contexts.get(index - 1) + "";
+ }
+
+ public String getNextSelected() {
+ int index = contexts.indexOf(selected);
+ if (index >= contexts.size()) {
+ return null;
+ }
+ return contexts.get(index + 1) + "";
+ }
+
+ public void setSelected(String selected) {
+ this.selected = selected;
+ show(getContainer(), selected);
+ }
+
+ public Container getContainer() {
+ if (container == null) {
+ container = (Container) ui.getObjectById(containerName);
+ }
+ return container;
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ pcs.addPropertyChangeListener(listener);
+ }
+
+ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ pcs.addPropertyChangeListener(propertyName, listener);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ pcs.removePropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ pcs.removePropertyChangeListener(propertyName, listener);
+ }
+
+ public void removePropertyChangeListeners() {
+ for (PropertyChangeListener l : pcs.getPropertyChangeListeners()) {
+ pcs.removePropertyChangeListener(l);
+ }
+ }
+}
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java 2009-03-16 18:44:15 UTC (rev 1268)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java 2009-03-18 08:45:58 UTC (rev 1269)
@@ -195,6 +195,17 @@
}
}
+ public void validate() {
+ if (step == null) {
+ // pas de validation quand aucune etape n'est sélectionnée
+ return;
+ }
+ boolean validate = validate(step);
+ this.validStep = validate;
+ // toujours forcer la propagation
+ firePropertyChange(VALID_STEP_PROPERTY_NAME, null, validStep);
+ }
+
protected Class<E> getStepClass() {
return stepClass;
}
@@ -210,17 +221,6 @@
validate();
}
- protected void validate() {
- if (step == null) {
- // pas de validation quand aucune etape n'est sélectionnée
- return;
- }
- boolean validate = validate(step);
- this.validStep = validate;
- // toujours forcer la propagation
- firePropertyChange(VALID_STEP_PROPERTY_NAME, null, validStep);
- }
-
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
pcs.firePropertyChange(propertyName, oldValue, newValue);
}
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java 2009-03-16 18:44:15 UTC (rev 1268)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java 2009-03-18 08:45:58 UTC (rev 1269)
@@ -34,6 +34,18 @@
return operation;
}
+ public Exception getError() {
+ return error;
+ }
+
+ public void setError(Exception e) {
+ error = e;
+ }
+
+ public void sendMessage(String msg) {
+ firePropertyChange("message", null, msg);
+ }
+
public abstract void start(JAXXContext context);
public abstract void beforeAction(JAXXContext context, M model) throws Exception;
@@ -44,8 +56,6 @@
public abstract WizardOperationState onCancel(M model, Exception e);
- public abstract void afterAction(M model, WizardOperationState result, Exception error);
-
protected abstract M getModel();
public WizardOperationState getOperationState() {
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java 2009-03-16 18:44:15 UTC (rev 1268)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java 2009-03-18 08:45:58 UTC (rev 1269)
@@ -49,44 +49,42 @@
}
public void cancel() {
- if (currentAction != null) {
- log.debug("cancel action " + currentAction);
- // on a une action en cours, on l'annule
- currentAction.cancel(true);
- }
- // on annule aussi le modele
+ log.info("cancel " + this);
+ this.canceled = true;
+
+ // on annule le modele
getModel().cancel();
- this.canceled = true;
+
// on rend la main au thread
setWaiting(false);
}
@SuppressWarnings("unchecked")
- public void launchOperation(E operation) {
+ public A launchOperation(E operation) {
- if (currentAction != null) {
+ if (currentAction != null && (!currentAction.isDone() || currentAction.operationState == WizardOperationState.RUNNING)) {
// on ne peut traiter qu'une seule opération à la fois
throw new IllegalStateException("can not add a operation when thread is busy, or has another operation to be done");
}
- try {
- currentAction = (A) operation.getActionClass().newInstance();
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
+ currentAction = (A) getModel().getOperationAction(operation);
+
// on libere le thread pour qu'il execute l'opération
setWaiting(false);
+
+ return currentAction;
}
+ public A getCurrentAction() {
+ return currentAction;
+ }
+
@Override
public void propertyChange(PropertyChangeEvent evt) {
log.trace(evt.getPropertyName() + " <" + evt.getOldValue() + " - " + evt.getNewValue() + ">");
if ("state".equals(evt.getPropertyName())) {
- //@SuppressWarnings("unchecked")
- //A action = (A) evt.getSource();
StateValue state = (StateValue) evt.getNewValue();
if (state == StateValue.DONE) {
// on rend la main au thread pour qu'il attende une prochaine operation
- //getModel().setOperationState(action.getOperation(), action.getOperationState());
setWaiting(false);
}
}
@@ -137,13 +135,17 @@
// est terminée ou a été annulée, on passera alors
// dans la méthode onPropertyChanged
- getModel().setOperationState(currentAction.getOperationState());
+ if (canceled) {
+ getModel().setOperationState(WizardOperationState.CANCELED);
+ } else {
+ getModel().setOperationState(currentAction.getOperationState());
+ }
// le thread n'écoute plus l'action car elle est terminée
// ou annulée
currentAction.removePropertyChangeListener(this);
// suppression de l'action
- currentAction = null;
+ //currentAction = null;
}
}
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java 2009-03-16 18:44:15 UTC (rev 1268)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java 2009-03-18 08:45:58 UTC (rev 1269)
@@ -1,9 +1,12 @@
package jaxx.runtime.swing.wizard;
+import java.util.Arrays;
import java.util.EnumMap;
import java.util.EnumSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
+import javax.swing.SwingWorker.StateValue;
/**
* Un modèle de wizard avec des opérations.
@@ -18,11 +21,8 @@
public static final String OPERATION_STATE_PROPERTY_NAME = "operationState";
public static final String MODEL_STATE_PROPERTY_NAME = "modelState";
public static final String WAS_STARTED_PROPERTY_NAME = "wasStarted";
+
/**
- * le type d'une opération
- */
-// protected Class<O> operationClass;
- /**
* La liste des opérations à effectuer
*/
protected Set<E> operations;
@@ -30,6 +30,7 @@
* Pour conserver les états des opérations
*/
protected Map<E, WizardOperationState> operationStates;
+ protected Map<E, WizardOperationAction> operationActions;
/**
* L'état générale du modèle
*/
@@ -45,6 +46,7 @@
Class<T> k = (Class) stepClass;
this.operationStates = (Map) new EnumMap(k);
this.operations = (Set<E>) EnumSet.noneOf(k);
+ this.operationActions = (Map) new EnumMap(k);
}
public Set<E> getOperations() {
@@ -73,6 +75,19 @@
return operationStates.get(operation);
}
+ public WizardOperationAction getOperationAction(E operation) {
+ WizardOperationAction action = operationActions.get(operation);
+ if (action == null) {
+ try {
+ action = operation.getActionClass().newInstance();
+ operationActions.put(operation, action);
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ return action;
+ }
+
public void setOperationState(WizardOperationState operationState) {
E operation = getOperation();
setOperationState(operation, operationState);
@@ -90,7 +105,7 @@
boolean[] result = new boolean[getSteps().size()];
int index = getSteps().indexOf(getStep());
if (index != -1) {
-
+
for (int i = 0, j = steps.size(); i < j; i++) {
if (i <= index) {
// tous les onglets inferieur ou egal au courant sont accessibles
@@ -106,7 +121,7 @@
(!previousStep.isOperation() || getOperationState(previousStep) == WizardOperationState.SUCCESSED));
}
}
- System.out.println("accessibles steps -------- " + java.util.Arrays.toString(result));
+ //System.out.println("accessibles steps -------- " + java.util.Arrays.toString(result));
return result;
}
@@ -121,12 +136,24 @@
}
public void cancel() {
+
for (E op : operations) {
if (getOperationState(op) == WizardOperationState.PENDING) {
// on annule l'opération à venir
setOperationState(op, WizardOperationState.CANCELED);
}
}
+ setModelState(WizardOperationState.CANCELED);
+ if (getStep() != null && getStep().isOperation()) {
+ WizardOperationAction action = getOperationAction(getStep());
+ if (action != null) {
+ if (!action.isCancelled() && !action.isDone() && action.getState() == StateValue.STARTED) {
+ System.out.println("cancel action " + action);
+ // on annule l'action
+ action.cancel(true);
+ }
+ }
+ }
}
public WizardOperationModel<E> addOperation(E operation) {
@@ -152,6 +179,10 @@
super.setSteps(steps);
// on force la propagation de la nouvelle liste
firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations);
+ updateOperationStates(Arrays.asList(steps));
+ }
+
+ public void updateOperationStates(List<E> steps) {
int index = 0;
for (E e : steps) {
fireIndexedPropertyChange(OPERATION_STATE_PROPERTY_NAME, index++, null, getOperationState(e));
@@ -185,7 +216,7 @@
case CANCELED:
//le modele devient annulé
setModelState(WizardOperationState.CANCELED);
- break;
+ return;
case PENDING:
//le modele est en attente
setModelState(WizardOperationState.PENDING);
@@ -210,6 +241,7 @@
}
break;
}
+ updateOperationStates(steps);
}
@Override
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java 2009-03-16 18:44:15 UTC (rev 1268)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java 2009-03-18 08:45:58 UTC (rev 1269)
@@ -1,6 +1,7 @@
package jaxx.runtime.swing.wizard;
-import javax.swing.JFrame;
+import java.awt.Window;
+import javax.swing.ImageIcon;
import jaxx.runtime.JAXXContext;
import jaxx.runtime.JAXXInitialContext;
import jaxx.runtime.JAXXObject;
@@ -20,85 +21,37 @@
protected UI ui;
- @SuppressWarnings("unchecked")
- public WizardUILancher(JAXXContext context, JFrame mainUI, Class<UI> uiClass, M model) {
- super();
+ public WizardUILancher(JAXXContext context, Class<UI> uiClass, Class<M> modelClass, String title, String tip, ImageIcon icon) {
+ this(context, uiClass, modelClass, null, title, tip, icon);
+ }
+
+ public WizardUILancher(JAXXContext context, Class<UI> uiClass, Class<M> modelClass, M model, String title, String tip, ImageIcon icon) {
try {
- // instanciate ui parent context
- JAXXInitialContext uiContext = new JAXXInitialContext();
- uiContext.add(mainUI == null ? context : mainUI);
- // parent context model
- uiContext.add(model);
- // apply action
- uiContext.add("apply", new Runnable() {
-
- @Override
- public void run() {
- doAction(ui);
- }
- });
- // cancel action
- uiContext.add("cancel", new Runnable() {
-
- @Override
- public void run() {
- doCancel(ui);
- }
- });
-
- // instanciate ui
- ui = (UI) ConstructorUtils.invokeConstructor(uiClass, new Object[]{mainUI, uiContext}, new Class[]{JFrame.class, JAXXContext.class});
-
+ ui = createUI(context, uiClass, modelClass, model, title, tip, icon);
} catch (Exception ex) {
throw new RuntimeException("could not instanciate launcher for reason " + ex.getMessage(), ex);
}
}
- @SuppressWarnings("unchecked")
- public WizardUILancher(JAXXContext context, JFrame mainUI, Class<UI> uiClass, Class<M> modelClass) {
- super();
+ public WizardUILancher(JAXXContext context, Window mainUI, Class<UI> uiClass, Class<M> modelClass, M model) {
try {
- // instanciate ui parent context
- JAXXInitialContext uiContext = new JAXXInitialContext();
- uiContext.add(mainUI == null ? context : mainUI);
- // parent context model
- uiContext.add(modelClass.newInstance());
- // apply action
- uiContext.add("apply", new Runnable() {
-
- @Override
- public void run() {
- doAction(ui);
- }
- });
- // cancel action
- uiContext.add("cancel", new Runnable() {
-
- @Override
- public void run() {
- doCancel(ui);
- }
- });
-
- // instanciate ui
- ui = (UI) ConstructorUtils.invokeConstructor(uiClass, new Object[]{mainUI, uiContext}, new Class[]{JFrame.class, JAXXContext.class});
-
+ ui = createUI(context, mainUI, uiClass, modelClass, model);
} catch (Exception ex) {
throw new RuntimeException("could not instanciate launcher for reason " + ex.getMessage(), ex);
}
}
+ public WizardUILancher(JAXXContext context, Window mainUI, Class<UI> uiClass, Class<M> modelClass) {
+ this(context, mainUI, uiClass, modelClass, null);
+ }
+
public void start() {
- try {
- init(ui);
- ui.start();
- } finally {
- dispose();
- }
+ init(ui);
+ start(ui);
}
- public void dispose() {
- // par defaut, on ne fait rien
+ protected void start(UI ui) {
+ ui.start();
}
public <T> T getContextValue(Class<T> clazz, String name) {
@@ -124,4 +77,86 @@
protected void doCancel(UI ui) {
}
+
+ protected void doClose(UI ui, boolean wasCanceld) {
+ }
+
+ @SuppressWarnings("unchecked")
+ protected UI createUI(JAXXContext context, Window mainUI, Class<UI> uiClass, Class<M> modelClass, M model) throws Exception {
+ JAXXInitialContext uiContext = new JAXXInitialContext();
+ uiContext.add(mainUI == null ? context : mainUI);
+ // parent context model
+ uiContext.add(modelClass.newInstance());
+ if (model != null) {
+ uiContext.add("incoming", model);
+ }
+ // apply action
+ uiContext.add("apply", new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ doAction(ui);
+ } finally {
+ doClose(ui,false);
+ }
+ }
+ });
+ // cancel action
+ uiContext.add("cancel", new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ doCancel(ui);
+ } finally {
+ doClose(ui,true);
+ }
+ }
+ });
+
+ // instanciate ui
+
+ UI newUI = (UI) ConstructorUtils.invokeConstructor(uiClass, new Object[]{mainUI, uiContext}, new Class[]{Window.class, JAXXContext.class});
+ return newUI;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected UI createUI(JAXXContext context, Class<UI> uiClass, Class<M> modelClass, M model, String title, String tip, ImageIcon icon) throws Exception {
+ JAXXInitialContext uiContext = new JAXXInitialContext();
+ uiContext.add(context);
+ // parent context model
+ uiContext.add(modelClass.newInstance());
+ if (model != null) {
+ uiContext.add("incoming", model);
+ }
+ // apply action
+ uiContext.add("apply", new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ doAction(ui);
+ } finally {
+ doClose(ui,false);
+ }
+ }
+ });
+ // cancel action
+ uiContext.add("cancel", new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ doCancel(ui);
+ } finally {
+ doClose(ui,true);
+ }
+ }
+ });
+
+ // instanciate ui
+ UI newUI = (UI) ConstructorUtils.invokeConstructor(uiClass, new Object[]{uiContext, title, tip, icon}, new Class[]{JAXXContext.class, String.class, String.class, ImageIcon.class});
+ return newUI;
+ }
}
1
0
r1268 - in jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime: . swing/wizard
by tchemit@users.labs.libre-entreprise.org 16 Mar '09
by tchemit@users.labs.libre-entreprise.org 16 Mar '09
16 Mar '09
Author: tchemit
Date: 2009-03-16 18:44:15 +0000 (Mon, 16 Mar 2009)
New Revision: 1268
Added:
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardStep.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardStepUI.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUtil.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/package.html
Removed:
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperation.java
Modified:
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/SwingUtil.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationStep.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUI.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java
Log:
wizard framework done
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/SwingUtil.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/SwingUtil.java 2009-03-15 11:23:33 UTC (rev 1267)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/SwingUtil.java 2009-03-16 18:44:15 UTC (rev 1268)
@@ -29,6 +29,7 @@
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.NoSuchElementException;
import java.util.Properties;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
@@ -413,6 +414,7 @@
public int size() {
return tabs.getTabCount();
}
+
public TabbedPaneIterator<O> reverse() {
setReverse(!reverse);
return this;
@@ -430,9 +432,9 @@
@Override
public O next() {
if (!hasNext()) {
- throw new IllegalStateException("no next objet! for " + this);
+ throw new NoSuchElementException();
}
- Component next = tabs.getComponent(index);
+ Component next = tabs.getComponentAt(index);
O result = get(index, next);
index += increment;
return result;
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java 2009-03-15 11:23:33 UTC (rev 1267)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java 2009-03-16 18:44:15 UTC (rev 1268)
@@ -2,17 +2,21 @@
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
-import java.util.List;
/**
* Un modèle de wizard.
*
- * @param <E> le type de l'énumération contenant les etapes.
*
+ * <b>Note:</b> le type des étapes doit être uné énumération qui implante
+ * {@link WizardStep}.
+ *
+ * @param <E> le type des étapes.
+ *
* @author tony
* @since 1.3
+ * @see WizardStep
*/
-public class WizardModel<E extends Enum<E>> {
+public class WizardModel<E extends WizardStep> {
public static final String STEPS_PROPERTY_NAME = "steps";
public static final String STEP_PROPERTY_NAME = "step";
@@ -26,7 +30,7 @@
/**
* Toutes les étapes à passer
*/
- protected List<E> steps;
+ protected java.util.List<E> steps;
/**
* L'étape courante
*/
@@ -36,11 +40,20 @@
*/
protected boolean validStep;
/**
+ * drapeau lorsque le modele effectue des operations
+ * de transformation de modele mais que les écouteurs
+ * ne devraient pas tenir compte des modifications
+ */
+ protected boolean valueAdjusting;
+ /**
* pour propager les changements dans le modèle vers l'ui
*/
protected PropertyChangeSupport pcs;
public WizardModel(Class<E> stepClass, E... steps) {
+ if (!Enum.class.isAssignableFrom(stepClass)) {
+ throw new IllegalArgumentException("stepClass must be an Enumeration but was " + stepClass.getName());
+ }
this.stepClass = stepClass;
this.pcs = new PropertyChangeSupport(this);
this.steps = new java.util.ArrayList<E>();
@@ -79,7 +92,7 @@
throw new NullPointerException("step can not be null");
}
if (!steps.contains(e)) {
- throw new IllegalStateException("step " + e + " is not in universe of steps (" + steps + ")");
+ throw new IllegalStateException("step " + e.toString() + " is not in universe of steps (" + steps + ")");
}
setStep(e);
}
@@ -98,6 +111,11 @@
}
public E getPreviousStep() {
+ E e = getPreviousStep(step);
+ return e;
+ }
+
+ public E getPreviousStep(E step) {
int index = getStepIndex(step);
if (index < 1) {
// si pas de step ou sur premier step
@@ -106,6 +124,15 @@
return steps.get(index - 1);
}
+ public E getNextStep(E step) {
+ int index = getStepIndex(step);
+ if (index < 1) {
+ // si pas de step ou sur premier step
+ return null;
+ }
+ return steps.get(index - 1);
+ }
+
public E getNextStep() {
int index = getStepIndex(step);
if (index == -1 || index == steps.size() - 1) {
@@ -115,10 +142,14 @@
return steps.get(index + 1);
}
- public List<E> getSteps() {
+ public java.util.List<E> getSteps() {
return steps;
}
+ public boolean isValueAdjusting() {
+ return valueAdjusting;
+ }
+
/**
* Change l'univers des etapes.
*
@@ -127,13 +158,17 @@
* @param steps le nouvel univers des etapes
*/
public void setSteps(E... steps) {
- List<E> oldValue = this.steps;
+ java.util.List<E> oldValue = this.steps;
this.steps = java.util.Collections.unmodifiableList(java.util.Arrays.asList(steps));
firePropertyChange(STEPS_PROPERTY_NAME, oldValue, this.steps);
// la propriete nextStep peut avoir changee
firePropertyChange(NEXT_STEP_PROPERTY_NAME, null, getNextStep());
}
+ public void setValueAdjusting(boolean valueAdjusting) {
+ this.valueAdjusting = valueAdjusting;
+ }
+
public boolean validate(E s) {
return step != null;
}
@@ -194,6 +229,10 @@
pcs.fireIndexedPropertyChange(propertyName, index, oldValue, newValue);
}
+ protected E[] updateStepUniverse() {
+ return null;
+ }
+
protected void updateUniverse() {
}
}
Deleted: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperation.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperation.java 2009-03-15 11:23:33 UTC (rev 1267)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperation.java 2009-03-16 18:44:15 UTC (rev 1268)
@@ -1,20 +0,0 @@
-package jaxx.runtime.swing.wizard;
-
-/**
- *
- * @param <Action>
- * @author tony
- * @since 1.3
- */
-public interface WizardOperation<Action extends WizardOperationAction> {
-
- String name();
-
- int ordinal();
-
- String getLabel();
-
- String getDescription();
-
- public Action newAction();
-}
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java 2009-03-15 11:23:33 UTC (rev 1267)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java 2009-03-16 18:44:15 UTC (rev 1268)
@@ -6,27 +6,31 @@
import org.apache.commons.logging.LogFactory;
/**
+ * La classe de base a implanter pour definir l'action d'une operation
+ * dans un wizard.
*
* @author tony
* @param <E> le type d'étapes
- * @param <O> le type d'opérations
* @param <M> le type de modèle
* @since 1.3
*/
-public abstract class WizardOperationAction<E extends Enum<E>, O extends Enum<O>, M extends WizardOperationModel<E, O>> extends SwingWorker<WizardOperationState, String> {
+public abstract class WizardOperationAction<E extends WizardOperationStep, M extends WizardOperationModel<E>> extends SwingWorker<WizardOperationState, String> {
/** to use log facility, just put in your code: log.info(\"...\"); */
private static final Log log = LogFactory.getLog(WizardOperationAction.class);
- O operation;
+ E operation;
WizardOperationState operationState;
Exception error;
- public WizardOperationAction(O operation) {
+ public WizardOperationAction(E operation) {
super();
+ if (!operation.isOperation()) {
+ throw new IllegalArgumentException("the step " + operation + " has no operation defined");
+ }
this.operation = operation;
}
- public O getOperation() {
+ public E getOperation() {
return operation;
}
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java 2009-03-15 11:23:33 UTC (rev 1267)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java 2009-03-16 18:44:15 UTC (rev 1268)
@@ -2,7 +2,6 @@
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
import java.util.Date;
import javax.swing.SwingWorker.StateValue;
import jaxx.runtime.JAXXContext;
@@ -18,14 +17,13 @@
* Note: Pour bloquer (ou débloquer) le thread, on utilise la méthode {@link #setWaiting(boolean)}
*
* @param <E> le type des etapes
- * @param <O> le type des operations
* @param <M> le type de modele
* @param <A> le type d'action d'operation
*
* @author tony
* @since 1.3
*/
-public abstract class WizardOperationActionThread<E extends Enum<E>, O extends Enum<O>, M extends WizardOperationModel<E, O>, A extends WizardOperationAction<E, O, M>> extends Thread implements PropertyChangeListener {
+public abstract class WizardOperationActionThread<E extends WizardOperationStep, M extends WizardOperationModel<E>, A extends WizardOperationAction<E, M>> extends Thread implements PropertyChangeListener {
/** to use log facility, just put in your code: log.info(\"...\"); */
private static final Log log = LogFactory.getLog(WizardOperationActionThread.class);
@@ -33,8 +31,6 @@
* l'état du thread si annulé
*/
private boolean canceled;
- /** suport of modification propagation */
- protected PropertyChangeSupport pcs;
protected Class<M> modelClass;
protected A currentAction;
/**
@@ -50,7 +46,6 @@
public WizardOperationActionThread(Class<M> modelClass) throws IllegalArgumentException {
super(WizardOperationActionThread.class.getSimpleName() + " " + new Date());
this.modelClass = modelClass;
- this.pcs = new PropertyChangeSupport(this);
}
public void cancel() {
@@ -66,20 +61,25 @@
setWaiting(false);
}
- public void launchOperation(A action) {
+ @SuppressWarnings("unchecked")
+ public void launchOperation(E operation) {
if (currentAction != null) {
// on ne peut traiter qu'une seule opération à la fois
throw new IllegalStateException("can not add a operation when thread is busy, or has another operation to be done");
}
- currentAction = action;
+ try {
+ currentAction = (A) operation.getActionClass().newInstance();
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
// on libere le thread pour qu'il execute l'opération
setWaiting(false);
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
- log.info(evt.getPropertyName() + " <" + evt.getOldValue() + " - " + evt.getNewValue() + ">");
+ log.trace(evt.getPropertyName() + " <" + evt.getOldValue() + " - " + evt.getNewValue() + ">");
if ("state".equals(evt.getPropertyName())) {
//@SuppressWarnings("unchecked")
//A action = (A) evt.getSource();
@@ -166,39 +166,6 @@
log.trace(this);
}
- // PropertyChanged support
- public void addPropertyChangeListener(PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(listener);
- }
-
- public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(propertyName, listener);
- }
-
- public void removePropertyChangeListener(PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(listener);
- }
-
- public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(propertyName, listener);
- }
-
- public synchronized boolean hasListeners(String propertyName) {
- return pcs.hasListeners(propertyName);
- }
-
- public synchronized PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
- return pcs.getPropertyChangeListeners(propertyName);
- }
-
- public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
- return pcs.getPropertyChangeListeners();
- }
-
- protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
- pcs.firePropertyChange(propertyName, oldValue, newValue);
- }
-
protected void setWaiting(boolean waiting) {
if (waiting && !canceled) {
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java 2009-03-15 11:23:33 UTC (rev 1267)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java 2009-03-16 18:44:15 UTC (rev 1268)
@@ -2,16 +2,17 @@
import java.util.EnumMap;
import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
/**
* Un modèle de wizard avec des opérations.
*
* @param <E> le type des étapes.
- * @param <O> le type des opérations.
* @author tony
* @since 1.3
*/
-public class WizardOperationModel<E extends Enum<E>, O extends Enum<O>> extends WizardModel<E> {
+public class WizardOperationModel<E extends WizardOperationStep> extends WizardModel<E> {
public static final String OPERATIONS_PROPERTY_NAME = "operations";
public static final String OPERATION_STATE_PROPERTY_NAME = "operationState";
@@ -20,15 +21,15 @@
/**
* le type d'une opération
*/
- protected Class<O> operationClass;
+// protected Class<O> operationClass;
/**
* La liste des opérations à effectuer
*/
- protected EnumSet<O> operations;
+ protected Set<E> operations;
/**
* Pour conserver les états des opérations
*/
- protected EnumMap<O, WizardOperationState> operationStates;
+ protected Map<E, WizardOperationState> operationStates;
/**
* L'état générale du modèle
*/
@@ -38,16 +39,15 @@
*/
protected boolean wasStarted;
- public WizardOperationModel(Class<E> stepClass, Class<O> operationClass, E... steps) {
+ @SuppressWarnings("unchecked")
+ public <T extends Enum<T>> WizardOperationModel(Class<E> stepClass, E... steps) {
super(stepClass, steps);
- this.operationClass = operationClass;
- this.operationStates = new EnumMap<O, WizardOperationState>(operationClass);
+ Class<T> k = (Class) stepClass;
+ this.operationStates = (Map) new EnumMap(k);
+ this.operations = (Set<E>) EnumSet.noneOf(k);
}
- public EnumSet<O> getOperations() {
- if (operations == null) {
- operations = EnumSet.noneOf(operationClass);
- }
+ public Set<E> getOperations() {
return operations;
}
@@ -60,43 +60,68 @@
}
@SuppressWarnings("unchecked")
- public O getOperation() {
- return ((WizardOperationStep<O>) getStep()).getOperation();
+ public E getOperation() {
+ return getStep() != null && getStep().isOperation() ? getStep() : null;
}
public WizardOperationState getOperationState() {
- O operation = getOperation();
+ E operation = getOperation();
return getOperationState(operation);
}
- public WizardOperationState getOperationState(O operation) {
+ public WizardOperationState getOperationState(E operation) {
return operationStates.get(operation);
}
public void setOperationState(WizardOperationState operationState) {
- O operation = getOperation();
+ E operation = getOperation();
setOperationState(operation, operationState);
}
- public void setOperationState(O operation, WizardOperationState operationState) {
+ public void setOperationState(E operation, WizardOperationState operationState) {
WizardOperationState oldValue = getOperationState(operation);
this.operationStates.put(operation, operationState);
- firePropertyChange(OPERATION_STATE_PROPERTY_NAME, oldValue, operationState);
- //fireIndexedPropertyChange(OPERATION_STATE_PROPERTY_NAME, getOperationIndex(operation), oldValue, operationStates);
+ fireIndexedPropertyChange(OPERATION_STATE_PROPERTY_NAME, getSteps().indexOf(operation), oldValue, operationState);
updateModelState(operation, operationState);
validate();
}
+ public boolean[] getAccessibleSteps() {
+ boolean[] result = new boolean[getSteps().size()];
+ int index = getSteps().indexOf(getStep());
+ if (index != -1) {
+
+ for (int i = 0, j = steps.size(); i < j; i++) {
+ if (i <= index) {
+ // tous les onglets inferieur ou egal au courant sont accessibles
+ result[i] = true;
+ continue;
+ }
+ // les onglets au dela de l'onglet sélectionné sont accessibles
+ // uniquement si l'onglet precedent est accessible, valide et son etat est a SUCCESSED
+ E previousStep = steps.get(i - 1);
+ result[i] = modelState == WizardOperationState.SUCCESSED ||
+ (result[i - 1] &&
+ validate(previousStep) &&
+ (!previousStep.isOperation() || getOperationState(previousStep) == WizardOperationState.SUCCESSED));
+ }
+ }
+ System.out.println("accessibles steps -------- " + java.util.Arrays.toString(result));
+ return result;
+ }
+
@Override
public void start() {
super.start();
+ updateUniverse();
+ //setSteps(steps.toArray((E[]) Array.newInstance(stepClass, steps.size())));
+
// le modèle n'est pas démarré
setModelState(WizardOperationState.PENDING);
- firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations);
}
public void cancel() {
- for (O op : operations) {
+ for (E op : operations) {
if (getOperationState(op) == WizardOperationState.PENDING) {
// on annule l'opération à venir
setOperationState(op, WizardOperationState.CANCELED);
@@ -104,10 +129,8 @@
}
}
- public WizardOperationModel<E, O> addOperation(O operation) {
- getOperations().add(operation);
- // on force la propagation de la nouvelle liste
- firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations);
+ public WizardOperationModel<E> addOperation(E operation) {
+ operations.add(operation);
// mis a jour de l'univers des etapes et operations
updateUniverse();
// validation
@@ -115,16 +138,27 @@
return this;
}
- public void removeOperation(O operation) {
- getOperations().remove(operation);
- // on force la propagation de la nouvelle liste
- firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations);
+ public void removeOperation(E operation) {
+ operations.remove(operation);
+
// mis a jour de l'univers des etapes et operations
updateUniverse();
// validation
validate();
}
+ @Override
+ public void setSteps(E... steps) {
+ super.setSteps(steps);
+ // on force la propagation de la nouvelle liste
+ firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations);
+ int index = 0;
+ for (E e : steps) {
+ fireIndexedPropertyChange(OPERATION_STATE_PROPERTY_NAME, index++, null, getOperationState(e));
+ }
+ firePropertyChange(MODEL_STATE_PROPERTY_NAME, null, modelState);
+ }
+
protected void setModelState(WizardOperationState modelState) {
WizardOperationState oldValue = this.modelState;
this.modelState = modelState;
@@ -137,33 +171,33 @@
}
}
- protected void updateModelState(O operation, WizardOperationState operationState) {
+ protected void updateModelState(E operation, WizardOperationState operationState) {
switch (operationState) {
case RUNNING:
- //le model est occupé
+ //le modele est occupé
setModelState(WizardOperationState.RUNNING);
break;
case FAILED:
- //le model est en attente
- setModelState(WizardOperationState.PENDING);
+ //le modele est en erreur
+ setModelState(WizardOperationState.FAILED);
break;
case CANCELED:
- //le model devient annulé
+ //le modele devient annulé
setModelState(WizardOperationState.CANCELED);
break;
case PENDING:
- //le model est en attente
+ //le modele est en attente
setModelState(WizardOperationState.PENDING);
break;
case NEED_FIX:
- //le model est en attente
+ //le modele est en attente
setModelState(WizardOperationState.PENDING);
break;
case SUCCESSED:
// on regarde si on peut passer le model a l'état success
boolean valid = true;
- for (O o : operations) {
+ for (E o : operations) {
if (getOperationState(o) != WizardOperationState.SUCCESSED) {
valid = false;
break;
@@ -178,9 +212,15 @@
}
}
- protected int getOperationIndex(O operation) {
+ @Override
+ protected void updateUniverse() {
+ E[] newSteps = updateStepUniverse();
+ setSteps(newSteps);
+ }
+
+ protected int getOperationIndex(E operation) {
int index = 0;
- for (O o : operations) {
+ for (E o : operations) {
if (operation == o) {
return index;
}
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationStep.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationStep.java 2009-03-15 11:23:33 UTC (rev 1267)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationStep.java 2009-03-16 18:44:15 UTC (rev 1268)
@@ -2,19 +2,33 @@
/**
*
- * @param <Operation>
+ * Le contrat a implanter pour une etapes dans le modèle de wizard avec
+ * opérations.
+ *
* @author tony
* @since 1.3
*/
-public interface WizardOperationStep<Operation extends Enum<Operation>> {
+public interface WizardOperationStep extends WizardStep {
- String name();
+ /**
+ * @return le label de l'opération
+ */
+ String getOperationLabel();
- int ordinal();
+ /**
+ * @return la description de l'opération
+ */
+ String getOperationDescription();
- String getLabel();
+ /**
+ * @return le type de l'action associée à l'étape ou <code>null</code> si
+ * l'étape n'a pas d'opération associée.
+ */
+ Class<? extends WizardOperationAction> getActionClass();
- String getDescription();
-
- Operation getOperation();
+ /**
+ * @return <code>true</code> si l'étape a une opération associée,
+ * <code>false</code> sinon.
+ */
+ boolean isOperation();
}
Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardStep.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardStep.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardStep.java 2009-03-16 18:44:15 UTC (rev 1268)
@@ -0,0 +1,20 @@
+package jaxx.runtime.swing.wizard;
+
+import java.io.Serializable;
+
+/**
+ * le contrat d'une étape d'un wizard.
+ *
+ * @author tony
+ * @since 1.3
+ */
+public interface WizardStep extends Serializable {
+
+ String name();
+
+ int ordinal();
+
+ String getLabel();
+
+ String getDescription();
+}
Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardStepUI.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardStepUI.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardStepUI.java 2009-03-16 18:44:15 UTC (rev 1268)
@@ -0,0 +1,14 @@
+package jaxx.runtime.swing.wizard;
+
+/**
+ * Le contrat d'une ui d'étape.
+ *
+ * @param <E> le type d'étape
+ * @param <M> le type de modèle
+ * @author tony
+ * @since 1.3
+ */
+public interface WizardStepUI<E extends WizardStep, M extends WizardModel<E>> {
+
+ E getStep();
+}
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUI.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUI.java 2009-03-15 11:23:33 UTC (rev 1267)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUI.java 2009-03-16 18:44:15 UTC (rev 1268)
@@ -12,13 +12,27 @@
* @author tony
* @since 1.3
*/
-public interface WizardUI<E extends Enum<E>, M extends WizardModel<E>> {
+public interface WizardUI<E extends WizardStep, M extends WizardModel<E>> {
- public E getSelectedStep();
-
M getModel();
+ E getSelectedStep();
+
+ WizardStepUI<E, M> getSelectedStepUI();
+
+ WizardStepUI<E, M> getStepUI(E step);
+
+ WizardStepUI<E, M> getStepUI(int stepIndex);
+
void start();
JTabbedPane getTabs();
+
+ void onStepsChanged(E[] steps);
+
+ void onStepChanged(E newStep);
+
+ void onModelStateChanged(WizardOperationState newState);
+
+ void onOperationStateChanged(E step,WizardOperationState newState) ;
}
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java 2009-03-15 11:23:33 UTC (rev 1267)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java 2009-03-16 18:44:15 UTC (rev 1268)
@@ -8,7 +8,7 @@
/**
*
- * Une classe pour lancer une ui avec wizard.
+ * Une classe pour lancer une ui de wizard.
*
* @param <E> le type des etapes
* @param <M> le type de modele
@@ -16,11 +16,45 @@
* @author tony
* @since 1.3
*/
-public abstract class WizardUILancher<E extends Enum<E>, M extends WizardModel<E>, UI extends WizardUI<E, M>> {
+public abstract class WizardUILancher<E extends WizardStep, M extends WizardModel<E>, UI extends WizardUI<E, M>> {
protected UI ui;
@SuppressWarnings("unchecked")
+ public WizardUILancher(JAXXContext context, JFrame mainUI, Class<UI> uiClass, M model) {
+ super();
+ try {
+ // instanciate ui parent context
+ JAXXInitialContext uiContext = new JAXXInitialContext();
+ uiContext.add(mainUI == null ? context : mainUI);
+ // parent context model
+ uiContext.add(model);
+ // apply action
+ uiContext.add("apply", new Runnable() {
+
+ @Override
+ public void run() {
+ doAction(ui);
+ }
+ });
+ // cancel action
+ uiContext.add("cancel", new Runnable() {
+
+ @Override
+ public void run() {
+ doCancel(ui);
+ }
+ });
+
+ // instanciate ui
+ ui = (UI) ConstructorUtils.invokeConstructor(uiClass, new Object[]{mainUI, uiContext}, new Class[]{JFrame.class, JAXXContext.class});
+
+ } catch (Exception ex) {
+ throw new RuntimeException("could not instanciate launcher for reason " + ex.getMessage(), ex);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
public WizardUILancher(JAXXContext context, JFrame mainUI, Class<UI> uiClass, Class<M> modelClass) {
super();
try {
@@ -64,7 +98,7 @@
}
public void dispose() {
- ui = null;
+ // par defaut, on ne fait rien
}
public <T> T getContextValue(Class<T> clazz, String name) {
Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUtil.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUtil.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUtil.java 2009-03-16 18:44:15 UTC (rev 1268)
@@ -0,0 +1,93 @@
+package jaxx.runtime.swing.wizard;
+
+import java.beans.IndexedPropertyChangeEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.reflect.Array;
+import org.apache.commons.logging.Log;
+
+/**
+ * Classe de méthodes utiles sur les wizard.
+ *
+ * @author tony
+ * @since 1.3
+ */
+public class WizardUtil {
+
+ protected WizardUtil() {
+ }
+
+ public static boolean acceptStates(WizardOperationState state, WizardOperationState... accepted) {
+ for (WizardOperationState s : accepted) {
+ if (s == state) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean rejectStates(WizardOperationState state, WizardOperationState... rejected) {
+ for (WizardOperationState s : rejected) {
+ if (s == state) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static void addDebugLogListener(final Log log, WizardModel model) {
+ if (log.isDebugEnabled()) {
+ model.addPropertyChangeListener(new PropertyChangeListener() {
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ log.debug(evt.getPropertyName() + " <" + evt.getOldValue() + " - " + evt.getNewValue() + ">");
+ }
+ });
+ }
+ }
+
+ public static void addTraceLogListener(final Log log,WizardModel model) {
+ if (log.isTraceEnabled()) {
+ model.addPropertyChangeListener(new PropertyChangeListener() {
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ log.trace(evt.getPropertyName() + " <" + evt.getOldValue() + " - " + evt.getNewValue() + ">");
+ }
+ });
+ }
+ }
+
+ public static <E extends WizardStep, M extends WizardModel<E>> void installWizardUIListeners(final WizardUI<E, M> ui) {
+ ui.getModel().addPropertyChangeListener(new PropertyChangeListener() {
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void propertyChange(PropertyChangeEvent evt) {
+ String propertyName = evt.getPropertyName();
+ if (WizardModel.STEPS_PROPERTY_NAME.equals(propertyName)) {
+ java.util.List<E> steps = (java.util.List<E>) evt.getNewValue();
+ ui.onStepsChanged(steps.toArray((E[]) Array.newInstance(ui.getModel().stepClass, steps.size())));
+ return;
+ }
+ if (WizardModel.STEP_PROPERTY_NAME.equals(propertyName)) {
+ ui.onStepChanged((E) evt.getNewValue());
+ return;
+ }
+ if (WizardOperationModel.MODEL_STATE_PROPERTY_NAME.equals(propertyName)) {
+ //TODO should be unicast : only for good stepUI ?
+ ui.onModelStateChanged((WizardOperationState) evt.getNewValue());
+ return;
+ }
+ if (WizardOperationModel.OPERATION_STATE_PROPERTY_NAME.equals(propertyName)) {
+ IndexedPropertyChangeEvent e = (IndexedPropertyChangeEvent) evt;
+ int stepIndex = e.getIndex();
+ E step = ui.getModel().getSteps().get(stepIndex);
+ ui.onOperationStateChanged(step, (WizardOperationState) evt.getNewValue());
+ return;
+ }
+ }
+ });
+ }
+}
Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/package.html
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/package.html (rev 0)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/package.html 2009-03-16 18:44:15 UTC (rev 1268)
@@ -0,0 +1,9 @@
+<html>
+ <body>
+ <h1>JAXX - Wizard framework</h1>
+
+ This package contains all the classes of the wizard framework.
+
+ TODO
+ </body>
+</html>
\ No newline at end of file
1
0
r1267 - jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard
by tchemit@users.labs.libre-entreprise.org 15 Mar '09
by tchemit@users.labs.libre-entreprise.org 15 Mar '09
15 Mar '09
Author: tchemit
Date: 2009-03-15 11:23:33 +0000 (Sun, 15 Mar 2009)
New Revision: 1267
Modified:
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java
Log:
rendre publique les m?\195?\169thode d'acces au context
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java 2009-03-14 19:24:14 UTC (rev 1266)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java 2009-03-15 11:23:33 UTC (rev 1267)
@@ -67,16 +67,7 @@
ui = null;
}
- protected void init(UI ui) {
- }
-
- protected void doAction(UI ui) {
- }
-
- protected void doCancel(UI ui) {
- }
-
- protected <T> T getContextValue(Class<T> clazz, String name) {
+ public <T> T getContextValue(Class<T> clazz, String name) {
if (ui == null) {
throw new NullPointerException("ui can not be null");
}
@@ -87,7 +78,16 @@
return ((JAXXObject) ui).getContextValue(clazz, name);
}
- protected <T> T getContextValue(Class<T> clazz) {
+ public <T> T getContextValue(Class<T> clazz) {
return getContextValue(clazz, null);
}
+
+ protected void init(UI ui) {
+ }
+
+ protected void doAction(UI ui) {
+ }
+
+ protected void doCancel(UI ui) {
+ }
}
1
0
r1266 - in jaxx/trunk: jaxx-compiler-api/src/main/java/jaxx/compiler jaxx-runtime-swing/src/main/java/jaxx/runtime jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard
by tchemit@users.labs.libre-entreprise.org 14 Mar '09
by tchemit@users.labs.libre-entreprise.org 14 Mar '09
14 Mar '09
Author: tchemit
Date: 2009-03-14 19:24:14 +0000 (Sat, 14 Mar 2009)
New Revision: 1266
Added:
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationState.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationStep.java
Removed:
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardAbstractOperationAction.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardAbstractOperationActionThread.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModelWithOperations.java
Modified:
jaxx/trunk/jaxx-compiler-api/src/main/java/jaxx/compiler/CompiledObject.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/SwingUtil.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperation.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUI.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java
Log:
wizard framework done
Modified: jaxx/trunk/jaxx-compiler-api/src/main/java/jaxx/compiler/CompiledObject.java
===================================================================
--- jaxx/trunk/jaxx-compiler-api/src/main/java/jaxx/compiler/CompiledObject.java 2009-03-13 22:00:34 UTC (rev 1265)
+++ jaxx/trunk/jaxx-compiler-api/src/main/java/jaxx/compiler/CompiledObject.java 2009-03-14 19:24:14 UTC (rev 1266)
@@ -20,75 +20,61 @@
import java.util.List;
import java.util.Map;
-
/**
* Represents an object in the <code>.java</code> file being generated during compilation. There is
* a <code>CompiledObject</code> for each class tag encountered, and certain tags may generate
* additional objects for various reasons.
*/
public class CompiledObject {
+
/** The object's id. */
private String id;
-
/** Java code referring to the object. */
private String javaCode;
-
/** The object's class. */
private ClassDescriptor objectClass;
-
/** The style class. */
private String styleClass;
-
/** The container containing this CompiledObject. */
private CompiledObject parent;
-
/** true if this object overrides an object of the same id in a superclass of the object being compiled */
private boolean override;
-
/**
* Comma-separated Java code snippets representing the parameters that should be passed to the object's
* constructor.
*/
private String constructorParams;
-
/**
* Java code snippet which performs basic initialization of the object (after it has already been constructed).
* Because CompiledObject initialization order cannot be guaranteed, it is not safe to refer to other
* CompiledObjects from initializationCode -- you must refer to them from additionCode instead.
*/
private StringBuffer initializationCode = new StringBuffer();
-
/**
* Java code snippet which completes setup by adding any child objects, or otherwise manipulates any refererenced
* objects. Because CompiledObject initialization order cannot be guaranteed, it is not safe to refer to other
* CompiledObjects from initializationCode -- you must refer to them from additionCode instead.
*/
private StringBuffer additionCode = new StringBuffer();
-
/** List of all registered event handlers. */
private List<EventHandler> eventHandlers = new ArrayList<EventHandler>();
-
/** All properties that have been applied to this CompiledObject. */
private Map<String, String> properties = new HashMap<String, String>();
-
/** generic types of the compiled object */
private String[] genericTypes;
-
/** a flag to indicate if javaBean full support must be support for this object by root object */
private boolean javaBean;
-
/** code to initialize the bean (can be null) */
private String javaBeanInitCode;
-
/** the type of the override object (can be null if no oveeride) */
private ClassDescriptor overrideType;
-
/**
* the decorator (if null will use {@link DefaultCompiledObjectDecorator}).
*/
private CompiledObjectDecorator decorator;
-
+
public class ChildRef {
+
CompiledObject child;
String constraints;
String childJavaCode;
@@ -142,7 +128,6 @@
buffer.append(JAXXCompiler.getLineSeparator());
}
}
-
private List<ChildRef> childs;
/**
@@ -158,7 +143,6 @@
this(id, objectClass, compiler, false);
}
-
/**
* Creates a new <code>CompiledObject</code>. To be useful, the object should be registered with a
* <code>JAXXCompiler</code> using {@link JAXXCompiler#registerCompiledObject registerCompiledObject}.
@@ -173,7 +157,6 @@
this(id, id, objectClass, compiler, force);
}
-
/**
* Creates a new <code>CompiledObject</code>. To be useful, the object should be registered with a
* <code>JAXXCompiler</code> using {@link JAXXCompiler#registerCompiledObject registerCompiledObject}.
@@ -202,7 +185,6 @@
this.childs = new ArrayList<ChildRef>();
}
-
public static boolean isValidID(String id) {
boolean valid = true;
if (id.length() == 0) {
@@ -224,7 +206,6 @@
return valid;
}
-
/**
* True if this object overrides an object in the superclass of the class being compiled. For this to be true, the
* class currently being compiled must be a subclass of another <code>JAXXObject</code> which has an
@@ -237,7 +218,6 @@
return override;
}
-
/**
* Sets whether this class overrides an identically-named object in the parent class.
*
@@ -248,7 +228,6 @@
this.override = override;
}
-
/**
* Returns this object's CSS style class.
*
@@ -258,7 +237,6 @@
return styleClass;
}
-
/**
* Sets this object's CSS style class.
*
@@ -268,7 +246,6 @@
this.styleClass = styleClass;
}
-
/**
* Returns this object's parent container. Non-visual components (and the root container) return <code>null</code>.
*
@@ -278,7 +255,6 @@
return parent;
}
-
/**
* Sets this object's parent container.
*
@@ -291,7 +267,6 @@
this.parent = parent;
}
-
/**
* Returns the name of the method that should be generated in the compiled <code>.java</code> file
* in order to create this object. This is just a suggestion and may be ignored.
@@ -302,7 +277,6 @@
return "create" + org.apache.commons.lang.StringUtils.capitalize(getId());
}
-
/**
* Returns the name of the method that should be generated in the compiled <code>.java</code> file
* in order to add children to this object. This is just a suggestion and may be ignored.
@@ -313,7 +287,6 @@
return "addChildrenTo" + org.apache.commons.lang.StringUtils.capitalize(getId());
}
-
/**
* Returns the type of this object.
*
@@ -323,7 +296,6 @@
return objectClass;
}
-
/**
* Returns this object's id. Generally, a field with this name will be created in the compiled <code>.java</code>
* file in order to represent this object.
@@ -334,7 +306,6 @@
return id;
}
-
/**
* Returns Java code used to refer to this object in the compiled Java file. This is usually the same as its
* id.
@@ -382,7 +353,6 @@
return constructorParams;
}
-
/**
* Sets the parameters to pass to this object's constructor.
*
@@ -393,7 +363,6 @@
this.constructorParams = constructorParams;
}
-
/**
* Returns the code that performs basic initialization of this object, after it has already been constructed.
* This basic code should not reference any other <code>CompiledObjects</code> as they may not have
@@ -411,7 +380,6 @@
return result.toString();
}
-
protected String getInitializationCode(EventHandler handler, JAXXCompiler compiler) {
MethodDescriptor addMethod = handler.getAddMethod();
ClassDescriptor listenerClass = addMethod.getParameterTypes()[0];
@@ -421,7 +389,6 @@
TypeManager.getJavaCode(compiler.getEventHandlerMethodName(handler)) + "));" + JAXXCompiler.getLineSeparator();
}
-
/**
* Returns Java code to complete final setup on this object. This code may reference other
* <code>CompiledObjects</code>, as they are guaranteed to have all been created by this point.
@@ -432,7 +399,6 @@
return additionCode.toString();
}
-
/**
* Appends code to the initialization code block. A line separator is automatically appended to the end.
*
@@ -444,7 +410,6 @@
this.initializationCode.append(JAXXCompiler.getLineSeparator());
}
-
/**
* Appends code to the addition code block. A line separator is automatically appended to the end.
*
@@ -456,7 +421,6 @@
this.additionCode.append(JAXXCompiler.getLineSeparator());
}
-
/**
* Stores a property for this object. The only effect of calling this method is that the property will
* be returned by <code>getProperties()</code>.
@@ -469,7 +433,6 @@
properties.put(property, value);
}
-
/**
* Returns all properties which have been set for this object.
*
@@ -480,7 +443,6 @@
return properties;
}
-
// TODO: remove this temporary method and complete switchover to MethodDescriptors
public void addEventHandler(String eventId, Method addMethod, Method listenerMethod, String code, JAXXCompiler compiler) {
try {
@@ -490,13 +452,11 @@
MethodDescriptor addMethodDescriptor = descriptor.getMethodDescriptor(addMethod.getName(), listenerDescriptor);
MethodDescriptor listenerMethodDescriptor = listenerDescriptor.getMethodDescriptor(listenerMethod.getName(), ClassDescriptorLoader.getClassDescriptor(listenerMethod.getParameterTypes()[0].getName()));
addEventHandler(eventId, addMethodDescriptor, listenerMethodDescriptor, code, compiler);
- }
- catch (Exception e) {
+ } catch (Exception e) {
throw new RuntimeException(e);
}
}
-
/**
* Adds an event listener to this object. The generated code will appear in the initialization block.
*
@@ -517,7 +477,6 @@
}
}
-
/**
* Adds a child component to this container. The child is added without layout constraints.
*
@@ -530,7 +489,6 @@
addChild(child, null, compiler);
}
-
/**
* Adds a child component to this container. This variant allows the Java code for a layout constraints
* object to be specified.
@@ -546,8 +504,7 @@
if (constraints != null) {
constraints = compiler.checkJavaCode(constraints);
}
- }
- catch (CompilerException e) {
+ } catch (CompilerException e) {
compiler.reportError("While parsing 'constraints' attribute: " + e.getMessage());
}
@@ -561,7 +518,7 @@
String delegateCode = containerDelegate != null ? "." + containerDelegate + "()" : "";
child.setParent(this);
-
+
childs.add(new ChildRef(child, constraints, child.getJavaCode(), delegateCode));
}
}
@@ -571,7 +528,6 @@
return getObjectClass().getName() + "[id='" + id + "']";
}
-
public void registerDataBinding(String src, String property, String assignment, JAXXCompiler compiler) throws CompilerException {
compiler.registerDataBinding(src, getId() + "." + property, assignment);
}
@@ -584,7 +540,7 @@
for (int i = 0, j = getGenericTypesLength(); i < j; i++) {
result += ", " + genericTypes[i];
}
- return "< " + result.substring(1) + " >";
+ return "< " + result.substring(2) + " >";
}
public void setGenericTypes(String[] genericTypes) {
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/SwingUtil.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/SwingUtil.java 2009-03-13 22:00:34 UTC (rev 1265)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/SwingUtil.java 2009-03-14 19:24:14 UTC (rev 1266)
@@ -409,7 +409,10 @@
public void reset() {
setReverse(reverse);
}
-
+
+ public int size() {
+ return tabs.getTabCount();
+ }
public TabbedPaneIterator<O> reverse() {
setReverse(!reverse);
return this;
Deleted: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardAbstractOperationAction.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardAbstractOperationAction.java 2009-03-13 22:00:34 UTC (rev 1265)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardAbstractOperationAction.java 2009-03-14 19:24:14 UTC (rev 1266)
@@ -1,94 +0,0 @@
-package jaxx.runtime.swing.wizard;
-
-import javax.swing.SwingWorker;
-import jaxx.runtime.JAXXContext;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- *
- * @author tony
- * @param <E>
- * @param <O>
- * @param <R>
- * @param <M>
- * @since 1.3
- */
-public abstract class WizardAbstractOperationAction<E extends Enum<E>,O extends Enum<O>, R extends Enum<R>, M extends WizardModelWithOperations<E,O,R>> extends SwingWorker<R, String> {
-
- /** to use log facility, just put in your code: log.info(\"...\"); */
- private static final Log log = LogFactory.getLog(WizardAbstractOperationAction.class);
- O operation;
- Exception error;
-
- public WizardAbstractOperationAction(O operation) {
- super();
- this.operation = operation;
- }
-
- public O getOperation() {
- return operation;
- }
-
- public abstract void start(JAXXContext context);
-
- public abstract void beforeAction(JAXXContext context, M model) throws Exception;
-
- public abstract R doAction(M model) throws Exception;
-
- public abstract R onError(M model, Exception e);
-
- public abstract R onCancel(M model, Exception e);
-
- public abstract void afterAction(M model, R result, Exception error);
-
- protected abstract M getModel();
-
- protected abstract JAXXContext getContext();
-
- @Override
- public String toString() {
- return super.toString() + " < operation: " + operation + ", state: " + getState() + " >";
- }
-
- @Override
- protected R doInBackground() throws Exception {
- R result;
- M model = getModel();
- try {
- log.info(this);
- beforeAction(getContext(), model);
- result = doAction(model);
- } catch (Exception e) {
- error = e;
- result = onError(model, e);
- }
- return result;
- }
-
- @Override
- protected void done() {
- R result = null;
- log.info(this);
- M model = getModel();
- try {
- if (isCancelled()) {
-
- result = onCancel(model, error);
- } else {
- result = get();
- }
- } catch (Exception e) {
- // ne devrait jamais arrivé ?
- log.error(e.getMessage(), e);
- throw new RuntimeException(e);
- } finally {
- // on enregistre le resultat de l'opération
-
- model.setOperationResult(operation, result);
-
- // on notifie le resultat de l'action
- firePropertyChange(WizardModelWithOperations.OPERATION_RESULT_PROPERTY_NAME, null, result);
- }
- }
-}
Deleted: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardAbstractOperationActionThread.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardAbstractOperationActionThread.java 2009-03-13 22:00:34 UTC (rev 1265)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardAbstractOperationActionThread.java 2009-03-14 19:24:14 UTC (rev 1266)
@@ -1,265 +0,0 @@
-package jaxx.runtime.swing.wizard;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-import java.util.Date;
-import jaxx.runtime.JAXXContext;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Thread qui réalise les opérations.
- *
- * Pour exécuter une nouvelle opération, on utilise la méthode
- * {@link #launchOperation(SynchroActionWorker)}.
- *
- * Le thread possède 2 états internes :
- *
- * - busy lorsqu'il exécute une opération
- *
- * - canceled lorqu'une annulation a été demandée via la méthode {@link #setCanceled(boolean)}
- *
- * Note: Pour bloquer (ou débloquer) le thread, on utilise la méthode {@link #setwaiting(boolean)}
- * @param <E> le type des etapes
- * @param <O> le type des operations
- * @param <R> le type des resultats d'operation
- * @param <M> le type de modele
- * @param <A> le type d'action d'operation
- *
- * @author tony
- * @since 1.3
- */
-public abstract class WizardAbstractOperationActionThread<E extends Enum<E>, O extends Enum<O>, R extends Enum<R>, M extends WizardModelWithOperations<E, O, R>, A extends WizardAbstractOperationAction<E, O, R, M>> extends Thread implements PropertyChangeListener {
-
- /** to use log facility, just put in your code: log.info(\"...\"); */
- private static final Log log = LogFactory.getLog(WizardAbstractOperationActionThread.class);
- public static final String BUSY_PROPERTY_NAME = "busy";
- public static final String CANCELED_PROPERTY_NAME = "canceled";
- /**
- * l'état du thread pendant les étapes non interactives
- */
- private boolean busy;
- /**
- * l'état du thread si annulé
- */
- private boolean canceled;
- /** suport of modification propagation */
- protected PropertyChangeSupport pcs;
- /** le context applicatif */
- protected JAXXContext cotext;
- protected Class<M> modelClass;
- protected A currentAction;
- /**
- * un lock pour permettre la suspension et la reprise du thread
- * lors du mode interactif.
- */
- private final Object LOCK = new Object();
-
- protected abstract M getModel();
- protected abstract JAXXContext getContext();
-
- public WizardAbstractOperationActionThread(Class<M> modelClass) throws IllegalArgumentException {
- super(WizardAbstractOperationActionThread.class.getSimpleName() + " " + new Date());
- this.modelClass = modelClass;
- this.pcs = new PropertyChangeSupport(this);
- }
-
- public boolean isBusy() {
- return busy;
- }
-
- public boolean isCanceled() {
- return canceled;
- }
-
- public void cancel() {
- setCanceled(true);
- //currentAction = null;
- setBusy(false);
- setWaiting(false);
- }
-
- public void launchOperation(A action) {
-
- if (busy || currentAction != null) {
- // on ne peut traiter qu'une seule opération à la fois
- throw new IllegalStateException("can not add a operation when thread is busy, or has another operation to be done");
- }
- currentAction = action;
- // on libere le thread pour qu'il execute l'opération
- setWaiting(false);
- }
-
- @Override
- public void propertyChange(PropertyChangeEvent evt) {
- if (WizardModelWithOperations.OPERATION_RESULT_PROPERTY_NAME.equals(evt.getPropertyName())) {
- // on rend la main au thread pour qu'il attende une prochaine operation
- setWaiting(false);
- }
- }
-
- @Override
- public void run() {
- try {
-
- // on vérifie que le context contient bien le modèle
- if (getModel()==null) {
- throw new NullPointerException("could not find model "+modelClass+" for "+this);
- }
-
- while (!canceled) {
-
- if (canceled) {
- // une annulation a été demandé
- // donc même si une opération est demandée, on ne la traite
- // pas
- break;
- }
-
- // en attente qu'une opération
- // le block est bloqué jusqu'à arrivée d'une opération
- // ou une demande d'annulation
- setWaiting(true);
-
- // le thread a repris la main, donc plus en attente
- log.trace("no more waiting " + this);
-
- if (!canceled) {
- // une opération a été demandée
-
- // le thread passe en éta occupé
- setBusy(true);
- // le thread écoute les modifications de l'action
- currentAction.addPropertyChangeListener(this);
- // démarrage de l'opération
- currentAction.start(getContext());
- // le thread est bloqué jusqu'à la fin de l'opération
- // ou une demande d'annulation
- setWaiting(true);
- // la main a ete rendue, le thread n'est plus actif
- setBusy(false);
- }
-
- // le thread reprend la main des que l'operation
- // est terminée ou a été annulée, on passera alors
- // dans la méthode onPropertyChanged
- if (currentAction != null) {
- // le thread n'écoute plus l'action car elle est terminée
- // ou annulée
- currentAction.removePropertyChangeListener(this);
- // suppression de l'action
- currentAction = null;
- }
-
- }
-
- } catch (Exception e) {
- throw new RuntimeException(e);
- } finally {
- if (busy) {
- setBusy(false);
- setWaiting(false);
- }
-
- log.info(this + " will close...");
- close();
- }
- }
-
- /**
- * La méthode pour nettoyer le thread, a la fermeture.
- *
- */
- protected void close() {
- // par defaut, on ne fait rien
- log.info(this);
- }
-
- // PropertyChanged support
- public void addPropertyChangeListener(PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(listener);
- }
-
- public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- pcs.addPropertyChangeListener(propertyName, listener);
- }
-
- public void removePropertyChangeListener(PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(listener);
- }
-
- public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- pcs.removePropertyChangeListener(propertyName, listener);
- }
-
- public synchronized boolean hasListeners(String propertyName) {
- return pcs.hasListeners(propertyName);
- }
-
- public synchronized PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
- return pcs.getPropertyChangeListeners(propertyName);
- }
-
- public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
- return pcs.getPropertyChangeListeners();
- }
-
- protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
- pcs.firePropertyChange(propertyName, oldValue, newValue);
- }
-
- protected void setBusy(boolean busy) {
- boolean oldValue = this.busy;
- this.busy = busy;
- firePropertyChange(BUSY_PROPERTY_NAME, oldValue, busy);
- }
-
- protected void setCanceled(boolean canceled) {
- boolean oldValue = this.canceled;
- this.canceled = canceled;
- if (currentAction != null) {
- log.info("cancel action " + currentAction);
- // on a une action en cours, on l'annule
- currentAction.cancel(true);
- }
- // on annule aussi le model
- getModel().cancel();
- //on notifie les écouteur que le thread est annulé
- firePropertyChange(CANCELED_PROPERTY_NAME, oldValue, canceled);
- }
-
- protected void setWaiting(boolean waiting) {
-
- if (waiting && !canceled) {
- // locking thread
- try {
- lockThread();
- } catch (InterruptedException ex) {
- log.error(ex.getMessage(), ex);
- canceled = true;
- }
- }
-
- if (!waiting) {
- // release lock
- unlockThread();
- }
- }
-
- protected void lockThread() throws InterruptedException {
- synchronized (LOCK) {
- log.trace(this);
- // lock
- LOCK.wait();
- }
- }
-
- protected void unlockThread() {
- synchronized (LOCK) {
- log.trace(this);
- // unlock
- LOCK.notify();
- }
- }
-}
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java 2009-03-13 22:00:34 UTC (rev 1265)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java 2009-03-14 19:24:14 UTC (rev 1266)
@@ -19,7 +19,6 @@
public static final String PREVIOUS_STEP_PROPERTY_NAME = "previousStep";
public static final String NEXT_STEP_PROPERTY_NAME = "nextStep";
public static final String VALID_STEP_PROPERTY_NAME = "validStep";
-
/**
* le type d'une etape du model (doit etre une enumeration)
*/
@@ -134,7 +133,7 @@
// la propriete nextStep peut avoir changee
firePropertyChange(NEXT_STEP_PROPERTY_NAME, null, getNextStep());
}
-
+
public boolean validate(E s) {
return step != null;
}
@@ -160,6 +159,7 @@
pcs.removePropertyChangeListener(l);
}
}
+
protected Class<E> getStepClass() {
return stepClass;
}
@@ -190,7 +190,10 @@
pcs.firePropertyChange(propertyName, oldValue, newValue);
}
+ protected void fireIndexedPropertyChange(String propertyName, int index, Object oldValue, Object newValue) {
+ pcs.fireIndexedPropertyChange(propertyName, index, oldValue, newValue);
+ }
+
protected void updateUniverse() {
-
}
}
Deleted: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModelWithOperations.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModelWithOperations.java 2009-03-13 22:00:34 UTC (rev 1265)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModelWithOperations.java 2009-03-14 19:24:14 UTC (rev 1266)
@@ -1,96 +0,0 @@
-package jaxx.runtime.swing.wizard;
-
-import java.util.EnumMap;
-import java.util.EnumSet;
-
-/**
- * Un modèle de wizard.
- *
- * @param <E> le type de l'énumération contenant les etapes.
- *
- * @param <O> le type de l'énumeration des opérations
- * @param <R> le type de l'énumération des résultats d'opération
- * @author tony
- * @since 1.3
- */
-public abstract class WizardModelWithOperations<E extends Enum<E>, O extends Enum<O>, R extends Enum<R>> extends WizardModel<E> {
-
- public static final String OPERATIONS_PROPERTY_NAME = "operations";
- public static final String OPERATION_RESULT_PROPERTY_NAME = "operationResult";
- /**
- * La liste des opérations à effectuer
- */
- protected EnumSet<O> operations;
- /**
- * Pour conserver les résultats des opérations
- */
- protected EnumMap<O, R> operationResults;
- protected Class<O> operationClass;
- protected Class<R> operationResultClass;
-
- public abstract void cancel();
-
- //protected abstract boolean isCancelResult(R operationResult);
- //protected abstract boolean isErrorResult(R operationResult);
-
- public WizardModelWithOperations(Class<E> stepClass, Class<O> operationClass, Class<R> operationResultClass, E... steps) {
- super(stepClass, steps);
- this.operationClass = operationClass;
- this.operationResultClass = operationResultClass;
- operationResults = new EnumMap<O, R>(operationClass);
- }
-
- public EnumSet<O> getOperations() {
- if (operations == null) {
- operations = EnumSet.noneOf(operationClass);
- }
- return operations;
- }
-
- public R getOperationResult(O operation) {
- return operationResults.get(operation);
- }
-
- public void setOperationResult(O operation, R operationResult) {
- R oldValue = getOperationResult(operation);
- operationResults.put(operation, operationResult);
- firePropertyChange(OPERATION_RESULT_PROPERTY_NAME, oldValue, operationResult);
- }
-
- @Override
- public void start() {
- super.start();
- firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations);
- }
-
- public WizardModelWithOperations<E, O, R> addOperation(O operation) {
- getOperations().add(operation);
- /*if (operation == SynchroOperation.EXPORT_DATA) {
- // pour exporter les données utilisateurs
- // les operations synchronisation de référentiel et validation
- // sont necessaires
- getOperations().add(SynchroOperation.SYNCHRONIZE_REFERENTIEL);
- getOperations().add(SynchroOperation.VALIDATION);
- }*/
- // on force la propagation de la nouvelle liste
- firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations);
-
- updateUniverse();
- validate();
- return this;
- }
-
- public void removeOperation(O operation) {
- getOperations().remove(operation);
- /*if (operation == SynchroOperation.SYNCHRONIZE_REFERENTIEL || operation == SynchroOperation.VALIDATION) {
- // pour exporter les données utilisateurs
- // les operations synchronisation de référentiel et validation
- // sont necessaires
- getOperations().remove(SynchroOperation.EXPORT_DATA);
- }*/
- // on force la propagation de la nouvelle liste
- firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations);
- updateUniverse();
- validate();
- }
-}
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperation.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperation.java 2009-03-13 22:00:34 UTC (rev 1265)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperation.java 2009-03-14 19:24:14 UTC (rev 1266)
@@ -6,7 +6,7 @@
* @author tony
* @since 1.3
*/
-public interface WizardOperation<Action extends WizardAbstractOperationAction> {
+public interface WizardOperation<Action extends WizardOperationAction> {
String name();
Copied: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java (from rev 1265, jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardAbstractOperationAction.java)
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java 2009-03-14 19:24:14 UTC (rev 1266)
@@ -0,0 +1,94 @@
+package jaxx.runtime.swing.wizard;
+
+import javax.swing.SwingWorker;
+import jaxx.runtime.JAXXContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @author tony
+ * @param <E> le type d'étapes
+ * @param <O> le type d'opérations
+ * @param <M> le type de modèle
+ * @since 1.3
+ */
+public abstract class WizardOperationAction<E extends Enum<E>, O extends Enum<O>, M extends WizardOperationModel<E, O>> extends SwingWorker<WizardOperationState, String> {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ private static final Log log = LogFactory.getLog(WizardOperationAction.class);
+ O operation;
+ WizardOperationState operationState;
+ Exception error;
+
+ public WizardOperationAction(O operation) {
+ super();
+ this.operation = operation;
+ }
+
+ public O getOperation() {
+ return operation;
+ }
+
+ public abstract void start(JAXXContext context);
+
+ public abstract void beforeAction(JAXXContext context, M model) throws Exception;
+
+ public abstract WizardOperationState doAction(M model) throws Exception;
+
+ public abstract WizardOperationState onError(M model, Exception e);
+
+ public abstract WizardOperationState onCancel(M model, Exception e);
+
+ public abstract void afterAction(M model, WizardOperationState result, Exception error);
+
+ protected abstract M getModel();
+
+ public WizardOperationState getOperationState() {
+ return operationState;
+ }
+
+ protected abstract JAXXContext getContext();
+
+ @Override
+ public String toString() {
+ return super.toString() + " < operation: " + operation + ", state: " + getState() + " >";
+ }
+
+ @Override
+ protected WizardOperationState doInBackground() throws Exception {
+ log.trace(this);
+ WizardOperationState result;
+ M model = getModel();
+ try {
+ beforeAction(getContext(), model);
+ result = doAction(model);
+ } catch (Exception e) {
+ error = e;
+ result = onError(model, e);
+ }
+ return result;
+ }
+
+ @Override
+ protected void done() {
+ log.trace(this);
+ WizardOperationState result = null;
+ try {
+ if (isCancelled()) {
+
+ result = onCancel(getModel(), error);
+ } else {
+ result = get();
+ }
+ } catch (Exception e) {
+ result = WizardOperationState.FAILED;
+ error = e;
+ // ne devrait jamais arrivé ?
+ log.error(e.getMessage(), e);
+ } finally {
+ // on enregistre le resultat de l'opération
+ this.operationState = result;
+ }
+ }
+}
Property changes on: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java (from rev 1265, jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardAbstractOperationActionThread.java)
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java 2009-03-14 19:24:14 UTC (rev 1266)
@@ -0,0 +1,235 @@
+package jaxx.runtime.swing.wizard;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.Date;
+import javax.swing.SwingWorker.StateValue;
+import jaxx.runtime.JAXXContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Thread qui réalise les opérations.
+ *
+ * Pour exécuter une nouvelle opération, on utilise la méthode
+ * {@link #launchOperation(SynchroActionWorker)}.
+ *
+ * Note: Pour bloquer (ou débloquer) le thread, on utilise la méthode {@link #setWaiting(boolean)}
+ *
+ * @param <E> le type des etapes
+ * @param <O> le type des operations
+ * @param <M> le type de modele
+ * @param <A> le type d'action d'operation
+ *
+ * @author tony
+ * @since 1.3
+ */
+public abstract class WizardOperationActionThread<E extends Enum<E>, O extends Enum<O>, M extends WizardOperationModel<E, O>, A extends WizardOperationAction<E, O, M>> extends Thread implements PropertyChangeListener {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ private static final Log log = LogFactory.getLog(WizardOperationActionThread.class);
+ /**
+ * l'état du thread si annulé
+ */
+ private boolean canceled;
+ /** suport of modification propagation */
+ protected PropertyChangeSupport pcs;
+ protected Class<M> modelClass;
+ protected A currentAction;
+ /**
+ * un lock pour permettre la suspension et la reprise du thread
+ * lors du mode interactif.
+ */
+ private final Object LOCK = new Object();
+
+ protected abstract M getModel();
+
+ protected abstract JAXXContext getContext();
+
+ public WizardOperationActionThread(Class<M> modelClass) throws IllegalArgumentException {
+ super(WizardOperationActionThread.class.getSimpleName() + " " + new Date());
+ this.modelClass = modelClass;
+ this.pcs = new PropertyChangeSupport(this);
+ }
+
+ public void cancel() {
+ if (currentAction != null) {
+ log.debug("cancel action " + currentAction);
+ // on a une action en cours, on l'annule
+ currentAction.cancel(true);
+ }
+ // on annule aussi le modele
+ getModel().cancel();
+ this.canceled = true;
+ // on rend la main au thread
+ setWaiting(false);
+ }
+
+ public void launchOperation(A action) {
+
+ if (currentAction != null) {
+ // on ne peut traiter qu'une seule opération à la fois
+ throw new IllegalStateException("can not add a operation when thread is busy, or has another operation to be done");
+ }
+ currentAction = action;
+ // on libere le thread pour qu'il execute l'opération
+ setWaiting(false);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ log.info(evt.getPropertyName() + " <" + evt.getOldValue() + " - " + evt.getNewValue() + ">");
+ if ("state".equals(evt.getPropertyName())) {
+ //@SuppressWarnings("unchecked")
+ //A action = (A) evt.getSource();
+ StateValue state = (StateValue) evt.getNewValue();
+ if (state == StateValue.DONE) {
+ // on rend la main au thread pour qu'il attende une prochaine operation
+ //getModel().setOperationState(action.getOperation(), action.getOperationState());
+ setWaiting(false);
+ }
+ }
+ }
+
+ @Override
+ public void run() {
+ try {
+
+ // on vérifie que le context contient bien le modèle
+ if (getModel() == null) {
+ throw new NullPointerException("could not find model " + modelClass + " for " + this);
+ }
+
+ while (!canceled) {
+
+ if (canceled) {
+ // une annulation a été demandé
+ // donc même si une opération est demandée, on ne la traite
+ // pas
+ break;
+ }
+
+ // en attente qu'une opération
+ // le block est bloqué jusqu'à arrivée d'une opération
+ // ou une demande d'annulation
+ setWaiting(true);
+
+ // le thread a repris la main, donc plus en attente
+ log.trace("no more waiting " + this);
+
+ if (!canceled) {
+ // une opération a été demandée
+
+ // le thread écoute les modifications de l'action
+ currentAction.addPropertyChangeListener(this);
+
+ // l'opération passe en etant en cours
+ getModel().setOperationState(WizardOperationState.RUNNING);
+
+ // démarrage de l'opération dans un worker
+ currentAction.start(getContext());
+ // le thread est bloqué jusqu'à la fin de l'opération
+ // ou une demande d'annulation
+ setWaiting(true);
+
+ // le thread reprend la main des que l'operation
+ // est terminée ou a été annulée, on passera alors
+ // dans la méthode onPropertyChanged
+
+ getModel().setOperationState(currentAction.getOperationState());
+
+ // le thread n'écoute plus l'action car elle est terminée
+ // ou annulée
+ currentAction.removePropertyChangeListener(this);
+ // suppression de l'action
+ currentAction = null;
+ }
+
+ }
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ unlockThread();
+ log.trace(this + " will close...");
+ close();
+ }
+ }
+
+ /**
+ * La méthode pour nettoyer le thread, a la fermeture.
+ *
+ */
+ protected void close() {
+ // par defaut, on ne fait rien
+ log.trace(this);
+ }
+
+ // PropertyChanged support
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ pcs.addPropertyChangeListener(listener);
+ }
+
+ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ pcs.addPropertyChangeListener(propertyName, listener);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ pcs.removePropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ pcs.removePropertyChangeListener(propertyName, listener);
+ }
+
+ public synchronized boolean hasListeners(String propertyName) {
+ return pcs.hasListeners(propertyName);
+ }
+
+ public synchronized PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
+ return pcs.getPropertyChangeListeners(propertyName);
+ }
+
+ public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
+ return pcs.getPropertyChangeListeners();
+ }
+
+ protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
+ pcs.firePropertyChange(propertyName, oldValue, newValue);
+ }
+
+ protected void setWaiting(boolean waiting) {
+
+ if (waiting && !canceled) {
+ // locking thread
+ try {
+ lockThread();
+ } catch (InterruptedException ex) {
+ log.error(ex.getMessage(), ex);
+ canceled = true;
+ }
+ }
+
+ if (!waiting) {
+ // release lock
+ unlockThread();
+ }
+ }
+
+ protected void lockThread() throws InterruptedException {
+ synchronized (LOCK) {
+ log.trace(this);
+ // lock
+ LOCK.wait();
+ }
+ }
+
+ protected void unlockThread() {
+ synchronized (LOCK) {
+ log.trace(this);
+ // unlock
+ LOCK.notify();
+ }
+ }
+}
Property changes on: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java (from rev 1265, jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModelWithOperations.java)
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java 2009-03-14 19:24:14 UTC (rev 1266)
@@ -0,0 +1,191 @@
+package jaxx.runtime.swing.wizard;
+
+import java.util.EnumMap;
+import java.util.EnumSet;
+
+/**
+ * Un modèle de wizard avec des opérations.
+ *
+ * @param <E> le type des étapes.
+ * @param <O> le type des opérations.
+ * @author tony
+ * @since 1.3
+ */
+public class WizardOperationModel<E extends Enum<E>, O extends Enum<O>> extends WizardModel<E> {
+
+ public static final String OPERATIONS_PROPERTY_NAME = "operations";
+ public static final String OPERATION_STATE_PROPERTY_NAME = "operationState";
+ public static final String MODEL_STATE_PROPERTY_NAME = "modelState";
+ public static final String WAS_STARTED_PROPERTY_NAME = "wasStarted";
+ /**
+ * le type d'une opération
+ */
+ protected Class<O> operationClass;
+ /**
+ * La liste des opérations à effectuer
+ */
+ protected EnumSet<O> operations;
+ /**
+ * Pour conserver les états des opérations
+ */
+ protected EnumMap<O, WizardOperationState> operationStates;
+ /**
+ * L'état générale du modèle
+ */
+ protected WizardOperationState modelState;
+ /**
+ * un drapeau pour savoir siune opération a été lancée
+ */
+ protected boolean wasStarted;
+
+ public WizardOperationModel(Class<E> stepClass, Class<O> operationClass, E... steps) {
+ super(stepClass, steps);
+ this.operationClass = operationClass;
+ this.operationStates = new EnumMap<O, WizardOperationState>(operationClass);
+ }
+
+ public EnumSet<O> getOperations() {
+ if (operations == null) {
+ operations = EnumSet.noneOf(operationClass);
+ }
+ return operations;
+ }
+
+ public WizardOperationState getModelState() {
+ return modelState;
+ }
+
+ public boolean isWasStarted() {
+ return wasStarted;
+ }
+
+ @SuppressWarnings("unchecked")
+ public O getOperation() {
+ return ((WizardOperationStep<O>) getStep()).getOperation();
+ }
+
+ public WizardOperationState getOperationState() {
+ O operation = getOperation();
+ return getOperationState(operation);
+ }
+
+ public WizardOperationState getOperationState(O operation) {
+ return operationStates.get(operation);
+ }
+
+ public void setOperationState(WizardOperationState operationState) {
+ O operation = getOperation();
+ setOperationState(operation, operationState);
+ }
+
+ public void setOperationState(O operation, WizardOperationState operationState) {
+ WizardOperationState oldValue = getOperationState(operation);
+ this.operationStates.put(operation, operationState);
+ firePropertyChange(OPERATION_STATE_PROPERTY_NAME, oldValue, operationState);
+ //fireIndexedPropertyChange(OPERATION_STATE_PROPERTY_NAME, getOperationIndex(operation), oldValue, operationStates);
+ updateModelState(operation, operationState);
+ validate();
+ }
+
+ @Override
+ public void start() {
+ super.start();
+ // le modèle n'est pas démarré
+ setModelState(WizardOperationState.PENDING);
+ firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations);
+ }
+
+ public void cancel() {
+ for (O op : operations) {
+ if (getOperationState(op) == WizardOperationState.PENDING) {
+ // on annule l'opération à venir
+ setOperationState(op, WizardOperationState.CANCELED);
+ }
+ }
+ }
+
+ public WizardOperationModel<E, O> addOperation(O operation) {
+ getOperations().add(operation);
+ // on force la propagation de la nouvelle liste
+ firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations);
+ // mis a jour de l'univers des etapes et operations
+ updateUniverse();
+ // validation
+ validate();
+ return this;
+ }
+
+ public void removeOperation(O operation) {
+ getOperations().remove(operation);
+ // on force la propagation de la nouvelle liste
+ firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations);
+ // mis a jour de l'univers des etapes et operations
+ updateUniverse();
+ // validation
+ validate();
+ }
+
+ protected void setModelState(WizardOperationState modelState) {
+ WizardOperationState oldValue = this.modelState;
+ this.modelState = modelState;
+ firePropertyChange(MODEL_STATE_PROPERTY_NAME, oldValue, modelState);
+ if (!wasStarted) {
+ if ((oldValue == null || oldValue == WizardOperationState.PENDING) && modelState == WizardOperationState.RUNNING) {
+ this.wasStarted = true;
+ firePropertyChange(WAS_STARTED_PROPERTY_NAME, false, true);
+ }
+ }
+ }
+
+ protected void updateModelState(O operation, WizardOperationState operationState) {
+
+ switch (operationState) {
+ case RUNNING:
+ //le model est occupé
+ setModelState(WizardOperationState.RUNNING);
+ break;
+ case FAILED:
+ //le model est en attente
+ setModelState(WizardOperationState.PENDING);
+ break;
+ case CANCELED:
+ //le model devient annulé
+ setModelState(WizardOperationState.CANCELED);
+ break;
+ case PENDING:
+ //le model est en attente
+ setModelState(WizardOperationState.PENDING);
+ break;
+ case NEED_FIX:
+ //le model est en attente
+ setModelState(WizardOperationState.PENDING);
+ break;
+ case SUCCESSED:
+ // on regarde si on peut passer le model a l'état success
+ boolean valid = true;
+ for (O o : operations) {
+ if (getOperationState(o) != WizardOperationState.SUCCESSED) {
+ valid = false;
+ break;
+ }
+ }
+ if (valid) {
+ setModelState(WizardOperationState.SUCCESSED);
+ } else {
+ setModelState(WizardOperationState.PENDING);
+ }
+ break;
+ }
+ }
+
+ protected int getOperationIndex(O operation) {
+ int index = 0;
+ for (O o : operations) {
+ if (operation == o) {
+ return index;
+ }
+ index++;
+ }
+ return -1;
+ }
+}
Property changes on: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java
___________________________________________________________________
Name: svn:mergeinfo
+
Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationState.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationState.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationState.java 2009-03-14 19:24:14 UTC (rev 1266)
@@ -0,0 +1,32 @@
+package jaxx.runtime.swing.wizard;
+
+/**
+ * Pour caractériser l'état d'une opération.
+ */
+public enum WizardOperationState {
+
+ /**
+ * quand l'opération n'a pas encore été réalisée
+ */
+ PENDING,
+ /**
+ * quand l'opération est en cours
+ */
+ RUNNING,
+ /**
+ * quand l'opération est annulé en cours d'exécution
+ */
+ CANCELED,
+ /**
+ * quand une erreur s'est produite pendant l'exécution
+ */
+ FAILED,
+ /**
+ * quand l'exécution s'est terminée mais requière des corrections
+ */
+ NEED_FIX,
+ /**
+ * quand l'exécution s'est terminée et ne requière pas de correction
+ */
+ SUCCESSED
+}
Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationStep.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationStep.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationStep.java 2009-03-14 19:24:14 UTC (rev 1266)
@@ -0,0 +1,20 @@
+package jaxx.runtime.swing.wizard;
+
+/**
+ *
+ * @param <Operation>
+ * @author tony
+ * @since 1.3
+ */
+public interface WizardOperationStep<Operation extends Enum<Operation>> {
+
+ String name();
+
+ int ordinal();
+
+ String getLabel();
+
+ String getDescription();
+
+ Operation getOperation();
+}
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUI.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUI.java 2009-03-13 22:00:34 UTC (rev 1265)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUI.java 2009-03-14 19:24:14 UTC (rev 1266)
@@ -18,8 +18,6 @@
M getModel();
- void init();
-
void start();
JTabbedPane getTabs();
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java 2009-03-13 22:00:34 UTC (rev 1265)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java 2009-03-14 19:24:14 UTC (rev 1266)
@@ -20,18 +20,14 @@
protected UI ui;
- protected abstract void doAction(UI ui);
-
@SuppressWarnings("unchecked")
public WizardUILancher(JAXXContext context, JFrame mainUI, Class<UI> uiClass, Class<M> modelClass) {
super();
try {
+ // instanciate ui parent context
JAXXInitialContext uiContext = new JAXXInitialContext();
- // instanciate ui
- // parent context
uiContext.add(mainUI == null ? context : mainUI);
- // parent context
- // model
+ // parent context model
uiContext.add(modelClass.newInstance());
// apply action
uiContext.add("apply", new Runnable() {
@@ -51,7 +47,7 @@
});
// instanciate ui
- ui = (UI) ConstructorUtils.invokeConstructor(uiClass, new Object[]{mainUI, uiContext});
+ ui = (UI) ConstructorUtils.invokeConstructor(uiClass, new Object[]{mainUI, uiContext}, new Class[]{JFrame.class, JAXXContext.class});
} catch (Exception ex) {
throw new RuntimeException("could not instanciate launcher for reason " + ex.getMessage(), ex);
@@ -59,20 +55,28 @@
}
public void start() {
- init(ui);
- //ui.start();
+ try {
+ init(ui);
+ ui.start();
+ } finally {
+ dispose();
+ }
}
+ public void dispose() {
+ ui = null;
+ }
+
protected void init(UI ui) {
}
- protected void afterInit(UI ui) {
+ protected void doAction(UI ui) {
}
protected void doCancel(UI ui) {
}
- public <T> T getContextValue(Class<T> clazz, String name) {
+ protected <T> T getContextValue(Class<T> clazz, String name) {
if (ui == null) {
throw new NullPointerException("ui can not be null");
}
@@ -83,11 +87,7 @@
return ((JAXXObject) ui).getContextValue(clazz, name);
}
- public <T> T getContextValue(Class<T> clazz) {
+ protected <T> T getContextValue(Class<T> clazz) {
return getContextValue(clazz, null);
}
-
- public void dispose() {
- ui = null;
- }
}
1
0