View Javadoc

    1   /*
    2    * $Id: SubsetIteratorTag.java 497654 2007-01-19 00:21:57Z rgielen $
    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 }