Author: tchemit Date: 2008-10-25 17:03:27 +0000 (Sat, 25 Oct 2008) New Revision: 994 Added: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JAXXInitialContext.java lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/ValidationBeanClass.jaxx Modified: lutinjaxx/trunk/jaxx-core/changelog lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXObjectGenerator.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java lutinjaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/CompilerTest.java Log: * improve BeanValidator tag : - add a beanInitializer attribute for set the validator's bean at runtime - add a default errorListModel value 'errors' *introduce JAXXInitialContext to fill JAXXContext at runtime before $initialize() method Modified: lutinjaxx/trunk/jaxx-core/changelog =================================================================== --- lutinjaxx/trunk/jaxx-core/changelog 2008-10-24 17:44:12 UTC (rev 993) +++ lutinjaxx/trunk/jaxx-core/changelog 2008-10-25 17:03:27 UTC (rev 994) @@ -1,5 +1,9 @@ ver-0-6 chemit 200811?? - * 20081024 [chemit] fix validator context lost if UI is launched from another thread + * 20081025 [chemit] improve BeanValidator tag : + - add a beanInitializer attribute for set the validator's bean at runtime + - add a default errorListModel value 'errors' + * 20081025 [chemit] introduce JAXXInitialContext to fill JAXXContext at runtime before $initialize() method + * 20081024 [chemit] fix validator context lost if UI is launched from another thread ver-0-5 chemit 20081002 * 20081017 [chemit] add validator support * 20081013 [chemit] can generate logger on jaxx files Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXObjectGenerator.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXObjectGenerator.java 2008-10-24 17:44:12 UTC (rev 993) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXObjectGenerator.java 2008-10-25 17:03:27 UTC (rev 994) @@ -141,12 +141,14 @@ } javaFile.addImport("jaxx.runtime.validator.BeanValidator"); - + javaFile.addImport("jaxx.runtime.JAXXInitialContext"); + if (compiler.getStylesheet() != null) { javaFile.addField(new JavaField(0, "java.util.Map", "$previousValues", "new java.util.HashMap()")); } javaFile.addMethod(createConstructor(className)); + javaFile.addMethod(createConstructorWithInitialContext(className)); javaFile.addMethod(createInitializer(className)); javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "BeanValidator<?>", "getValidator", new JavaArgument[]{new JavaArgument("String", "validatorId")}, null, "return (BeanValidator)(validatorIds.contains(validatorId)?getObjectById(validatorId):null);")); @@ -399,7 +401,22 @@ return new JavaMethod(Modifier.PUBLIC, null, className, null, null, code.toString()); } + protected JavaMethod createConstructorWithInitialContext(String className) throws CompilerException { + StringBuffer code = new StringBuffer(); + String constructorParams = compiler.getRootObject().getConstructorParams(); + if (constructorParams != null) { + code.append(" super(").append(constructorParams).append(");"); + code.append(JAXXCompiler.getLineSeparator()); + } + code.append("initialContext.to(this);"); + code.append(JAXXCompiler.getLineSeparator()); + code.append("$initialize();"); + code.append(JAXXCompiler.getLineSeparator()); + JavaArgument arg = new JavaArgument("jaxx.runtime.JAXXInitialContext","initialContext"); + return new JavaMethod(Modifier.PUBLIC, null, className, new JavaArgument[]{arg}, null, code.toString()); + } + protected JavaMethod createInitializer(String className) throws CompilerException { StringBuffer code = new StringBuffer(); CompiledObject root = compiler.getRootObject(); Added: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JAXXInitialContext.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JAXXInitialContext.java (rev 0) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JAXXInitialContext.java 2008-10-25 17:03:27 UTC (rev 994) @@ -0,0 +1,133 @@ +package jaxx.runtime; + +import java.awt.Container; +import java.util.LinkedHashSet; +import java.util.Map.Entry; +import java.util.Set; + +/** + * An initial context to be inject in a {@link JAXXObject}. + * <p/> + * The method {@link #add(Object)} register a simple value. + * <p/> + * The method {@link #add(String, Object)} register a named value. + * <p/> + * The method {@link #to(JAXXObject)} inject in the {@link JAXXObject} the values registred in the initial context. + * <p/> + * The initial context is also a "limited" {@link JAXXContext}, since we can only use the two methods + * <p/> + * {@link #getContextValue(Class)} or {@link #getContextValue(Class, String)}. + * + * @see JAXXContext + */ +public class JAXXInitialContext implements JAXXContext { + + public static class JAXXInitialContextEntry implements Entry<String, Object> { + + protected String key; + protected Object value; + + public JAXXInitialContextEntry(String key, Object value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public Object getValue() { + return value; + } + + public Object setValue(Object value) { + Object oldValue = this.value; + this.value = value; + return oldValue; + } + + } + + protected Set<Entry<String, Object>> entries; + + public JAXXInitialContext() { + entries = new LinkedHashSet<Entry<String, Object>>(); + } + + /** + * Register a simple (none named) value in the context. + * + * @param value the value to be registred in the context + * @return the instance of the context + */ + public JAXXInitialContext add(Object value) { + return add(null, value); + } + + /** + * Register a named value in the context. + * + * @param name the name of the value + * @param value the value to registred + * @return the instance of the context + */ + public JAXXInitialContext add(String name, Object value) { + entries.add(new JAXXInitialContextEntry(name, value)); + return this; + } + + /** + * Inject all the registed values into the {@link JAXXObject} + * + * @param dst the object to fill. + */ + public void to(JAXXObject dst) { + for (Entry<String, Object> entry : entries) { + if (entry.getKey() == null) { + dst.setContextValue(entry.getValue()); + } else { + dst.setContextValue(entry.getValue(), entry.getKey()); + } + } + } + + @SuppressWarnings({"unchecked"}) + public <T> T getContextValue(Class<T> clazz) { + T result = null; + for (Entry<String, Object> entry : entries) { + if (clazz.isAssignableFrom(entry.getValue().getClass())) { + result = (T) entry.getValue(); + break; + } + } + return result; + } + + @SuppressWarnings({"unchecked"}) + public <T> T getContextValue(Class<T> clazz, String name) { + T result = null; + for (Entry<String, Object> entry : entries) { + if (name.equals(entry.getKey()) && clazz.isAssignableFrom(entry.getValue().getClass())) { + result = (T) entry.getValue(); + } + } + return result; + } + + public void setContextValue(Object o) { + throw new RuntimeException("not implemented"); + } + + public void setContextValue(Object o, String name) { + throw new RuntimeException("not implemented"); + } + + public <O extends Container> O getParentContainer(Class<O> clazz) { + throw new RuntimeException("not implemented"); + } + + public <O extends Container> O getParentContainer(Object top, Class<O> clazz) { + throw new RuntimeException("not implemented"); + } + +} Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java 2008-10-24 17:44:12 UTC (rev 993) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java 2008-10-25 17:03:27 UTC (rev 994) @@ -29,7 +29,12 @@ public static final String BEAN_VALIDATOR_TAG = BeanValidator.class.getSimpleName(); 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_LIST_MODEL_DEFAULT = "errors"; + public static final String AUTOFIELD_ATTRIBUTE = "autoField"; public static final String UI_CLASS_ATTRIBUTE = "uiClass"; public static final String STRICT_MODE_ATTRIBUTE = "strictMode"; @@ -37,12 +42,6 @@ /** to use log facility, just put in your code: log.info(\"...\"); */ static Log log = LogFactory.getLog(BeanValidatorHandler.class); - /** - * Creates a new <code>DefaultObjectHandler</code> which provides support for the specified class. The - * class is not actually introspected until the {@link #compileFirstPass} method is invoked. - * - * @param beanClass the class which this handler supports - */ public BeanValidatorHandler(ClassDescriptor beanClass) { super(beanClass); ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, BeanValidator.class); @@ -72,69 +71,18 @@ CompiledBeanValidator info = (CompiledBeanValidator) objectMap.get(tag); - String tmp; + boolean error = info.addErrorListModel(tag, this, compiler); - tmp = info.getErrorListModel(); - if (tmp != null) { - if (compiler.checkReference(tag, tmp, true, ERROR_LIST_MODEL_ATTRIBUTE)) { - String code = getSetPropertyCode(info.getJavaCode(), ERROR_LIST_MODEL_ATTRIBUTE, tmp, compiler); - info.appendAdditionCode(code); - } + if (!error) { + error = info.addUiClass(this, compiler); } - tmp = info.getUiClass(); - if (tmp != null) { - try { - ClassDescriptor uiClass = ClassDescriptorLoader.getClassDescriptor(tmp); - if (!ClassDescriptorLoader.getClassDescriptor(AbstractBeanValidatorUI.class).isAssignableFrom(uiClass)) { - compiler.reportError("attribute 'ui' :'" + tmp + "' is not assignable from class " + AbstractBeanValidatorUI.class); - } else { - String code = getSetPropertyCode(info.getJavaCode(), UI_CLASS_ATTRIBUTE, uiClass.getName() + ".class", compiler); - info.appendAdditionCode(code); - } - } catch (ClassNotFoundException e) { - compiler.reportError("class not found '" + tmp + "'"); - } + if (!error) { + error = info.addBean(tag, this, compiler); } - String bean = info.getBean(); - boolean error = false; - if (bean != null) { - if (compiler.checkReference(tag, bean, true, BEAN_ATTRIBUTE)) { - String code = getSetPropertyCode(info.getJavaCode(), BEAN_ATTRIBUTE, bean, compiler); - info.appendAdditionCode(code); - // add generic type to validator - JAXXBeanInfo beanInfo = info.getBeanDescriptor(compiler); - info.setGenericTypes(new String[]{beanInfo.getJAXXBeanDescriptor().getClassDescriptor().getName()}); - } else { - error=true; - } - - //TODO: checkthe bean is not already used in another validator - if (!error && compiler.isBeanUsedByValidator(bean)) { - compiler.reportError("the bean '" + bean + "' is already used in another the validator, can not used it in '" + tag + "'"); - error = true; - } - - if (!error && info.getAutoField()) { - //if (bean == null) { - // compiler.reportError("tag '" + tag.getLocalName() + "' need a " + BEAN_ATTRIBUTE + " attribute to use autofield mode"); - //} else { - registerAutoFieldBean(tag, compiler, info); - // } - } - - if (!error && info.getBeanDescriptor(compiler) != null) { - - // add fieldrepresentation invocations - addFieldRepresentations(tag, compiler, info); - - // register the validator in compiler - compiler.registerValidator(info); - } - - } else { - compiler.reportError("tag '" + tag + "' requires a bean attribute"); + if (error) { + log.warn("error were detected in second compile pass of CompiledObject [" + info + "]"); } // close the compiled object @@ -152,77 +100,21 @@ if (compiler.getOptions().isVerbose()) { log.info(propertyName + " : " + stringValue + " for " + object); } + // delegate to the compiled object with is statefull (but not the tag handler) object.addProperty(propertyName, stringValue); } - protected void registerAutoFieldBean(Element tag, JAXXCompiler compiler, CompiledBeanValidator info) { - JAXXBeanInfo beanInfo = info.getBeanDescriptor(compiler); - for (JAXXPropertyDescriptor beanProperty : beanInfo.getJAXXPropertyDescriptors()) { - String descriptionName = beanProperty.getName(); - if (compiler.getOptions().isVerbose()) { - log.info("try to bind on bean " + beanInfo.getJAXXBeanDescriptor().getName() + " property " + descriptionName); - } - if (beanProperty.getWriteMethodDescriptor() == null) { - // read-only property - continue; - } - if (info.getFields().containsKey(descriptionName)) { - // already defined in field - continue; - } - if (!compiler.checkReference(tag, descriptionName, info.getStrictMode(), null)) { - // no editor component found - continue; - } - // ok add the field mapping - info.addField(descriptionName, descriptionName, compiler); - } - } - - protected void addFieldRepresentations(Element tag, JAXXCompiler compiler, CompiledBeanValidator info) { - for (Entry<String, String> entry : info.getFields().entrySet()) { - String propertyName = entry.getKey(); - String component = entry.getValue(); - if (!checkBeanProperty(compiler, info, propertyName)) { - // property not find on bean - continue; - } - if (!compiler.checkReference(tag, component, true, null)) { - // editor component not find on ui - continue; - } - if (compiler.isComponentUsedByValidator(component)) { - // component is already used by another validator - compiler.reportError("component '" + component + "' is already used by another validator."); - continue; - } - String keyCode = TypeManager.getJavaCode(propertyName); - info.appendAdditionCode(info.getJavaCode() + ".setFieldRepresentation(" + keyCode + ", " + component + ");"); - - } - } - - protected boolean checkBeanProperty(JAXXCompiler compiler, CompiledBeanValidator info, String propertyName) { - - for (JAXXPropertyDescriptor beanProperty : info.getBeanDescriptor(compiler).getJAXXPropertyDescriptors()) { - if (beanProperty.getName().equals(propertyName)) { - if (beanProperty.getWriteMethodDescriptor() == null) { - // read-onlyproperty - compiler.reportError("could not bind the readonly property '" + propertyName + "' on bean [" + info.getBean() + "] "); - return false; - } - return true; - } - } - compiler.reportError("could not find the property '" + propertyName + "' on bean [" + info.getBean() + "] "); - return false; - } - - /** @author chemit */ + /** + * The compiled objet representing a BeanValidator to be generated in JAXXObject + * + * @author chemit + */ public static class CompiledBeanValidator extends CompiledObject { protected Map<String, String> fields; protected String bean; + protected String beanClass; + protected String beanInitializer; protected String uiClass; protected String errorListModel; protected Boolean autoField; @@ -251,6 +143,19 @@ } return; } + if (BEAN_CLASS_ATTRIBUTE.equals(property)) { + if (value != null && !value.trim().isEmpty()) { + beanClass = value; + } + return; + } + if (BEAN_INITIALIZER_ATTRIBUTE.equals(property)) { + if (value != null && !value.trim().isEmpty()) { + beanInitializer = value; + } + return; + } + if (ERROR_LIST_MODEL_ATTRIBUTE.equals(property)) { if (value != null && !value.trim().isEmpty()) { errorListModel = value; @@ -281,17 +186,6 @@ super.addProperty(property, value); } - public void addField(String id, String component, JAXXCompiler compiler) { - if (fields.containsKey(id)) { - compiler.reportError("duplicate field '" + id + "' for validator " + this); - } else { - if (compiler.getOptions().isVerbose()) { - log.info("add field <" + id + ":" + component + ">"); - } - fields.put(id, component); - } - } - public String getBean() { return bean; } @@ -312,20 +206,31 @@ return uiClass; } + public String getBeanClass() { + return beanClass; + } + public JAXXBeanInfo getBeanDescriptor(JAXXCompiler compiler) { - if (beanDescriptor == null && bean != null) { + if (beanDescriptor == null && foundBean()) { + + String beanClassName = null; try { - String beanClassName = compiler.getSymbolTable().getClassTagIds().get(bean); - if (beanClassName == null) { - compiler.reportError("could not find class of the bean '" + bean + "'"); - return null; + // get the real bean class name (from bean or beanClass) + if (beanClass != null) { + beanClassName = beanClass; + } else { + 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(beanClassName); - beanDescriptor = getJAXXBeanInfo(beanClassDescriptor); + beanDescriptor = DefaultObjectHandler.getJAXXBeanInfo(beanClassDescriptor); } catch (ClassNotFoundException e) { - compiler.reportError("could not load class " + bean); + compiler.reportError("could not load class " + beanClassName); } catch (IntrospectionException e) { - compiler.reportError("could not load class " + bean); + compiler.reportError("could not load class " + beanClassName); } } return beanDescriptor; @@ -336,5 +241,175 @@ // do nothing compiler.reportError("can not add CompiledObject in the tag '" + BEAN_VALIDATOR_TAG + " (only field tags)"); } + + public boolean foundBean() { + return !(bean == null && beanClass == null); + } + + protected boolean addUiClass(BeanValidatorHandler handler, JAXXCompiler compiler) { + boolean withError = false; + if (uiClass != null) { + try { + ClassDescriptor uiClazz = ClassDescriptorLoader.getClassDescriptor(uiClass); + if (!ClassDescriptorLoader.getClassDescriptor(AbstractBeanValidatorUI.class).isAssignableFrom(uiClazz)) { + compiler.reportError("attribute 'ui' :'" + uiClass + "' is not assignable from class " + AbstractBeanValidatorUI.class); + withError = true; + } else { + String code = handler.getSetPropertyCode(getJavaCode(), UI_CLASS_ATTRIBUTE, uiClazz.getName() + ".class", compiler); + appendAdditionCode(code); + } + } catch (ClassNotFoundException e) { + compiler.reportError("class not found '" + uiClass + "'"); + withError = true; + } + } + return withError; + } + + protected boolean addErrorListModel(Element tag, BeanValidatorHandler handler, JAXXCompiler compiler) { + if (errorListModel == null) { + // try with the default "errors" + + if (!compiler.checkReference(tag, ERROR_LIST_MODEL_DEFAULT, true, ERROR_LIST_MODEL_ATTRIBUTE)) { + return true; + } + String code = handler.getSetPropertyCode(getJavaCode(), ERROR_LIST_MODEL_ATTRIBUTE, ERROR_LIST_MODEL_DEFAULT, compiler); + appendAdditionCode(code); + return false; + } + + if (!compiler.checkReference(tag, errorListModel, true, ERROR_LIST_MODEL_ATTRIBUTE)) { + return true; + } + + String code = handler.getSetPropertyCode(getJavaCode(), ERROR_LIST_MODEL_ATTRIBUTE, errorListModel, compiler); + appendAdditionCode(code); + + return false; + } + + protected boolean addBean(Element tag, BeanValidatorHandler handler, JAXXCompiler compiler) { + + if (!foundBean()) { + compiler.reportError("tag '" + tag + "' requires a 'bean' or a 'beanClass' attribute"); + return true; + } + + if (bean != null) { + + if (!compiler.checkReference(tag, bean, true, BEAN_ATTRIBUTE)) { + // could not find bean in compiled object + return true; + } + + if (compiler.isBeanUsedByValidator(bean)) { + compiler.reportError("the bean '" + bean + "' is already used in another the validator, can not used it in '" + tag + "'"); + return true; + } + + if (beanInitializer != null) { + compiler.reportWarning("tag '" + tag + "' found a 'bean' and a 'beanInitializer' attributes, 'beanInitializer' is skipped"); + } + beanInitializer = bean; + } + + if (beanInitializer != null) { + String code = handler.getSetPropertyCode(getJavaCode(), BEAN_ATTRIBUTE, compiler.checkJavaCode(beanInitializer), compiler); + appendAdditionCode(code); + } + + // add generic type to validator + JAXXBeanInfo beanInfo = getBeanDescriptor(compiler); + setGenericTypes(new String[]{beanInfo.getJAXXBeanDescriptor().getClassDescriptor().getName()}); + + if (getAutoField()) { + registerAutoFieldBean(tag, compiler, beanInfo); + } + + if (getBeanDescriptor(compiler) != null) { + + // add fieldrepresentation invocations + addFieldRepresentations(tag, compiler); + + // register the validator in compiler + compiler.registerValidator(this); + + } + + return false; + } + + protected void addFieldRepresentations(Element tag, JAXXCompiler compiler) { + for (Entry<String, String> entry : fields.entrySet()) { + String propertyName = entry.getKey(); + String component = entry.getValue(); + if (!checkBeanProperty(compiler, propertyName)) { + // property not find on bean + continue; + } + if (!compiler.checkReference(tag, component, true, null)) { + // editor component not find on ui + continue; + } + if (compiler.isComponentUsedByValidator(component)) { + // 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 + ");"); + + } + } + + protected void registerAutoFieldBean(Element tag, JAXXCompiler compiler, JAXXBeanInfo beanInfo) { + for (JAXXPropertyDescriptor beanProperty : beanInfo.getJAXXPropertyDescriptors()) { + String descriptionName = beanProperty.getName(); + if (compiler.getOptions().isVerbose()) { + log.info("try to bind on bean " + beanInfo.getJAXXBeanDescriptor().getName() + " property " + descriptionName); + } + if (beanProperty.getWriteMethodDescriptor() == null) { + // read-only property + continue; + } + if (fields.containsKey(descriptionName)) { + // already defined in field + continue; + } + if (!compiler.checkReference(tag, descriptionName, getStrictMode(), null)) { + // no editor component found + continue; + } + // ok add the field mapping + registerField(descriptionName, descriptionName, compiler); + } + } + + public void registerField(String id, String component, JAXXCompiler compiler) { + if (fields.containsKey(id)) { + compiler.reportError("duplicate field '" + id + "' for validator " + this); + } else { + if (compiler.getOptions().isVerbose()) { + log.info("add field <" + id + ":" + component + ">"); + } + fields.put(id, component); + } + } + + protected boolean checkBeanProperty(JAXXCompiler compiler, String propertyName) { + + for (JAXXPropertyDescriptor beanProperty : getBeanDescriptor(compiler).getJAXXPropertyDescriptors()) { + if (beanProperty.getName().equals(propertyName)) { + if (beanProperty.getWriteMethodDescriptor() == null) { + // read-onlyproperty + compiler.reportError("could not bind the readonly property '" + propertyName + "' on bean [" + getBean() + "] "); + return false; + } + return true; + } + } + compiler.reportError("could not find the property '" + propertyName + "' on bean [" + getBean() + "] "); + return false; + } } } \ No newline at end of file Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java 2008-10-24 17:44:12 UTC (rev 993) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java 2008-10-25 17:03:27 UTC (rev 994) @@ -42,7 +42,7 @@ return; } - CompiledBeanValidator validator = (CompiledBeanValidator) compiler.getOpenComponent(); + CompiledBeanValidator info = (CompiledBeanValidator) compiler.getOpenComponent(); String name = tag.getAttribute(NAME_ATTRIBUTE); String component = tag.getAttribute(COMPONENT_ATTRIBUTE); @@ -61,15 +61,15 @@ } component = component.trim(); - // check component is not already used by this validator - if (validator.getFields().containsValue(component)) { + // check component is not already used by this compiled object + if (info.getFields().containsValue(component)) { compiler.reportError(FIELD_VALIDATOR_TAG + " tag found a attribute " + COMPONENT_ATTRIBUTE + " ["+component+"] already used in this validator"); return; } - // check component exist (again perharps, but if error will known exactly which tag failed...) + // check component exist (again perharps, but let the error knows exactly which tag failed...) if (compiler.checkReference(tag, component, true, COMPONENT_ATTRIBUTE)) { // add a field - validator.addField(name, component, compiler); + info.registerField(name, component, compiler); } Modified: lutinjaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/CompilerTest.java =================================================================== --- lutinjaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/CompilerTest.java 2008-10-24 17:44:12 UTC (rev 993) +++ lutinjaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/CompilerTest.java 2008-10-25 17:03:27 UTC (rev 994) @@ -178,7 +178,7 @@ public void testValidatorOk() throws Exception { mojo.execute(); - assertEquals(1, mojo.getFiles().length); + assertEquals(2, mojo.getFiles().length); } Copied: lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/ValidationBeanClass.jaxx (from rev 968, lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/Validation.jaxx) =================================================================== --- lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/ValidationBeanClass.jaxx (rev 0) +++ lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/ValidationBeanClass.jaxx 2008-10-25 17:03:27 UTC (rev 994) @@ -0,0 +1,111 @@ +<Application title="Validation.jaxx"> + + <!-- models --> + <Identity id='identity'/> + + <!-- errors model --> + <jaxx.runtime.validator.BeanValidatorErrorListModel id='errors'/> + + <!-- validators --> + <BeanValidator id='validator3' autoField='true' beanClass='testcases.validator.ok.Identity' errorListModel='errors'> + <field name="email" component="email2"/> + </BeanValidator> + + <Table fill='both'> + <row> + <cell weightx='1' weighty='1' insets='6, 3, 0, 0'> + <JPanel border='{BorderFactory.createTitledBorder("Identify Form")}' + layout='{new GridLayout()}' width='250' height='140'> + <Table anchor='west' fill='both'> + <row> + <cell> + <JLabel text='FirstName:'/> + </cell> + <cell weightx='1'> + <JTextField id='firstName' text='{identity.getFirstName()}' + onKeyReleased='identity.setFirstName(firstName.getText())'/> + </cell> + </row> + <row> + <cell> + <JLabel text='LastName:'/> + </cell> + <cell weightx='1'> + <JTextField id='lastName' text='{identity.getLastName()}' + onKeyReleased='identity.setLastName(lastName.getText())'/> + </cell> + </row> + <row> + <cell> + <JLabel text='Email:'/> + </cell> + <cell weightx='1'> + <JTextField id='email2' text='{identity.getEmail()}' + onKeyReleased='identity.setEmail(email2.getText())'/> + </cell> + </row> + + <row> + <cell> + <JLabel text='Age:'/> + </cell> + <cell> + <JSlider id='age' minimum='0' maximum='100' value='{identity.getAge()}' + onStateChanged='identity.setAge(age.getValue())'/> + </cell> + </row> + </Table> + </JPanel> + </cell> + <cell weightx='1' weighty='1' insets='6, 3, 0, 0'> + <JPanel border='{BorderFactory.createTitledBorder("Identity Model")}' + layout='{new GridLayout()}' width='250' height='120'> + <Table anchor='west' fill='both'> + <row> + <cell> + <JLabel text='FirstName:'/> + </cell> + <cell weightx='1'> + <JLabel text='{identity.getFirstName()}'/> + </cell> + </row> + <row> + <cell> + <JLabel text='LastName:'/> + </cell> + <cell weightx='1'> + <JLabel text='{identity.getLastName()}'/> + </cell> + </row> + <row> + <cell> + <JLabel text='Email:'/> + </cell> + <cell weightx='1'> + <JLabel text='{identity.getEmail()}'/> + </cell> + </row> + + <row> + <cell> + <JLabel text='Age:'/> + </cell> + <cell> + <JLabel text='{identity.getAge()}'/> + </cell> + </row> + </Table> + </JPanel> + </cell> + </row> + <row> + <cell columns='2' fill="both"> + <JPanel border='{BorderFactory.createTitledBorder("Errors")}' layout='{new GridLayout()}' height='200' width='500'> + <JScrollPane> + <JList model='{errors}'/> + </JScrollPane> + </JPanel> + </cell> + </row> + </Table> +</Application> Property changes on: lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/validator/ok/ValidationBeanClass.jaxx ___________________________________________________________________ Name: svn:mergeinfo +