View Javadoc

1   /*
2    * $Id: Param.java 451544 2006-09-30 05:38:02Z mrdon $
3    *
4    * Copyright 2006 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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/>&lt;param name="color"&gt;blue&lt;/param&gt; &lt;-- (A) --&gt;
50   * <br/>&lt;param name="color" value="blue"/&gt; &lt;-- (B) --&gt;
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   * &lt;ui:component&gt;
60   *  &lt;ui:param name="key"     value="[0]"/&gt;
61   *  &lt;ui:param name="value"   value="[1]"/&gt;
62   *  &lt;ui:param name="context" value="[2]"/&gt;
63   * &lt;/ui:component&gt;
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   * &lt;s:text name="cart.total.cost"&gt;
76   *     &lt;s:param value="#session.cartTotal"/&gt;
77   * &lt;/s:text&gt;
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 }