/*
* Copyright (c) 2006-2013 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:
* Christopher Herrick
*/
package edu.harvard.i2b2.crc.dao.setfinder.querybuilder.temporal;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.JAXBElement;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import edu.harvard.i2b2.common.exception.I2B2DAOException;
import edu.harvard.i2b2.common.exception.I2B2Exception;
import edu.harvard.i2b2.common.exception.StackTraceUtil;
import edu.harvard.i2b2.common.util.axis2.ServiceClient;
import edu.harvard.i2b2.common.util.jaxb.JAXBUnWrapHelper;
import edu.harvard.i2b2.common.util.jaxb.JAXBUtil;
import edu.harvard.i2b2.common.util.jaxb.JAXBUtilException;
import edu.harvard.i2b2.crc.datavo.CRCJAXBUtil;
import edu.harvard.i2b2.crc.datavo.i2b2message.FacilityType;
import edu.harvard.i2b2.crc.datavo.i2b2message.MessageHeaderType;
import edu.harvard.i2b2.crc.datavo.i2b2message.RequestHeaderType;
import edu.harvard.i2b2.crc.datavo.i2b2message.RequestMessageType;
import edu.harvard.i2b2.crc.datavo.i2b2message.ResponseMessageType;
import edu.harvard.i2b2.crc.datavo.i2b2message.SecurityType;
import edu.harvard.i2b2.crc.datavo.i2b2message.BodyType;
import edu.harvard.i2b2.crc.datavo.ontology.ConceptType;
import edu.harvard.i2b2.crc.datavo.ontology.XmlValueType;
import edu.harvard.i2b2.crc.datavo.pdo.PatientDataType;
import edu.harvard.i2b2.crc.datavo.pdo.PatientSet;
import edu.harvard.i2b2.crc.datavo.pdo.PatientType;
import edu.harvard.i2b2.crc.datavo.pdo.query.PatientDataResponseType;
import edu.harvard.i2b2.crc.datavo.pm.GetUserConfigurationType;
import edu.harvard.i2b2.crc.datavo.pm.ProjectType;
import edu.harvard.i2b2.crc.datavo.setfinder.query.ItemType;
import edu.harvard.i2b2.crc.util.ItemKeyUtil;
import edu.harvard.i2b2.crc.util.QueryProcessorUtil;
/**
* Temporal Panel Cell Query Item
*
* <P>
* Cell Query query object that wraps the item tag found in the query definition
* xml for cell query items. It roughly corresponds to a panel in the query UI. Panel is responsible
* for organizing the sql that comes back from individual panel items - sql from
* items should be logically or'd together. It is also the container that holds
* the panel constraint types - occurrence, dates, and exclude.
*
* @author Christopher Herrick
*
*/
public class TemporalPanelCellQueryItem extends TemporalPanelItem {
private JAXBUtil jaxbUtil = null;
private static Log log = LogFactory.getLog(TemporalPanelCellQueryItem.class);
private XmlValueType requestXml = null;
private String cellUrl = null;
private String patientNums = null;
public TemporalPanelCellQueryItem(TemporalPanel parent, ItemType item, ConceptType conceptType)
throws I2B2Exception {
super(parent, item, conceptType);
parseCellItem();
}
protected void parseCellItem() throws I2B2Exception {
super.parseItem();
cellUrl = conceptType.getDimcode();
if (cellUrl!=null&&cellUrl.toLowerCase().startsWith(ItemKeyUtil.ITEM_KEY_CELLID))
cellUrl = cellUrl.substring(ItemKeyUtil.ITEM_KEY_CELLID.length());
if (conceptType.getMetadataxml()!=null){
requestXml = conceptType.getMetadataxml();
}
jaxbUtil = CRCJAXBUtil.getJAXBUtil();
}
@Override
protected String buildSql() throws I2B2DAOException {
try {
this.callCellUrlWithRequest();
this.dimCode = patientNums;
} catch (Exception e) {
log.debug(e.getStackTrace());
e.printStackTrace();
return "";
}
if (returnEncounterNum()||
returnInstanceNum()||
this.hasItemDateConstraint()||
this.hasModiferConstraint()||
this.hasPanelDateConstraint()||
this.hasPanelOccurrenceConstraint()||
this.hasValueConstraint()
//||parent.isTimingQuery()
){
return super.buildSql();
}
else{
return "select "
+ this.factTableColumn + " from " + noLockSqlServer
+ parent.getDatabaseSchema() + this.tableName
+ " " + " where " + this.columnName + " "
+ this.operator + " " + this.dimCode
+ "";
}
}
@Override
protected String getJoinTable() {
if (returnInstanceNum()||
hasItemDateConstraint()||
hasPanelDateConstraint()||
hasValueConstraint()||
hasPanelOccurrenceConstraint()) {
return "observation_fact";
} else if (returnEncounterNum()
//||parent.isTimingQuery()
) {
return "visit_dimension";
} else {
return "patient_dimension";
}
}
public PatientSet getPatientSetFromResponseXML(String responseXML)
throws Exception {
JAXBUtil jaxbUtil = CRCJAXBUtil.getJAXBUtil();
@SuppressWarnings("rawtypes")
JAXBElement jaxbElement = jaxbUtil.unMashallFromString(responseXML);
ResponseMessageType messageType = (ResponseMessageType) jaxbElement
.getValue();
BodyType bodyType = messageType.getMessageBody();
PatientDataResponseType responseType = (PatientDataResponseType) new JAXBUnWrapHelper()
.getObjectByClass(bodyType.getAny(),
PatientDataResponseType.class);
PatientDataType patientDataType = responseType.getPatientData();
PatientSet patientSet = patientDataType.getPatientSet();
return patientSet;
}
public ProjectType callCellUrlWithRequest() throws Exception {
RequestMessageType requestMessageType = getI2B2RequestMessage(parent.getRequestorSecurityType(), parent.getProjectId());
OMElement requestElement = null;
ProjectType projectType = null;
try {
String requestXmlString = createRequestXmlString();
requestElement = buildOMElement(requestMessageType, requestXmlString);
log.debug("call cell request xml " + requestElement);
String response = ServiceClient.sendREST(cellUrl, requestElement);
log.debug("Got Response");
PatientSet pSet = getPatientSetFromResponseXML(response);
if (pSet!=null){
StringBuffer patientList = new StringBuffer();
patientList.append("(");
boolean first = true;
for (PatientType patient : pSet.getPatient()){
if (!first){
patientList.append(", ");
}
else
first = false;
if (patient.getPatientId()!=null&&patient.getPatientId().getValue()!=null)
patientList.append(patient.getPatientId().getValue());
}
patientList.append(")");
patientNums = patientList.toString();
}
} catch (XMLStreamException e) {
e.printStackTrace();
throw new I2B2Exception("" + StackTraceUtil.getStackTrace(e));
} catch (Exception e) {
e.printStackTrace();
throw new I2B2Exception("" + StackTraceUtil.getStackTrace(e));
}
log.debug("Returning ProjectType");
return projectType;
}
private OMElement buildOMElement(RequestMessageType requestMessageType, String requestXml)
throws XMLStreamException, JAXBUtilException {
StringWriter strWriter = new StringWriter();
edu.harvard.i2b2.crc.datavo.i2b2message.ObjectFactory hiveof = new edu.harvard.i2b2.crc.datavo.i2b2message.ObjectFactory();
jaxbUtil.marshaller(hiveof.createRequest(requestMessageType), strWriter);
//insert request
String msgBody = "<message_body/>";
String xmlrequest = strWriter.toString();
int index = xmlrequest.indexOf(msgBody);
if (index>=0){
xmlrequest = xmlrequest.substring(0, index) + "<message_body>" + requestXml + "</message_body>" + xmlrequest.substring(index + msgBody.length()+1);
}
StringReader strReader = new StringReader(xmlrequest);
XMLInputFactory xif = XMLInputFactory.newInstance();
XMLStreamReader reader = xif.createXMLStreamReader(strReader);
StAXOMBuilder builder = new StAXOMBuilder(reader);
OMElement request = builder.getDocumentElement();
return request;
}
private RequestMessageType getI2B2RequestMessage(SecurityType securityType, String projectId) throws Exception {
QueryProcessorUtil queryUtil = QueryProcessorUtil.getInstance();
MessageHeaderType messageHeaderType = (MessageHeaderType) queryUtil
.getSpringBeanFactory().getBean("message_header");
messageHeaderType.setSecurity(securityType);
messageHeaderType.setProjectId(projectId);
messageHeaderType.setReceivingApplication(messageHeaderType
.getSendingApplication());
FacilityType facilityType = new FacilityType();
facilityType.setFacilityName("sample");
messageHeaderType.setSendingFacility(facilityType);
messageHeaderType.setReceivingFacility(facilityType);
// build message body
// GetUserInfoType getUserInfoType = null;
GetUserConfigurationType userConfig = new GetUserConfigurationType();
userConfig.getProject().add(projectId);
RequestMessageType requestMessageType = new RequestMessageType();
BodyType bodyType = new BodyType();
requestMessageType.setMessageBody(bodyType);
requestMessageType.setMessageHeader(messageHeaderType);
RequestHeaderType requestHeader = new RequestHeaderType();
requestHeader.setResultWaittimeMs(180000);
requestMessageType.setRequestHeader(requestHeader);
return requestMessageType;
}
private String createRequestXmlString(){
String xmlRootString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
StringBuffer requestXmlString= new StringBuffer();
if (requestXml!=null){
if (requestXml.getAny().size()>0&&requestXml.getAny().get(0).getNodeName().toLowerCase().equals("cellrequest")){
Element request = requestXml.getAny().get(0);
for (int i = 0; i < request.getChildNodes().getLength(); i++){
String nodeString = convertNodeToString(request.getChildNodes().item(i));
if (nodeString.startsWith(xmlRootString)){
nodeString = nodeString.substring(xmlRootString.length()).trim();
}
if (nodeString.length()>0) {
requestXmlString.append(nodeString);
}
}
}
}
return requestXmlString.toString();
}
private String convertNodeToString(Node request) {
StringWriter writer = new StringWriter();
Transformer transformer;
try {
transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new DOMSource(request), new StreamResult(writer));
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return writer.toString();
}
}