1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.struts2.components;
22
23 import java.io.Writer;
24
25 import org.apache.struts2.views.annotations.StrutsTag;
26 import org.apache.struts2.views.annotations.StrutsTagAttribute;
27 import org.apache.struts2.StrutsException;
28
29 import com.opensymphony.xwork2.util.ValueStack;
30
31 /***
32 * <!-- START SNIPPET: javadoc -->
33 * <p>This tag can be used to parameterize other tags.</p>
34 * The include tag and bean tag are examples of such tags.
35 * <p/>
36 * The parameters can be added with or without a name as key.
37 * If the tag provides a name attribute the parameters are added using the
38 * {@link Component#addParameter(String, Object) addParamter} method.
39 * For unnamed parameters the Tag must implement the {@link UnnamedParametric} interface defined in
40 * this class (e.g. The TextTag does this).
41 * <p/>
42 * This tag has the following two paramters.
43 * <!-- START SNIPPET: params -->
44 * <ul>
45 * <li>name (String) - the name of the parameter</li>
46 * <li>value (Object) - the value of the parameter</li>
47 * </ul>
48 * <!-- END SNIPPET: params -->
49 * <p/>
50 * <b>Note:</b>
51 * When you declare the param tag, the value can be defined in either a <tt>value</tt> attribute or
52 * as text between the start and end tag. Struts behaves a bit different according to these two situations.
53 * This is best illustrated using an example:
54 * <br/><param name="color">blue</param> <-- (A) -->
55 * <br/><param name="color" value="blue"/> <-- (B) -->
56 * <br/>In the first situation (A) the value would be evaluated to the stack as a <tt>java.lang.String</tt> object.
57 * And in situation (B) the value would be evaluated to the stack as a <tt>java.lang.Object</tt> object.
58 * <br/>For more information see <a href="http://jira.opensymphony.com/browse/WW-808">WW-808</a>.
59 * <!-- END SNIPPET: javadoc -->
60 *
61 * <p/> <b>Examples</b>
62 * <!-- START SNIPPET: example -->
63 * <pre>
64 * <ui:component>
65 * <ui:param name="key" value="[0]"/>
66 * <ui:param name="value" value="[1]"/>
67 * <ui:param name="context" value="[2]"/>
68 * </ui:component>
69 * </pre>
70 * <!-- END SNIPPET: example -->
71 * <p/>
72 * <!-- START SNIPPET: exampledescription -->
73 * where the key will be the identifier and the value the result of an OGNL expression run against the current
74 * ValueStack.
75 * <!-- END SNIPPET: exampledescription -->
76 * <p/>
77 * This second example demonstrates how the text tag can use parameters from this param tag.
78 * <!-- START SNIPPET: example2 -->
79 * <pre>
80 * <s:text name="cart.total.cost">
81 * <s:param value="#session.cartTotal"/>
82 * </s:text>
83 * </pre>
84 * <!-- END SNIPPET: example2 -->
85 * <p/>
86 *
87 * @see Include
88 * @see Bean
89 * @see Text
90 *
91 */
92 @StrutsTag(name="param", tldTagClass="org.apache.struts2.views.jsp.ParamTag", description="Parametrize other tags")
93 public class Param extends Component {
94 protected String name;
95 protected String value;
96
97 public Param(ValueStack stack) {
98 super(stack);
99 }
100
101 public boolean end(Writer writer, String body) {
102 Component component = findAncestor(Component.class);
103 if (value != null) {
104 if (component instanceof UnnamedParametric) {
105 ((UnnamedParametric) component).addParameter(findValue(value));
106 } else {
107 String name = findString(this.name);
108
109 if (name == null) {
110 throw new StrutsException("No name found for following expression: " + name);
111 }
112
113 Object value = findValue(this.value);
114 component.addParameter(name, value);
115 }
116 } else {
117 if (component instanceof UnnamedParametric) {
118 ((UnnamedParametric) component).addParameter(body);
119 } else {
120 component.addParameter(findString(name), body);
121 }
122 }
123
124 return super.end(writer, "");
125 }
126
127 public boolean usesBody() {
128 return true;
129 }
130
131 @StrutsTagAttribute(description="Name of Parameter to set")
132 public void setName(String name) {
133 this.name = name;
134 }
135
136 @StrutsTagAttribute(description="Value expression for Parameter to set", defaultValue="The value of evaluating provided name against stack")
137 public void setValue(String value) {
138 this.value = value;
139 }
140
141
142 /***
143 * Tags can implement this to support nested param tags without the <tt>name</tt> attribute.
144 * <p/>
145 * The {@link Text TextTag} uses this approach. For unnamed parameters an example is given in the class
146 * javadoc for {@link Param ParamTag}.
147 */
148 public interface UnnamedParametric {
149
150 /***
151 * Adds the given value as a parameter to the outer tag.
152 * @param value the value
153 */
154 public void addParameter(Object value);
155 }
156
157 }