/** * 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.web.taglib; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspTagException; import javax.servlet.jsp.tagext.BodyTagSupport; import org.apache.commons.beanutils.BeanComparator; import org.apache.commons.collections.comparators.ComparableComparator; import org.apache.commons.collections.comparators.ReverseComparator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openmrs.Obs; public class ForEachObsTag extends BodyTagSupport { public static final long serialVersionUID = 1L; private final Log log = LogFactory.getLog(getClass()); int count = 0; List<Obs> matchingObs = null; // Properties accessible through tag attributes private Collection<Obs> obs; private Integer conceptId; private Integer num = null; private String sortBy; private Boolean descending = Boolean.FALSE; private String var; public int doStartTag() { if (obs == null || obs.isEmpty()) { log.error("ForEachObsTag skipping body due to obs param = " + obs); return SKIP_BODY; } // First retrieve all observations matching the passed concept id, if provided. // If not provided, return all observations matchingObs = new ArrayList<Obs>(); for (Iterator<Obs> i = obs.iterator(); i.hasNext();) { Obs o = i.next(); if (conceptId == null || (o.getConcept() != null && o.getConcept().getConceptId().intValue() == conceptId.intValue())) { matchingObs.add(o); } } log.debug("ForEachObsTag found " + matchingObs.size() + " observations matching conceptId = " + conceptId); // Next, sort these observations if (sortBy == null || sortBy.equals("")) { sortBy = "obsDatetime"; } Comparator comp = new BeanComparator(sortBy, (descending ? new ReverseComparator(new ComparableComparator()) : new ComparableComparator())); Collections.sort(matchingObs, comp); // Return appropriate number of results if (matchingObs.isEmpty()) { return SKIP_BODY; } else { pageContext.setAttribute(var, matchingObs.get(count++)); return EVAL_BODY_BUFFERED; } } /** * @see javax.servlet.jsp.tagext.IterationTag#doAfterBody() */ public int doAfterBody() throws JspException { if (matchingObs.size() > count && (num == null || count < num.intValue())) { pageContext.setAttribute(var, matchingObs.get(count++)); return EVAL_BODY_BUFFERED; } else { return SKIP_BODY; } } /** * @see javax.servlet.jsp.tagext.Tag#doEndTag() */ public int doEndTag() throws JspException { try { if (count > 0 && bodyContent != null) { count = 0; bodyContent.writeOut(bodyContent.getEnclosingWriter()); } } catch (java.io.IOException e) { throw new JspTagException("IO Error: " + e.getMessage()); } return EVAL_PAGE; } /** * @return the obs */ public Collection<Obs> getObs() { return obs; } /** * @param obs the obs to set */ public void setObs(Collection<Obs> obs) { this.obs = obs; } /** * @return the conceptId */ public Integer getConceptId() { return conceptId; } /** * @param conceptId the conceptId to set */ public void setConceptId(Integer conceptId) { this.conceptId = conceptId; } /** * @return the Num */ public Integer getNum() { return num; } /** * @param Num the Num to set */ public void setNum(Integer num) { this.num = num; } /** * @param var the var to set */ public void setVar(String var) { this.var = var; } /** * @return the descending */ public Boolean getDescending() { return descending; } /** * @param descending the descending to set */ public void setDescending(Boolean descending) { this.descending = descending; } /** * @return the sortBy */ public String getSortBy() { return sortBy; } /** * @param sortBy the sortBy to set */ public void setSortBy(String sortBy) { this.sortBy = sortBy; } }