View Javadoc

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