/**
* Copyright (c) 2009-2010 Misys Open Source Solutions (MOSS) and others
*
* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* Contributors:
* Misys Open Source Solutions - initial API and implementation
* -
*/
package org.openhealthtools.openxds.registry;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openhealthexchange.openpixpdq.data.MessageHeader;
import org.openhealthexchange.openpixpdq.data.Patient;
import org.openhealthexchange.openpixpdq.data.PatientIdentifier;
import org.openhealthexchange.openpixpdq.ihe.configuration.IheConfigurationException;
import org.openhealthexchange.openpixpdq.ihe.impl_v2.hl7.HL7Header;
import org.openhealthexchange.openpixpdq.ihe.impl_v2.hl7.HL7v231;
import org.openhealthexchange.openpixpdq.ihe.log.MessageStore;
import org.openhealthexchange.openpixpdq.util.ExceptionUtil;
import org.openhealthtools.common.utils.AssigningAuthorityUtil;
import org.openhealthtools.openxds.XdsFactory;
import org.openhealthtools.openxds.registry.api.RegistryLifeCycleContext;
import org.openhealthtools.openxds.registry.api.RegistryPatientContext;
import org.openhealthtools.openxds.registry.api.RegistryPatientException;
import org.openhealthtools.openxds.registry.api.XdsRegistryLifeCycleService;
import org.openhealthtools.openxds.registry.api.XdsRegistryPatientService;
import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.app.Application;
import ca.uhn.hl7v2.app.ApplicationException;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.model.v231.datatype.CX;
import ca.uhn.hl7v2.model.v231.group.ADT_A39_PIDPD1MRGPV1;
import ca.uhn.hl7v2.model.v231.message.ACK;
import ca.uhn.hl7v2.model.v231.message.ADT_A01;
import ca.uhn.hl7v2.model.v231.message.ADT_A04;
import ca.uhn.hl7v2.model.v231.message.ADT_A05;
import ca.uhn.hl7v2.model.v231.message.ADT_A08;
import ca.uhn.hl7v2.model.v231.message.ADT_A39;
import ca.uhn.hl7v2.model.v231.segment.MRG;
import ca.uhn.hl7v2.model.v231.segment.PID;
import com.misyshealthcare.connect.net.Identifier;
/**
* This class processes PIX Feed message in HL7 v2.3.1 format. It
* handles the PIX Feed transaction (including also PIX Update
* and PIX Merge transactions) of the PIX profile.
* The supported message type includes ADT^A01, ADT^A04, ADT^A05,
* ADT^A08 and ADT^A40.
*
* @author <a href="mailto:wenzhi.li@misys.com">Wenzhi Li</a>
*
*/
class PixFeedHandler extends BaseHandler implements Application {
private static Log log = LogFactory.getLog(PixFeedHandler.class);
private XdsRegistryImpl actor = null;
/** The XDS Registry Patient Manager*/
private XdsRegistryPatientService patientManager = null;
/**
* Constructor
*
* @param actor the {@link XdsRegistryImpl} actor
*/
PixFeedHandler(XdsRegistryImpl actor) {
super(actor.getPixRegistryConnection());
this.actor = actor;
this.patientManager = actor.getPatientManager();
assert this.connection != null;
assert this.patientManager != null;
}
/**
* Whether an incoming message can be processed by this handler.
*
* @return <code>true</code> if the incoming message can be processed;
* otherwise <code>false</code>.
*/
public boolean canProcess(Message theIn) {
if (theIn instanceof ADT_A01 || theIn instanceof ADT_A04 ||
theIn instanceof ADT_A05 || theIn instanceof ADT_A08 ||
theIn instanceof ADT_A39 )
return true;
else
return false;
}
/**
* Processes the incoming PIX Feed Message. Valid messages
* are ADT^A01, ADT^A04, ADT^A05, ADT^A08 and ADT^A40.
*
* @param msgIn the incoming message
*/
public Message processMessage(Message msgIn) throws ApplicationException,
HL7Exception {
Message retMessage = null;
MessageStore store = actor.initMessageStore(msgIn, true);
//String encodedMessage = HapiUtil.encodeMessage(msgIn);
//log.info("Received message:\n" + encodedMessage + "\n\n");
try {
HL7Header hl7Header = new HL7Header(msgIn);
//Populate MessageStore to persist the message
hl7Header.populateMessageStore(store);
if (msgIn instanceof ADT_A01 || //Admission of in-patient into a facility
msgIn instanceof ADT_A04 || //Registration of an outpatient for a visit of the facility
msgIn instanceof ADT_A05) { //Pre-admission of an in-patient
retMessage = processCreate(msgIn);
} else if (msgIn instanceof ADT_A08) { //Update patient information
retMessage = processUpdate(msgIn);
} else if (msgIn instanceof ADT_A39) { //Merge Patients
retMessage = processMerge(msgIn);
} else {
String errorMsg = "Unexpected request to PIX Manager server. "
+ "Valid message types are ADT^A01, ADT^A04, ADT^A05, ADT^A08 and ADT^A40";
throw new ApplicationException(errorMsg);
}
} catch (ApplicationException e) {
if (store !=null) {
store.setErrorMessage( e.getMessage() );
}
throw new ApplicationException(ExceptionUtil.strip(e.getMessage()), e);
} catch (HL7Exception e) {
if (store !=null) {
store.setErrorMessage( e.getMessage() );
}
throw new HL7Exception(ExceptionUtil.strip(e.getMessage()), e);
} finally {
//Persist the message
if (store !=null) {
actor.saveMessageStore(retMessage, false, store);
}
}
return retMessage;
}
/**
* Processes PIX Feed Create Patient message in HL72.3.1.
*
* @param msgIn the PIX Feed request message
* @return a response message for PIX Feed
* @throws ApplicationException If Application has trouble
* @throws HL7Exception if something is wrong with HL7 message
*/
private Message processCreate(Message msgIn)
throws ApplicationException, HL7Exception {
assert msgIn instanceof ADT_A01 ||
msgIn instanceof ADT_A04 ||
msgIn instanceof ADT_A05;
HL7Header hl7Header = new HL7Header(msgIn);
//If it is for A08, we redirect it to processUpdate.
if(hl7Header.getTriggerEvent().equals("A08")) {
return processUpdate(msgIn);
}
//Create Acknowledgment and its Header
ACK reply = initAcknowledgment(hl7Header);
//Validate incoming message first
PID pid = (PID)msgIn.get("PID");
PatientIdentifier patientId = getPatientIdentifiers(pid);
boolean isValidMessage = validateMessage(reply, hl7Header, patientId, null, true);
if (!isValidMessage) return reply;
//Invoke eMPI function
MessageHeader header = hl7Header.toMessageHeader();
RegistryPatientContext context = new RegistryPatientContext(header);
Patient patient = getPatient(msgIn);
try {
patientManager.createPatient(patient, context);
}catch (RegistryPatientException e) {
throw new ApplicationException(e);
}
HL7v231.populateMSA(reply.getMSA(), "AA", hl7Header.getMessageControlId());
//TODO: revisit Audit
//Finally, Audit Log PIX Feed Success
//auditLog(hl7Header, patient, AuditCodeMappings.EventActionCode.Create);
return reply;
}
/**
* Processes PIX Feed Update Patient message.
*
* @param msgIn the PIX Feed request message
* @return a response message for PIX Feed
* @throws ApplicationException If Application has trouble
* @throws HL7Exception if something is wrong with HL7 message
*/
private Message processUpdate(Message msgIn) throws ApplicationException,
HL7Exception {
assert msgIn instanceof ADT_A01 ||
msgIn instanceof ADT_A08 ;
HL7Header hl7Header = new HL7Header(msgIn);
//Create Acknowledgment and its Header
ACK reply = initAcknowledgment(hl7Header);
//Validate incoming message first
PID pid = (PID)msgIn.get("PID");
PatientIdentifier patientId = getPatientIdentifiers(pid);
boolean isValidMessage = validateMessage(reply, hl7Header, patientId, null, false);
if (!isValidMessage) return reply;
//Invoke eMPI function
MessageHeader header = hl7Header.toMessageHeader();
RegistryPatientContext context = new RegistryPatientContext(header);
Patient patient = getPatient(msgIn);
try {
//Update Patient
patientManager.updatePatient(patient, context);
} catch (RegistryPatientException e) {
throw new ApplicationException(e);
}
HL7v231.populateMSA(reply.getMSA(), "AA", hl7Header.getMessageControlId());
//TODO: revisit Audit
//Finally, Audit Log PIX Feed Success
//auditLog(hl7Header, patient, AuditCodeMappings.EventActionCode.Update);
return reply;
}
/**
* Processes PIX Feed Merge Patient message.
*
* @param msgIn the PIX Feed request message
* @return a response message for PIX Feed
* @throws ApplicationException If Application has trouble
* @throws HL7Exception if something is wrong with HL7 message
*/
private Message processMerge(Message msgIn)
throws ApplicationException, HL7Exception {
assert msgIn instanceof ADT_A39;
HL7Header hl7Header = new HL7Header(msgIn);
//Create Acknowledgment and its Header
ACK reply = initAcknowledgment(hl7Header);
//Validate incoming message first
ADT_A39_PIDPD1MRGPV1 requestId = ((ADT_A39)msgIn).getPIDPD1MRGPV1();
PatientIdentifier patientId = getPatientIdentifiers(requestId.getPID());
PatientIdentifier mrgPatientId = getMrgPatientIdentifiers(requestId.getMRG());
boolean isValidMessage = validateMessage(reply, hl7Header, patientId, mrgPatientId, false);
if (!isValidMessage) return reply;
//Invoke eMPI function
MessageHeader header = hl7Header.toMessageHeader();
RegistryPatientContext context = new RegistryPatientContext(header);
Patient patient = getPatient(msgIn);
Patient mrgPatient = getMrgPatient(msgIn);
try {
//Merge Patients
patientManager.mergePatients(patient, mrgPatient, context);
}catch (RegistryPatientException e) {
throw new ApplicationException(e);
}
String survivingPatient = getPatientIdentifier(patient.getPatientIds());
String mergePatient = getPatientIdentifier(mrgPatient.getPatientIds());
XdsRegistryLifeCycleService lifeCycleManager = XdsFactory.getXdsRegistryLifeCycleService();
try {
lifeCycleManager.mergePatients(survivingPatient, mergePatient, new RegistryLifeCycleContext());
} catch (Exception e) {
try{
patientManager.unmergePatients(patient, mrgPatient, context);
}catch (Exception e1) {
throw new ApplicationException(e1);
}
log.error("error while merging patient document in xds regsitry");
throw new ApplicationException(e);
}
HL7v231.populateMSA(reply.getMSA(), "AA", hl7Header.getMessageControlId());
//TODO: revisit Audit
//Finally, Audit Log PIX Feed Success
//auditLog(hl7Header, patient, AuditCodeMappings.EventActionCode.Update);
//auditLog(hl7Header, mrgPatient, AuditCodeMappings.EventActionCode.Delete);
return reply;
}
private String getPatientIdentifier(List<PatientIdentifier> patient){
for (PatientIdentifier patientIdentifier: patient) {
String assignAuth = getAssigningAuthority(patientIdentifier);
String assignFac = getAssigningFacility(patientIdentifier);
String patientId = patientIdentifier.getId();
String typeCode = patientIdentifier.getIdentifierTypeCode();
if(assignFac == null && typeCode ==null)
return patientId + "^^^" + assignAuth ;
else if(assignFac !=null && typeCode == null){
return patientId + "^^^" + assignAuth + "^^" + assignFac;
}else if(assignFac == null && typeCode != null){
return patientId + "^^^" + assignAuth + "^"+ typeCode;
}else if(assignFac != null && typeCode != null){
return patientId + "^^^" + assignAuth + "^" + typeCode + "^" + assignFac;
}
}
return null;
}
private String getAssigningFacility(PatientIdentifier patientIdentifier){
String assignFacNam = patientIdentifier.getAssigningFacility().getNamespaceId();
String assignFacUniversal = patientIdentifier.getAssigningFacility().getUniversalId();
String assignFacUniversaltype = patientIdentifier.getAssigningFacility().getUniversalIdType();
if(assignFacNam != null && assignFacUniversal != null && assignFacUniversaltype !=null)
return assignFacNam +"&"+ assignFacUniversal + "&"+ assignFacUniversaltype;
else if(assignFacNam == null && assignFacUniversal != null && assignFacUniversaltype !=null){
return "&"+ assignFacUniversal + "&"+ assignFacUniversaltype;
}else if(assignFacNam != null && assignFacUniversaltype == null){
return assignFacNam + "&"+ assignFacUniversal + "&";
}
return null;
}
private String getAssigningAuthority(PatientIdentifier patientIdentifier){
String assignFacNam = patientIdentifier.getAssigningAuthority().getNamespaceId();
String assignFacUniversal = patientIdentifier.getAssigningAuthority().getUniversalId();
String assignFacUniversaltype = patientIdentifier.getAssigningAuthority().getUniversalIdType();
if(assignFacNam != null && assignFacUniversal != null && assignFacUniversaltype !=null)
return assignFacNam +"&"+ assignFacUniversal + "&"+ assignFacUniversaltype;
else if(assignFacNam == null && assignFacUniversal != null && assignFacUniversaltype !=null){
return "&"+ assignFacUniversal + "&"+ assignFacUniversaltype;
}else if(assignFacNam != null && assignFacUniversaltype == null){
return assignFacNam + "&"+ assignFacUniversal + "&";
}
return null;
}
//TODO: revisit Audit log
// /**
// * Audit Logging of PIX Feed message.
// *
// * @param hl7Header the header message from the source application
// * @param patient the patient to create, update or merged
// * @param eventActionCode the {@link EventActionCode}
// */
// private void auditLog(HL7Header hl7Header, Patient patient, AuditCodeMappings.EventActionCode eventActionCode) {
// if (actor.getAuditTrail() == null)
// return;
//
// String userId = hl7Header.getSendingFacility().getNamespaceId() + "|" +
// hl7Header.getSendingApplication().getNamespaceId();
// String messageId = hl7Header.getMessageControlId();
// //TODO: Get the ip address of the source application
// String sourceIp = "127.0.0.1";
//
// ActiveParticipant source = new ActiveParticipant(userId, messageId, sourceIp);
//
// ParticipantObject patientObj = new ParticipantObject(patient);
// patientObj.setDetail(hl7Header.getMessageControlId());
//
// actor.getAuditTrail().logPixFeed(source, patientObj, eventActionCode);
// }
/**
* Initiates an acknowledgment instance for the incoming message.
*
* @param hl7Header the message header of the incoming message
* @return an {@link ACK} instance
* @throws HL7Exception if something is wrong with HL7 message
* @throws ApplicationException If Application has trouble
*/
private ACK initAcknowledgment(HL7Header hl7Header) throws HL7Exception, ApplicationException {
//Send Response
ACK reply = new ACK();
//For the response message, the ReceivingApplication and ReceivingFacility
//will become the sendingApplication and sendingFacility;
//Also the sendingApplication and sendingFacility will become the
//receivingApplication and receivingFacility.
Identifier serverApplication = getServerApplication();
Identifier serverFacility = getServerFacility();
Identifier sendingApplication = hl7Header.getSendingApplication();
Identifier sendingFacility = hl7Header.getSendingFacility();
try {
String event = hl7Header.getTriggerEvent();
HL7v231.populateMSH(reply.getMSH(), "ACK", event, getMessageControlId(),
serverApplication, serverFacility, sendingApplication, sendingFacility);
} catch (IheConfigurationException e) {
throw new ApplicationException("Error populate message header", e);
}
return reply;
}
/**
* Validates a patient identifier domain, namely, assigning authority.
*
* @param reply the reply message to be populated if the validation fails
* @param patientId the patient id
* @param incomingMessageId the incoming message id
* @return <code>true</code> if the patient domain is validated successfully;
* otherwise <code>false</code>.
* @throws HL7Exception if something is wrong with HL7 message
*/
private boolean validateDomain(ACK reply, PatientIdentifier patientId, String incomingMessageId)
throws HL7Exception {
Identifier domain = patientId.getAssigningAuthority();
boolean domainOk = AssigningAuthorityUtil.validateDomain(
domain, connection);
if (!domainOk) {
HL7v231.populateMSA(reply.getMSA(), "AE", incomingMessageId);
//segmentId=PID, sequence=1, fieldPosition=3, fieldRepetition=1,componentNubmer=4
HL7v231.populateERR(reply.getERR(), "PID", "1", "3", "1", "4",
"204", "Unknown Key Identifier");
return false;
}
return true;
}
/**
* Validates the receiving facility and receiving application of an incoming message.
*
* @param reply the reply message to be populated if any validation is failed
* @param receivingApplication the receiving application of the incoming message
* @param receivingFacility the receiving facility of the incoming message
* @param expectedApplication the expected receiving application
* @param expectedFacility the expected receiving facility
* @param incomingMessageId the incoming message
* @return <code>true</code> if validation is passed;
* otherwise <code>false</code>.
* @throws HL7Exception if something is wrong with HL7 message
* @throws ApplicationException if something is wrong with the application
*/
private boolean validateReceivingFacilityApplication(ACK reply, Identifier receivingApplication,
Identifier receivingFacility, Identifier expectedApplication, Identifier expectedFacility,
String incomingMessageId)
throws HL7Exception, ApplicationException
{
//In case of tests, don't validate receiving application and facility,
//It is not easy to switch to different receiving applications and facilities
boolean isTest = Boolean.parseBoolean(connection.getProperty("test"));
if (isTest) return true;
//We first need to validate ReceivingApplication and ReceivingFacility.
//Currently we are not validating SendingApplication and SendingFacility
if (!receivingApplication.equals(expectedApplication)) {
HL7v231.populateMSA(reply.getMSA(), "AE", incomingMessageId);
//segmentId=MSH, sequence=1, fieldPosition=5, fieldRepetition=1, componentNubmer=1
HL7v231.populateERR(reply.getERR(), "MSH", "1", "5", "1", "1",
null, "Unknown Receiving Application");
return false;
}
if (!receivingFacility.equals(expectedFacility)) {
HL7v231.populateMSA(reply.getMSA(), "AE", incomingMessageId);
//segmentId=MSH, sequence=1, fieldPosition=6, fieldRepetition=1, componentNubmer=1
HL7v231.populateERR(reply.getERR(), "MSH", "1", "6", "1", "1",
null, "Unknown Receiving Facility");
return false;
}
return true;
}
/**
* Validates the incoming Message in this order:
*
* <ul>
* <li> Validate Receiving Facility and Receiving Application</li>
* <li> Validate Domain </li>
* <li> Validate patient Id <li>
* <li> Validate merge patient Id if applicable<li>
* </ul>
*
* @param reply the reply message to be populated if any validation is failed
* @param hl7Header the message header of the incoming message
* @param patientId the id of the patient to be validated
* @param mrgPatientId the id of the patient to be merged
* @param isPixCreate Whether this validation is for PIX patient creation
* @return <code>true</code> if the message is correct; <code>false</code>otherwise.
* @throws HL7Exception if something is wrong with HL7 message
* @throws ApplicationException if something is wrong with the application
*/
private boolean validateMessage(ACK reply, HL7Header hl7Header, PatientIdentifier patientId, PatientIdentifier mrgPatientId, boolean isPixCreate)
throws HL7Exception, ApplicationException {
Identifier serverApplication = getServerApplication();
Identifier serverFacility = getServerFacility();
Identifier receivingApplication = hl7Header.getReceivingApplication();
Identifier receivingFacility = hl7Header.getReceivingFacility();
String incomingMessageId = hl7Header.getMessageControlId();
//1. validate receiving facility and receiving application
boolean isValidFacilityApplication = validateReceivingFacilityApplication(reply,
receivingApplication, receivingFacility,
serverApplication, serverFacility, incomingMessageId);
if (!isValidFacilityApplication) return false;
//2.validate the domain
boolean isValidDomain = validateDomain(reply, patientId, incomingMessageId);
if (!isValidDomain) return false;
//3. validate ID itself
if (!isPixCreate) {
//Do not valid patient id for PIX patient creation
boolean isValidPid = validatePatientId(reply, patientId, hl7Header.toMessageHeader(), false, incomingMessageId);
if (!isValidPid) return false;
}
//4. validate mrgPatientId
if (mrgPatientId != null) {
boolean isValidMrgPid = validatePatientId(reply, mrgPatientId, hl7Header.toMessageHeader(), true, incomingMessageId);
if (!isValidMrgPid) return false;
}
//Finally, it must be true when it reaches here
return true;
}
/**
* Checks the given whether the given patient id is a valid patient id.
*
* @param reply the reply message to be populated if any validation is failed
* @param patientId the patient id to be checked
* @param header the incoming message header
* @param isMrgPatientId whether the patient id to be checked is a merge patient id.
* @param incomingMessageId the incoming message id.
* @return <code>true</code> if the patientId is valid; otherwise <code>false</code>.
* @throws HL7Exception if something is wrong with HL7 message
* @throws ApplicationException if something is wrong with the application
*/
private boolean validatePatientId(ACK reply, PatientIdentifier patientId,
MessageHeader header, boolean isMrgPatientId, String incomingMessageId)
throws HL7Exception, ApplicationException{
boolean validPatient;
RegistryPatientContext context = new RegistryPatientContext(header);
try {
validPatient = patientManager.isValidPatient(patientId, context);
} catch (RegistryPatientException e) {
throw new ApplicationException(e);
}
if (!validPatient) {
HL7v231.populateMSA(reply.getMSA(), "AE", incomingMessageId);
if (isMrgPatientId){
//segmentId=MRG, sequence=1, fieldPosition=1, fieldRepetition=1, componentNubmer=1
HL7v231.populateERR(reply.getERR(), "MRG", "1", "1", "1", "1",
"204", "Unknown Key Identifier");
} else {
//segmentId=PID, sequence=1, fieldPosition=3, fieldRepetition=1, componentNubmer=1
HL7v231.populateERR(reply.getERR(), "PID", "1", "3", "1", "1",
"204", "Unknown Key Identifier");
}
}
return validPatient;
}
/**
* Converts a PIX Feed Patient message to a {@link Patient} object.
*
* @param msgIn the incoming PIX Feed message
* @return a {@link Patient} object
* @throws ApplicationException if something is wrong with the application
*/
private Patient getPatient(Message msgIn) throws ApplicationException,HL7Exception {
HL7v231ToBaseConvertor convertor = null;
if (msgIn.getVersion().equals("2.3.1")) {
convertor = new HL7v231ToBaseConvertor(msgIn, connection);
} else {
throw new ApplicationException("Unexpected HL7 version");
}
Patient patientDesc = new Patient();
patientDesc.setPatientIds(convertor.getPatientIds());
patientDesc.setPatientName(convertor.getPatientName());
patientDesc.setMonthersMaidenName(convertor.getMotherMaidenName());
patientDesc.setBirthDateTime(convertor.getBirthDate());
patientDesc.setAdministrativeSex(convertor.getSexType());
patientDesc.setPatientAlias(convertor.getPatientAliasName());
patientDesc.setRace(convertor.getRace());
patientDesc.setPrimaryLanguage(convertor.getPrimaryLanguage());
patientDesc.setMaritalStatus(convertor.getMartialStatus());
patientDesc.setReligion(convertor.getReligion());
patientDesc.setPatientAccountNumber(convertor.getpatientAccountNumber());
patientDesc.setSsn(convertor.getSsn());
patientDesc.setDriversLicense(convertor.getDriversLicense());
patientDesc.setMonthersId(convertor.getMonthersId());
patientDesc.setEthnicGroup(convertor.getEthnicGroup());
patientDesc.setBirthPlace(convertor.getBirthPlace());
patientDesc.setBirthOrder(convertor.getBirthOrder());
patientDesc.setCitizenship(convertor.getCitizenShip());
patientDesc.setDeathDate(convertor.getDeathDate());
//TODO: patientDesc.setDeathIndicator(convertor.getDeathIndicator());
patientDesc.setPhoneNumbers(convertor.getPhoneList());
patientDesc.setAddresses(convertor.getAddressList());
patientDesc.setVisits(convertor.getVisitList());
return patientDesc;
}
/**
* Extracts the merge patient out of a PIX Merge Patient message.
*
* @param msgIn the incoming PIX Merge message
* @return a {@link Patient} object that represents the merge patient
* @throws ApplicationException if something is wrong with the application
*/
private Patient getMrgPatient(Message msgIn) throws ApplicationException, HL7Exception {
HL7v231ToBaseConvertor convertor = null;
convertor = new HL7v231ToBaseConvertor(msgIn, connection);
Patient patientDesc = new Patient();
patientDesc.setPatientIds(convertor.getMrgPatientIds());
patientDesc.setPatientName(convertor.getMrgPatientName());
patientDesc.setPatientAccountNumber(convertor
.getMrgpatientAccountNumber());
patientDesc.setVisits(convertor.getMrgVisitList());
return patientDesc;
}
/**
* Gets the patient identifier from a Patient PID segment.
*
* @param pid the PID segment
* @return a {@link PatientIdentifier}
*/
private PatientIdentifier getPatientIdentifiers(PID pid) {
PatientIdentifier identifier = new PatientIdentifier();
CX[] cxs = pid.getPatientIdentifierList();
for (CX cx : cxs) {
Identifier assignAuth = new Identifier(cx.getAssigningAuthority()
.getNamespaceID().getValue(), cx.getAssigningAuthority()
.getUniversalID().getValue(), cx.getAssigningAuthority()
.getUniversalIDType().getValue());
Identifier assignFac = new Identifier(cx.getAssigningFacility()
.getNamespaceID().getValue(), cx.getAssigningFacility()
.getUniversalID().getValue(), cx.getAssigningFacility()
.getUniversalIDType().getValue());
identifier.setAssigningAuthority(AssigningAuthorityUtil.reconcileIdentifier(assignAuth, connection));
identifier.setAssigningFacility(assignFac);
identifier.setId(cx.getID().getValue());
identifier.setIdentifierTypeCode(cx.getIdentifierTypeCode()
.getValue());
}
return identifier;
}
/**
* Gets the merge patient identifier out of a MRG segment.
*
* @param MRG segment the merge segment
* @return a {@link PatientIdentifier}
*/
private PatientIdentifier getMrgPatientIdentifiers(MRG mrg) {
PatientIdentifier identifier = new PatientIdentifier();
CX[] cxs = mrg.getPriorPatientIdentifierList();
for (CX cx : cxs) {
Identifier assignAuth = new Identifier(cx.getAssigningAuthority()
.getNamespaceID().getValue(), cx.getAssigningAuthority()
.getUniversalID().getValue(), cx.getAssigningAuthority()
.getUniversalIDType().getValue());
Identifier assignFac = new Identifier(cx.getAssigningFacility()
.getNamespaceID().getValue(), cx.getAssigningFacility()
.getUniversalID().getValue(), cx.getAssigningFacility()
.getUniversalIDType().getValue());
identifier.setAssigningAuthority(AssigningAuthorityUtil.reconcileIdentifier(assignAuth, connection));
identifier.setAssigningFacility(assignFac);
identifier.setId(cx.getID().getValue());
identifier.setIdentifierTypeCode(cx.getIdentifierTypeCode()
.getValue());
}
return identifier;
}
}