/**
* 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.hl7.impl;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.Encounter;
import org.openmrs.Location;
import org.openmrs.PatientIdentifier;
import org.openmrs.PatientIdentifierType;
import org.openmrs.Person;
import org.openmrs.User;
import org.openmrs.api.APIException;
import org.openmrs.api.context.Context;
import org.openmrs.api.impl.BaseOpenmrsService;
import org.openmrs.hl7.HL7Constants;
import org.openmrs.hl7.HL7InArchive;
import org.openmrs.hl7.HL7InError;
import org.openmrs.hl7.HL7InQueue;
import org.openmrs.hl7.HL7Service;
import org.openmrs.hl7.HL7Source;
import org.openmrs.hl7.db.HL7DAO;
import org.openmrs.util.OpenmrsConstants;
import org.openmrs.util.OpenmrsUtil;
import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.app.Application;
import ca.uhn.hl7v2.app.ApplicationException;
import ca.uhn.hl7v2.app.MessageTypeRouter;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.model.v25.datatype.CX;
import ca.uhn.hl7v2.model.v25.datatype.PL;
import ca.uhn.hl7v2.model.v25.datatype.XCN;
import ca.uhn.hl7v2.model.v25.segment.PID;
import ca.uhn.hl7v2.parser.EncodingNotSupportedException;
import ca.uhn.hl7v2.parser.GenericParser;
/**
* OpenMRS HL7 API default methods This class shouldn't be instantiated by itself. Use the
* {@link org.openmrs.api.context.Context}
*
* @see org.openmrs.hl7.HL7Service
*/
public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
private Log log = LogFactory.getLog(this.getClass());
private static HL7ServiceImpl instance;
protected HL7DAO dao;
private GenericParser parser;
private MessageTypeRouter router;
/**
* Private constructor to only support on singleton instance.
* @see #getInstance()
*/
private HL7ServiceImpl() {
}
/**
* Singleton Factory method
*
* @return a singleton instance of this HL7ServiceImpl class
*/
public static HL7ServiceImpl getInstance() {
if (instance == null) {
instance = new HL7ServiceImpl();
}
return instance;
}
/**
* @see org.openmrs.hl7.HL7Service#setHL7DAO(org.openmrs.hl7.db.HL7DAO)
*/
public void setHL7DAO(HL7DAO dao) {
this.dao = dao;
}
/**
* Used by spring to inject the parser
*
* @param parser the parser to use
*/
public void setParser(GenericParser parser) {
this.parser = parser;
}
/**
* Used by spring to inject the router
*
* @param router the router to use
*/
public void setRouter(MessageTypeRouter router) {
this.router = router;
}
/**
* @see org.openmrs.hl7.HL7Service#saveHL7Source(org.openmrs.hl7.HL7Source)
*/
public HL7Source saveHL7Source(HL7Source hl7Source) throws APIException {
if (hl7Source.getCreator() == null)
hl7Source.setCreator(Context.getAuthenticatedUser());
if (hl7Source.getDateCreated() == null)
hl7Source.setDateCreated(new Date());
return dao.saveHL7Source(hl7Source);
}
/**
* @see org.openmrs.hl7.HL7Service#purgeHL7Source(org.openmrs.hl7.HL7Source)
*/
public void purgeHL7Source(HL7Source hl7Source) throws APIException {
dao.deleteHL7Source(hl7Source);
}
/**
* @see org.openmrs.hl7.HL7Service#retireHL7Source(org.openmrs.hl7.HL7Source)
*/
public HL7Source retireHL7Source(HL7Source hl7Source) throws APIException {
throw new APIException("Not implemented yet");
}
/**
* @see org.openmrs.hl7.HL7Service#createHL7Source(org.openmrs.hl7.HL7Source)
* @deprecated
*/
public void createHL7Source(HL7Source hl7Source) {
Context.getHL7Service().saveHL7Source(hl7Source);
}
/**
* @see org.openmrs.hl7.HL7Service#getHL7Source(java.lang.Integer)
*/
public HL7Source getHL7Source(Integer hl7SourceId) {
return dao.getHL7Source(hl7SourceId);
}
/**
* @see org.openmrs.hl7.HL7Service#getAllHL7Sources()
*/
public List<HL7Source> getAllHL7Sources() throws APIException {
return dao.getAllHL7Sources();
}
/**
* @see org.openmrs.hl7.HL7Service#getHL7SourceByName(java.lang.String)
*/
public HL7Source getHL7SourceByName(String name) throws APIException {
return dao.getHL7SourceByName(name);
}
/**
* @see org.openmrs.hl7.HL7Service#getHL7Source(java.lang.String)
* @deprecated
*/
public HL7Source getHL7Source(String name) {
return getHL7SourceByName(name);
}
/**
* @see org.openmrs.hl7.HL7Service#getHL7Sources()
* @deprecated
*/
public Collection<HL7Source> getHL7Sources() {
return getAllHL7Sources();
}
/**
* @see org.openmrs.hl7.HL7Service#updateHL7Source(org.openmrs.hl7.HL7Source)
* @deprecated
*/
public void updateHL7Source(HL7Source hl7Source) {
Context.getHL7Service().saveHL7Source(hl7Source);
}
/**
* @see org.openmrs.hl7.HL7Service#deleteHL7Source(org.openmrs.hl7.HL7Source)
* @deprecated
*/
public void deleteHL7Source(HL7Source hl7Source) {
Context.getHL7Service().purgeHL7Source(hl7Source);
}
/**
* @see org.openmrs.hl7.HL7Service#getAllHL7InQueues()
*/
public List<HL7InQueue> getAllHL7InQueues() throws APIException {
return dao.getAllHL7InQueues();
}
/**
* @see org.openmrs.hl7.HL7Service#purgeHL7InQueue(org.openmrs.hl7.HL7InQueue)
*/
public void purgeHL7InQueue(HL7InQueue hl7InQueue) {
dao.deleteHL7InQueue(hl7InQueue);
}
/**
* @see org.openmrs.hl7.HL7Service#saveHL7InQueue(org.openmrs.hl7.HL7InQueue)
*/
public HL7InQueue saveHL7InQueue(HL7InQueue hl7InQueue) throws APIException {
if (hl7InQueue.getDateCreated() == null)
hl7InQueue.setDateCreated(new Date());
if (hl7InQueue.getMessageState() == null)
hl7InQueue.setMessageState(HL7Constants.HL7_STATUS_PENDING);
return dao.saveHL7InQueue(hl7InQueue);
}
/**
* @see org.openmrs.hl7.HL7Service#createHL7InQueue(org.openmrs.hl7.HL7InQueue)
* @deprecated
*/
public void createHL7InQueue(HL7InQueue hl7InQueue) {
Context.getHL7Service().saveHL7InQueue(hl7InQueue);
}
/**
* @see org.openmrs.hl7.HL7Service#getHL7InQueue(java.lang.Integer)
*/
public HL7InQueue getHL7InQueue(Integer hl7InQueueId) {
return dao.getHL7InQueue(hl7InQueueId);
}
/**
* @see org.openmrs.hl7.HL7Service#getHL7InQueues()
* @deprecated
*/
public Collection<HL7InQueue> getHL7InQueues() {
return getAllHL7InQueues();
}
/**
* @see org.openmrs.hl7.HL7Service#getNextHL7InQueue()
*/
public HL7InQueue getNextHL7InQueue() {
return dao.getNextHL7InQueue();
}
/**
* @see org.openmrs.hl7.HL7Service#deleteHL7InQueue(org.openmrs.hl7.HL7InQueue)
* @deprecated
*/
public void deleteHL7InQueue(HL7InQueue hl7InQueue) {
Context.getHL7Service().purgeHL7InQueue(hl7InQueue);
}
/**
* @see org.openmrs.hl7.HL7Service#getHL7InArchiveByState(java.lang.Integer)
*/
public List<HL7InArchive> getHL7InArchiveByState(Integer state) throws APIException {
return dao.getHL7InArchiveByState(state);
}
/**
* @see org.openmrs.hl7.HL7Service#getAllHL7InArchives()
*/
public List<HL7InArchive> getAllHL7InArchives() throws APIException {
return dao.getAllHL7InArchives();
}
/**
* @see org.openmrs.hl7.HL7Service#purgeHL7InArchive(org.openmrs.hl7.HL7InArchive)
*/
public void purgeHL7InArchive(HL7InArchive hl7InArchive) throws APIException {
dao.deleteHL7InArchive(hl7InArchive);
}
/**
* @see org.openmrs.hl7.HL7Service#saveHL7InArchive(org.openmrs.hl7.HL7InArchive)
*/
public HL7InArchive saveHL7InArchive(HL7InArchive hl7InArchive) throws APIException {
hl7InArchive.setDateCreated(new Date());
return dao.saveHL7InArchive(hl7InArchive);
}
/**
* @see org.openmrs.hl7.HL7Service#createHL7InArchive(org.openmrs.hl7.HL7InArchive)
* @deprecated
*/
public void createHL7InArchive(HL7InArchive hl7InArchive) {
Context.getHL7Service().saveHL7InArchive(hl7InArchive);
}
/**
* @see org.openmrs.hl7.HL7Service#getHL7InArchive(java.lang.Integer)
*/
public HL7InArchive getHL7InArchive(Integer hl7InArchiveId) {
return dao.getHL7InArchive(hl7InArchiveId);
}
/**
* @see org.openmrs.hl7.HL7Service#getHL7InArchives()
* @deprecated
*/
public Collection<HL7InArchive> getHL7InArchives() {
return getAllHL7InArchives();
}
/**
* @see org.openmrs.hl7.HL7Service#updateHL7InArchive(org.openmrs.hl7.HL7InArchive)
* @deprecated
*/
public void updateHL7InArchive(HL7InArchive hl7InArchive) {
Context.getHL7Service().saveHL7InArchive(hl7InArchive);
}
/**
* @see org.openmrs.hl7.HL7Service#deleteHL7InArchive(org.openmrs.hl7.HL7InArchive)
* @deprecated
*/
public void deleteHL7InArchive(HL7InArchive hl7InArchive) {
Context.getHL7Service().purgeHL7InArchive(hl7InArchive);
}
/**
* @see org.openmrs.hl7.HL7Service#getAllHL7InErrors()
*/
public List<HL7InError> getAllHL7InErrors() throws APIException {
return dao.getAllHL7InErrors();
}
/**
* @see org.openmrs.hl7.HL7Service#purgeHL7InError(org.openmrs.hl7.HL7InError)
*/
public void purgeHL7InError(HL7InError hl7InError) throws APIException {
dao.deleteHL7InError(hl7InError);
}
/**
* @see org.openmrs.hl7.HL7Service#saveHL7InError(org.openmrs.hl7.HL7InError)
*/
public HL7InError saveHL7InError(HL7InError hl7InError) throws APIException {
hl7InError.setDateCreated(new Date());
return dao.saveHL7InError(hl7InError);
}
/**
* @see org.openmrs.hl7.HL7Service#createHL7InError(org.openmrs.hl7.HL7InError)
* @deprecated
*/
public void createHL7InError(HL7InError hl7InError) {
Context.getHL7Service().saveHL7InError(hl7InError);
}
/**
* @see org.openmrs.hl7.HL7Service#getHL7InError(java.lang.Integer)
*/
public HL7InError getHL7InError(Integer hl7InErrorId) {
return dao.getHL7InError(hl7InErrorId);
}
/**
* @see org.openmrs.hl7.HL7Service#getHL7InErrors()
* @deprecated
*/
public Collection<HL7InError> getHL7InErrors() {
return dao.getAllHL7InErrors();
}
/**
* @deprecated
* @see org.openmrs.hl7.HL7Service#updateHL7InError(org.openmrs.hl7.HL7InError)
*/
public void updateHL7InError(HL7InError hl7InError) {
Context.getHL7Service().saveHL7InError(hl7InError);
}
/**
* @see org.openmrs.hl7.HL7Service#deleteHL7InError(org.openmrs.hl7.HL7InError)
* @deprecated
*/
public void deleteHL7InError(HL7InError hl7InError) {
Context.getHL7Service().purgeHL7InError(hl7InError);
}
/**
* @param xcn HL7 component of data type XCN (extended composite ID number and name for persons)
* (see HL7 2.5 manual Ch.2A.86)
* @return Internal ID # of the specified user, or null if that user can't be found or is
* ambiguous
*/
public Integer resolveUserId(XCN xcn) throws HL7Exception {
// TODO: properly handle family and given names. For now I'm treating
// givenName+familyName as a username.
String idNumber = xcn.getIDNumber().getValue();
String familyName = xcn.getFamilyName().getSurname().getValue();
String givenName = xcn.getGivenName().getValue();
// unused
// String assigningAuthority = xcn.getAssigningAuthority()
// .getUniversalID().getValue();
/*
* if ("null".equals(familyName)) familyName = null; if
* ("null".equals(givenName)) givenName = null; if
* ("null".equals(assigningAuthority)) assigningAuthority = null;
*/
if (idNumber != null && idNumber.length() > 0) {
// log.debug("searching for user by id " + idNumber);
try {
Integer userId = new Integer(idNumber);
User user = Context.getUserService().getUser(userId);
return user.getUserId();
}
catch (Exception e) {
log.error("Invalid user ID '" + idNumber + "'", e);
return null;
}
} else {
// log.debug("searching for user by name");
try {
StringBuilder username = new StringBuilder();
if (familyName != null) {
username.append(familyName);
}
if (givenName != null) {
if (username.length() > 0)
username.append(" "); // separate names with a space
username.append(givenName);
}
// log.debug("looking for username '" + username + "'");
User user = Context.getUserService().getUserByUsername(username.toString());
return user.getUserId();
}
catch (Exception e) {
log.error("Error resolving user with id '" + idNumber + "' family name '" + familyName
+ "' and given name '" + givenName + "'", e);
return null;
}
}
}
/**
* @see org.openmrs.hl7.HL7Service#resolvePersonId(ca.uhn.hl7v2.model.v25.datatype.XCN)
*/
public Integer resolvePersonId(XCN xcn) throws HL7Exception {
String idNumber = xcn.getIDNumber().getValue();
String familyName = xcn.getFamilyName().getSurname().getValue();
String givenName = xcn.getGivenName().getValue();
if (idNumber != null && idNumber.length() > 0) {
try {
Person person = Context.getPersonService().getPerson(new Integer(idNumber));
return person.getPersonId();
}
catch (Exception e) {
log.error("Invalid person ID '" + idNumber + "'", e);
return null;
}
} else {
List<Person> persons = Context.getPersonService().getPeople(givenName + " " + familyName, null);
if (persons.size() == 1) {
return persons.get(0).getPersonId();
} else if (persons.size() == 0) {
log.error("Couldn't find a person named " + givenName + " " + familyName);
return null;
} else {
log.error("Found more than one person named " + givenName + " " + familyName);
return null;
}
}
}
/**
* @param pl HL7 component of data type PL (person location) (see Ch 2.A.53)
* @return internal identifier of the specified location, or null if it is not found or
* ambiguous
*/
public Integer resolveLocationId(PL pl) throws HL7Exception {
// TODO: Get rid of hack that allows first component to be an integer
// location.location_id
String pointOfCare = pl.getPointOfCare().getValue();
String facility = pl.getFacility().getUniversalID().getValue();
// HACK: try to treat the first component (which should be "Point of
// Care" as an internal openmrs location_id
try {
Integer locationId = new Integer(pointOfCare);
Location l = Context.getLocationService().getLocation(locationId);
return l == null ? null : l.getLocationId();
}
catch (Exception ex) {
if (facility == null) { // we have no tricks left up our sleeve, so
// throw an exception
throw new HL7Exception("Error trying to treat PL.pointOfCare '" + pointOfCare
+ "' as a location.location_id", ex);
}
}
// Treat the 4th component "Facility" as location.name
try {
Location l = Context.getLocationService().getLocation(facility);
if (l == null) {
log.debug("Couldn't find a location named '" + facility + "'");
}
return l == null ? null : l.getLocationId();
}
catch (Exception ex) {
log.error("Error trying to treat PL.facility '" + facility + "' as a location.name", ex);
return null;
}
}
/**
* @param pid A PID segment of an hl7 message
* @return The internal id number of the Patient described by the PID segment, or null of the
* patient is not found, or if the PID segment is ambiguous
* @throws HL7Exception
*/
public Integer resolvePatientId(PID pid) throws HL7Exception {
// TODO: Properly handle assigning authority. If specified it's
// currently treated as PatientIdentifierType.name
// TODO: Throw exceptions instead of returning null in some cases
// TODO: Don't hydrate Patient objects unnecessarily
// TODO: Determine how to handle assigning authority and openmrs
// patient_id numbers
Integer patientId = null;
CX[] patientIdentifierList = pid.getPatientIdentifierList();
if (patientIdentifierList.length < 1)
throw new HL7Exception("Missing patient identifier in PID segment");
// TODO other potential identifying characteristics in PID we could use
// to identify the patient
// XPN[] patientName = pid.getPersonName();
// String gender = pid.getAdministrativeSex().getValue();
// TS dateOfBirth = pid.getDateTimeOfBirth();
// Take the first uniquely matching identifier
for (CX identifier : patientIdentifierList) {
String hl7PatientId = identifier.getIDNumber().getValue();
// TODO if 1st component is blank, check 2nd and 3rd of assigning
// authority
String assigningAuthority = identifier.getAssigningAuthority().getNamespaceID().getValue();
if (assigningAuthority != null && assigningAuthority.length() > 0) {
// Assigning authority defined
try {
PatientIdentifierType pit = Context.getPatientService().getPatientIdentifierTypeByName(
assigningAuthority);
if (pit == null) {
log.warn("Can't find PatientIdentifierType named '" + assigningAuthority + "'");
continue; // skip identifiers with unknown type
}
List<PatientIdentifier> matchingIds = Context.getPatientService().getPatientIdentifiers(hl7PatientId,
Collections.singletonList(pit), null, null, null);
if (matchingIds == null || matchingIds.size() < 1) {
// no matches
log.warn("NO matches found for " + hl7PatientId);
continue; // try next identifier
} else if (matchingIds.size() == 1) {
// unique match -- we're done
return matchingIds.get(0).getPatient().getPatientId();
} else {
// ambiguous identifier
log.debug("Ambiguous identifier in PID. " + matchingIds.size() + " matches for identifier '"
+ hl7PatientId + "' of type '" + pit + "'");
continue; // try next identifier
}
}
catch (Exception e) {
log.error("Error resolving patient identifier '" + hl7PatientId + "' for assigning authority '"
+ assigningAuthority + "'", e);
continue;
}
} else {
try {
log.debug("PID contains patient ID '" + hl7PatientId
+ "' without assigning authority -- assuming patient.patient_id");
patientId = Integer.parseInt(hl7PatientId);
return patientId;
}
catch (NumberFormatException e) {
// throw new HL7Exception("Invalid patient ID '" +
// hl7PatientId + "'");
log.warn("Invalid patient ID '" + hl7PatientId + "'");
}
}
}
return null;
}
/**
* @see org.openmrs.hl7.HL7Service#garbageCollect()
*/
public void garbageCollect() {
dao.garbageCollect();
}
/**
* @see org.openmrs.hl7.HL7Service#encounterCreated(org.openmrs.Encounter)
* @deprecated This method is no longer needed. When an encounter is created in the ROUR01
* handler, it is created with all obs. Any AOP hooking should be done on the
* EncounterService.createEncounter(Encounter) method
*/
public void encounterCreated(Encounter encounter) {
// nothing is done here in core. Modules override/hook on this method
}
/**
* @see org.openmrs.hl7.HL7Service#processHL7InQueue(org.openmrs.hl7.HL7InQueue)
*/
public HL7InQueue processHL7InQueue(HL7InQueue hl7InQueue) throws HL7Exception {
if (hl7InQueue == null)
throw new HL7Exception("hl7InQueue argument cannot be null");
// mark this queue object as processing so that it isn't processed twice
if (OpenmrsUtil.nullSafeEquals(HL7Constants.HL7_STATUS_PROCESSING, hl7InQueue.getMessageState()))
throw new HL7Exception("The hl7InQueue message with id: " + hl7InQueue.getHL7InQueueId()
+ " is already processing. " + ",key=" + hl7InQueue.getHL7SourceKey() + ")");
else
hl7InQueue.setMessageState(HL7Constants.HL7_STATUS_PROCESSING);
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();
try {
// Parse the inbound HL7 message using the parser
// NOT making a direct call here so that AOP can happen around this method
Message parsedMessage = Context.getHL7Service().parseHL7String(hl7Message);
// Send the parsed message to our receiver routine for processing into db
// NOT making a direct call here so that AOP can happen around this method
Message result = Context.getHL7Service().processHL7Message(parsedMessage);
// Move HL7 inbound queue entry into the archive before exiting
log.debug("Archiving HL7 inbound queue entry");
Context.getHL7Service().saveHL7InArchive(new HL7InArchive(hl7InQueue));
log.debug("Removing HL7 message from inbound queue");
Context.getHL7Service().purgeHL7InQueue(hl7InQueue);
}
catch (HL7Exception e) {
boolean skipError = false;
log.error("Unable to process hl7inqueue: " + hl7InQueue.getHL7InQueueId(), e);
log.error("Hl7inqueue source: " + hl7InQueue.getHL7Source());
log.error("hl7_processor.ignore_missing_patient_non_local? "
+ Context.getAdministrationService().getGlobalProperty(
OpenmrsConstants.GLOBAL_PROPERTY_IGNORE_MISSING_NONLOCAL_PATIENTS, "false"));
if (e.getCause() != null
&& e.getCause().getMessage().equals("Could not resolve patient")
&& !hl7InQueue.getHL7Source().getName().equals("local")
&& Context.getAdministrationService().getGlobalProperty(
OpenmrsConstants.GLOBAL_PROPERTY_IGNORE_MISSING_NONLOCAL_PATIENTS, "false").equals("true")) {
skipError = true;
}
if (!skipError)
setFatalError(hl7InQueue, "Trouble parsing HL7 message (" + hl7InQueue.getHL7SourceKey() + ")", e);
}
catch (Throwable t) {
setFatalError(hl7InQueue, "Exception while attempting to process HL7 In Queue (" + hl7InQueue.getHL7SourceKey()
+ ")", t);
}
return hl7InQueue;
}
/**
* Convenience method to respond to fatal errors by moving the queue entry into an error bin
* prior to aborting
*/
private void setFatalError(HL7InQueue hl7InQueue, String error, Throwable cause) {
HL7InError hl7InError = new HL7InError(hl7InQueue);
hl7InError.setError(error);
if (cause == null)
hl7InError.setErrorDetails("");
else {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
cause.printStackTrace(pw);
pw.flush();
sw.flush();
hl7InError.setErrorDetails(sw.toString());
}
Context.getHL7Service().saveHL7InError(hl7InError);
Context.getHL7Service().purgeHL7InQueue(hl7InQueue);
log.error(error, cause);
}
/**
* @see org.openmrs.hl7.HL7Service#parseHL7Message(java.lang.String)
*/
public Message parseHL7String(String hl7Message) throws HL7Exception {
// Any pre-parsing for HL7 messages would go here
// or a module can use AOP to pre-parse the message
// First, try and parse the message
Message message;
try {
message = parser.parse(hl7Message);
}
catch (EncodingNotSupportedException e) {
throw new HL7Exception("HL7 encoding not supported", e);
}
catch (ca.uhn.hl7v2.HL7Exception e) {
throw new HL7Exception("Error parsing message", e);
}
return message;
}
/**
* @see org.openmrs.hl7.HL7Service#processHL7Message(ca.uhn.hl7v2.model.Message)
*/
public Message processHL7Message(Message message) throws HL7Exception {
// Any post-parsing (pre-routing) processing would go here
// or a module can use AOP to do the post-parsing
Message response;
try {
if (!router.canProcess(message))
throw new HL7Exception("No route for hl7 message: " + message.getName()
+ ". Make sure you have a module installed that registers a hl7handler for this type");
response = router.processMessage(message);
}
catch (ApplicationException e) {
throw new HL7Exception("Error while processing HL7 message: " + message.getName(), e);
}
return response;
}
/**
* Sets the given handlers as router applications that are available to HAPI when it is parsing
* an hl7 message.<br/>
* This method is usually used by Spring and the handlers are set in the
* applicationContext-server.xml method.<br/>
* The key in the map is a string like "ORU_R01" where the first part is the message type and
* the second is the trigger event.
*
* @param handlers a map from MessageName to Application object
*/
public void setHL7Handlers(Map<String, Application> handlers) {
// loop over all the given handlers and add them to the router
for (Map.Entry<String, Application> entry : handlers.entrySet()) {
String messageName = entry.getKey();
if (!messageName.contains("_"))
throw new APIException("Invalid messageName. The format must be messageType_triggerEvent, e.g: ORU_R01");
String messageType = messageName.split("_")[0];
String triggerEvent = messageName.split("_")[1];
router.registerApplication(messageType, triggerEvent, entry.getValue());
}
}
}