View Javadoc

1   /*
2    * $Id: IteratorGeneratorTag.java 439747 2006-09-03 09:22:46Z 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.views.jsp.iterator;
19  
20  import javax.servlet.jsp.JspException;
21  
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  import org.apache.struts2.util.IteratorGenerator;
25  import org.apache.struts2.util.IteratorGenerator.Converter;
26  import org.apache.struts2.views.jsp.StrutsBodyTagSupport;
27  
28  
29  /***
30   * <!-- START SNIPPET: javadoc -->
31   * <b>NOTE: JSP-TAG</b>
32   * 
33   * <p>Generate an iterator based on the val attribute supplied.</P>
34   * 
35   * <b>NOTE:</b> The generated iterator will <b>ALWAYS</b> be pushed into the top of the stack, and poped
36   * at the end of the tag.
37   * <!-- END SNIPPET: javadoc -->
38   *
39   * <!-- START SNIPPET: params -->
40   * <ul>
41   * 		<li>val* (Object) - the source to be parsed into an iterator </li>
42   * 		<li>count (Object) - the max number (Integer, Float, Double, Long, String) entries to be in the iterator</li>
43   * 		<li>separator (String) - the separator to be used in separating the <i>val</i> into entries of the iterator</li>
44   *  	<li>id (String) - the id to store the resultant iterator into page context, if such id is supplied</li>
45   *  	<li>converter (Object) - the converter (must extends off IteratorGenerator.Converter interface) to convert the String entry parsed from <i>val</i> into an object</li>
46   * </ul>
47   * <!-- END SNIPPET: params -->
48   *
49   *
50   * <!-- START SNIPPET: example -->
51   * Example One:
52   * <pre>
53   * Generate a simple iterator
54   * &lt;s:generator val="%{'aaa,bbb,ccc,ddd,eee'}"&gt;
55   *	&lt;s:iterator&gt;
56   *		&lt;s:property /&gt;&lt;br/&gt;
57   *	&lt;/s:iterator&gt;
58   * &lt;/s:generator&gt;
59   * </pre>
60   * This generates an iterator and print it out using the iterator tag.
61   *
62   * Example Two:
63   * <pre>
64   * Generate an iterator with count attribute
65   * &lt;s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" count="3"&gt;
66   *	&lt;s:iterator&gt;
67   *		&lt;s:property /&gt;&lt;br/&gt;
68   *	&lt;/s:iterator&gt;
69   * &lt;/s:generator&gt;
70   * </pre>
71   * This generates an iterator, but only 3 entries will be available in the iterator
72   * generated, namely aaa, bbb and ccc respectively because count attribute is set to 3
73   *
74   * Example Three:
75   * <pre>
76   * Generate an iterator with id attribute
77   * &lt;s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" count="4" separator="," id="myAtt" /&gt;
78   * &lt;%
79   * 	Iterator i = (Iterator) pageContext.getAttribute("myAtt");
80   * 	while(i.hasNext()) {
81   * 		String s = (String) i.next(); %>
82   * 		&lt;%=s%&gt; &lt;br/&gt;
83   * &lt;% 	}
84   * %&gt;
85   * </pre>
86   * This generates an iterator and put it in the PageContext under the key as specified
87   * by the id attribute.
88   *
89   *
90   * Example Four:
91   * <pre>
92   * Generate an iterator with comparator attribute
93   * &lt;s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" converter="%{myConverter}"&gt;
94   *	&lt;s:iterator&gt;
95   * 		&lt;s:property /&gt;&lt;br/&gt;
96   * 	&lt;/s:iterator&gt;
97   * &lt;/s:generator&gt;
98   *
99   *
100  * public class GeneratorTagAction extends ActionSupport {
101  *
102  *   ....
103  *
104  *	 public Converter getMyConverter() {
105  *		return new Converter() {
106  *			public Object convert(String value) throws Exception {
107  *				return "converter-"+value;
108  *			}
109  *		};
110  *	 }
111  *
112  *   ...
113  *
114  * }
115  * </pre>
116  * This will generate an iterator with each entries decided by the converter supplied. With
117  * this converter, it simply add "converter-" to each entries.
118  * <!-- END SNIPPET: example -->
119  *
120  * @see org.apache.struts2.util.IteratorGenerator
121  *
122  * @s.tag name="generator" tld-body-content="JSP"
123  * description="Generate an iterator for a iterable source."
124  */
125 public class IteratorGeneratorTag extends StrutsBodyTagSupport {
126 
127 	private static final long serialVersionUID = 2968037295463973936L;
128 
129 	public static final String DEFAULT_SEPARATOR = ",";
130 
131 	private static final Log _log = LogFactory.getLog(IteratorGeneratorTag.class);
132 
133     String countAttr;
134     String separatorAttr;
135     String valueAttr;
136     String converterAttr;
137 
138     IteratorGenerator iteratorGenerator = null;
139 
140     /***
141      * @s.tagattribute required="false" type="Integer"
142      * description="the max number entries to be in the iterator"
143      */
144     public void setCount(String count) {
145         countAttr = count;
146     }
147 
148     /***
149      * @s.tagattribute required="true" type="String"
150      * description="the separator to be used in separating the <i>val</i> into entries of the iterator"
151      */
152     public void setSeparator(String separator) {
153         separatorAttr = separator;
154     }
155 
156     /***
157      * @s.tagattribute required="true"
158      * description="the source to be parsed into an iterator"
159      */
160     public void setVal(String val) {
161         valueAttr = val;
162     }
163 
164     /***
165      * @s.tagattribute required="false" type="org.apache.struts2.util.IteratorGenerator.Converter"
166      * description="the converter to convert the String entry parsed from <i>val</i> into an object"
167      */
168     public void setConverter(String aConverter) {
169     	converterAttr = aConverter;
170     }
171 
172     /***
173      * @s.tagattribute required="false" type="String"
174      * description="the id to store the resultant iterator into page context, if such id is supplied"
175      */
176     public void setId(String string) {
177         super.setId(string);
178     }
179 
180     public int doStartTag() throws JspException {
181 
182     	// value
183     	Object value = findValue(valueAttr);
184 
185     	// separator
186     	String separator = DEFAULT_SEPARATOR;
187     	if (separatorAttr != null && separatorAttr.length() > 0) {
188     		separator = findString(separatorAttr);
189     	}
190 
191     	// TODO: maybe this could be put into an Util class, or there is already one?
192     	// count
193     	int count = 0;
194     	if (countAttr != null && countAttr.length() > 0) {
195     		Object countObj = findValue(countAttr);
196     		if (countObj instanceof Integer) {
197     			count = ((Integer)countObj).intValue();
198     		}
199     		else if (countObj instanceof Float) {
200     			count = ((Float)countObj).intValue();
201     		}
202     		else if (countObj instanceof Long) {
203     			count = ((Long)countObj).intValue();
204     		}
205     		else if (countObj instanceof Double) {
206     			count = ((Long)countObj).intValue();
207     		}
208     		else if (countObj instanceof String) {
209     			try {
210     				count = Integer.parseInt((String)countObj);
211     			}
212     			catch(NumberFormatException e) {
213     				_log.warn("unable to convert count attribute ["+countObj+"] to number, ignore count attribute", e);
214     			}
215     		}
216     	}
217 
218     	// converter
219     	Converter converter = null;
220     	if (converterAttr != null && converterAttr.length() > 0) {
221     		converter = (Converter) findValue(converterAttr);
222     	}
223 
224 
225     	iteratorGenerator = new IteratorGenerator();
226     	iteratorGenerator.setValues(value);
227     	iteratorGenerator.setCount(count);
228     	iteratorGenerator.setSeparator(separator);
229     	iteratorGenerator.setConverter(converter);
230 
231     	iteratorGenerator.execute();
232 
233 
234 
235     	// push resulting iterator into stack
236     	getStack().push(iteratorGenerator);
237     	if (getId() != null && getId().length() > 0) {
238     		// if an id is specified, we have the resulting iterator set into
239     		// the pageContext attribute as well
240     		pageContext.setAttribute(getId(), iteratorGenerator);
241     	}
242 
243         return EVAL_BODY_INCLUDE;
244     }
245 
246     public int doEndTag() throws JspException {
247     	// pop resulting iterator from stack at end tag
248     	getStack().pop();
249     	iteratorGenerator = null; // clean up
250 
251     	return EVAL_PAGE;
252     }
253 }