blob: 7df704f1cf6fc9da96bb6bd4dea77067d1fda3c9 [file] [log] [blame]
/*
* $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.SubsetIteratorFilter;
import org.apache.struts2.util.SubsetIteratorFilter.Decider;
import org.apache.struts2.views.jsp.StrutsBodyTagSupport;
/**
* <!-- START SNIPPET: javadoc -->
* <b>NOTE: JSP-TAG</b>
*
* <p>A tag that takes an iterator and outputs a subset of it. It delegates to
* {@link org.apache.struts2.util.SubsetIteratorFilter} internally to
* perform the subset functionality.</p>
* <!-- END SNIPPET: javadoc -->
*
* <!-- START SNIPPET: params -->
* <ul>
* <li>count (Object) - Indicate the number of entries to be in the resulting subset iterator</li>
* <li>source* (Object) - Indicate the source of which the resulting subset iterator is to be derived base on</li>
* <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>
* <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>
* <li>id (String) - Indicate the pageContext attribute id to store the resultant subset iterator in</li>
* </ul>
* <!-- END SNIPPET: params -->
*
*
* <pre>
* <!-- START SNIPPET: action -->
* public class MySubsetTagAction extends ActionSupport {
* public String execute() throws Exception {
* l = new ArrayList();
* l.add(new Integer(1));
* l.add(new Integer(2));
* l.add(new Integer(3));
* l.add(new Integer(4));
* l.add(new Integer(5));
* return "done";
* }
*
*
* public Integer[] getMyArray() {
* return a;
* }
*
* public List getMyList() {
* return l;
* }
*
* public Decider getMyDecider() {
* return new Decider() {
* public boolean decide(Object element) throws Exception {
* int i = ((Integer)element).intValue();
* return (((i % 2) == 0)?true:false);
* }
* };
* }
* }
* <!-- END SNIPPET: action -->
* </pre>
*
*
* <pre>
* <!-- START SNIPPET: example1 -->
* &lt;!-- s: List basic --&gt;
* &lt;s:subset source="myList"&gt;
* &lt;s:iterator&gt;
* &lt;s:property /&gt;
* &lt;/s:iterator&gt;
* &lt;/s:subset&gt;
* <!-- END SNIPPET: example1 -->
* </pre>
*
* <pre>
* <!-- START SNIPPET: example2 -->
* &lt;!-- B: List with count --&gt;
* &lt;s:subset source="myList" count="3"&gt;
* &lt;s:iterator&gt;
* &lt;s:property /&gt;
* &lt;/s:iterator&gt;
* &lt;/s:subset&gt;
* <!-- END SNIPPET: example2 -->
* </pre>
*
* <pre>
* <!-- START SNIPPET: example3 -->
* &lt;!-- C: List with start -->
* &lt;s:subset source="myList" count="13" start="3"&gt;
* &lt;s:iterator&gt;
* &lt;s:property /&gt;
* &lt;/s:iterator&gt;
* &lt;/s:subset&gt;
* <!-- END SNIPPET: example3 -->
* </pre>
*
* <pre>
* <!-- START SNIPPET: example4 -->
* &lt;!-- D: List with id --&gt;
* &lt;s:subset id="mySubset" source="myList" count="13" start="3" /&gt;
* &lt;%
* Iterator i = (Iterator) pageContext.getAttribute("mySubset");
* while(i.hasNext()) {
* %&gt;
* &lt;%=i.next() %&gt;
* &lt;% } %&gt;
* <!-- END SNIPPET: example4 -->
* </pre>
*
* <pre>
* <!-- START SNIPPET: example5 -->
* &lt;!-- D: List with Decider --&gt;
* &lt;s:subset source="myList" decider="myDecider"&gt;
* &lt;s:iterator&gt;
* &lt;s:property /&gt;
* &lt;/s:iterator&gt;
* &lt;/s:subset&gt;
* <!-- END SNIPPET: example5 -->
* </pre>
*
*
* @s.tag name="subset" tld-body-content="JSP"
* description="Takes an iterator and outputs a subset of it"
*/
@StrutsTag(name="subset", tldTagClass="org.apache.struts2.views.jsp.iterator.SubsetIteratorTag",
description="Takes an iterator and outputs a subset of it.")
public class SubsetIteratorTag extends StrutsBodyTagSupport {
private static final long serialVersionUID = -6252696081713080102L;
private static final Log _log = LogFactory.getLog(SubsetIteratorTag.class);
String countAttr;
String sourceAttr;
String startAttr;
String deciderAttr;
SubsetIteratorFilter subsetIteratorFilter = null;
@StrutsTagAttribute(type="Integer", description="Indicate the number of entries to be in the resulting subset iterator")
public void setCount(String count) {
countAttr = count;
}
@StrutsTagAttribute(description="Indicate the source of which the resulting subset iterator is to be derived base on")
public void setSource(String source) {
sourceAttr = source;
}
/**
* @s.tagattribute required="false" type="Integer"
* 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"
*/
@StrutsTagAttribute(type="Integer",
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")
public void setStart(String start) {
startAttr = start;
}
@StrutsTagAttribute(type="org.apache.struts2.util.SubsetIteratorFilter.Decider",
description="Extension to plug-in a decider to determine if that particular entry is to be included in the resulting subset iterator")
public void setDecider(String decider) {
deciderAttr = decider;
}
public int doStartTag() throws JspException {
// source
Object source = null;
if (sourceAttr == null && sourceAttr.length() <= 0) {
source = findValue("top");
} else {
source = findValue(sourceAttr);
}
// count
int count = -1;
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);
}
}
}
// start
int start = 0;
if (startAttr != null && startAttr.length() > 0) {
Object startObj = findValue(startAttr);
if (startObj instanceof Integer) {
start = ((Integer)startObj).intValue();
}
else if (startObj instanceof Float) {
start = ((Float)startObj).intValue();
}
else if (startObj instanceof Long) {
start = ((Long)startObj).intValue();
}
else if (startObj instanceof Double) {
start = ((Long)startObj).intValue();
}
else if (startObj instanceof String) {
try {
start = Integer.parseInt((String)startObj);
}
catch(NumberFormatException e) {
_log.warn("unable to convert count attribute ["+startObj+"] to number, ignore count attribute", e);
}
}
}
// decider
Decider decider = null;
if (deciderAttr != null && deciderAttr.length() > 0) {
Object deciderObj = findValue(deciderAttr);
if (! (deciderObj instanceof Decider)) {
throw new JspException("decider found from stack ["+deciderObj+"] does not implement "+Decider.class);
}
decider = (Decider) deciderObj;
}
subsetIteratorFilter = new SubsetIteratorFilter();
subsetIteratorFilter.setCount(count);
subsetIteratorFilter.setDecider(decider);
subsetIteratorFilter.setSource(source);
subsetIteratorFilter.setStart(start);
subsetIteratorFilter.execute();
getStack().push(subsetIteratorFilter);
if (getId() != null) {
pageContext.setAttribute(getId(), subsetIteratorFilter);
}
return EVAL_BODY_INCLUDE;
}
public int doEndTag() throws JspException {
getStack().pop();
subsetIteratorFilter = null;
return EVAL_PAGE;
}
}