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