View Javadoc

1   /*
2    * $Id: SubsetIteratorTag.java 651946 2008-04-27 13:41:38Z apetrelli $
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  
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   * &lt;!-- s: List basic --&gt;
94   *    &lt;s:subset source="myList"&gt;
95   *       &lt;s:iterator&gt;
96   *          &lt;s:property /&gt;
97   *       &lt;/s:iterator&gt;
98   *    &lt;/s:subset&gt;
99   * <!-- END SNIPPET: example1 -->
100  * </pre>
101  *
102  * <pre>
103  * <!-- START SNIPPET: example2 -->
104  * &lt;!-- B: List with count --&gt;
105  *    &lt;s:subset source="myList" count="3"&gt;
106  *       &lt;s:iterator&gt;
107  *           &lt;s:property /&gt;
108  *       &lt;/s:iterator&gt;
109  *     &lt;/s:subset&gt;
110  * <!-- END SNIPPET: example2 -->
111  * </pre>
112  *
113  * <pre>
114  * <!-- START SNIPPET: example3 -->
115  * &lt;!--  C: List with start -->
116  *      &lt;s:subset source="myList" count="13" start="3"&gt;
117  *         &lt;s:iterator&gt;
118  *           &lt;s:property /&gt;
119  *         &lt;/s:iterator&gt;
120  *      &lt;/s:subset&gt;
121  * <!-- END SNIPPET: example3 -->
122  * </pre>
123  *
124  * <pre>
125  * <!-- START SNIPPET: example4 -->
126  * &lt;!--  D: List with var --&gt;
127  *      &lt;s:subset var="mySubset" source="myList" count="13" start="3" /&gt;
128  *      &lt;%
129  *          Iterator i = (Iterator) pageContext.getAttribute("mySubset");
130  *          while(i.hasNext()) {
131  *      %&gt;
132  *      &lt;%=i.next() %&gt;
133  *      &lt;%  } %&gt;
134  * <!-- END SNIPPET: example4 -->
135  * </pre>
136  *
137  * <pre>
138  * <!-- START SNIPPET: example5 -->
139  *  &lt;!--  D: List with Decider --&gt;
140  *      &lt;s:subset source="myList" decider="myDecider"&gt;
141  *             &lt;s:iterator&gt;
142  *                  &lt;s:property /&gt;
143  *             &lt;/s:iterator&gt;
144  *      &lt;/s:subset&gt;
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         // source
207         Object source = null;
208         if (sourceAttr == null || sourceAttr.length() == 0) {
209             source = findValue("top");
210         } else {
211             source = findValue(sourceAttr);
212         }
213 
214         // count
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         // start
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         // decider
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 }