001: /*
002: * $Id: Param.java 497654 2007-01-19 00:21:57Z rgielen $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts2.components;
022:
023: import java.io.Writer;
024:
025: import org.apache.struts2.views.annotations.StrutsTag;
026: import org.apache.struts2.views.annotations.StrutsTagAttribute;
027: import org.apache.struts2.StrutsException;
028:
029: import com.opensymphony.xwork2.util.ValueStack;
030:
031: /**
032: * <!-- START SNIPPET: javadoc -->
033: * <p>This tag can be used to parameterize other tags.</p>
034: * The include tag and bean tag are examples of such tags.
035: * <p/>
036: * The parameters can be added with or without a name as key.
037: * If the tag provides a name attribute the parameters are added using the
038: * {@link Component#addParameter(String, Object) addParamter} method.
039: * For unnamed parameters the Tag must implement the {@link UnnamedParametric} interface defined in
040: * this class (e.g. The TextTag does this).
041: * <p/>
042: * This tag has the following two paramters.
043: * <!-- START SNIPPET: params -->
044: * <ul>
045: * <li>name (String) - the name of the parameter</li>
046: * <li>value (Object) - the value of the parameter</li>
047: * </ul>
048: * <!-- END SNIPPET: params -->
049: * <p/>
050: * <b>Note:</b>
051: * When you declare the param tag, the value can be defined in either a <tt>value</tt> attribute or
052: * as text between the start and end tag. Struts behaves a bit different according to these two situations.
053: * This is best illustrated using an example:
054: * <br/><param name="color">blue</param> <-- (A) -->
055: * <br/><param name="color" value="blue"/> <-- (B) -->
056: * <br/>In the first situation (A) the value would be evaluated to the stack as a <tt>java.lang.String</tt> object.
057: * And in situation (B) the value would be evaluated to the stack as a <tt>java.lang.Object</tt> object.
058: * <br/>For more information see <a href="http://jira.opensymphony.com/browse/WW-808">WW-808</a>.
059: * <!-- END SNIPPET: javadoc -->
060: *
061: * <p/> <b>Examples</b>
062: * <!-- START SNIPPET: example -->
063: * <pre>
064: * <ui:component>
065: * <ui:param name="key" value="[0]"/>
066: * <ui:param name="value" value="[1]"/>
067: * <ui:param name="context" value="[2]"/>
068: * </ui:component>
069: * </pre>
070: * <!-- END SNIPPET: example -->
071: * <p/>
072: * <!-- START SNIPPET: exampledescription -->
073: * where the key will be the identifier and the value the result of an OGNL expression run against the current
074: * ValueStack.
075: * <!-- END SNIPPET: exampledescription -->
076: * <p/>
077: * This second example demonstrates how the text tag can use parameters from this param tag.
078: * <!-- START SNIPPET: example2 -->
079: * <pre>
080: * <s:text name="cart.total.cost">
081: * <s:param value="#session.cartTotal"/>
082: * </s:text>
083: * </pre>
084: * <!-- END SNIPPET: example2 -->
085: * <p/>
086: *
087: * @see Include
088: * @see Bean
089: * @see Text
090: *
091: */
092: @StrutsTag(name="param",tldTagClass="org.apache.struts2.views.jsp.ParamTag",description="Parametrize other tags")
093: public class Param extends Component {
094: protected String name;
095: protected String value;
096:
097: public Param(ValueStack stack) {
098: super (stack);
099: }
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)
106: .addParameter(findValue(value));
107: } else {
108: String name = findString(this .name);
109:
110: if (name == null) {
111: throw new StrutsException(
112: "No name found for following expression: "
113: + name);
114: }
115:
116: Object value = findValue(this .value);
117: component.addParameter(name, value);
118: }
119: } else {
120: if (component instanceof UnnamedParametric) {
121: ((UnnamedParametric) component).addParameter(body);
122: } else {
123: component.addParameter(findString(name), body);
124: }
125: }
126:
127: return super .end(writer, "");
128: }
129:
130: public boolean usesBody() {
131: return true;
132: }
133:
134: @StrutsTagAttribute(description="Name of Parameter to set")
135: public void setName(String name) {
136: this .name = name;
137: }
138:
139: @StrutsTagAttribute(description="Value expression for Parameter to set",defaultValue="The value of evaluating provided name against stack")
140: public void setValue(String value) {
141: this .value = value;
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: }
|