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