1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.jelly.tags.core;
17
18 import java.lang.reflect.InvocationTargetException;
19 import java.util.Map;
20
21 import org.apache.commons.beanutils.BeanUtils;
22 import org.apache.commons.jelly.JellyTagException;
23 import org.apache.commons.jelly.TagSupport;
24 import org.apache.commons.jelly.XMLOutput;
25 import org.apache.commons.jelly.expression.Expression;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29
30 /*** A tag which sets a variable from the result of an expression
31 *
32 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
33 * @version $Revision: 155420 $
34 */
35 public class SetTag extends TagSupport {
36
37 /*** The Log to which logging calls will be made. */
38 private static final Log log = LogFactory.getLog(SetTag.class);
39
40 /*** The variable name to export. */
41 private String var;
42
43 /*** The variable scope to export */
44 private String scope;
45
46 /*** The expression to evaluate. */
47 private Expression value;
48
49 /*** The default value */
50 private Expression defaultValue;
51
52 /*** The target object on which to set a property. */
53 private Object target;
54
55 /*** The name of the property to set on the target object. */
56 private String property;
57
58 /*** Should we XML encode the body of this tag as text? */
59 private boolean encode = true;
60
61 public SetTag() {
62 }
63
64
65
66 public void doTag(XMLOutput output) throws JellyTagException {
67
68 if ( var != null ) {
69 if ( target != null || property != null ) {
70 throw new JellyTagException( "The 'target' and 'property' attributes cannot be used in combination with the 'var' attribute" );
71 }
72 }
73 else {
74 if ( target == null ) {
75 throw new JellyTagException( "Either a 'var' or a 'target' attribute must be defined for this tag" );
76 }
77 if ( property == null ) {
78 throw new JellyTagException( "The 'target' attribute requires the 'property' attribute" );
79 }
80 }
81
82 Object answer = null;
83 if ( value != null ) {
84 answer = value.evaluate(context);
85 if (defaultValue != null && isEmpty(answer)) {
86 answer = defaultValue.evaluate(context);
87 }
88 }
89 else {
90 answer = getBodyText(isEncode());
91 }
92
93 if ( var != null ) {
94 if ( scope != null ) {
95 context.setVariable(var, scope, answer);
96 }
97 else {
98 context.setVariable(var, answer);
99 }
100 }
101 else {
102 setPropertyValue( target, property, answer );
103 }
104 }
105
106
107
108 /*** Sets the variable name to define for this expression
109 */
110 public void setVar(String var) {
111 this.var = var;
112 }
113
114 /***
115 * Sets the variable scope for this variable. For example setting this value to 'parent' will
116 * set this value in the parent scope. When Jelly is run from inside a Servlet environment
117 * then other scopes will be available such as 'request', 'session' or 'application'.
118 *
119 * Other applications may implement their own custom scopes.
120 */
121 public void setScope(String scope) {
122 this.scope = scope;
123 }
124
125 /*** Sets the expression to evaluate. */
126 public void setValue(Expression value) {
127 this.value = value;
128 }
129
130 /***
131 * Sets the default value to be used if the value exprsesion results
132 * in a null value or blank String
133 */
134 public void setDefaultValue(Expression defaultValue) {
135 this.defaultValue = defaultValue;
136 }
137
138 /*** Sets the target object on which to set a property. */
139 public void setTarget(Object target) {
140 this.target = target;
141 }
142
143 /*** Sets the name of the property to set on the target object. */
144 public void setProperty(String property) {
145 this.property = property;
146 }
147
148 /***
149 * Returns whether the body of this tag will be XML encoded or not.
150 */
151 public boolean isEncode() {
152 return encode;
153 }
154
155 /***
156 * Sets whether the body of the tag should be XML encoded as text (so that < and > are
157 * encoded as &lt; and &gt;) or leave the text as XML which is the default.
158 * This is only used if this tag is specified with no value so that the text body of this
159 * tag is used as the body.
160 */
161 public void setEncode(boolean encode) {
162 this.encode = encode;
163 }
164
165
166
167
168 protected void setPropertyValue( Object target, String property, Object value ) {
169 try {
170 if ( target instanceof Map ) {
171 Map map = (Map) target;
172 map.put( property, value );
173 }
174 else {
175 BeanUtils.setProperty( target, property, value );
176 }
177 } catch (InvocationTargetException e) {
178 log.error( "Failed to set the property: " + property + " on bean: " + target + " to value: " + value + " due to exception: " + e, e );
179 } catch (IllegalAccessException e) {
180 log.error( "Failed to set the property: " + property + " on bean: " + target + " to value: " + value + " due to exception: " + e, e );
181 }
182 }
183
184 /***
185 * @param value
186 * @return true if the given value is null or an empty String
187 */
188 protected boolean isEmpty(Object value) {
189 if (value == null) {
190 return true;
191 }
192 if (value instanceof String) {
193 String s = (String) value;
194 return s.length() == 0;
195 }
196 return false;
197 }
198
199 }