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; } } }