Author: tchemit Date: 2008-10-17 16:44:40 +0000 (Fri, 17 Oct 2008) New Revision: 947 Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/BeanValidatorHandler.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/FieldValidatorHandler.java Log: implements autoField behaviour add some checking on beans Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/BeanValidatorHandler.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/BeanValidatorHandler.java 2008-10-17 16:43:39 UTC (rev 946) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/BeanValidatorHandler.java 2008-10-17 16:44:40 UTC (rev 947) @@ -7,6 +7,8 @@ import jaxx.CompilerException; import jaxx.compiler.CompiledObject; import jaxx.compiler.JAXXCompiler; +import jaxx.introspection.JAXXBeanInfo; +import jaxx.introspection.JAXXPropertyDescriptor; import jaxx.reflect.ClassDescriptor; import jaxx.reflect.ClassDescriptorLoader; import jaxx.runtime.BeanValidator; @@ -16,6 +18,7 @@ import org.apache.commons.logging.LogFactory; import org.w3c.dom.Element; +import java.beans.IntrospectionException; import java.io.IOException; import java.util.Map; import java.util.Map.Entry; @@ -24,10 +27,10 @@ public class BeanValidatorHandler extends DefaultObjectHandler { public static final String BEAN_VALIDATOR_TAG = BeanValidator.class.getSimpleName(); - public static final String BEAN_ATTRIBUTE = "bean"; public static final String ERROR_LIST_MODEL_ATTRIBUTE = "errorListModel"; public static final String AUTOFIELD_ATTRIBUTE = "autoField"; + public static final String STRICT_MODE_ATTRIBUTE = "strictMode"; /** to use log facility, just put in your code: log.info(\"...\"); */ static Log log = LogFactory.getLog(BeanValidatorHandler.class); @@ -49,6 +52,16 @@ } @Override + protected void compileChildTagFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + log.info(tag); + if (!tag.getLocalName().equals(FieldValidatorHandler.FIELD_VALIDATOR_TAG)) { + compiler.reportError("tag '" + tag.getParentNode().getLocalName() + "' may only contain " + FieldValidatorHandler.FIELD_VALIDATOR_TAG + " as children, but found : " + tag.getLocalName()); + } else { + compiler.compileFirstPass(tag); + } + } + + @Override public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { super.compileSecondPass(tag, compiler); @@ -58,54 +71,44 @@ String tmp = info.getErrorListModel(); if (tmp != null) { - //todo should check object exists - String code = getSetPropertyCode(info.getJavaCode(), ERROR_LIST_MODEL_ATTRIBUTE, tmp, compiler); - info.appendAdditionCode(code); + if (compiler.checkReference(tag, tmp, true, ERROR_LIST_MODEL_ATTRIBUTE)) { + String code = getSetPropertyCode(info.getJavaCode(), ERROR_LIST_MODEL_ATTRIBUTE, tmp, compiler); + info.appendAdditionCode(code); + } } String bean = info.getBean(); if (bean != null) { - //todo should check object exists - String code = getSetPropertyCode(info.getJavaCode(), BEAN_ATTRIBUTE, bean, compiler); - info.appendAdditionCode(code); + if (compiler.checkReference(tag, bean, true, BEAN_ATTRIBUTE)) { + String code = getSetPropertyCode(info.getJavaCode(), BEAN_ATTRIBUTE, bean, compiler); + info.appendAdditionCode(code); + } } - Boolean doAutoField = info.getAutoField(); - - if (doAutoField != null && doAutoField) { + if (info.getAutoField()) { if (bean == null) { compiler.reportError("tag '" + tag.getLocalName() + "' need a " + BEAN_ATTRIBUTE + " attribute to use autofield mode"); } else { - //todo generate auto fields from bean property with matching component - log.info("doAutoField for bean " + bean); + registerAutoFieldBean(tag, compiler, info); } } - for (Entry<String, String> entry : info.getFields().entrySet()) { - String keyCode = TypeManager.getJavaCode(entry.getKey()); - //todo should check object exists - info.appendAdditionCode(info.getJavaCode() + ".setFieldRepresentation(" + keyCode + ", " + entry.getValue() + ");"); - } + // add fieldrepresentation invocations + addFieldRepresentations(tag, compiler, info); + // register the validator in compiler compiler.registerValidator(info); + + // close the compiled object compiler.closeComponent(info); } @Override protected void setDefaults(CompiledObject object, Element tag, JAXXCompiler compiler) { + // open the compiled object compiler.openInvisibleComponent(object); } @Override - protected void compileChildTagFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { - log.info(tag); - if (!tag.getLocalName().equals(FieldValidatorHandler.FIELD_VALIDATOR_TAG)) { - compiler.reportError("tag '" + tag.getParentNode().getLocalName() + "' may only contain " + FieldValidatorHandler.FIELD_VALIDATOR_TAG + " as children, but found : " + tag.getLocalName()); - } else { - compiler.compileFirstPass(tag); - } - } - - @Override public void setAttribute(CompiledObject object, String propertyName, String stringValue, boolean inline, JAXXCompiler compiler) { if (compiler.getOptions().isVerbose()) { log.info(propertyName + " : " + stringValue + " for " + object); @@ -113,6 +116,61 @@ object.addProperty(propertyName, stringValue); } + protected void registerAutoFieldBean(Element tag, JAXXCompiler compiler, CompiledBeanValidator info) { + for (JAXXPropertyDescriptor beanProperty : info.getBeanDescriptor(compiler).getJAXXPropertyDescriptors()) { + String descriptionName = beanProperty.getName(); + log.info("doAutoField on 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; + } + 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 */ public static class CompiledBeanValidator extends CompiledObject { @@ -120,6 +178,8 @@ protected String bean; protected String errorListModel; protected Boolean autoField; + protected Boolean strictMode; + protected JAXXBeanInfo beanDescriptor; public CompiledBeanValidator(String id, ClassDescriptor objectClass, JAXXCompiler compiler) { super(id, objectClass, compiler); @@ -156,15 +216,22 @@ } return; } + if (STRICT_MODE_ATTRIBUTE.equals(property)) { + if (value != null && !value.trim().isEmpty()) { + strictMode = (Boolean) TypeManager.convertFromString(value, Boolean.class); + } + return; + } + //todo should not allowed to find other attributes 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); + compiler.reportError("duplicate field '" + id + "' for validator " + this); } else { - log.info("add field <"+id+":"+component+">"); + log.info("add field <" + id + ":" + component + ">"); fields.put(id, component); } } @@ -177,16 +244,32 @@ return errorListModel; } - public Boolean getAutoField() { - return autoField; + public boolean getAutoField() { + return autoField != null && autoField; } + public boolean getStrictMode() { + return strictMode != null && strictMode; + } + + public JAXXBeanInfo getBeanDescriptor(JAXXCompiler compiler) { + if (beanDescriptor == null && bean != null) { + try { + ClassDescriptor beanClassDescriptor = ClassDescriptorLoader.getClassDescriptor(compiler.getSymbolTable().getClassTagIds().get(bean)); + beanDescriptor = getJAXXBeanInfo(beanClassDescriptor); + } catch (ClassNotFoundException e) { + compiler.reportError("could not load class " + bean); + } catch (IntrospectionException e) { + compiler.reportError("could not load class " + bean); + } + } + return beanDescriptor; + } + @Override public void addChild(CompiledObject child, String constraints, JAXXCompiler compiler) throws CompilerException { // do nothing compiler.reportError("can not add CompiledObject in the tag '" + BEAN_VALIDATOR_TAG + " (only field tags)"); } - - } } \ No newline at end of file Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/FieldValidatorHandler.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/FieldValidatorHandler.java 2008-10-17 16:43:39 UTC (rev 946) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/FieldValidatorHandler.java 2008-10-17 16:44:40 UTC (rev 947) @@ -52,12 +52,22 @@ } name = name.trim(); if (component == null || component.trim().isEmpty()) { - compiler.reportError(FIELD_VALIDATOR_TAG + " tag requires a " + COMPONENT_ATTRIBUTE + " attribute"); - return; + // try to use the name as component + if (!compiler.checkReference(tag, name, false, name)) { + compiler.reportError(FIELD_VALIDATOR_TAG + " tag requires a " + COMPONENT_ATTRIBUTE + " attribute, try to use the name attribute ["+name+"] for the component, but no such component found"); + return; + } + component = name; } component = component.trim(); - validator.addField(name, component, compiler); + // check component exist (again perharps, but if error will known exactly which tag failed...) + if (compiler.checkReference(tag, component, true, component)) { + // add a field + validator.addField(name, component, compiler); + } + + } } \ No newline at end of file
participants (1)
-
tchemit@users.labs.libre-entreprise.org