View Javadoc

1   /*
2    * $Id: SubsetIteratorTag.java 439747 2006-09-03 09:22:46Z mrdon $
3    *
4    * Copyright 2006 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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   * &lt;!-- s: List basic --&gt;
87   *    &lt;s:subset source="myList"&gt;
88   *	     &lt;s:iterator&gt;
89   *		    &lt;s:property /&gt;
90   *	     &lt;/s:iterator&gt;
91   *    &lt;/s:subset&gt;
92   * <!-- END SNIPPET: example1 -->
93   * </pre>
94   *
95   * <pre>
96   * <!-- START SNIPPET: example2 -->
97   * &lt;!-- B: List with count --&gt;
98   *    &lt;s:subset source="myList" count="3"&gt;
99   * 	     &lt;s:iterator&gt;
100  * 		     &lt;s:property /&gt;
101  * 	     &lt;/s:iterator&gt;
102  *     &lt;/s:subset&gt;
103  * <!-- END SNIPPET: example2 -->
104  * </pre>
105  *
106  * <pre>
107  * <!-- START SNIPPET: example3 -->
108  * &lt;!--  C: List with start -->
109  *      &lt;s:subset source="myList" count="13" start="3"&gt;
110  * 	       &lt;s:iterator&gt;
111  * 		     &lt;s:property /&gt;
112  * 	       &lt;/s:iterator&gt;
113  *      &lt;/s:subset&gt;
114  * <!-- END SNIPPET: example3 -->
115  * </pre>
116  *
117  * <pre>
118  * <!-- START SNIPPET: example4 -->
119  * &lt;!--  D: List with id --&gt;
120  *      &lt;s:subset id="mySubset" source="myList" count="13" start="3" /&gt;
121  *      &lt;%
122  * 	        Iterator i = (Iterator) pageContext.getAttribute("mySubset");
123  *          while(i.hasNext()) {
124  *      %&gt;
125  *      &lt;%=i.next() %&gt;
126  *      &lt;%  } %&gt;
127  * <!-- END SNIPPET: example4 -->
128  * </pre>
129  *
130  * <pre>
131  * <!-- START SNIPPET: example5 -->
132  *  &lt;!--  D: List with Decider --&gt;
133  *      &lt;s:subset source="myList" decider="myDecider"&gt;
134  * 	           &lt;s:iterator&gt;
135  *		            &lt;s:property /&gt;
136  *	           &lt;/s:iterator&gt;
137  *      &lt;/s:subset&gt;
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         // source
195         Object source = null;
196         if (sourceAttr == null && sourceAttr.length() <= 0) {
197         	source = findValue("top");
198         } else {
199             source = findValue(sourceAttr);
200         }
201 
202         // count
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         // start
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         // decider
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 }