/* * Copyright (c) 2006-2007 Massachusetts General Hospital * All rights reserved. This program and the accompanying materials * are made available under the terms of the i2b2 Software License v1.0 * which accompanies this distribution. * * Contributors: * Mike Mendis - initial API and implementation */ package de.hpi.i2b2.girix; import edu.harvard.i2b2.common.exception.I2B2Exception; import edu.harvard.i2b2.common.util.jaxb.DTOFactory; import edu.harvard.i2b2.common.util.jaxb.JAXBUtil; import edu.harvard.i2b2.common.util.jaxb.JAXBUtilException; import de.hpi.i2b2.girix.datavo.i2b2message.ApplicationType; import de.hpi.i2b2.girix.datavo.i2b2message.BodyType; import de.hpi.i2b2.girix.datavo.i2b2message.FacilityType; import de.hpi.i2b2.girix.datavo.i2b2message.MessageControlIdType; import de.hpi.i2b2.girix.datavo.i2b2message.MessageHeaderType; import de.hpi.i2b2.girix.datavo.i2b2message.PasswordType; import de.hpi.i2b2.girix.datavo.i2b2message.ProcessingIdType; import de.hpi.i2b2.girix.datavo.i2b2message.RequestHeaderType; import de.hpi.i2b2.girix.datavo.i2b2message.RequestMessageType; import de.hpi.i2b2.girix.datavo.i2b2message.ResponseHeaderType; import de.hpi.i2b2.girix.datavo.i2b2message.ResponseMessageType; import de.hpi.i2b2.girix.datavo.i2b2message.ResultStatusType; import de.hpi.i2b2.girix.datavo.i2b2message.SecurityType; import de.hpi.i2b2.girix.datavo.i2b2message.StatusType; import de.hpi.i2b2.girix.datavo.pdo.query.FactOutputOptionType; import de.hpi.i2b2.girix.datavo.pdo.query.FilterListType; import de.hpi.i2b2.girix.datavo.pdo.query.GetPDOFromInputListRequestType; import de.hpi.i2b2.girix.datavo.pdo.query.InputOptionListType; import de.hpi.i2b2.girix.datavo.pdo.query.ItemType; import de.hpi.i2b2.girix.datavo.pdo.query.OutputOptionListType; import de.hpi.i2b2.girix.datavo.pdo.query.OutputOptionNameType; import de.hpi.i2b2.girix.datavo.pdo.query.OutputOptionSelectType; import de.hpi.i2b2.girix.datavo.pdo.query.OutputOptionType; import de.hpi.i2b2.girix.datavo.pdo.query.PanelType; import de.hpi.i2b2.girix.datavo.pdo.query.PatientListType; import de.hpi.i2b2.girix.datavo.pdo.query.PdoQryHeaderType; import de.hpi.i2b2.girix.datavo.pdo.query.PdoRequestTypeType; import de.hpi.i2b2.girix.datavo.pdo.query.RequestType; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.impl.builder.StAXOMBuilder; import java.io.StringReader; import java.io.StringWriter; import java.math.BigDecimal; import java.util.Date; import java.util.List; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; // Utility class to create and transform message related objects public class MessageUtil { /* * =============== Response methods (for responses to requesting clients) =============== */ // Create normal response message type out of the other message parts public static ResponseMessageType createResponseMessageType(MessageHeaderType messageHeader, ResponseHeaderType respHeader, BodyType bodyType) { ResponseMessageType respMsgType = new ResponseMessageType(); respMsgType.setMessageHeader(messageHeader); respMsgType.setMessageBody(bodyType); respMsgType.setResponseHeader(respHeader); return respMsgType; } // Create response message type with given error message public static ResponseMessageType doBuildErrorResponseMessageType(MessageHeaderType messageHeaderType, String errorMessage) { MessageHeaderType messageHeader = createResponseMessageHeaderType(messageHeaderType); ResponseHeaderType respHeader = createResponseHeaderType("ERROR", errorMessage); ResponseMessageType respMessageType = createResponseMessageType(messageHeader, respHeader, null); return respMessageType; } // Create response message header based on request message header public static MessageHeaderType createResponseMessageHeaderType(MessageHeaderType messageHeaderType) { MessageHeaderType messageHeader = new MessageHeaderType(); messageHeader.setI2B2VersionCompatible(new BigDecimal("1.1")); messageHeader.setHl7VersionCompatible(new BigDecimal("2.4")); ApplicationType appType = new ApplicationType(); appType.setApplicationName("GIRIX Cell"); appType.setApplicationVersion("1.0"); messageHeader.setSendingApplication(appType); FacilityType facility = new FacilityType(); facility.setFacilityName("i2b2 Hive"); messageHeader.setSendingFacility(facility); if (messageHeaderType != null) { if (messageHeaderType.getSendingApplication() != null) { messageHeader.setReceivingApplication(messageHeaderType.getSendingApplication()); } messageHeader.setReceivingFacility(messageHeaderType.getSendingFacility()); } Date currentDate = new Date(); DTOFactory factory = new DTOFactory(); messageHeader.setDatetimeOfMessage(factory.getXMLGregorianCalendar(currentDate.getTime())); MessageControlIdType mcIdType = new MessageControlIdType(); mcIdType.setInstanceNum(1); if (messageHeaderType != null) { if (messageHeaderType.getMessageControlId() != null) { mcIdType.setMessageNum(messageHeaderType.getMessageControlId().getMessageNum()); mcIdType.setSessionId(messageHeaderType.getMessageControlId().getSessionId()); } } messageHeader.setMessageControlId(mcIdType); ProcessingIdType proc = new ProcessingIdType(); proc.setProcessingId("P"); proc.setProcessingMode("I"); messageHeader.setProcessingId(proc); messageHeader.setAcceptAcknowledgementType("AL"); messageHeader.setApplicationAcknowledgementType("AL"); messageHeader.setCountryCode("DE"); if (messageHeaderType != null) { if(messageHeaderType.getProjectId() != null) { messageHeader.setProjectId(messageHeaderType.getProjectId()); } } return messageHeader; } // Creates ResponseHeader for the given type and value public static ResponseHeaderType createResponseHeaderType(String type, String value) { ResponseHeaderType respHeader = new ResponseHeaderType(); StatusType status = new StatusType(); status.setType(type); status.setValue(value); ResultStatusType resStat = new ResultStatusType(); resStat.setStatus(status); respHeader.setResultStatus(resStat); return respHeader; } /* * =============== Request methods (for request to CRC cell) =============== */ // Create request message type out of the other message parts public static RequestMessageType createRequestMessageType(MessageHeaderType messageHeader, RequestHeaderType reqHeader, BodyType bodyType) { RequestMessageType reqMsgType = new RequestMessageType(); reqMsgType.setMessageHeader(messageHeader); reqMsgType.setMessageBody(bodyType); reqMsgType.setRequestHeader(reqHeader); return reqMsgType; } // Create request message header public static MessageHeaderType createRequestMessageHeaderType(String domain, String username, String password, String projectid) { MessageHeaderType messageHeader = new MessageHeaderType(); messageHeader.setI2B2VersionCompatible(new BigDecimal("1.1")); messageHeader.setHl7VersionCompatible(new BigDecimal("2.4")); ApplicationType sendAppType = new ApplicationType(); sendAppType.setApplicationName("GIRIX Cell"); sendAppType.setApplicationVersion("1.0"); messageHeader.setSendingApplication(sendAppType); FacilityType sendFacility = new FacilityType(); sendFacility.setFacilityName("i2b2 Hive"); messageHeader.setSendingFacility(sendFacility); ApplicationType recvAppType = new ApplicationType(); recvAppType.setApplicationName("i2b2_DataRepositoryCell"); recvAppType.setApplicationVersion("1.7"); messageHeader.setReceivingApplication(recvAppType); FacilityType recvFacility = new FacilityType(); recvFacility.setFacilityName("PHS"); messageHeader.setReceivingFacility(recvFacility); Date currentDate = new Date(); DTOFactory factory = new DTOFactory(); messageHeader.setDatetimeOfMessage(factory.getXMLGregorianCalendar(currentDate.getTime())); SecurityType secType = new SecurityType(); secType.setDomain(domain); secType.setUsername(username); PasswordType pwt = new PasswordType(); pwt.setValue(password); secType.setPassword(pwt); messageHeader.setSecurity(secType); MessageControlIdType mcIdType = new MessageControlIdType(); mcIdType.setInstanceNum(0); mcIdType.setMessageNum(generateMessageId()); mcIdType.setSessionId("1"); messageHeader.setMessageControlId(mcIdType); ProcessingIdType proc = new ProcessingIdType(); proc.setProcessingId("P"); proc.setProcessingMode("I"); messageHeader.setProcessingId(proc); messageHeader.setAcceptAcknowledgementType("AL"); messageHeader.setApplicationAcknowledgementType("AL"); messageHeader.setCountryCode("DE"); messageHeader.setProjectId(projectid); return messageHeader; } // Creates RequestHeader public static RequestHeaderType createRequestHeaderType() { RequestHeaderType reqHeader = new RequestHeaderType(); reqHeader.setResultWaittimeMs(25000); return reqHeader; } // Create PDOHeader public static PdoQryHeaderType createPDOHeader() { PdoQryHeaderType pqht = new PdoQryHeaderType(); pqht.setPatientSetLimit(0); pqht.setEstimatedTime(180000); pqht.setRequestType(PdoRequestTypeType.GET_PDO_FROM_INPUT_LIST); return pqht; } // Create PDORequest public static RequestType createPDORequest(int pdoCollID, List<ItemType> conceptsList) { GetPDOFromInputListRequestType pdoReqType = new GetPDOFromInputListRequestType(); // Specify patient list by collection id InputOptionListType iolt = new InputOptionListType(); PatientListType plt = new PatientListType(); plt.setPatientSetCollId(String.valueOf(pdoCollID)); plt.setMin(0); plt.setMax(0); iolt.setPatientList(plt); pdoReqType.setInputList(iolt); boolean conceptAvailable = true; if (conceptsList.size() == 0) conceptAvailable = false; // Specify filter list if a concept was specified if (conceptAvailable) { FilterListType flt = new FilterListType(); PanelType pt = new PanelType(); pt.setName("The panel name"); // not relevant pt.setPanelNumber(1); pt.setPanelAccuracyScale(1); pt.setInvert(0); pt.getItem().addAll(conceptsList); flt.getPanel().add(pt); pdoReqType.setFilterList(flt); } // Specify output options OutputOptionListType oolt = new OutputOptionListType(); oolt.setNames(OutputOptionNameType.ASATTRIBUTES); // Patient set OutputOptionType ootForPatientSet = new OutputOptionType(); ootForPatientSet.setSelect(OutputOptionSelectType.USING_INPUT_LIST); ootForPatientSet.setOnlykeys(false); ootForPatientSet.setTechdata(true); oolt.setPatientSet(ootForPatientSet); // Observation set if (conceptAvailable) { FactOutputOptionType ootForObsSet = new FactOutputOptionType(); ootForObsSet.setBlob(false); ootForObsSet.setOnlykeys(false); ootForObsSet.setTechdata(true); oolt.setObservationSet(ootForObsSet); // Concept informations (we need the concept_path) OutputOptionType ootForConceptSet = new OutputOptionType(); ootForConceptSet.setSelect(OutputOptionSelectType.USING_FILTER_LIST); ootForConceptSet.setOnlykeys(false); oolt.setConceptSetUsingFilterList(ootForConceptSet); // Create a general OutputOptionType OutputOptionType oot = new OutputOptionType(); oot.setOnlykeys(false); oot.setSelect(OutputOptionSelectType.USING_FILTER_LIST); oot.setTechdata(true); // Remaining sets oolt.setModifierSetUsingFilterList(oot); oolt.setEventSet(oot); oolt.setObserverSetUsingFilterList(oot); } pdoReqType.setOutputOption(oolt); return pdoReqType; } /* * =============== Conversion and helper methods =============== */ // Convert XML string to RequestMessageType (JAXB) = unmarshalling the request (from client) public static RequestMessageType convertXMLTORequestMessageType(String xmlString) throws I2B2Exception { try { RequestMessageType rmt = (RequestMessageType) GIRIXUtil.getJAXBUtil().unMashallFromString(xmlString).getValue(); if (rmt == null) { throw new I2B2Exception("Null value from unmarshall for VDO xml : " + xmlString); } return rmt; } catch (JAXBUtilException e) { throw new I2B2Exception("Umarshaller error: " + e.getMessage() + xmlString, e); } } // Convert XML string to ResponseMessageType (JAXB) = unmarshalling the response (from CRC) public static ResponseMessageType convertXMLTOResponseMessageType(String xmlString) throws I2B2Exception { try { ResponseMessageType rmt = (ResponseMessageType) GIRIXUtil.getJAXBUtil().unMashallFromString(xmlString).getValue(); if (rmt == null) { throw new I2B2Exception("Null value from unmarshall for VDO xml : " + xmlString); } return rmt; } catch (JAXBUtilException e) { throw new I2B2Exception("Umarshaller error: " + e.getMessage() + xmlString, e); } } // Convert ResponseMessageType (JAXB) to XML string = marshalling the response (to client) public static String convertResponseMessageTypeToXML(ResponseMessageType respMessageType) throws I2B2Exception { StringWriter strWriter = null; try { JAXBUtil jaxbUtil = GIRIXUtil.getJAXBUtil(); strWriter = new StringWriter(); de.hpi.i2b2.girix.datavo.i2b2message.ObjectFactory objectFactory = new de.hpi.i2b2.girix.datavo.i2b2message.ObjectFactory(); jaxbUtil.marshaller(objectFactory.createResponse(respMessageType), strWriter); } catch (JAXBUtilException e) { throw new I2B2Exception("Error converting response message type to string " + e.getMessage(), e); } return strWriter.toString(); } // Convert RequestMessageType (JAXB) to XML string = marshalling the request (to CRC) public static String convertRequestMessageTypeToXML(RequestMessageType reqMessageType) throws I2B2Exception { StringWriter strWriter = null; try { JAXBUtil jaxbUtil = GIRIXUtil.getJAXBUtil(); strWriter = new StringWriter(); de.hpi.i2b2.girix.datavo.i2b2message.ObjectFactory objectFactory = new de.hpi.i2b2.girix.datavo.i2b2message.ObjectFactory(); jaxbUtil.marshaller(objectFactory.createRequest(reqMessageType), strWriter); } catch (JAXBUtilException e) { throw new I2B2Exception("Error converting response message type to string " + e.getMessage(), e); } return strWriter.toString(); } // Convert XML string to OMElement (for responses after marshalling) public static OMElement convertXMLToOMElement(String xmlString) throws I2B2Exception { OMElement returnElement = null; try { StringReader strReader = new StringReader(xmlString); XMLInputFactory xif = XMLInputFactory.newInstance(); XMLStreamReader reader = xif.createXMLStreamReader(strReader); StAXOMBuilder builder = new StAXOMBuilder(reader); returnElement = builder.getDocumentElement(); } catch (XMLStreamException e) { throw new I2B2Exception("Error while converting XML to OMElement" + e.getMessage(), e); } return returnElement; } /** * Function to generate i2b2 message header message number * * @return String */ private static String generateMessageId() { StringWriter strWriter = new StringWriter(); for(int i=0; i<20; i++) { int num = getValidAcsiiValue(); strWriter.append((char)num); } return strWriter.toString(); } /** * Function to generate random number used in message number * * @return int */ private static int getValidAcsiiValue() { int number = 48; while(true) { number = 48+(int) Math.round(Math.random() * 74); if((number > 47 && number < 58) || (number > 64 && number < 91) || (number > 96 && number < 123)) { break; } } return number; } }