/* * Created on May 8, 2004 * * To change the template for this generated file go to * Window - Preferences - Java - Code Generation - Code and Comments */ package org.anodyneos.xp.tag.core; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; import javax.servlet.jsp.el.ELException; import javax.servlet.jsp.el.ExpressionEvaluator; import javax.servlet.jsp.el.VariableResolver; import org.anodyneos.xp.XpException; import org.anodyneos.xp.XpOutput; import org.anodyneos.xp.tagext.XpTagSupport; import org.xml.sax.SAXException; /** * SetTag supports setting a value of a scripting variable or a property of a * target that may be a java bean or Map. * * <xp:set @value @var [@scope]/> * * <xp:set @var [@scope]>bodyContent </xp:set> * * <xp:set @value @target @property/> * * <xp:set @target @property>bodyContent </xp:set> * * @author jvas */ public class SetTag extends XpTagSupport { private Object value; private Object target; private String property; private String scope; private String var; /** * */ public SetTag() { super(); } public void setValue(Object value) { this.value = value; } public void setTarget(Object target) { this.target = target; } public void setProperty(String property) { this.property = property; } public void setScope(String scope) { this.scope = scope; } public void setVar(String var) { this.var = var; } public void doTag(XpOutput out) throws XpException, ELException, SAXException { if (null == value) { if (getXpBody() != null) { // get value from body value = getXpBody().invokeToString(); } else { value = null; } } if (null != var) { // simple case, setting a scripting variable if (null == scope) { getXpContext().setAttribute(var, value); } else { getXpContext().setAttribute(var, value, getXpContext().resolveScope(scope)); } } else { // must have target and property if (target instanceof Map) { if(value == null) { ((Map) target).remove(property); } else { ((Map) target).put(property, value); } } else if (target != null) { // must be a javaBean try { PropertyDescriptor pd[] = Introspector.getBeanInfo(target.getClass()).getPropertyDescriptors(); boolean succeeded = false; for (int i=0; i < pd.length; i++) { if(pd[i].getName().equals(property)) { Method m = pd[i].getWriteMethod(); if (m == null) { throw new XpException("No setter method"); } if (value != null) { try { m.invoke(target, new Object[] { convertToExpectedType(value, m.getParameterTypes()[0])}); } catch (ELException ex) { throw new XpException(ex.getMessage()); } } else { m.invoke(target, new Object[] {null}); } succeeded = true; } } if (!succeeded) { throw new XpException("No setter method"); } } catch (IllegalAccessException ex) { throw new XpException(ex.getMessage()); } catch (IntrospectionException ex) { throw new XpException(ex.getMessage()); } catch (InvocationTargetException ex) { throw new XpException(ex.getMessage()); } } else { throw new XpException("Must provide target or var attribute"); } } } /** * Convert an object to an expected type according to the conversion * rules of the Expression Language. */ private Object convertToExpectedType( final Object val, Class expectedType ) throws ELException { ExpressionEvaluator evaluator = getXpContext().getExpressionEvaluator(); return evaluator.evaluate( "${result}", expectedType, new VariableResolver() { public Object resolveVariable( String pName ) { return val; } }, null ); } }