Java tutorial
/** * 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.diagnosiscapturerwanda.util; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import javax.servlet.http.HttpSession; import org.apache.commons.lang.WordUtils; import org.openmrs.Concept; import org.openmrs.ConceptName; import org.openmrs.ConceptNumeric; import org.openmrs.ConceptSearchResult; import org.openmrs.Encounter; import org.openmrs.EncounterRole; import org.openmrs.EncounterType; import org.openmrs.Location; import org.openmrs.Obs; import org.openmrs.OpenmrsObject; import org.openmrs.Order; import org.openmrs.OrderType; import org.openmrs.Patient; import org.openmrs.Provider; import org.openmrs.Visit; import org.openmrs.api.AdministrationService; import org.openmrs.api.ConceptService; import org.openmrs.api.context.Context; import org.openmrs.module.diagnosiscapturerwanda.MetadataDictionary; import org.openmrs.module.diagnosiscapturerwanda.jsonconverter.DiagnosisCustomListConverter; import org.openmrs.module.diagnosiscapturerwanda.jsonconverter.DiagnosisCustomOpenmrsObjectConverter; import org.openmrs.ui.framework.BasicUiUtils; import org.openmrs.util.OpenmrsConstants; import org.springframework.util.StringUtils; /** * this is a util class for business logic type functions. * NOTE -- the lab metadata lookups are here, because I want these to use the simplelabentry global properties to load lab metadata. */ public class DiagnosisUtil { /** * This is the main method for converting either a List<Object> or OpenmrsObject to JSON * @param o * @return */ public static String convertToJSON(Object o) { BasicUiUtils bu = new BasicUiUtils(); Object toConvert = null; if (o instanceof List) { DiagnosisCustomListConverter conv = new DiagnosisCustomListConverter(); toConvert = conv.convert((List<?>) o); } else if (o instanceof OpenmrsObject) { DiagnosisCustomOpenmrsObjectConverter conv = new DiagnosisCustomOpenmrsObjectConverter(); toConvert = conv.convert((OpenmrsObject) o); } else { //what the hell, try to convert even if we don't know what it is: toConvert = o; } return bu.toJson(toConvert); } /** * jquery autocomplete widget needs shit to look like: { label: "Choice1", value: "id1" } , { label: "Choice2", value: "id2" } * @param cList * @return */ public static String convertToJSONAutoComplete(List<Concept> cList) { BasicUiUtils bu = new BasicUiUtils(); List<AutoCompleteObj> ret = new ArrayList<AutoCompleteObj>(); Locale currentLocale = Context.getLocale(); if (cList != null) { for (Concept c : cList) { for (ConceptName cn : c.getNames()) { AutoCompleteObj o = new AutoCompleteObj(); o.setValue(c.getConceptId()); if (cn.getLocale().equals(currentLocale)) { o.setLabel(cn.getName()); } else { String label = cn.getName() + "<span class='otherHit'> ⇒ " + c.getName(currentLocale) + "</span>"; o.setLabel(label); } ret.add(o); } } } return bu.toJson(ret); } /* * Returns a list of concepts based on choice of grouping and classification * must handle invalid ids * grouping ID are the diagnosis body systems * classificaitonId is the injury/diagnosis/symptom/... conceptSet */ public static List<Concept> getConceptListByGroupingAndClassification(Integer groupingId, Integer classificationId) { List<Concept> groupsRet = new ArrayList<Concept>(); List<Concept> classificationRet = new ArrayList<Concept>(); if (groupingId != null) { Concept groups = Context.getConceptService().getConcept(groupingId); if (groups != null) { for (Concept cs : groups.getSetMembers()) { if (!groupsRet.contains(cs)) groupsRet.add(cs); } } } if (classificationId != null) { Concept cats = Context.getConceptService().getConcept(classificationId); if (cats != null) { for (Concept cs : cats.getSetMembers()) { if (!classificationRet.contains(cs)) classificationRet.add(cs); } } } //filter and return: if (groupingId != null && classificationId != null) { List<Concept> ret = intersection(groupsRet, classificationRet); Collections.sort(ret, new ConceptNameComparator()); return ret; } else if (classificationId == null) { Collections.sort(groupsRet, new ConceptNameComparator()); return groupsRet; } else if (groupingId == null) { Collections.sort(classificationRet, new ConceptNameComparator()); return classificationRet; } else return new ArrayList<Concept>(); } /** * concept name comparator * @author dthomas * */ private static class ConceptNameComparator implements Comparator<Concept> { @Override public int compare(Concept o1, Concept o2) { return o1.getName().getName().compareTo(o2.getName().getName()); //put in alphabetical order by locale } } /** * helper class to intersect two arrayLists * @param <T> * @param list1 * @param list2 * @return */ private static <T> List<T> intersection(List<T> list1, List<T> list2) { List<T> list = new ArrayList<T>(); for (T t : list1) { if (list2.contains(t)) { list.add(t); } } return list; } /** * Returns the simplelabentry supported lab tests based on global property * simplelabentry.supportedTests * * @return */ public static List<Concept> getSupportedLabTests() { String gpString = Context.getAdministrationService().getGlobalProperty("simplelabentry.supportedTests"); List<Concept> ret = new ArrayList<Concept>(); for (StringTokenizer st = new StringTokenizer(gpString, ","); st.hasMoreTokens();) { String s = st.nextToken().trim(); Concept c = Context.getConceptService().getConceptByUuid(s); if (c == null) { try { c = Context.getConceptService().getConcept(Integer.valueOf(s)); } catch (Exception ex) { } } if (c != null) { //for lazy loading c.getSetMembers(); ret.add(c); } else throw new RuntimeException( "Unable to load concept " + s + " from global property simplelabentry.supportedTests"); } return ret; } /** * return the encounterType specified by simplelabentry.labTestEncounterType * @return */ public static EncounterType getLabTestEncounterType() { String gpString = Context.getAdministrationService() .getGlobalProperty("simplelabentry.labTestEncounterType"); EncounterType ret = Context.getEncounterService().getEncounterTypeByUuid(gpString); if (ret == null) { try { ret = Context.getEncounterService().getEncounterType(Integer.valueOf(gpString)); } catch (Exception ex) { } } if (ret != null) return ret; else throw new RuntimeException("Unable to load EncounterType " + gpString + " from global property simplelabentry.labTestEncounterType"); } /** * should return the orderType specified by simplelabentry.labOrderType * @return */ public static OrderType getLabOrderType() { String gpString = Context.getAdministrationService().getGlobalProperty("simplelabentry.labOrderType"); OrderType ret = Context.getOrderService().getOrderTypeByUuid(gpString); Order o = new Order(); if (ret == null) { try { ret = Context.getOrderService().getOrderType(Integer.valueOf(gpString)); } catch (Exception ex) { } } if (ret != null) return ret; else throw new RuntimeException("Unable to load EncounterType " + gpString + " from global property simplelabentry.labOrderType"); } public static Location getLocationLoggedIn(HttpSession session) { return (Location) session.getAttribute(MetadataDictionary.SESSION_ATTRIBUTE_DIAGNOSIS_WORKSTATION_LOCATION); } public static Date[] getStartAndEndOfDay(Date datetime) { Calendar cal = Calendar.getInstance(); cal.setTime(datetime); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); Date startOfDay = cal.getTime(); cal.add(Calendar.DAY_OF_MONTH, 1); cal.add(Calendar.MILLISECOND, -1); Date endOfDay = cal.getTime(); return new Date[] { startOfDay, endOfDay }; } /** * Util method for finding the visit. EncounterUuid and encounterId can be null. * @param encounter -- usually the registration encounter, but it can be any encounter associated with a primary care Visit * @param patient (required) * @param session (required) * @return the visit */ public static Visit findVisit(Encounter enc, Patient patient, HttpSession session) throws RuntimeException { if (patient == null || session == null) throw new RuntimeException("patient and session are required in util method findVisit"); Visit visit = null; if (enc != null) visit = enc.getVisit(); if (visit == null) { //find the visit the hard way... Date earliestStartDate = DiagnosisUtil.getStartAndEndOfDay(new Date())[0]; Date latestStartDate = DiagnosisUtil.getStartAndEndOfDay(new Date())[1]; if (enc != null) { earliestStartDate = DiagnosisUtil.getStartAndEndOfDay(enc.getEncounterDatetime())[0]; latestStartDate = DiagnosisUtil.getStartAndEndOfDay(enc.getEncounterDatetime())[1]; } List<Visit> vList = Context.getVisitService().getVisits( Collections.singletonList(MetadataDictionary.VISIT_TYPE_OUTPATIENT), Collections.singletonList(patient), Collections.singleton(getLocationLoggedIn(session)), null, earliestStartDate, latestStartDate, null, null, null, true, false); if (vList != null && !vList.isEmpty()) visit = vList.get(0); } if (visit == null) throw new RuntimeException("You must register the patient first!"); return visit; } /** * check to see if visit start date is between (or equal to) day's start and end * @param v * @return */ public static boolean isVisitToday(Visit v) { if ((getStartAndEndOfDay(v.getStartDatetime())[0].getTime() <= v.getStartDatetime().getTime()) && (v.getStartDatetime().getTime() <= getStartAndEndOfDay(v.getStartDatetime())[1].getTime())) return true; return false; } /** * calculate BMI. Ripped directly out of default openmrs portlet controller */ public static String bmiAsString(Patient p, Visit visit) { String bmiAsString = "?"; if (visit != null) { Date[] visitDates = DiagnosisUtil.getStartAndEndOfDay(visit.getStartDatetime()); Date[] visitDatesStop = DiagnosisUtil.getStartAndEndOfDay(visit.getStopDatetime()); AdministrationService as = Context.getAdministrationService(); ConceptService cs = Context.getConceptService(); List<Obs> patientObs = Context.getObsService().getObservationsByPerson(p); Obs latestWeight = null; Obs latestHeight = null; try { String weightString = as.getGlobalProperty("concept.weight"); ConceptNumeric weightConcept = null; if (StringUtils.hasLength(weightString)) weightConcept = cs .getConceptNumeric(cs.getConcept(Integer.valueOf(weightString)).getConceptId()); String heightString = as.getGlobalProperty("concept.height"); ConceptNumeric heightConcept = null; if (StringUtils.hasLength(heightString)) heightConcept = cs .getConceptNumeric(cs.getConcept(Integer.valueOf(heightString)).getConceptId()); for (Obs obs : patientObs) { if (obs.getConcept().equals(weightConcept)) { if ((obs.getObsDatetime().after(visitDates[0]) && obs.getObsDatetime().before(visitDatesStop[1])) || obs.getObsDatetime().compareTo(visitDates[0]) == 0 || obs.getObsDatetime().compareTo(visitDatesStop[0]) == 0) { latestWeight = obs; } } else if (obs.getConcept().equals(heightConcept)) { if (p.getAge(visit.getStartDatetime()) > 15) { if (latestHeight == null || obs.getObsDatetime().compareTo(latestHeight.getObsDatetime()) > 0 && p.getAge(obs.getObsDatetime()) > 15) latestHeight = obs; } else if ((obs.getObsDatetime().after(visitDates[0]) && obs.getObsDatetime().before(visitDatesStop[1])) || obs.getObsDatetime().compareTo(visitDates[0]) == 0 || obs.getObsDatetime().compareTo(visitDatesStop[0]) == 0) { latestHeight = obs; } } } if (latestWeight != null && latestHeight != null) { double weightInKg; double heightInM; if (weightConcept.getUnits().equals("kg")) weightInKg = latestWeight.getValueNumeric(); else if (weightConcept.getUnits().equals("lb")) weightInKg = latestWeight.getValueNumeric() * 0.45359237; else throw new IllegalArgumentException( "Can't handle units of weight concept: " + weightConcept.getUnits()); if (heightConcept.getUnits().equals("cm")) heightInM = latestHeight.getValueNumeric() / 100; else if (heightConcept.getUnits().equals("m")) heightInM = latestHeight.getValueNumeric(); else if (heightConcept.getUnits().equals("in")) heightInM = latestHeight.getValueNumeric() * 0.0254; else throw new IllegalArgumentException( "Can't handle units of height concept: " + heightConcept.getUnits()); double bmi = weightInKg / (heightInM * heightInM); String temp = "" + bmi; bmiAsString = temp.substring(0, temp.indexOf('.') + 2); } } catch (Exception ex) { ex.printStackTrace(); return ""; } } return bmiAsString; } /** * hack to best approximate real-time extension of a visit by adding another encounter, or if encounter being added to visit is back-entry. * I'm giving an 8 hour window to extend a visit. * @param V */ private static Date getEncounterDatetimeFromVisit(Visit v) { Date maxDateInVisit = v.getStartDatetime(); try { for (Encounter e : v.getEncounters()) { if (!e.isVoided() && e.getEncounterDatetime().getTime() > maxDateInVisit.getTime()) maxDateInVisit = e.getEncounterDatetime(); } } catch (Exception ex) { //pass } Calendar visit = Calendar.getInstance(); visit.setTime(maxDateInVisit); visit.add(Calendar.HOUR_OF_DAY, 8);//this is a guess //either return now if encounter is happening within 8 hours of max event, or return max event if (visit.getTime().getTime() < (new Date()).getTime()) //its back entry return visit.getTime(); else return new Date(); } /** * utility to build the diagnosis/findings encounter */ public static Encounter buildEncounter(Patient patient, EncounterType encType, Visit visit) { Encounter encounter = new Encounter(); encounter.setPatient(patient); encounter.setEncounterDatetime(getEncounterDatetimeFromVisit(visit)); encounter.setEncounterType(encType); String locStr = Context.getAuthenticatedUser() .getUserProperty(OpenmrsConstants.USER_PROPERTY_DEFAULT_LOCATION); Location userLocation = null; try { userLocation = Context.getLocationService().getLocation(Integer.valueOf(locStr)); } catch (Exception ex) { //pass } encounter.setLocation(userLocation); encounter.setProvider(Context.getAuthenticatedUser().getPerson()); //TODO: fix this return encounter; } /** * util to instantiate new obs: */ public static Obs buildObs(Patient p, Concept concept, Date obsDatetime, Concept answer, String value, Double valueNumeric, Location location) { Obs ret = new Obs(); ret.setConcept(concept); ret.setCreator(Context.getAuthenticatedUser()); ret.setDateCreated(new Date()); ret.setLocation(location); ret.setObsDatetime(obsDatetime); ret.setPerson(p); if (answer != null) ret.setValueCoded(answer); if (value != null && !value.equals("")) ret.setValueText(value); if (valueNumeric != null) ret.setValueNumeric(valueNumeric); return ret; } /** * util to build a new order */ public static Order buildOrder(Patient p, Concept c, Encounter e) { Order order = new Order(); order.setConcept(c); order.setCreator(Context.getAuthenticatedUser()); order.setDateCreated(new Date()); order.setDiscontinued(false); order.setOrderer(Context.getAuthenticatedUser()); order.setOrderType(getLabOrderType()); order.setPatient(p); order.setStartDate(e.getEncounterDatetime()); order.setVoided(false); return order; } /** * pull the most recent encounter out of a visit by encounterType * @param v * @param et * @return */ public static Encounter findEncounterByTypeInVisit(Visit v, EncounterType et) { if (et == null) return null; List<Encounter> eList = new ArrayList<Encounter>(); for (Encounter e : v.getEncounters()) { if (!e.isVoided() && et.equals(e.getEncounterType())) eList.add(e); } if (eList.size() == 0) return null; Collections.sort(eList, new Comparator<Encounter>() { @Override public int compare(Encounter o1, Encounter o2) { return o2.getEncounterDatetime().compareTo(o1.getEncounterDatetime()); //this is supposed to be chronological desc } }); return eList.get(eList.size() - 1); } /** * Auto generated method comment * * @param diagnosisConcepts * @return */ public static List<ConceptName> convertToAutoComplete(List<ConceptSearchResult> diagnosisConcepts) { List<ConceptName> ret = new ArrayList<ConceptName>(); if (diagnosisConcepts != null) { for (ConceptSearchResult c : diagnosisConcepts) { for (ConceptName cn : c.getConcept().getNames()) { ret.add(cn); } } } Collections.sort(ret, new Comparator<ConceptName>() { @Override public int compare(ConceptName o1, ConceptName o2) { return o1.getName().compareTo(o2.getName()); } }); return ret; } public static List<AutoCompleteObj> convertToAutoCompleteObj(List<ConceptSearchResult> diagnosisConcepts) { List<AutoCompleteObj> ret = new ArrayList<AutoCompleteObj>(); Locale currentLocale = Context.getLocale(); if (diagnosisConcepts != null) { for (ConceptSearchResult c : diagnosisConcepts) { for (ConceptName cn : c.getConcept().getNames()) { AutoCompleteObj o = new AutoCompleteObj(); o.setValue(c.getConcept().getConceptId()); if (cn.getName().equals(c.getConcept().getDisplayString())) { o.setLabel(WordUtils.capitalizeFully(cn.getName())); } else { String label = WordUtils.capitalizeFully(WordUtils.capitalizeFully(cn.getName())) + "<span class='otherHit'> ⇒ " + WordUtils.capitalizeFully(c.getConcept().getDisplayString()) + "</span>"; o.setLabel(label); } ret.add(o); } } } Collections.sort(ret, new Comparator<AutoCompleteObj>() { @Override public int compare(AutoCompleteObj o1, AutoCompleteObj o2) { return o1.getLabel().compareTo(o2.getLabel()); } }); return ret; } /** * Auto generated method comment * * @param findingsConcepts * @return */ public static List<AutoCompleteObj> convertConceptToAutoCompleteObj(List<Concept> findingsConcepts) { List<AutoCompleteObj> ret = new ArrayList<AutoCompleteObj>(); Locale currentLocale = Context.getLocale(); if (findingsConcepts != null) { for (Concept c : findingsConcepts) { for (ConceptName cn : c.getNames()) { AutoCompleteObj o = new AutoCompleteObj(); o.setValue(c.getConceptId()); if (cn.getName().equals(c.getDisplayString())) { o.setLabel(WordUtils.capitalizeFully(cn.getName())); } else { String label = WordUtils.capitalizeFully(cn.getName()) + "<span class='otherHit'> ⇒ " + WordUtils.capitalizeFully(c.getDisplayString()) + "</span>"; o.setLabel(label); } ret.add(o); } } } Collections.sort(ret, new Comparator<AutoCompleteObj>() { @Override public int compare(AutoCompleteObj o1, AutoCompleteObj o2) { return o1.getLabel().compareTo(o2.getLabel()); } }); return ret; } public static List<AutoCompleteObj> getCategories() { List<AutoCompleteObj> categories = new ArrayList<AutoCompleteObj>(); Concept concept = MetadataDictionary.CONCEPT_SET_ICPC_DIAGNOSIS_GROUPING_CATEGORIES; for (Concept c : concept.getSetMembers()) { AutoCompleteObj obj = new AutoCompleteObj(); obj.setValue(c.getConceptId()); ConceptName cn = c.getShortNameInLanguage(Context.getLocale().getLanguage()); if (cn == null) { cn = c.getName(); } obj.setLabel(cn.getName()); categories.add(obj); } return categories; } /** * Auto generated method comment * * @param v * @return */ public static List<VisitPOJO> getVisitPOJO(List<Visit> v) { List<VisitPOJO> visits = new ArrayList<VisitPOJO>(); for (Visit visit : v) { VisitPOJO pojo = new VisitPOJO(); pojo.setDate(visit.getStartDatetime()); pojo.setLocation(visit.getLocation().getName()); pojo.setPatient(visit.getPatient()); pojo.setId(visit.getId()); Set<Encounter> encounters = visit.getEncounters(); Encounter diagnosis = null; for (Encounter e : encounters) { if (e.getEncounterType().equals(MetadataDictionary.ENCOUNTER_TYPE_DIAGNOSIS)) { diagnosis = e; break; } } if (diagnosis != null) { Map<EncounterRole, Set<Provider>> providers = diagnosis.getProvidersByRoles(); for (EncounterRole er : providers.keySet()) { for (Provider p : providers.get(er)) { pojo.setProvider(p.getName()); } } for (Obs o : diagnosis.getAllObs()) { if (o.getConcept() .equals(MetadataDictionary.CONCEPT_SET_PRIMARY_CARE_PRIMARY_DIAGNOSIS_CONSTRUCT)) { for (Obs go : o.getGroupMembers()) { if (go.getConcept().equals(MetadataDictionary.CONCEPT_PRIMARY_CARE_DIAGNOSIS) && go.getValueCoded() != null) { pojo.setDiagnosis(WordUtils.capitalizeFully(go.getValueCoded().getDisplayString())); break; } if (go.getConcept().equals(MetadataDictionary.CONCEPT_DIAGNOSIS_NON_CODED) && go.getValueText() != null && !go.getValueText().equals("")) { pojo.setDiagnosis(go.getValueText()); break; } } } } } visits.add(pojo); } return visits; } }