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.SubsetIteratorFilter;
25 import org.apache.struts2.util.SubsetIteratorFilter.Decider;
26 import org.apache.struts2.views.jsp.StrutsBodyTagSupport;
27
28
29 /***
30 * <!-- START SNIPPET: javadoc -->
31 * <b>NOTE: JSP-TAG</b>
32 *
33 * <p>A tag that takes an iterator and outputs a subset of it. It delegates to
34 * {@link org.apache.struts2.util.SubsetIteratorFilter} internally to
35 * perform the subset functionality.</p>
36 * <!-- END SNIPPET: javadoc -->
37 *
38 * <!-- START SNIPPET: params -->
39 * <ul>
40 * <li>count (Object) - Indicate the number of entries to be in the resulting subset iterator</li>
41 * <li>source* (Object) - Indicate the source of which the resulting subset iterator is to be derived base on</li>
42 * <li>start (Object) - Indicate the starting index (eg. first entry is 0) of entries in the source to be available as the first entry in the resulting subset iterator</li>
43 * <li>decider (Object) - Extension to plug-in a decider to determine if that particular entry is to be included in the resulting subset iterator</li>
44 * <li>id (String) - Indicate the pageContext attribute id to store the resultant subset iterator in</li>
45 * </ul>
46 * <!-- END SNIPPET: params -->
47 *
48 *
49 * <pre>
50 * <!-- START SNIPPET: action -->
51 * public class MySubsetTagAction extends ActionSupport {
52 * public String execute() throws Exception {
53 * l = new ArrayList();
54 * l.add(new Integer(1));
55 * l.add(new Integer(2));
56 * l.add(new Integer(3));
57 * l.add(new Integer(4));
58 * l.add(new Integer(5));
59 * return "done";
60 * }
61 *
62 *
63 * public Integer[] getMyArray() {
64 * return a;
65 * }
66 *
67 * public List getMyList() {
68 * return l;
69 * }
70 *
71 * public Decider getMyDecider() {
72 * return new Decider() {
73 * public boolean decide(Object element) throws Exception {
74 * int i = ((Integer)element).intValue();
75 * return (((i % 2) == 0)?true:false);
76 * }
77 * };
78 * }
79 * }
80 * <!-- END SNIPPET: action -->
81 * </pre>
82 *
83 *
84 * <pre>
85 * <!-- START SNIPPET: example1 -->
86 * <!-- s: List basic -->
87 * <s:subset source="myList">
88 * <s:iterator>
89 * <s:property />
90 * </s:iterator>
91 * </s:subset>
92 * <!-- END SNIPPET: example1 -->
93 * </pre>
94 *
95 * <pre>
96 * <!-- START SNIPPET: example2 -->
97 * <!-- B: List with count -->
98 * <s:subset source="myList" count="3">
99 * <s:iterator>
100 * <s:property />
101 * </s:iterator>
102 * </s:subset>
103 * <!-- END SNIPPET: example2 -->
104 * </pre>
105 *
106 * <pre>
107 * <!-- START SNIPPET: example3 -->
108 * <!-- C: List with start -->
109 * <s:subset source="myList" count="13" start="3">
110 * <s:iterator>
111 * <s:property />
112 * </s:iterator>
113 * </s:subset>
114 * <!-- END SNIPPET: example3 -->
115 * </pre>
116 *
117 * <pre>
118 * <!-- START SNIPPET: example4 -->
119 * <!-- D: List with id -->
120 * <s:subset id="mySubset" source="myList" count="13" start="3" />
121 * <%
122 * Iterator i = (Iterator) pageContext.getAttribute("mySubset");
123 * while(i.hasNext()) {
124 * %>
125 * <%=i.next() %>
126 * <% } %>
127 * <!-- END SNIPPET: example4 -->
128 * </pre>
129 *
130 * <pre>
131 * <!-- START SNIPPET: example5 -->
132 * <!-- D: List with Decider -->
133 * <s:subset source="myList" decider="myDecider">
134 * <s:iterator>
135 * <s:property />
136 * </s:iterator>
137 * </s:subset>
138 * <!-- END SNIPPET: example5 -->
139 * </pre>
140 *
141 *
142 * @s.tag name="subset" tld-body-content="JSP"
143 * description="Takes an iterator and outputs a subset of it"
144 */
145 public class SubsetIteratorTag extends StrutsBodyTagSupport {
146
147 private static final long serialVersionUID = -6252696081713080102L;
148
149 private static final Log _log = LogFactory.getLog(SubsetIteratorTag.class);
150
151 String countAttr;
152 String sourceAttr;
153 String startAttr;
154 String deciderAttr;
155
156 SubsetIteratorFilter subsetIteratorFilter = null;
157
158
159 /***
160 * @s.tagattribute required="false" type="Integer"
161 * description="Indicate the number of entries to be in the resulting subset iterator"
162 */
163 public void setCount(String count) {
164 countAttr = count;
165 }
166
167 /***
168 * @s.tagattribute required="false"
169 * description="Indicate the source of which the resulting subset iterator is to be derived base on"
170 */
171 public void setSource(String source) {
172 sourceAttr = source;
173 }
174
175 /***
176 * @s.tagattribute required="false" type="Integer"
177 * description="Indicate the starting index (eg. first entry is 0) of entries in the source to be available as the first entry in the resulting subset iterator"
178 */
179 public void setStart(String start) {
180 startAttr = start;
181 }
182
183 /***
184 * @s.tagattribute required="false" type="org.apache.struts2.util.SubsetIteratorFilter.Decider"
185 * description="Extension to plug-in a decider to determine if that particular entry is to be included in the resulting subset iterator"
186 */
187 public void setDecider(String decider) {
188 deciderAttr = decider;
189 }
190
191
192 public int doStartTag() throws JspException {
193
194
195 Object source = null;
196 if (sourceAttr == null && sourceAttr.length() <= 0) {
197 source = findValue("top");
198 } else {
199 source = findValue(sourceAttr);
200 }
201
202
203 int count = -1;
204 if (countAttr != null && countAttr.length() > 0) {
205 Object countObj = findValue(countAttr);
206 if (countObj instanceof Integer) {
207 count = ((Integer)countObj).intValue();
208 }
209 else if (countObj instanceof Float) {
210 count = ((Float)countObj).intValue();
211 }
212 else if (countObj instanceof Long) {
213 count = ((Long)countObj).intValue();
214 }
215 else if (countObj instanceof Double) {
216 count = ((Long)countObj).intValue();
217 }
218 else if (countObj instanceof String) {
219 try {
220 count = Integer.parseInt((String)countObj);
221 }
222 catch(NumberFormatException e) {
223 _log.warn("unable to convert count attribute ["+countObj+"] to number, ignore count attribute", e);
224 }
225 }
226 }
227
228
229 int start = 0;
230 if (startAttr != null && startAttr.length() > 0) {
231 Object startObj = findValue(startAttr);
232 if (startObj instanceof Integer) {
233 start = ((Integer)startObj).intValue();
234 }
235 else if (startObj instanceof Float) {
236 start = ((Float)startObj).intValue();
237 }
238 else if (startObj instanceof Long) {
239 start = ((Long)startObj).intValue();
240 }
241 else if (startObj instanceof Double) {
242 start = ((Long)startObj).intValue();
243 }
244 else if (startObj instanceof String) {
245 try {
246 start = Integer.parseInt((String)startObj);
247 }
248 catch(NumberFormatException e) {
249 _log.warn("unable to convert count attribute ["+startObj+"] to number, ignore count attribute", e);
250 }
251 }
252 }
253
254
255 Decider decider = null;
256 if (deciderAttr != null && deciderAttr.length() > 0) {
257 Object deciderObj = findValue(deciderAttr);
258 if (! (deciderObj instanceof Decider)) {
259 throw new JspException("decider found from stack ["+deciderObj+"] does not implement "+Decider.class);
260 }
261 decider = (Decider) deciderObj;
262 }
263
264
265 subsetIteratorFilter = new SubsetIteratorFilter();
266 subsetIteratorFilter.setCount(count);
267 subsetIteratorFilter.setDecider(decider);
268 subsetIteratorFilter.setSource(source);
269 subsetIteratorFilter.setStart(start);
270 subsetIteratorFilter.execute();
271
272 getStack().push(subsetIteratorFilter);
273 if (getId() != null) {
274 pageContext.setAttribute(getId(), subsetIteratorFilter);
275 }
276
277 return EVAL_BODY_INCLUDE;
278 }
279
280 public int doEndTag() throws JspException {
281
282 getStack().pop();
283
284 subsetIteratorFilter = null;
285
286 return EVAL_PAGE;
287 }
288 }