/** * 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.Calendar; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; 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.Encounter; import org.openmrs.Obs; import org.openmrs.api.ConceptService; import org.openmrs.api.PatientSetService; import org.openmrs.api.context.Context; import org.openmrs.util.OpenmrsUtil; public class SummaryTest extends TagSupport { private static final long serialVersionUID = 102731753333L; private final Log log = LogFactory.getLog(getClass()); private Collection<Obs> observations; private Collection<Encounter> encounters; private String var; private String ifTrue; private String ifFalse; public int doStartTag() { Boolean ret = false; if ((ifTrue == null || ifTrue.length() == 0) && (ifFalse == null || ifFalse.length() == 0)) { ret = true; } else { if (ifTrue != null && ifTrue.length() > 0) ret |= evaluate(ifTrue); if (ifFalse != null && ifFalse.length() > 0) ret |= !evaluate(ifFalse); } pageContext.setAttribute(var, ret); return SKIP_BODY; } public int doEndTag() { observations = null; var = null; ifTrue = null; ifFalse = null; return EVAL_PAGE; } private boolean evaluate(String expr) { expr = expr.trim(); log.debug("evaluate " + expr); List<String> commands = new ArrayList<String>(); { StringBuilder command = new StringBuilder(); String[] lines = expr.split("\n"); for (String line : lines) { if (line.trim().startsWith("!")) { if (command.length() > 0) { commands.add(command.toString()); command = new StringBuilder(); } } command.append(line.trim()); command.append("\n"); } if (command.length() > 0) commands.add(command.toString()); } boolean andMode = true; List<Boolean> commandResults = new ArrayList<Boolean>(); for (String s : commands) { String command = (new StringTokenizer(s.toUpperCase())).nextToken(); if (command.equals("!AND")) { andMode = true; } else if (command.equals("!OR")) { andMode = false; } else if (command.equals("!OBSCHECK")) { s = s.substring("!OBSCHECK".length()).trim(); commandResults.add(handleObsCheck(s)); } else { throw new RuntimeException("Don't know how to handle command " + command + "\n" + s); } } boolean ret = andMode ? true : false; for (Boolean b : commandResults) { if (andMode) ret &= b; else ret |= b; } return ret; } private boolean handleObsCheck(String expr) { log.debug("handleObsCheck(" + expr + ")"); expr = expr.trim(); if (expr.length() == 0) return true; Map<String, String> args = new HashMap<String, String>(); String[] lines = expr.split("\n"); for (String s : lines) { s = s.trim(); int ind = s.indexOf(':'); String key = s.substring(0, ind).toLowerCase(); String val = s.substring(ind + 1); args.put(key, val); log.debug(key + " -> " + val); } PatientSetService.TimeModifier test = PatientSetService.TimeModifier.ANY; Set<Concept> conceptsOfInterest = new HashSet<Concept>(); Date fromDate = null; Date toDate = null; if (args.containsKey("test")) test = PatientSetService.TimeModifier.valueOf(args.get("test").trim().toUpperCase()); String conceptName = args.get("concept"); if (conceptName == null) throw new IllegalArgumentException("You must specify a concept"); { ConceptService cs = Context.getConceptService(); boolean isSet = conceptName.startsWith("set:"); if (isSet) conceptName = conceptName.substring("set:".length()); Concept c = cs.getConceptByName(conceptName); if (c == null) { log.warn("Can't find concept " + conceptName); } else { if (isSet) conceptsOfInterest.addAll(cs.getConceptsByConceptSet(c)); else conceptsOfInterest.add(c); } } if (args.containsKey("timespan")) { // [last|next defaults to last] [# defaults to 1] [m|d|y defaults to m] boolean inPast = true; int timeUnit = Calendar.MONTH; Integer time = 1; String ts = args.get("timespan"); String[] s = ts.split(" "); for (String str : s) { if (str.length() == 0) continue; if (str.startsWith("l")) inPast = true; else if (str.startsWith("n")) inPast = false; else if (str.startsWith("m")) timeUnit = Calendar.MONTH; else if (str.startsWith("d")) timeUnit = Calendar.DAY_OF_MONTH; else if (str.startsWith("y")) timeUnit = Calendar.YEAR; else time = Integer.valueOf(str); } Calendar c = Calendar.getInstance(); c.add(timeUnit, (inPast ? -1 : 1) * time); if (inPast) fromDate = c.getTime(); else toDate = c.getTime(); } log.debug("test:" + test); log.debug("concepts of interest:" + conceptsOfInterest); log.debug("fromDate:" + fromDate); log.debug("toDate:" + toDate); List<Obs> obsThatMatter = new ArrayList<Obs>(); for (Obs o : observations) { if (conceptsOfInterest.contains(o.getConcept()) && (fromDate == null || OpenmrsUtil.compare(fromDate, o.getObsDatetime()) <= 0) && (toDate == null || OpenmrsUtil.compare(o.getObsDatetime(), toDate) <= 0)) { obsThatMatter.add(o); } } log.debug("obsThatMatter (" + obsThatMatter.size() + "): " + obsThatMatter); if (test == PatientSetService.TimeModifier.ANY) { return obsThatMatter.size() > 0; } else if (test == PatientSetService.TimeModifier.NO) { return obsThatMatter.size() == 0; } else { throw new RuntimeException("Can't handle test:" + test); } } public String getIfFalse() { return ifFalse; } public void setIfFalse(String ifFalse) { this.ifFalse = ifFalse; } public String getIfTrue() { return ifTrue; } public void setIfTrue(String ifTrue) { this.ifTrue = ifTrue; } public Collection<Obs> getObservations() { return observations; } public void setObservations(Collection<Obs> observations) { this.observations = observations; } public String getVar() { return var; } public void setVar(String var) { this.var = var; } public Collection<Encounter> getEncounters() { return encounters; } public void setEncounters(Collection<Encounter> encounters) { this.encounters = encounters; } }