1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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 * <s:generator val="%{'aaa,bbb,ccc,ddd,eee'}">
55 * <s:iterator>
56 * <s:property /><br/>
57 * </s:iterator>
58 * </s:generator>
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 * <s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" count="3">
66 * <s:iterator>
67 * <s:property /><br/>
68 * </s:iterator>
69 * </s:generator>
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 * <s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" count="4" separator="," id="myAtt" />
78 * <%
79 * Iterator i = (Iterator) pageContext.getAttribute("myAtt");
80 * while(i.hasNext()) {
81 * String s = (String) i.next(); %>
82 * <%=s%> <br/>
83 * <% }
84 * %>
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 * <s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" converter="%{myConverter}">
94 * <s:iterator>
95 * <s:property /><br/>
96 * </s:iterator>
97 * </s:generator>
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
183 Object value = findValue(valueAttr);
184
185
186 String separator = DEFAULT_SEPARATOR;
187 if (separatorAttr != null && separatorAttr.length() > 0) {
188 separator = findString(separatorAttr);
189 }
190
191
192
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
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
236 getStack().push(iteratorGenerator);
237 if (getId() != null && getId().length() > 0) {
238
239
240 pageContext.setAttribute(getId(), iteratorGenerator);
241 }
242
243 return EVAL_BODY_INCLUDE;
244 }
245
246 public int doEndTag() throws JspException {
247
248 getStack().pop();
249 iteratorGenerator = null;
250
251 return EVAL_PAGE;
252 }
253 }