/**
* 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.io.IOException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.Concept;
import org.openmrs.ConceptName;
import org.openmrs.Obs;
import org.openmrs.api.ObsService;
import org.openmrs.api.context.Context;
import org.openmrs.api.context.UserContext;
import org.openmrs.util.OpenmrsUtil;
public class ActiveListWidget extends TagSupport {
private static final long serialVersionUID = 14352322222L;
private final Log log = LogFactory.getLog(getClass());
private Collection<Obs> observations;
private Boolean showDate = false;
private String displayStyle = "ol";
private Date onDate;
// pipe-separated lists of "conceptId" or "name:CONCEPT NAME". starting with "set:" means treat this as a set.
private String addConcept;
private String removeConcept;
private String otherGroupedConcepts;
public ActiveListWidget() {
}
public int doStartTag() {
UserContext userContext = Context.getUserContext();
Locale loc = userContext.getLocale();
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, loc);
Set<Concept> addConceptList = OpenmrsUtil.conceptSetHelper(addConcept);
Set<Concept> removeConceptList = OpenmrsUtil.conceptSetHelper(removeConcept);
List<Concept> otherConceptList = OpenmrsUtil.conceptListHelper(otherGroupedConcepts);
boolean doObsGroups = otherConceptList.size() > 0;
if (onDate == null)
onDate = new Date();
// maps Concept to the date that became active
Map<Concept, Obs> activeList = new HashMap<Concept, Obs>();
for (Obs o : observations) {
// skip observations in the future
if (OpenmrsUtil.compare(o.getObsDatetime(), onDate) > 0)
continue;
Concept c = o.getConcept();
Concept toDo = o.getValueCoded();
if (toDo == null)
toDo = c;
if (addConceptList.contains(o.getConcept())) {
Date newActiveDate = o.getObsDatetime();
Obs tmp = activeList.get(c);
Date currentActiveDate = tmp == null ? null : tmp.getObsDatetime();
if (currentActiveDate == null || newActiveDate.compareTo(currentActiveDate) < 0)
activeList.put(toDo, o);
} else if (removeConceptList.contains(o.getConcept())) {
activeList.remove(toDo);
}
}
List<Map.Entry<Concept, Obs>> ordered = new ArrayList<Map.Entry<Concept, Obs>>(activeList.entrySet());
Collections.sort(ordered, new Comparator<Map.Entry<Concept, Obs>>() {
public int compare(Map.Entry<Concept, Obs> left, Map.Entry<Concept, Obs> right) {
return left.getValue().getObsDatetime().compareTo(right.getValue().getObsDatetime());
}
});
Map<Obs, Collection<Obs>> obsGroups = new HashMap<Obs, Collection<Obs>>();
if (doObsGroups) {
ObsService os = Context.getObsService();
for (Obs o : activeList.values())
if (o.isObsGrouping())
obsGroups.put(o, o.getGroupMembers());
}
StringBuilder sb = new StringBuilder();
String before = "";
String after = "";
String obsGroupHeader = "";
String beforeItem = "";
String afterItem = "";
String obsGroupItemSeparator = "";
if ("ol".equals(displayStyle) || "ul".equals(displayStyle)) {
before = "<" + displayStyle + ">";
after = "</" + displayStyle + ">";
beforeItem = "<li>";
afterItem = "</li>";
obsGroupItemSeparator = ", ";
} else if (displayStyle.startsWith("separator:")) {
afterItem = displayStyle.substring(displayStyle.indexOf(":") + 1);
obsGroupItemSeparator = " ";
} else if ("table".equals(displayStyle)) {
before = "<table>";
after = "</table>";
beforeItem = "<tr><td>";
afterItem = "</td></tr>";
obsGroupItemSeparator = "</td><td>";
if (doObsGroups) {
StringBuilder s = new StringBuilder();
s.append("<tr><th></th>");
for (Concept c : otherConceptList) {
ConceptName cn = c.getBestShortName(loc);
s.append("<th><small>" + cn.getName() + "</small></th>");
}
s.append("</tr>");
obsGroupHeader = s.toString();
}
} else {
throw new RuntimeException("Unknown displayStyle: " + displayStyle);
}
if (ordered.size() > 0) {
sb.append(before);
sb.append(obsGroupHeader);
for (Map.Entry<Concept, Obs> e : ordered) {
sb.append(beforeItem);
sb.append(e.getKey().getName(loc, false).getName());
if (showDate)
sb.append(" ").append(df.format(e.getValue().getObsDatetime()));
if (doObsGroups) {
Collection<Obs> obsGroup = obsGroups.get(e.getValue());
for (Concept c : otherConceptList) {
sb.append(obsGroupItemSeparator);
if (obsGroup != null) {
for (Obs o : obsGroup) {
if (c.equals(o.getConcept())) {
sb.append(o.getValueAsString(loc));
break;
}
}
}
}
}
sb.append(afterItem);
}
sb.append(after);
}
try {
JspWriter w = pageContext.getOut();
w.println(sb);
}
catch (IOException ex) {
log.error("Error while writing to JSP", ex);
}
return SKIP_BODY;
}
public int doEndTag() {
observations = null;
addConcept = null;
removeConcept = null;
otherGroupedConcepts = null;
showDate = false;
displayStyle = "ol";
onDate = null;
return EVAL_PAGE;
}
// getters and setters
public String getAddConcept() {
return addConcept;
}
public void setAddConcept(String addConcept) {
this.addConcept = addConcept;
}
public String getRemoveConcept() {
return removeConcept;
}
public void setRemoveConcept(String removeConcept) {
this.removeConcept = removeConcept;
}
public String getDisplayStyle() {
return displayStyle;
}
public void setDisplayStyle(String displayStyle) {
if (displayStyle == null || displayStyle.length() == 0)
return;
this.displayStyle = displayStyle;
}
public Collection<Obs> getObservations() {
return observations;
}
public void setObservations(Collection<Obs> observations) {
this.observations = observations;
}
public Boolean getShowDate() {
return showDate;
}
public void setShowDate(Boolean showDate) {
if (showDate == null)
return;
this.showDate = showDate;
}
public Date getOnDate() {
return onDate;
}
public void setOnDate(Date onDate) {
if (onDate == null)
return;
this.onDate = onDate;
}
public String getOtherGroupedConcepts() {
return otherGroupedConcepts;
}
public void setOtherGroupedConcepts(String otherGroupedConcepts) {
if (otherGroupedConcepts == null || otherGroupedConcepts.length() == 0)
return;
this.otherGroupedConcepts = otherGroupedConcepts;
}
}