/** * @see org.openmrs.logic.Rule#eval(org.openmrs.logic.LogicContext, java.lang.Integer, * java.util.Map) */ public Result eval(LogicContext context, Integer patientId, Map<String, Object> parameters) throws LogicException { Integer index = null; List<Result> results = null; Result distinctResult = null; if (parameters != null) { Object param1Obj = parameters.get("param1"); if (param1Obj != null) { index = Integer.parseInt((String) param1Obj); } results = (List<Result>) parameters.get("param2"); } if (index != null && results != null && index < results.toArray().length) { // Sort the results by date Collections.sort(results, new ResultDateComparator()); // Reverse the list Collections.reverse(results); distinctResult = (Result) results.toArray()[index]; } if (distinctResult == null) { distinctResult = new Result(); } if (distinctResult.toString() == null) { distinctResult.setValueText(String.valueOf(distinctResult.toNumber())); } return distinctResult; }
/** * @return string representation of the result. For non-text results, this will either be the * overridden text value (if specifically defined) or a string representation of the default * datatype value. If the result is a list, then the string representation of all members a * joined with commas. */ public String toString() { if (isSingleResult()) { if (datatype == null) { return valueText == null ? "" : valueText; } switch (datatype) { case BOOLEAN: return (valueBoolean ? "true" : "false"); case CODED: return (valueCoded == null ? "" : valueCoded.getBestName(Context.getLocale()).getName()); case DATETIME: return (valueDatetime == null ? "" : Context.getDateFormat().format(valueDatetime)); case NUMERIC: return (valueNumeric == null ? "" : String.valueOf(valueNumeric)); case TEXT: return (valueText == null ? "" : valueText); default: return valueText; } } StringBuffer s = new StringBuffer(); for (Result r : this) { if (s.length() > 0) { s.append(","); } s.append(r.toString()); } return s.toString(); }
/** * @return boolean representation of the result. For non-boolean results, this will either be the * overridden boolean value (if specifically defined) or a boolean representation of the * default datatype. If the result is a list, then return false only if all members are false * <table> * <th> * <td>Datatype</td> * <td>Returns</td></th> * <tr> * <td>CODED</td> * <td>false for concept FALSE<br> * true for all others</td> * </tr> * <tr> * <td>DATETIME</td> * <td>true for any date value<br> * false if the date is null</td> * </tr> * <tr> * <td>NUMERIC</td> * <td>true for any non-zero number<br> * false for zero</td> * </tr> * <tr> * <td>TEXT</td> * <td>true for any non-blank value<br> * false if blank or null</td> * </tr> * </table> */ public Boolean toBoolean() { if (isSingleResult()) { if (datatype == null) { return valueBoolean; } switch (datatype) { case BOOLEAN: return (valueBoolean == null ? false : valueBoolean); case CODED: return (valueCoded == null ? false : true); // TODO: return // false for "FALSE" // concept case DATETIME: return (valueDatetime == null ? false : true); case NUMERIC: return (valueNumeric == null || valueNumeric == 0 ? false : true); case TEXT: return (valueText == null || valueText.length() < 1 ? false : true); default: return valueBoolean; } } for (Result r : this) { if (!r.toBoolean()) { return false; } } return true; }
/** * @return true if the result is equal to the given result or is a list containing a member equal * to the given result */ public boolean contains(Result result) { if (isSingleResult()) { return this.equals(result); } for (Result r : this) { if (r.contains(result)) { return true; } } return false; }
/** * @return true if result contains a coded value with the given concept id (if the result is a * list, then returns true if <em>any</em> member has a matching coded value) */ public boolean containsConcept(Integer conceptId) { if (isSingleResult()) { return (valueCoded != null && valueCoded.getConceptId().equals(conceptId)); } for (Result r : this) { if (r.containsConcept(conceptId)) { return true; } } return false; }
/** @return true if the result has any non-zero, non-empty value */ public boolean exists() { if (isSingleResult()) { return ((valueBoolean != null && valueBoolean) || valueCoded != null || valueDatetime != null || (valueNumeric != null && valueNumeric != 0) || (valueText != null && valueText.length() > 0)); } for (Result r : this) { if (r.exists()) { return true; } } return false; }
/** * Limits results by a given encounter id * * @see org.openmrs.logic.Rule#eval(org.openmrs.logic.LogicContext, org.openmrs.Patient, * java.util.Map) */ public Result eval(LogicContext context, Integer patientId, Map<String, Object> parameters) throws LogicException { if (parameters == null) { return Result.emptyResult(); } String conceptName = (String) parameters.get("param1"); if (conceptName == null) { return Result.emptyResult(); } Result ruleResult = null; Integer encounterId = (Integer) parameters.get("encounterId"); if (encounterId == null) { return Result.emptyResult(); } LogicCriteria conceptCriteria = new LogicCriteriaImpl(conceptName); LogicCriteria fullCriteria = null; LogicCriteria encounterCriteria = new LogicCriteriaImpl("encounterId").equalTo(encounterId.intValue()); fullCriteria = conceptCriteria.and(encounterCriteria); ruleResult = context.read(patientId, context.getLogicDataSource("obs"), fullCriteria.last()); if (ruleResult != null && ruleResult.size() > 0) { return ruleResult.get(0); } return Result.emptyResult(); }
/** @return all results greater than the given value */ public Result gt(Integer value) { if (isSingleResult()) { if (valueNumeric == null || valueNumeric <= value) { return emptyResult; } return this; } List<Result> matches = new ArrayList<Result>(); for (Result r : this) { if (!r.gt(value).isEmpty()) { matches.add(r); } } if (matches.size() < 1) { return emptyResult; } return new Result(matches); }
/** @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (obj == null || !(obj instanceof Result)) { return false; } Result r = (Result) obj; if (EmptyResult.class.isAssignableFrom(r.getClass()) && this.isEmpty()) { return true; } if (EmptyResult.class.isAssignableFrom(this.getClass()) && r.isEmpty()) { return true; } if (isSingleResult() && r.isSingleResult()) { if (datatype == null) { return false; } // both are single results switch (datatype) { case BOOLEAN: return (valueBoolean.equals(r.valueBoolean)); case CODED: return (valueCoded.equals(r.valueCoded)); case DATETIME: return (valueDatetime.equals(r.valueDatetime)); case NUMERIC: return (valueNumeric.equals(r.valueNumeric)); case TEXT: return (valueText.equals(r.valueText)); default: return false; } } if (isSingleResult() || r.isSingleResult()) { // we already know they're not both single results, so if one is // single, it's not a match return false; } if (this.size() != r.size()) { return false; } // at this point, we have two results that are lists, so members must // match exactly for (int i = 0; i < this.size(); i++) { if (!this.get(i).equals(r.get(i))) { return false; } } return true; }
/** * @return the chronologically (based on result date) last result * @should get the most recent result given multiple results * @should get the result given a single result * @should get an empty result given an empty result * @should get the result with null result date */ public Result latest() { if (isSingleResult()) { return this; } Result last = emptyResult(); // default the returned result to the first item // in case all resultDates are null if (size() > 0) { last = get(0); } for (Result r : this) { if ((last.getResultDate() == null || (r.getResultDate() != null && r.getResultDate().after(last.getResultDate())))) { last = r; } } return last; }
/** * @return the chronologically (based on result date) first result * @should get the first result given multiple results * @should get the result given a single result * @should get an empty result given an empty result * @should not get the result with null result date given other results * @should get one result with null result dates for all results */ public Result earliest() { if (isSingleResult()) { return this; } Result first = emptyResult(); // default the returned result to the first item // in case all resultDates are null if (size() > 0) { first = get(0); } for (Result r : this) { if (r != null && r.getResultDate() != null && (first.getResultDate() == null || r.getResultDate().before(first.getResultDate()))) { first = r; } } return first; }
/** TODO make this test use assert statements instead of printing to stdout */ @Test public void shouldObservationRule() { LogicService logicService = Context.getLogicService(); Cohort patients = new Cohort(); Map<Integer, Result> result = null; patients.addMember(2); try { Result r = logicService.eval(2, new LogicCriteriaImpl("CD4 COUNT")); Assert.assertNotNull(r); Assert.assertEquals(0, r.size()); result = logicService.eval(patients, new LogicCriteriaImpl("CD4 COUNT")); Assert.assertNotNull(result); result = logicService.eval(patients, new LogicCriteriaImpl("CD4 COUNT").lt(170)); Assert.assertNotNull(result); result = logicService.eval(patients, new LogicCriteriaImpl("CD4 COUNT").gt(185)); Assert.assertNotNull(result); result = logicService.eval(patients, new LogicCriteriaImpl("CD4 COUNT").equalTo(190)); Assert.assertNotNull(result); Calendar cal = Calendar.getInstance(); cal.set(2006, 3, 11); result = logicService.eval(patients, new LogicCriteriaImpl("CD4 COUNT").before(cal.getTime())); Assert.assertNotNull(result); result = logicService.eval( patients, new LogicCriteriaImpl("CD4 COUNT").lt(190).before(cal.getTime())); Assert.assertNotNull(result); result = logicService.eval(patients, new LogicCriteriaImpl("CD4 COUNT").after(cal.getTime())); Assert.assertNotNull(result); result = logicService.eval(patients, new LogicCriteriaImpl("CD4 COUNT").last()); Assert.assertNotNull(result); result = logicService.eval( patients, new LogicCriteriaImpl("CD4 COUNT").last().before(cal.getTime())); Assert.assertNotNull(result); result = logicService.eval(patients, new LogicCriteriaImpl("CD4 COUNT").not().lt(150)); Assert.assertNotNull(result); result = logicService.eval(patients, new LogicCriteriaImpl("CD4 COUNT").not().not().lt(150)); Assert.assertNotNull(result); patients.addMember(2); patients.addMember(3); result = logicService.eval(patients, new LogicCriteriaImpl("CD4 COUNT").lt(200)); Assert.assertNotNull(result); patients.addMember(39); result = logicService.eval( patients, new LogicCriteriaImpl("PROBLEM ADDED").contains("HUMAN IMMUNODEFICIENCY VIRUS")); Assert.assertNotNull(result); result = logicService.eval(patients, new LogicCriteriaImpl("CD4 COUNT")); Assert.assertNotNull(result); result = logicService.eval( patients, new LogicCriteriaImpl("CD4 COUNT").within(Duration.months(1))); Assert.assertNotNull(result); } catch (LogicException e) { log.error("testObservationRule: Error generated", e); } }