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.hl7output.web.controller; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openmrs.Encounter; import org.openmrs.Patient; import org.openmrs.PatientIdentifierType; import org.openmrs.api.context.Context; import org.openmrs.hl7.HL7InArchive; import org.openmrs.hl7.HL7InError; import org.openmrs.hl7.HL7InQueue; import org.openmrs.hl7.HL7Source; import org.openmrs.module.hl7output.api.LogEncounterService; import org.openmrs.module.hl7output.extension.html.HL7Receiver; import org.openmrs.module.hl7output.model.GetEncounterLog; import org.openmrs.module.hl7output.model.MatchingEncounters; import org.openmrs.module.hl7output.model.PostEncounterLog; import org.openmrs.module.hl7output.util.GenerateORU_R01; import org.openmrs.module.webservices.rest.SimpleObject; import org.openmrs.module.webservices.rest.web.v1_0.controller.BaseCrudController; import org.openmrs.module.webservices.rest.web.v1_0.resource.PatientResource; import org.openmrs.module.webservices.rest.web.response.ConversionException; import org.openmrs.module.webservices.rest.web.response.ResponseException; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import ca.uhn.hl7v2.HL7Exception; import ca.uhn.hl7v2.model.v25.message.ORU_R01; @Controller @RequestMapping(value = "/rest/RHEA/patient/") public class RHEApatientController extends BaseCrudController<PatientResource> { private Log log = LogFactory.getLog(this.getClass()); private HL7Receiver receiver = new HL7Receiver(); @RequestMapping(value = "/{ecID}/encounters", method = RequestMethod.GET) @ResponseBody public Object getEncounters(@PathVariable("ecID") String enterpriseId, @RequestParam(value = "encounterUniqueId", required = false) String encounterUniqueId, @RequestParam(value = "dateStart", required = false) String dateStart, @RequestParam(value = "dateEnd", required = false) String dateEnd, HttpServletRequest request, HttpServletResponse response) throws ResponseException { LogEncounterService service = Context.getService(LogEncounterService.class); Date fromDate = null; Date toDate = null; Patient p = null; ORU_R01 r01 = null; log.info("RHEA Controller call detected..."); log.info("Enterprise Patient Id is :" + enterpriseId); log.info("encounterUniqueId is :" + encounterUniqueId); log.info("dateStart is :" + dateStart); GetEncounterLog getEncounterLog = new GetEncounterLog(); getEncounterLog.setEncounterUniqueId(encounterUniqueId); // first, we create from and to data objects out of the String // parameters if (enterpriseId == null) { log.info("Error : missing enterpriseId"); getEncounterLog.setResult("Error, missing enterpriseId"); service.saveGetEncounterLog(getEncounterLog); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); return null; } getEncounterLog.setEnterpriseId(enterpriseId); SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy"); try { if (dateStart != null) fromDate = format.parse(dateStart); } catch (ParseException e) { log.info("Error : failed to parse specidied start date : " + dateStart); getEncounterLog.setResult("Error, incorrectly parsed start date"); service.saveGetEncounterLog(getEncounterLog); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); return null; } log.info("fromDate is :" + fromDate); try { if (dateEnd != null) toDate = format.parse(dateEnd); } catch (ParseException e) { log.info("Error : failed to parse specidied end date : " + dateEnd); getEncounterLog.setResult("Error, incorrectly parsed start date"); service.saveGetEncounterLog(getEncounterLog); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); return null; } log.info("toDate is :" + toDate); getEncounterLog.setDateEnd(toDate); getEncounterLog.setDateStart(fromDate); // Next, we try to retrieve the matching patient object if (enterpriseId != null) { PatientIdentifierType patientIdentifierType = Context.getPatientService() .getPatientIdentifierTypeByName("ECID"); List<PatientIdentifierType> identifierTypeList = new ArrayList<PatientIdentifierType>(); identifierTypeList.add(patientIdentifierType); List<Patient> patients = Context.getPatientService().getPatients(null, enterpriseId, identifierTypeList, false); //I am not checking the identifier type here. Need to come back and add a check for this if (patients.size() == 1) { p = patients.get(0); } } // if the patient doesn't exist, we need to return 400-BAD REQUEST // because the parameters are malformed if (p == null) { log.info("Error : failed to retreive patient for the given uuid : " + enterpriseId); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); } else { log.info("Patient id : " + p.getPatientId() + "was retreived..."); if (p != null) { //get all the encounters for this patient List<Encounter> encounterList = Context.getEncounterService().getEncountersByPatient(p); //if the enconteruniqueId is not null, we can isolate the given encounter if (encounterUniqueId != null) { Iterator<Encounter> i = encounterList.iterator(); while (i.hasNext()) { if (!i.next().getUuid().equals(encounterUniqueId)) i.remove(); } } //If the encounterUniqueId was not given, we will try to filter encounters based on from and to dates List<Encounter> filteredEncounterList = new ArrayList<Encounter>(); if (fromDate != null || toDate != null) { for (Encounter encounter : encounterList) { if (fromDate != null && toDate != null) { if ((encounter.getEncounterDatetime().after(fromDate)) && (encounter.getEncounterDatetime().before(toDate))) { filteredEncounterList.add(encounter); } } else if (fromDate == null) { if (encounter.getEncounterDatetime().before(toDate)) { filteredEncounterList.add(encounter); } } else { if (encounter.getEncounterDatetime().after(fromDate)) { filteredEncounterList.add(encounter); } } } log.info("The number of matching encounters are :" + filteredEncounterList.size()); encounterList = filteredEncounterList; } log.info("Calling the ORU_R01 parser..."); SortedSet<MatchingEncounters> encounterSet = new TreeSet<MatchingEncounters>(); for (Encounter e : encounterList) { MatchingEncounters matchingEncounters = new MatchingEncounters(); matchingEncounters.setGetEncounterLog(getEncounterLog); matchingEncounters.setEncounterId(e.getEncounterId()); encounterSet.add(matchingEncounters); } getEncounterLog.setLogTime(new Date()); if (encounterList.size() > 0) getEncounterLog.setResult("Results Retrived"); if (encounterList.size() == 0) getEncounterLog.setResult("No Results Retrived"); //Now we will generate the HL7 message GenerateORU_R01 R01Util = new GenerateORU_R01(); try { r01 = R01Util.generateORU_R01Message(p, encounterList); } catch (Exception e) { getEncounterLog.setResult("Error : Processing hl7 message failed"); service.saveGetEncounterLog(getEncounterLog); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return null; } getEncounterLog.getMatchingEncounters().clear(); getEncounterLog.setMatchingEncounters(encounterSet); service.saveGetEncounterLog(getEncounterLog); } try { // Convert the ORU_R01 object into a byte stream ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(r01); oos.flush(); oos.close(); bos.close(); byte[] data = bos.toByteArray(); // Write the bytestream into the HttpServletResponse ServletOutputStream stream = response.getOutputStream(); stream.write(data); stream.flush(); response.getWriter().flush(); response.getWriter().close(); //NOTE : Im returning the ORU_R01 object as a bytestream AND a session object. Why both ? remove one later ! request.getSession().setAttribute("oru_r01", r01); response.setStatus(HttpServletResponse.SC_OK); } catch (IOException e) { e.printStackTrace(); } } // Return null for now return null; } @RequestMapping(value = "/{ecID}/encounters", method = RequestMethod.POST) @ResponseBody public Object createEncounters(@RequestBody String hl7, @PathVariable("ecID") String enterpriseId, HttpServletRequest request, HttpServletResponse response) throws ResponseException { Patient patient = null; LogEncounterService service = Context.getService(LogEncounterService.class); PostEncounterLog postEncounterLog = new PostEncounterLog(); postEncounterLog.setEnterpriseId(enterpriseId); postEncounterLog.setHl7data(hl7); postEncounterLog.setDateCreated(new Date()); postEncounterLog.setUserId(Context.getUserContext().getAuthenticatedUser().getUserId()); SimpleObject post = new SimpleObject(); log.info("RHEA HL7 Message Controller call detected..."); String[] hl7split = hl7.split("\\|"); if (hl7split.length < 10) { postEncounterLog.setErrorMessage("The HL7 message is too short or has a wrong format"); postEncounterLog.setValid(false); service.savePostEncounterLog(postEncounterLog); log.info("The HL7 message is too short or has a wrong format: " + hl7); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); return null; } postEncounterLog.setValid(true); service.savePostEncounterLog(postEncounterLog); if (enterpriseId != null) { PatientIdentifierType patientIdentifierType = Context.getPatientService() .getPatientIdentifierTypeByName("ECID"); List<PatientIdentifierType> identifierTypeList = new ArrayList<PatientIdentifierType>(); identifierTypeList.add(patientIdentifierType); List<Patient> patients = Context.getPatientService().getPatients(null, enterpriseId, identifierTypeList, false); //I am not checking the identifier type here. Need to come back and add a check for this if (patients.size() == 1) { patient = patients.get(0); } } if (patient == null) { log.info("Error, Patient is missing : " + hl7); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); } else { String sourceKey = hl7split[9]; String source = hl7split[3]; log.info("Source key : " + sourceKey); log.info("Source : " + source); log.info("data :" + hl7); log.info("enterprise id :" + enterpriseId); post.add("sourceKey", sourceKey); post.add("source", source); post.add("data", hl7); //For RHEA, should the source be a single static entity ? HL7Source hl7Source = Context.getHL7Service().getHL7SourceByName(source); if (hl7Source == null) { throw new ConversionException("The " + source + " source was not recognized"); } log.info("Creating HL7InQueue object..."); HL7InQueue hl7InQueue = new HL7InQueue(); hl7InQueue.setHL7Data(hl7); log.info("hl7 message is : " + hl7.toString()); hl7InQueue.setHL7Source(hl7Source); log.info("hl7 source is : " + hl7Source.toString()); hl7InQueue.setHL7SourceKey(sourceKey); log.info("hl7 source key is : " + sourceKey); Context.getHL7Service().saveHL7InQueue(hl7InQueue); try { //Call the processor method processHL7InQueue(hl7InQueue, enterpriseId); } catch (HL7Exception e) { e.printStackTrace(); HL7InError error = new HL7InError(hl7InQueue); error.setError(e.getMessage()); Context.getHL7Service().saveHL7InError(error); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); } catch (Exception e) { e.printStackTrace(); HL7InError error = new HL7InError(hl7InQueue); error.setError(e.getMessage()); Context.getHL7Service().saveHL7InError(error); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } //Object created = getResource().create(post, context); //return RestUtil.created(response, created); } return null; } public void processHL7InQueue(HL7InQueue hl7InQueue, String enterpriseId) throws HL7Exception, Exception { if (log.isDebugEnabled()) log.debug("Processing HL7 inbound queue (id=" + hl7InQueue.getHL7InQueueId() + ",key=" + hl7InQueue.getHL7SourceKey() + ")"); // Parse the HL7 into an HL7Message or abort with failure String hl7Message = hl7InQueue.getHL7Data(); // Send the inbound HL7 message to our receiver routine for // processing if (log.isDebugEnabled()) log.debug("Sending HL7 message to HL7 receiver"); receiver.processMessage(hl7Message, enterpriseId); // Move HL7 inbound queue entry into the archive before exiting if (log.isDebugEnabled()) log.debug("Archiving HL7 inbound queue entry"); HL7InArchive hl7InArchive = new HL7InArchive(hl7InQueue); Context.getHL7Service().saveHL7InArchive(hl7InArchive); if (log.isDebugEnabled()) log.debug("Removing HL7 message from inbound queue"); //NOTE : the purging of the HL7Queue is done in theOpenMRS Core (hl7serviceimpl class). DONT call it here. // clean up memory after processing each queue entry (otherwise, the // memory-intensive process may crash or eat up all our memory) Context.getHL7Service().garbageCollect(); } }