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