package org.akaza.openclinica.web.restful;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
import net.sf.json.xml.XMLSerializer;
import org.akaza.openclinica.bean.extract.odm.FullReportBean;
import org.akaza.openclinica.bean.login.UserAccountBean;
import org.akaza.openclinica.bean.managestudy.StudyBean;
import org.akaza.openclinica.bean.managestudy.StudySubjectBean;
import org.akaza.openclinica.dao.managestudy.StudyDAO;
import org.akaza.openclinica.dao.managestudy.StudySubjectDAO;
import org.akaza.openclinica.dao.submit.SubjectDAO;
import org.akaza.openclinica.i18n.core.LocaleResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.sun.jersey.api.view.Viewable;
/***
* * Rest service for ODM clinical data usage
* ROOT_CONTEXT/rest/clinicaldata/{format}/{mode}/{STUDYOID} format:xml/ json
* mode:view
*
* @author jnyayapathi
*
*/
@Path("/clinicaldata")
@Component
@Scope("prototype")
public class ODMClinicaDataResource {
private static final Logger LOGGER = LoggerFactory
.getLogger(ODMClinicaDataResource.class);
private static final int INDENT_LEVEL = 2;
private ClinicalDataCollectorResource clinicalDataCollectorResource;
private MetadataCollectorResource metadataCollectorResource;
private DataSource dataSource;
public MetadataCollectorResource getMetadataCollectorResource() {
return metadataCollectorResource;
}
public void setMetadataCollectorResource(
MetadataCollectorResource metadataCollectorResource) {
this.metadataCollectorResource = metadataCollectorResource;
}
public ClinicalDataCollectorResource getClinicalDataCollectorResource() {
return clinicalDataCollectorResource;
}
public void setClinicalDataCollectorResource(
ClinicalDataCollectorResource clinicalDataCollectorResource) {
this.clinicalDataCollectorResource = clinicalDataCollectorResource;
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
/**
* @api {get} /rest/clinicaldata/json/view/:study/:subject/:event/:form Retrieve case report forms - JSON
* @apiVersion 3.8.0
* @apiName getODMClinicaldataJSON
* @apiGroup Subject
* @apiPermission user
*
* @apiDescription Annotated case report forms in printable HTML format. Use asterisks in place of OIDs as wildcards
*
* @apiParam {String} study Study or Site OID.
* @apiParam {String} subject Subject Key or ID.
* @apiParam {String} event Study Event Definition OID. Use '*' for all.
* @apiParam {String} form Case Report Form Version OID. Use '*' for all.
*
*
* @apiError NoAccessRight Only authenticated users can access the data.
* @apiError NotFound The resource was not found.
*
*/
@GET
@Path("/json/view/{studyOID}/{studySubjectIdentifier}/{studyEventOID}/{formVersionOID}")
@Produces(MediaType.APPLICATION_JSON)
public String getODMClinicaldata(@PathParam("studyOID") String studyOID,
@PathParam("formVersionOID") String formVersionOID,
@PathParam("studyEventOID") String studyEventOID,
@PathParam("studySubjectIdentifier") String studySubjectIdentifier,
@DefaultValue("n") @QueryParam("includeDNs") String includeDns,
@DefaultValue("n") @QueryParam("includeAudits") String includeAudits,@Context HttpServletRequest request) {
LOGGER.debug("Requesting clinical data resource");
boolean includeDN=false;
boolean includeAudit= false;
if(includeDns.equalsIgnoreCase("no")||includeDns.equalsIgnoreCase("n")) includeDN=false;
if(includeAudits.equalsIgnoreCase("no")||includeAudits.equalsIgnoreCase("n")) includeAudit=false;
if(includeDns.equalsIgnoreCase("yes")||includeDns.equalsIgnoreCase("y")) includeDN=true;
if(includeAudits.equalsIgnoreCase("yes")||includeAudits.equalsIgnoreCase("y")) includeAudit=true;
int userId = ((UserAccountBean)request.getSession().getAttribute("userBean")).getId();
XMLSerializer xmlSerializer = new XMLSerializer();
FullReportBean report = getMetadataCollectorResource().collectODMMetadataForClinicalData(studyOID,
formVersionOID,
getClinicalDataCollectorResource()
.generateClinicalData(studyOID, getStudySubjectOID(studySubjectIdentifier,studyOID),
studyEventOID, formVersionOID,includeDN,includeAudit,request.getLocale(), userId));
if(report.getClinicalDataMap()==null)
return null;
report.createOdmXml(true);
//xmlSerializer.setForceTopLevelObject(true);
xmlSerializer.setTypeHintsEnabled(true);
JSON json = xmlSerializer.read(report.getXmlOutput().toString().trim());
JSONClinicalDataPostProcessor processor = new JSONClinicalDataPostProcessor(request.getLocale());
processor.process((JSONObject) json);
// JSONClinicalDataPostProcessor processor = new JSONClinicalDataPostProcessor(LocaleResolver.getLocale(request));
// processor.process(json);
return json.toString(INDENT_LEVEL);
}
/**
* @api {get} /rest/clinicaldata/html/print/:study/:subject/:event/:form Retrieve case report forms - HTML
* @apiVersion 3.8.0
* @apiName getPrintCRFController
* @apiGroup Subject
* @apiPermission user
*
* @apiDescription Annotated case report forms in printable HTML format. Use asterisks in place of OIDs as wildcards
*
* @apiParam {String} study Study or Site OID.
* @apiParam {String} subject Subject Key or ID.
* @apiParam {String} event Study Event Definition OID. Use '*' for all.
* @apiParam {String} form Case Report Form Version OID. Use '*' for all.
*
*
* @apiError NoAccessRight Only authenticated users can access the data.
* @apiError NotFound The resource was not found.
*
* @apiErrorExample Response (example):
* HTTP/1.1 401 Not Authenticated
* {
* "error": "NoAccessRight"
* }
*/
@GET
@Path("/html/print/{studyOID}/{studySubjectIdentifier}/{eventOID}/{formVersionOID}")
public Viewable getPrintCRFController(@Context HttpServletRequest request,
@Context HttpServletResponse response,
@PathParam("studyOID") String studyOID,
@PathParam("studySubjectIdentifier") String studySubjectIdentifier,
@PathParam("eventOID") String eventOID,
@PathParam("formVersionOID") String formVersionOID, @DefaultValue("n") @QueryParam("includeDNs") String includeDns,
@DefaultValue("n") @QueryParam("includeAudits") String includeAudits)
throws Exception {
request.setCharacterEncoding("UTF-8");
request.setAttribute("studyOID", studyOID);
request.setAttribute("studySubjectOID", getStudySubjectOID(studySubjectIdentifier,studyOID));
request.setAttribute("eventOID", eventOID);
request.setAttribute("formVersionOID", formVersionOID);
request.setAttribute("includeAudits", includeAudits);
request.setAttribute("includeDNs", includeDns);
return new Viewable("/WEB-INF/jsp/printcrf.jsp", null);
}
/**
* @api {get} /rest/clinicaldata/xml/view/:study/:subject/:event/:form Retrieve case report forms - XML
* @apiVersion 3.8.0
* @apiName getODMMetadata
* @apiGroup Subject
* @apiPermission user
*
* @apiDescription Annotated case report forms in printable HTML format. Use asterisks in place of OIDs as wildcards
*
* @apiParam {String} study Study or Site OID.
* @apiParam {String} subject Subject Key or ID.
* @apiParam {String} event Study Event Definition OID. Use '*' for all.
* @apiParam {String} form Case Report Form Version OID. Use '*' for all.
*
*
* @apiError NoAccessRight Only authenticated users can access the data.
* @apiError NotFound The resource was not found.
*
* @apiErrorExample Response (example):
* HTTP/1.1 401 Not Authenticated
* {
* "error": "NoAccessRight"
* }
*/
@GET
@Path("/xml/view/{studyOID}/{studySubjectIdentifier}/{studyEventOID}/{formVersionOID}")
@Produces(MediaType.TEXT_XML)
public String getODMMetadata(@PathParam("studyOID") String studyOID,
@PathParam("formVersionOID") String formVersionOID,
@PathParam("studySubjectIdentifier") String studySubjectIdentifier,
@PathParam("studyEventOID") String studyEventOID,
@DefaultValue("n") @QueryParam("includeDNs") String includeDns,
@DefaultValue("n") @QueryParam("includeAudits") String includeAudits,@Context HttpServletRequest request) {
LOGGER.debug("Requesting clinical data resource");
boolean includeDN=false;
boolean includeAudit= false;
int userId = ((UserAccountBean)request.getSession().getAttribute("userBean")).getId();
if(includeDns.equalsIgnoreCase("no")||includeDns.equalsIgnoreCase("n")) includeDN=false;
if(includeAudits.equalsIgnoreCase("no")||includeAudits.equalsIgnoreCase("n")) includeAudit=false;
if(includeDns.equalsIgnoreCase("yes")||includeDns.equalsIgnoreCase("y")) includeDN=true;
if(includeAudits.equalsIgnoreCase("yes")||includeAudits.equalsIgnoreCase("y")) includeAudit=true;
FullReportBean report = getMetadataCollectorResource()
.collectODMMetadataForClinicalData(
studyOID,
formVersionOID,
getClinicalDataCollectorResource()
.generateClinicalData(studyOID, getStudySubjectOID(studySubjectIdentifier,studyOID),
studyEventOID, formVersionOID,includeDN,includeAudit,request.getLocale(), userId));
report.createOdmXml(true);
LOGGER.debug(report.getXmlOutput().toString().trim());
return report.getXmlOutput().toString().trim();
}
/**
* This function checks to see whether the supplied subject identifier is a Study Subject OID or a Study Subject ID.
* If a valid Study Subject OID or wildcard (*) is supplied, just return it.
* If a Study Subject ID is supplied, a lookup is done to get the Study Subject OID and return that.
*/
private String getStudySubjectOID(String subjectIdentifier, String studyOID)
{
StudySubjectDAO studySubjectDAO = new StudySubjectDAO(getDataSource());
StudySubjectBean studySubject = studySubjectDAO.findByOid(subjectIdentifier);
if (subjectIdentifier.equals("*") ||
(studySubject != null && studySubject.getOid() != null)) return subjectIdentifier;
else
{
StudyDAO studyDAO = new StudyDAO(getDataSource());
StudyBean study = studyDAO.findByOid(studyOID);
studySubject = studySubjectDAO.findByLabelAndStudy(subjectIdentifier,study);
if (studySubject != null && studySubject.getOid() != null) return studySubject.getOid();
else return subjectIdentifier;
}
}
}