Index: UseBeanTag.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/jelly/src/java/org/apache/commons/jelly/tags/core/UseBeanTag.java,v retrieving revision 1.14 diff -u -r1.14 UseBeanTag.java --- UseBeanTag.java 24 Feb 2004 14:10:38 -0000 1.14 +++ UseBeanTag.java 30 Aug 2004 00:22:44 -0000 @@ -16,13 +16,17 @@ package org.apache.commons.jelly.tags.core; import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; import java.util.Map; +import java.util.Set; import org.apache.commons.beanutils.BeanUtils; - +import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.jelly.JellyTagException; -import org.apache.commons.jelly.MissingAttributeException; import org.apache.commons.jelly.MapTagSupport; +import org.apache.commons.jelly.MissingAttributeException; import org.apache.commons.jelly.XMLOutput; import org.apache.commons.jelly.impl.BeanSource; @@ -44,12 +48,27 @@ * @version $Revision: 1.3 $ */ public class UseBeanTag extends MapTagSupport implements BeanSource { + /** The default value for {@link #ignoreUnknownProps}. + */ + public static final boolean DEFAULT_IGNORE_UNKNOWN_PROPS = false; /** the current bean instance */ private Object bean; /** the default class to use if no Class is specified */ private Class defaultClass; + + /**a Set of Strings of property names to ignore (remove from the + * Map of attributes before passing to ConvertUtils) + */ + private Set ignoreProperties; + + /** If this tag finds an attribute in the XML that's not + * ignored by {@link #ignoreProperties} and isn't a + * bean property, should it throw an exception? + * @see #setIgnoreUnknownProps(boolean) + */ + private boolean ignoreUnknownProps = DEFAULT_IGNORE_UNKNOWN_PROPS; public UseBeanTag() { } @@ -74,7 +93,8 @@ public void doTag(XMLOutput output) throws JellyTagException { Map attributes = getAttributes(); String var = (String) attributes.get( "var" ); - Object classObject = attributes.remove( "class" ); + Object classObject = attributes.get( "class" ); + addIgnoreProperty("class"); try { // this method could return null in derived classes @@ -163,10 +183,24 @@ /** * Sets the properties on the bean. Derived tags could implement some custom * type conversion etc. + *

+ * This method ignores all property names in the Set returned by {@link #getIgnorePropertySet()}. */ protected void setBeanProperties(Object bean, Map attributes) throws JellyTagException { + Map attrsToUse = new HashMap(attributes); + attrsToUse.keySet().removeAll(getIgnorePropertySet()); + + if (!isIgnoreUnknownProps()) { + for (Iterator i=attributes.keySet().iterator();i.hasNext();) { + String attrName = (String)i.next(); + if (! PropertyUtils.isWriteable(bean, attrName)) { + throw new JellyTagException("No bean property found: " + attrName); + } + } + } + try { - BeanUtils.populate(bean, attributes); + BeanUtils.copyProperties(bean, attrsToUse); } catch (IllegalAccessException e) { throw new JellyTagException("could not set the properties of the bean",e); } catch (InvocationTargetException e) { @@ -196,5 +230,42 @@ */ protected Class getDefaultClass() { return defaultClass; + } + + /** Adds a name to the Set of property names that will be skipped when setting + * bean properties. In other words, names added here won't be set into the bean + * if they're present in the attribute Map. + * @param name + */ + protected void addIgnoreProperty(String name) { + getIgnorePropertySet().add(name); + } + + /** Gets the Set of property names that should be ignored when setting the + * properties of the bean. + * @return + */ + protected Set getIgnorePropertySet() { + if (ignoreProperties == null) { + ignoreProperties = new HashSet(); + } + + return ignoreProperties; + } + + /** @see {@link #setIgnoreUnknownProps(boolean)} + * @return + */ + public boolean isIgnoreUnknownProps() { + return false; + } + + /** If this tag finds an attribute in the XML that's not + * ignored by {@link #ignoreProperties} and isn't a + * bean property, should it throw an exception? + * @param ignoreUnknownProps Sets {@link #ignoreUnknownProps}. + */ + public void setIgnoreUnknownProps(boolean ignoreUnknownProps) { + this.ignoreUnknownProps = ignoreUnknownProps; } }