| /* |
| * $Id$ |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.struts2.views.jsp.iterator; |
| |
| import javax.servlet.jsp.JspException; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.struts2.views.annotations.StrutsTag; |
| import org.apache.struts2.views.annotations.StrutsTagAttribute; |
| import org.apache.struts2.util.IteratorGenerator; |
| import org.apache.struts2.util.IteratorGenerator.Converter; |
| import org.apache.struts2.views.jsp.StrutsBodyTagSupport; |
| |
| |
| /** |
| * <!-- START SNIPPET: javadoc --> |
| * <b>NOTE: JSP-TAG</b> |
| * |
| * <p>Generate an iterator based on the val attribute supplied.</P> |
| * |
| * <b>NOTE:</b> The generated iterator will <b>ALWAYS</b> be pushed into the top of the stack, and poped |
| * at the end of the tag. |
| * <!-- END SNIPPET: javadoc --> |
| * |
| * <!-- START SNIPPET: params --> |
| * <ul> |
| * <li>val* (Object) - the source to be parsed into an iterator </li> |
| * <li>count (Object) - the max number (Integer, Float, Double, Long, String) entries to be in the iterator</li> |
| * <li>separator (String) - the separator to be used in separating the <i>val</i> into entries of the iterator</li> |
| * <li>id (String) - the id to store the resultant iterator into page context, if such id is supplied</li> |
| * <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> |
| * </ul> |
| * <!-- END SNIPPET: params --> |
| * |
| * |
| * <!-- START SNIPPET: example --> |
| * Example One: |
| * <pre> |
| * Generate a simple iterator |
| * <s:generator val="%{'aaa,bbb,ccc,ddd,eee'}"> |
| * <s:iterator> |
| * <s:property /><br/> |
| * </s:iterator> |
| * </s:generator> |
| * </pre> |
| * This generates an iterator and print it out using the iterator tag. |
| * |
| * Example Two: |
| * <pre> |
| * Generate an iterator with count attribute |
| * <s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" count="3"> |
| * <s:iterator> |
| * <s:property /><br/> |
| * </s:iterator> |
| * </s:generator> |
| * </pre> |
| * This generates an iterator, but only 3 entries will be available in the iterator |
| * generated, namely aaa, bbb and ccc respectively because count attribute is set to 3 |
| * |
| * Example Three: |
| * <pre> |
| * Generate an iterator with id attribute |
| * <s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" count="4" separator="," id="myAtt" /> |
| * <% |
| * Iterator i = (Iterator) pageContext.getAttribute("myAtt"); |
| * while(i.hasNext()) { |
| * String s = (String) i.next(); %> |
| * <%=s%> <br/> |
| * <% } |
| * %> |
| * </pre> |
| * This generates an iterator and put it in the PageContext under the key as specified |
| * by the id attribute. |
| * |
| * |
| * Example Four: |
| * <pre> |
| * Generate an iterator with comparator attribute |
| * <s:generator val="%{'aaa,bbb,ccc,ddd,eee'}" converter="%{myConverter}"> |
| * <s:iterator> |
| * <s:property /><br/> |
| * </s:iterator> |
| * </s:generator> |
| * |
| * |
| * public class GeneratorTagAction extends ActionSupport { |
| * |
| * .... |
| * |
| * public Converter getMyConverter() { |
| * return new Converter() { |
| * public Object convert(String value) throws Exception { |
| * return "converter-"+value; |
| * } |
| * }; |
| * } |
| * |
| * ... |
| * |
| * } |
| * </pre> |
| * This will generate an iterator with each entries decided by the converter supplied. With |
| * this converter, it simply add "converter-" to each entries. |
| * <!-- END SNIPPET: example --> |
| * |
| * @see org.apache.struts2.util.IteratorGenerator |
| */ |
| @StrutsTag(name="generator", tldTagClass="org.apache.struts2.views.jsp.iterator.IteratorGeneratorTag", |
| description="Generate an iterator for a iterable source.") |
| public class IteratorGeneratorTag extends StrutsBodyTagSupport { |
| |
| private static final long serialVersionUID = 2968037295463973936L; |
| |
| public static final String DEFAULT_SEPARATOR = ","; |
| |
| private static final Log _log = LogFactory.getLog(IteratorGeneratorTag.class); |
| |
| String countAttr; |
| String separatorAttr; |
| String valueAttr; |
| String converterAttr; |
| |
| IteratorGenerator iteratorGenerator = null; |
| |
| @StrutsTagAttribute(type="Integer",description="The max number entries to be in the iterator") |
| public void setCount(String count) { |
| countAttr = count; |
| } |
| |
| /** |
| * @s.tagattribute required="true" type="String" |
| * description="the separator to be used in separating the <i>val</i> into entries of the iterator" |
| */ |
| @StrutsTagAttribute(required=true, description="The separator to be used in separating the <i>val</i> into entries of the iterator") |
| public void setSeparator(String separator) { |
| separatorAttr = separator; |
| } |
| |
| /** |
| * @s.tagattribute required="true" |
| * description="the source to be parsed into an iterator" |
| */ |
| @StrutsTagAttribute(required=true, description="The source to be parsed into an iterator") |
| public void setVal(String val) { |
| valueAttr = val; |
| } |
| |
| @StrutsTagAttribute(type="org.apache.struts2.util.IteratorGenerator.Converter", |
| description="The converter to convert the String entry parsed from <i>val</i> into an object") |
| public void setConverter(String aConverter) { |
| converterAttr = aConverter; |
| } |
| |
| /** |
| * @s.tagattribute required="false" type="String" |
| * description="the id to store the resultant iterator into page context, if such id is supplied" |
| */ |
| @StrutsTagAttribute(description="The id to store the resultant iterator into page context, if such id is supplied") |
| public void setId(String string) { |
| super.setId(string); |
| } |
| |
| public int doStartTag() throws JspException { |
| |
| // value |
| Object value = findValue(valueAttr); |
| |
| // separator |
| String separator = DEFAULT_SEPARATOR; |
| if (separatorAttr != null && separatorAttr.length() > 0) { |
| separator = findString(separatorAttr); |
| } |
| |
| // TODO: maybe this could be put into an Util class, or there is already one? |
| // count |
| int count = 0; |
| if (countAttr != null && countAttr.length() > 0) { |
| Object countObj = findValue(countAttr); |
| if (countObj instanceof Integer) { |
| count = ((Integer)countObj).intValue(); |
| } |
| else if (countObj instanceof Float) { |
| count = ((Float)countObj).intValue(); |
| } |
| else if (countObj instanceof Long) { |
| count = ((Long)countObj).intValue(); |
| } |
| else if (countObj instanceof Double) { |
| count = ((Long)countObj).intValue(); |
| } |
| else if (countObj instanceof String) { |
| try { |
| count = Integer.parseInt((String)countObj); |
| } |
| catch(NumberFormatException e) { |
| _log.warn("unable to convert count attribute ["+countObj+"] to number, ignore count attribute", e); |
| } |
| } |
| } |
| |
| // converter |
| Converter converter = null; |
| if (converterAttr != null && converterAttr.length() > 0) { |
| converter = (Converter) findValue(converterAttr); |
| } |
| |
| |
| iteratorGenerator = new IteratorGenerator(); |
| iteratorGenerator.setValues(value); |
| iteratorGenerator.setCount(count); |
| iteratorGenerator.setSeparator(separator); |
| iteratorGenerator.setConverter(converter); |
| |
| iteratorGenerator.execute(); |
| |
| |
| |
| // push resulting iterator into stack |
| getStack().push(iteratorGenerator); |
| if (getId() != null && getId().length() > 0) { |
| // if an id is specified, we have the resulting iterator set into |
| // the pageContext attribute as well |
| pageContext.setAttribute(getId(), iteratorGenerator); |
| } |
| |
| return EVAL_BODY_INCLUDE; |
| } |
| |
| public int doEndTag() throws JspException { |
| // pop resulting iterator from stack at end tag |
| getStack().pop(); |
| iteratorGenerator = null; // clean up |
| |
| return EVAL_PAGE; |
| } |
| } |