1 16 package org.apache.commons.jelly.impl; 17 18 import java.lang.reflect.InvocationTargetException ; 19 import java.lang.reflect.Method ; 20 import java.util.HashSet ; 21 import java.util.Iterator ; 22 import java.util.Map ; 23 import java.util.Set ; 24 25 import org.apache.commons.beanutils.ConvertingWrapDynaBean; 26 import org.apache.commons.collections.BeanMap; 27 import org.apache.commons.jelly.DynaBeanTagSupport; 28 import org.apache.commons.jelly.JellyTagException; 29 import org.apache.commons.jelly.MissingAttributeException; 30 import org.apache.commons.jelly.Tag; 31 import org.apache.commons.jelly.XMLOutput; 32 import org.apache.commons.jelly.expression.Expression; 33 import org.apache.commons.logging.Log; 34 import org.apache.commons.logging.LogFactory; 35 36 46 public class DynamicBeanTag extends DynaBeanTagSupport implements BeanSource { 47 48 49 private static final Log log = LogFactory.getLog(DynamicBeanTag.class); 50 51 52 private static final Object [] emptyArgs = {}; 53 54 55 private Class beanClass; 56 57 58 private Object bean; 59 60 61 private Method method; 62 63 67 private String variableNameAttribute; 68 69 70 private String var; 71 72 73 private Set setAttributesSet = new HashSet (); 74 75 76 private Map attributes; 77 78 85 public DynamicBeanTag(Class beanClass, Map attributes, String variableNameAttribute, Method method) { 86 this.beanClass = beanClass; 87 this.method = method; 88 this.attributes = attributes; 89 this.variableNameAttribute = variableNameAttribute; 90 } 91 92 public void beforeSetAttributes() throws JellyTagException { 93 try { 95 bean = beanClass.newInstance(); 96 setDynaBean( new ConvertingWrapDynaBean( bean ) ); 97 } catch (InstantiationException e) { 98 throw new JellyTagException("Could not instantiate dynabean",e); 99 } catch (IllegalAccessException e) { 100 throw new JellyTagException("Could not instantiate dynabean",e); 101 } 102 103 setAttributesSet.clear(); 104 } 105 106 public void setAttribute(String name, Object value) throws JellyTagException { 107 boolean isVariableName = false; 108 if (variableNameAttribute != null ) { 109 if ( variableNameAttribute.equals( name ) ) { 110 if (value == null) { 111 var = null; 112 } 113 else { 114 var = value.toString(); 115 } 116 isVariableName = true; 117 } 118 } 119 if (! isVariableName) { 120 121 setAttributesSet.add(name); 125 126 128 super.setAttribute(name, value); 129 } 130 } 131 132 public void doTag(XMLOutput output) throws JellyTagException { 135 136 for ( Iterator iter = attributes.values().iterator(); iter.hasNext(); ) { 138 Attribute attribute = (Attribute) iter.next(); 139 String name = attribute.getName(); 140 if ( ! setAttributesSet.contains( name ) ) { 141 if ( attribute.isRequired() ) { 142 throw new MissingAttributeException(name); 143 } 144 Object value = null; 146 Expression expression = attribute.getDefaultValue(); 147 if ( expression != null ) { 148 value = expression.evaluate(context); 149 } 150 151 if ( value != null ) { 153 super.setAttribute(name, value); 154 } 155 } 156 } 157 158 if (bean instanceof Tag) 160 { 161 Tag tag = (Tag) bean; 162 tag.setBody(getBody()); 163 tag.setContext(getContext()); 164 tag.setParent(getParent()); 165 ((Tag) bean).doTag(output); 166 167 return; 168 } 169 170 invokeBody(output); 171 172 if ( var != null ) { 174 context.setVariable(var, bean); 175 } 176 177 if ( method != null ) { 179 try { 180 method.invoke( bean, emptyArgs ); 181 } 182 catch (IllegalAccessException e) { 183 methodInvocationException(bean, method, e); 184 } 185 catch (IllegalArgumentException e) { 186 methodInvocationException(bean, method, e); 187 } 188 catch (InvocationTargetException e) { 189 191 Throwable inner = e.getTargetException(); 192 193 throw new JellyTagException(inner); 194 195 } 196 } 197 } 198 199 208 private void methodInvocationException(Object bean, Method method, Exception e) throws JellyTagException { 209 log.error("Could not invoke " + method, e); 210 BeanMap beanMap = new BeanMap(bean); 211 212 log.error("Bean properties:"); 213 for (Iterator i = beanMap.keySet().iterator(); i.hasNext();) { 214 String property = (String ) i.next(); 215 Object value = beanMap.get(property); 216 log.error(property + " -> " + value); 217 } 218 219 log.error(beanMap); 220 throw new JellyTagException(e); 221 } 222 223 228 public Object getBean() { 229 return bean; 230 } 231 } 232 | Popular Tags |