View Javadoc

    1   /*
    2    * $Id: IteratorGeneratorTag.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.IteratorGenerator;
    30  import org.apache.struts2.util.IteratorGenerator.Converter;
    31  import org.apache.struts2.views.jsp.StrutsBodyTagSupport;
    32
    33
    34  /***
    35   * <!-- START SNIPPET: javadoc -->
    36   * <b>NOTE: JSP-TAG</b>
    37   *
    38   * <p>Generate an iterator based on the val attribute supplied.</P>
    39   *
    40   * <b>NOTE:</b> The generated iterator will <b>ALWAYS</b> be pushed into the top of the stack, and poped
    41   * at the end of the tag.
    42   * <!-- END SNIPPET: javadoc -->
    43   *
    44   * <!-- START SNIPPET: params -->
    45   * <ul>
    46   *      <li>val* (Object) - the source to be parsed into an iterator </li>
    47   *      <li>count (Object) - the max number (Integer, Float, Double, Long, String) entries to be in the iterator</li>
    48   *      <li>separator (String) - the separator to be used in separating the <i>val</i> into entries of the iterator</li>
    49   *      <li>id (String) - the id to store the resultant iterator into page context, if such id is supplied</li>
    50   *      <li>converter (Object) - the converter (must extends off IteratorGenerator.Converter interface) to convert the String entry parsed from <i>val</i> into an object</li>
    51   * </ul>
    52   * <!-- END SNIPPET: params -->
    53   *
    54   *
    55   * <!-- START SNIPPET: example -->
    56   * Example One:
    57   * <pre>
    58   * Generate a simple iterator
    59   * &lt;s:generator val="%{'aaa,bbb,ccc,ddd,eee'}"&gt;
    60   *  &lt;s:iterator&gt;
    61   *      &lt;s:property /&gt;&lt;br/&gt;
    62   *  &lt;/s:iterator&gt;
    63   * &lt;/s:generator&gt;
    64   * </pre>
    65   * This generates an iterator and print it out using the iterator tag.
    66   *
    67   * Example Two:
    68   * <pre>
    69   * Generate an iterator with count attribute
    70   * &lt;s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" count="3"&gt;
    71   *  &lt;s:iterator&gt;
    72   *      &lt;s:property /&gt;&lt;br/&gt;
    73   *  &lt;/s:iterator&gt;
    74   * &lt;/s:generator&gt;
    75   * </pre>
    76   * This generates an iterator, but only 3 entries will be available in the iterator
    77   * generated, namely aaa, bbb and ccc respectively because count attribute is set to 3
    78   *
    79   * Example Three:
    80   * <pre>
    81   * Generate an iterator with id attribute
    82   * &lt;s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" count="4" separator="," id="myAtt" /&gt;
    83   * &lt;%
    84   *  Iterator i = (Iterator) pageContext.getAttribute("myAtt");
    85   *  while(i.hasNext()) {
    86   *      String s = (String) i.next(); %>
    87   *      &lt;%=s%&gt; &lt;br/&gt;
    88   * &lt;%    }
    89   * %&gt;
    90   * </pre>
    91   * This generates an iterator and put it in the PageContext under the key as specified
    92   * by the id attribute.
    93   *
    94   *
    95   * Example Four:
    96   * <pre>
    97   * Generate an iterator with comparator attribute
    98   * &lt;s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" converter="%{myConverter}"&gt;
    99   *  &lt;s:iterator&gt;
    100  *      &lt;s:property /&gt;&lt;br/&gt;
    101  *  &lt;/s:iterator&gt;
    102  * &lt;/s:generator&gt;
    103  *
    104  *
    105  * public class GeneratorTagAction extends ActionSupport {
    106  *
    107  *   ....
    108  *
    109  *   public Converter getMyConverter() {
    110  *      return new Converter() {
    111  *          public Object convert(String value) throws Exception {
    112  *              return "converter-"+value;
    113  *          }
    114  *      };
    115  *   }
    116  *
    117  *   ...
    118  *
    119  * }
    120  * </pre>
    121  * This will generate an iterator with each entries decided by the converter supplied. With
    122  * this converter, it simply add "converter-" to each entries.
    123  * <!-- END SNIPPET: example -->
    124  *
    125  * @see org.apache.struts2.util.IteratorGenerator
    126  */
    127 @StrutsTag(name="generator", tldTagClass="org.apache.struts2.views.jsp.iterator.IteratorGeneratorTag",
    128         description="Generate an iterator for a iterable source.")
    129 public class IteratorGeneratorTag extends StrutsBodyTagSupport {
    130
    131     private static final long serialVersionUID = 2968037295463973936L;
    132
    133     public static final String DEFAULT_SEPARATOR = ",";
    134
    135     private static final Log _log = LogFactory.getLog(IteratorGeneratorTag.class);
    136
    137     String countAttr;
    138     String separatorAttr;
    139     String valueAttr;
    140     String converterAttr;
    141
    142     IteratorGenerator iteratorGenerator = null;
    143
    144     @StrutsTagAttribute(type="Integer",description="The max number entries to be in the iterator")
    145     public void setCount(String count) {
    146         countAttr = count;
    147     }
    148
    149     /***
    150      * @s.tagattribute required="true" type="String"
    151      * description="the separator to be used in separating the <i>val</i> into entries of the iterator"
    152      */
    153     @StrutsTagAttribute(required=true, description="The separator to be used in separating the <i>val</i> into entries of the iterator")
    154     public void setSeparator(String separator) {
    155         separatorAttr = separator;
    156     }
    157
    158     /***
    159      * @s.tagattribute required="true"
    160      * description="the source to be parsed into an iterator"
    161      */
    162     @StrutsTagAttribute(required=true, description="The source to be parsed into an iterator")
    163     public void setVal(String val) {
    164         valueAttr = val;
    165     }
    166
    167     @StrutsTagAttribute(type="org.apache.struts2.util.IteratorGenerator.Converter",
    168             description="The converter to convert the String entry parsed from <i>val</i> into an object")
    169     public void setConverter(String aConverter) {
    170         converterAttr = aConverter;
    171     }
    172
    173     /***
    174      * @s.tagattribute required="false" type="String"
    175      * description="the id to store the resultant iterator into page context, if such id is supplied"
    176      */
    177     @StrutsTagAttribute(description="The id to store the resultant iterator into page context, if such id is supplied")
    178     public void setId(String string) {
    179         super.setId(string);
    180     }
    181
    182     public int doStartTag() throws JspException {
    183
    184         // value
    185         Object value = findValue(valueAttr);
    186
    187         // separator
    188         String separator = DEFAULT_SEPARATOR;
    189         if (separatorAttr != null && separatorAttr.length() > 0) {
    190             separator = findString(separatorAttr);
    191         }
    192
    193         // TODO: maybe this could be put into an Util class, or there is already one?
    194         // count
    195         int count = 0;
    196         if (countAttr != null && countAttr.length() > 0) {
    197             Object countObj = findValue(countAttr);
    198             if (countObj instanceof Integer) {
    199                 count = ((Integer)countObj).intValue();
    200             }
    201             else if (countObj instanceof Float) {
    202                 count = ((Float)countObj).intValue();
    203             }
    204             else if (countObj instanceof Long) {
    205                 count = ((Long)countObj).intValue();
    206             }
    207             else if (countObj instanceof Double) {
    208                 count = ((Long)countObj).intValue();
    209             }
    210             else if (countObj instanceof String) {
    211                 try {
    212                     count = Integer.parseInt((String)countObj);
    213                 }
    214                 catch(NumberFormatException e) {
    215                     _log.warn("unable to convert count attribute ["+countObj+"] to number, ignore count attribute", e);
    216                 }
    217             }
    218         }
    219
    220         // converter
    221         Converter converter = null;
    222         if (converterAttr != null && converterAttr.length() > 0) {
    223             converter = (Converter) findValue(converterAttr);
    224         }
    225
    226
    227         iteratorGenerator = new IteratorGenerator();
    228         iteratorGenerator.setValues(value);
    229         iteratorGenerator.setCount(count);
    230         iteratorGenerator.setSeparator(separator);
    231         iteratorGenerator.setConverter(converter);
    232
    233         iteratorGenerator.execute();
    234
    235
    236
    237         // push resulting iterator into stack
    238         getStack().push(iteratorGenerator);
    239         if (getId() != null && getId().length() > 0) {
    240             // if an id is specified, we have the resulting iterator set into
    241             // the pageContext attribute as well
    242             pageContext.setAttribute(getId(), iteratorGenerator);
    243         }
    244
    245         return EVAL_BODY_INCLUDE;
    246     }
    247
    248     public int doEndTag() throws JspException {
    249         // pop resulting iterator from stack at end tag
    250         getStack().pop();
    251         iteratorGenerator = null; // clean up
    252
    253         return EVAL_PAGE;
    254     }
    255 }