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