/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
package org.openehealth.coala.communication;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.openehealth.coala.util.PXSDateConverter;
import org.slf4j.Logger;
/**
* Class to build HL7 (v2.5) PDQ (Patient Demographic Queries) requests.
*
* @author ckarmen, hhein
*
*/
public class PdqMessageBuilderImpl implements PdqMessageBuilder {
private static final Logger LOG = org.slf4j.LoggerFactory
.getLogger(PdqMessageBuilderImpl.class);
// TODO Auslagern in globale Konfiguration (Interface, Spring, etc.)
private static final String HL7_PatientIdAssigningAuthorityUniversalId = "2.16.840.1.113883.3.37.4.1.1.2.2.1";
private static final String HL7_PatientIdAssigningAuthorityUniversalIdType = "ISO";
private static final String HL7_SendingFacility = "SendingFacility";
private static final String HL7_ReceivingFacility = "ReceivingFacility";
private static final String HL7_SendingApplication = "CoALA";
private static final String HL7_ReceivingApplication = "PXS";
// HL7 static segments
private static final String PID_PatientID = "@PID.3.1^";
private static final String PID_LastName = "@PID.5.1^";
private static final String PID_GivenName = "@PID.5.2^";
private static final String PID_DoB = "@PID.7^";
private static final String PID_PatientIdAssigningAuthorityUniversalId = "@PID.3.4.2^";
private static final String PID_PatientIdAssigningAuthorityUniversalIdType = "@PID.3.4.3^";
private static final String HL7_SEPERATOR = "|";
private PXSDateConverter pxsDateConverter;
/* (non-Javadoc)
* @see org.openehealth.coala.communication.PdqMessageBuilder#setPxsDateConverter(org.openehealth.coala.util.PXSDateConverter)
*/
@Override
public void setPxsDateConverter(PXSDateConverter pxsDateConverter) {
this.pxsDateConverter = pxsDateConverter;
}
/* (non-Javadoc)
* @see org.openehealth.coala.communication.PdqMessageBuilder#buildPdqRequest(java.lang.String, java.lang.String, java.lang.String, java.util.Date)
*/
@Override
public String buildPdqRequest(String thePatientId,
String theGivenName, String theLastName, Date theDoB) {
return buildPdqRequest(thePatientId,
HL7_PatientIdAssigningAuthorityUniversalId, theGivenName,
theLastName, theDoB);
}
/* (non-Javadoc)
* @see org.openehealth.coala.communication.PdqMessageBuilder#buildPdqRequest(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.util.Date)
*/
@Override
public String buildPdqRequest(String thePatientId,
String thePatientIdAssigningAuthorityUniversalId,
String theGivenName, String theLastName, Date theDoB) {
String thePatientIdStr = "", theGivenNameStr = "", theLastNameStr = "", theDoBStr = "", isAnd = "";
if (!isNullorEmpty(thePatientId)
&& !isNullorEmpty(thePatientIdAssigningAuthorityUniversalId)) {
thePatientIdStr = PID_PatientID + thePatientId + "~"
+ PID_PatientIdAssigningAuthorityUniversalId
+ thePatientIdAssigningAuthorityUniversalId + "~"
+ PID_PatientIdAssigningAuthorityUniversalIdType
+ HL7_PatientIdAssigningAuthorityUniversalIdType;
isAnd = "~";
}
Charset charset = Charset.forName("ISO-8859-1");
if (!isNullorEmpty(theGivenName)) {
/*
* Charset conversion from UTF-8 to ISO encoding as MPI HL7 queries
* will fail for umlauts otherwise!
*/
String givenNameISO = new String(theGivenName.getBytes(), charset);
theGivenName = givenNameISO;
theGivenNameStr = isAnd + PID_GivenName + theGivenName;
isAnd = "~";
}
if (!isNullorEmpty(theLastName)) {
/*
* Charset conversion from UTF-8 to ISO encoding as MPI HL7 queries
* will fail for umlauts otherwise!
*/
String lastNameISO = new String(theLastName.getBytes(), charset);
theLastName = lastNameISO;
theLastNameStr = isAnd + PID_LastName + theLastName;
isAnd = "~";
}
if (theDoB != null) {
theDoBStr = isAnd + PID_DoB
+ pxsDateConverter.DateToShortString(theDoB);
}
final String QBP_MESSAGE_TYPE = "QBP^Q22";
String aMessageHeader = generateMSH(QBP_MESSAGE_TYPE);
String aQPDSegment = "QPD|Q22^Find Candidates" + HL7_SEPERATOR
+ getRandomNumber(17) + getRandomNumber(18) + HL7_SEPERATOR
+ thePatientIdStr + theGivenNameStr + theLastNameStr
+ theDoBStr + HL7_SEPERATOR;
// Response Control Parameter: "I" means that response should come
// immediately
final String RPC_SEGMENT = "RCP" + HL7_SEPERATOR + "I" + HL7_SEPERATOR;
String hl7request = aMessageHeader + "\n" + aQPDSegment + "\n"
+ RPC_SEGMENT;
LOG.info(hl7request);
return hl7request;
}
/**
* Generates a generic HL7 header segment.
*
* @param theMessageType
* HL7 message type
* @return HL7 header segment
*/
private String generateMSH(String theMessageType) {
// HINT: PXSDateConverted() is not used for the purpose that missing time
// AND timezone may cause timing issues for HL7 server.
SimpleDateFormat aSDF = new SimpleDateFormat("yyyyMMddHHmmssSSZ");
long aRandom = getRandomNumber(19);
StringBuilder hl7header = new StringBuilder("MSH" + HL7_SEPERATOR);
hl7header.append("^~\\&" + HL7_SEPERATOR);
hl7header.append(HL7_SendingApplication + HL7_SEPERATOR);
hl7header.append(HL7_SendingFacility + HL7_SEPERATOR);
hl7header.append(HL7_ReceivingApplication + HL7_SEPERATOR);
hl7header.append(HL7_ReceivingFacility + HL7_SEPERATOR);
hl7header.append(aSDF.format(new Date()) + HL7_SEPERATOR);
hl7header.append(HL7_SEPERATOR);
hl7header.append(theMessageType + HL7_SEPERATOR);
hl7header.append(aRandom + HL7_SEPERATOR);
hl7header.append("P" + HL7_SEPERATOR);
hl7header.append(HL7_VERSION + HL7_SEPERATOR);
hl7header.append(HL7_SEPERATOR + HL7_SEPERATOR + HL7_SEPERATOR
+ HL7_SEPERATOR + HL7_SEPERATOR + HL7_SEPERATOR);
return hl7header.toString();
}
/**
* Generates a random number.
*
* @param theLength
* Length of digits (max. 19!)
* @return the random number
*/
private long getRandomNumber(int theLength) {
return (long) (Math.random() * Math.pow(10, theLength));
}
/**
* Checks if given String is "" or null.
*
* @param theString
* String to check
* @return true when string is "" or null
*/
private boolean isNullorEmpty(String theString) {
return (theString == null || theString.equals(""));
}
}