/**
* The contents of this file are subject to the OpenMRS Public License
* Version 1.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://license.openmrs.org
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* Copyright (C) OpenMRS, LLC. All Rights Reserved.
*/
package org.openmrs.module.reporting.web.taglib;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.jstl.core.LoopTagStatus;
import javax.servlet.jsp.tagext.BodyTagSupport;
/**
* This tag allows iterating across an range of elements
*/
public class ForEachTag extends BodyTagSupport {
public static final long serialVersionUID = 1232300L;
private Iterator<?> records;
private int count;
//***** PROPERTIES *****
private Object items;
private String var;
private String varStatus;
/**
* @see BodyTagSupport#doStartTag()
*/
public int doStartTag() {
records = null;
count = 0;
if (items != null) {
if (items instanceof Iterable<?>) {
records = ((Iterable<?>) items).iterator();
}
else if (items instanceof Object[]) {
Object[] arr = (Object[]) items;
records = Arrays.asList(arr).iterator();
}
else if (items instanceof Map<?, ?>) {
records = ((Map<?, ?>) items).entrySet().iterator();
}
}
if (records == null || !records.hasNext()) {
records = null;
return SKIP_BODY;
}
else {
return EVAL_BODY_BUFFERED;
}
}
/**
* @see javax.servlet.jsp.tagext.BodyTag#doInitBody()
*/
public void doInitBody() throws JspException {
if (records.hasNext()) {
iterate();
}
}
/**
* @see javax.servlet.jsp.tagext.IterationTag#doAfterBody()
*/
public int doAfterBody() throws JspException {
if (records.hasNext()) {
iterate();
return EVAL_BODY_BUFFERED;
}
else {
return SKIP_BODY;
}
}
/**
* Iterates the next object in the iterator
*/
private void iterate() {
final Object obj = records.next();
count++;
if (obj != null) {
if (var != null) {
pageContext.setAttribute(var, obj);
}
if (varStatus != null) {
LoopTagStatus s = new LoopTagStatus() {
public boolean isLast() { return !records.hasNext(); }
public boolean isFirst() { return count == 1; }
public Integer getStep() { return 1; }
public int getIndex() { return count-1; }
public int getCount() { return count; }
public Integer getBegin() { return null; }
public Object getCurrent() { return obj; }
public Integer getEnd() { return null; }
};
pageContext.setAttribute(varStatus, s);
}
}
else {
if (var != null) {
pageContext.removeAttribute(var);
}
if (varStatus != null) {
pageContext.removeAttribute(varStatus);
}
}
}
/**
* @see javax.servlet.jsp.tagext.Tag#doEndTag()
*/
public int doEndTag() throws JspException {
try {
if (getBodyContent() != null && records != null)
getBodyContent().writeOut(getBodyContent().getEnclosingWriter());
}
catch (java.io.IOException e) {
throw new JspTagException("IO Error: " + e.getMessage());
}
return EVAL_PAGE;
}
/**
* @return the items
*/
public Object getItems() {
return items;
}
/**
* @param items the items to set
*/
public void setItems(Object items) {
this.items = items;
}
/**
* @return the var
*/
public String getVar() {
return var;
}
/**
* @param var the var to set
*/
public void setVar(String var) {
this.var = var;
}
/**
* @return the varStatus
*/
public String getVarStatus() {
return varStatus;
}
/**
* @param varStatus the varStatus to set
*/
public void setVarStatus(String varStatus) {
this.varStatus = varStatus;
}
}