001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: * $Header:$
018: */
019: package org.apache.beehive.netui.tags.databinding.invoke;
020:
021: import javax.servlet.jsp.JspException;
022: import javax.servlet.jsp.tagext.Tag;
023:
024: import org.apache.beehive.netui.tags.AbstractClassicTag;
025: import org.apache.beehive.netui.util.Bundle;
026:
027: /**
028: * <p>
029: * A tag that is used to add an argument to a method that will be called
030: * on some object. This tag can be nested within tags that extend the AbstractCallMethod
031: * class. Those tags are:
032: * <ul>
033: * <li>{@link CallMethod}</li>
034: * <li>{@link CallPageFlow}</li>
035: * </ul>
036: * </p>
037: * <p>
038: * The {@link MethodParameter} tags are used to parameterize the method that the {@link AbstractCallMethod} class
039: * will call; each <code>methodParameter</code> tag represents a single parameter. These tags are evaluated
040: * in order and the parameters they describe are passed in order.
041: * </p>
042: * <p>
043: * Overloaded methods on an object can be invoked by setting the <code>type</code> attribute on each
044: * <code>methodParameter</code> tag that is embedded in a method invocation tag. The type name must
045: * exactly match the primitive type name or the fully qualified class name of the argument. The
046: * <code>methodParameter</code> tags must also be in the order that they will be passed to this method.
047: * The value of the type attribute must be an exact match of the type if it were printed after having been
048: * accessed through Java reflection.
049: * </p>
050: * <p>
051: * In order to pass <code>null</code> as an argument to a method, the null attribute must be set on this tag.
052: * Either the null attribute or the value attribute must be set on this tag.
053: * </p>
054: * <p>
055: * This example shows how to pass parameters to the method call <code>foo(int integer, String string)</code>.
056: * <pre>
057: * <netui-data:methodParamter value="42"/>
058: * <netui-data:methodParamter null="true"/>
059: * </pre>
060: * This will correspond to the method call:<br/>
061: * <pre>
062: * foo(42, null);
063: * </pre>
064: * The following sample shows how to pass parameters to the method call <code>foo(int integer, String string)</code>
065: * where the class has both of the methods <code>foo(int integer, String string)</code> and
066: * <code>foo(Integer integer, String string)</code>.
067: * <pre>
068: * <netui-data:methodParamter type="int" value="42"/>
069: * <netui-data:methodParamter type="java.lang.String" null="true"/>
070: * </pre>
071: * This will correspond to the method call:<br/>
072: * <pre>
073: * foo(42, null);
074: * </pre>
075: * </p>
076: *
077: * @jsptagref.tagdescription
078: * <p>
079: * A tag that is used to add an argument to a method that will be called
080: * on some object. This tag can be nested within tags that extend the AbstractCallMethod
081: * class. Those tags are:
082: * <ul>
083: * <li>{@link CallMethod}</li>
084: * <li>{@link CallPageFlow}</li>
085: * </ul>
086: * </p>
087: * <p>
088: * The {@link MethodParameter} tags are used to parameterize the method that the {@link AbstractCallMethod} class
089: * will call; each <code>methodParameter</code> tag represents a single parameter. These tags are evaluated
090: * in order and the parameters they describe are passed in order.
091: * </p>
092: * <p>
093: * Overloaded methods on an object can be invoked by setting the <code>type</code> attribute on each
094: * <code>methodParameter</code> tag that is embedded in a method invocation tag. The type name must
095: * exactly match the primitive type name or the fully qualified class name of the argument. The
096: * <code>methodParameter</code> tags must also be in the order that they will be passed to this method.
097: * The value of the type attribute must be an exact match of the type if it were printed after having been
098: * accessed through Java reflection.
099: * </p>
100: * <p>
101: * In order to pass <code>null</code> as an argument to a method, the null attribute must be set on this tag.
102: * Either the null attribute or the value attribute must be set on this tag.
103: * </p>
104: *
105: * @example
106: * <p>
107: * This example shows how to pass parameters to the method call <code>foo(int integer, String string)</code>.
108: * <pre>
109: * <netui-data:methodParamter value="42"/>
110: * <netui-data:methodParamter null="true"/>
111: * </pre>
112: * This will correspond to the method call:<br/>
113: * <pre>
114: * foo(42, null);
115: * </pre>
116: * The following sample shows how to pass parameters to the method call <code>foo(int integer, String string)</code>
117: * where the class has both of the methods <code>foo(int integer, String string)</code> and
118: * <code>foo(Integer integer, String string)</code>.
119: * <pre>
120: * <netui-data:methodParamter type="int" value="42"/>
121: * <netui-data:methodParamter type="java.lang.String" null="true"/>
122: * </pre>
123: * This will correspond to the method call:<br/>
124: * <pre>
125: * foo(42, null);
126: * </pre>
127: * </p>
128: *
129: * @netui:tag name="methodParameter"
130: * description="Use this tag to add an argument to a method that will be called on some object."
131: */
132: public class MethodParameter extends AbstractClassicTag {
133:
134: /**
135: * An identifier denoting that the value of this method parameter
136: * should be treated as 'null'.
137: */
138: public static final Integer NULL_ARG = new Integer(-1);
139:
140: private boolean _isNull = false;
141: private Object _value = null;
142: private String _type = null;
143:
144: /**
145: * Get the name of this tag. This is used to identify the type of this tag
146: * for reporting tag errors.
147: *
148: * @return a constant String representing the name of this tag.
149: */
150: public String getTagName() {
151: return "MethodParamter";
152: }
153:
154: /**
155: * <p/>
156: * Set a String matching the type of this parameter on the method to invoke.
157: * </p>
158: * <p/>
159: * This name should match the primitive type name or fully qualified class
160: * name of the parameters on the signature of the method to which this
161: * parameter will be passed.
162: * </p>
163: * <p/>
164: * For example:
165: * <table>
166: * <tr><td>Method Signature</td><td>Argument Name</td><td>Type value</td></tr>
167: * <tr><td>addToPrice(int price)</td><td>price</td><td><code>int</code></td></tr>
168: * <tr><td>addToPrice(Integer price)</td><td>price</td><td><code>java.lang.Integer</code></td></tr>
169: * </table>
170: *
171: * @param type the type name
172: * @jsptagref.attributedescription <p>
173: * Set a String matching the type of this parameter on the method to invoke.
174: * </p>
175: * <p/>
176: * This name should match the primitive type name or fully qualified class
177: * name of the parameters on the signature of the method to which this
178: * parameter will be passed.
179: * </p>
180: * <p/>
181: * For example:
182: * <table border='1'>
183: * <tr><td><b>Method Signature</b></td><td><b>Argument Name</b></td><td><b>Type value</b></td></tr>
184: * <tr><td>addToPrice(int price)</td><td>price</td><td><code>int</code></td></tr>
185: * <tr><td>addToPrice(Integer price)</td><td>price</td><td><code>java.lang.Integer</code></td></tr>
186: * </table>
187: * @jsptagref.attributesyntaxvalue <i>string_type</i>
188: * @netui:attribute required="false"
189: */
190: public void setType(String type) {
191: _type = type;
192: }
193:
194: /**
195: * Sets the value of the method parameter that will be passed
196: * to the method call. This String can be an expression.
197: * If the value is not an expression that references
198: * an Ojbect, the {@link AbstractCallMethod#doEndTag()} will attempt to convert
199: * the String to type that matches the position of the MethodParameter
200: * tag in the list of MethodParameter tags nested inside of an {@link AbstractCallMethod}
201: * tag.
202: *
203: * @param value a String value which may be an expression
204: * @jsptagref.attributedescription The value of the method parameter that will be passed to the method call.
205: * @jsptagref.attributesyntaxvalue <i>expression_value</i>
206: * @netui:attribute required="false" rtexprvalue="true"
207: */
208: public void setValue(Object value) {
209: _value = value;
210: }
211:
212: /**
213: * Sets a boolean that describes that the parameter that should be passed
214: * to the method is null.
215: *
216: * @param isNull a value that describes whether or not this tag should pass null; if
217: * <code>true</code> null will be passed; otherwise the value from the value attribute
218: * will be passed.
219: * @jsptagref.attributedescription Boolean. Determines if the parameter passed to the method is null.
220: * @jsptagref.attributesyntaxvalue <i>boolean_passNullValue</i>
221: * @netui:attribute required="false" rtexprvalue="true"
222: */
223: public void setNull(boolean isNull) {
224: _isNull = isNull;
225: }
226:
227: /**
228: * Start this tag's lifecycle. Verify that this tag is nested within
229: * a {@link AbstractCallMethod} tag and that one of the "null" and "value"
230: * attributes are set.
231: *
232: * @return {@link #SKIP_BODY}
233: * @throws JspException if an error occurs getting the parameter
234: */
235: public int doStartTag() throws JspException {
236: Tag parent = getParent();
237: if (parent == null || !(parent instanceof AbstractCallMethod)) {
238: String msg = Bundle
239: .getErrorString("Tags_MethodParameter_invalidParent");
240: registerTagError(msg, null);
241: reportErrors();
242: return SKIP_BODY;
243: }
244:
245: if (!_isNull && _value == null) {
246: String msg = Bundle
247: .getErrorString("Tags_MethodParameter_undefinedValue");
248: registerTagError(msg, null);
249: reportErrors();
250: return SKIP_BODY;
251: }
252:
253: return SKIP_BODY;
254: }
255:
256: /**
257: * Prepare the value to pass up to the {@link AbstractCallMethod} type
258: * parent.
259: *
260: * @return {@link #EVAL_PAGE} to continue evaluating the page
261: */
262: public int doEndTag() throws JspException {
263:
264: if (hasErrors())
265: reportErrors();
266: else {
267: AbstractCallMethod cm = (AbstractCallMethod) getParent();
268: cm.addParameter(_type, _isNull ? null : _value);
269: }
270:
271: localRelease();
272: return EVAL_PAGE;
273: }
274:
275: /**
276: * Reset all of the fields of this tag.
277: */
278: protected void localRelease() {
279: super .localRelease();
280: _isNull = false;
281: _value = null;
282: _type = null;
283: }
284: }
|