package org.akaza.openclinica.service; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import javax.sql.DataSource; import javax.xml.parsers.DocumentBuilderFactory; import org.akaza.openclinica.bean.core.Role; import org.akaza.openclinica.bean.core.Utils; import org.akaza.openclinica.bean.login.UserAccountBean; import org.akaza.openclinica.bean.managestudy.StudyBean; import org.akaza.openclinica.bean.submit.CRFVersionBean; import org.akaza.openclinica.dao.hibernate.CrfDao; import org.akaza.openclinica.dao.hibernate.CrfVersionDao; import org.akaza.openclinica.dao.hibernate.EventDefinitionCrfDao; import org.akaza.openclinica.dao.hibernate.EventDefinitionCrfTagDao; import org.akaza.openclinica.dao.hibernate.StudyDao; import org.akaza.openclinica.dao.hibernate.StudyEventDefinitionDao; import org.akaza.openclinica.dao.hibernate.StudyParameterValueDao; import org.akaza.openclinica.dao.hibernate.StudyUserRoleDao; import org.akaza.openclinica.dao.hibernate.UserAccountDao; import org.akaza.openclinica.domain.Status; import org.akaza.openclinica.domain.datamap.CrfBean; import org.akaza.openclinica.domain.datamap.CrfVersion; import org.akaza.openclinica.domain.datamap.EventDefinitionCrf; import org.akaza.openclinica.domain.datamap.EventDefinitionCrfTag; import org.akaza.openclinica.domain.datamap.Study; import org.akaza.openclinica.domain.datamap.StudyEventDefinition; import org.akaza.openclinica.domain.datamap.StudyParameterValue; import org.akaza.openclinica.domain.datamap.StudyUserRole; import org.akaza.openclinica.domain.datamap.StudyUserRoleId; import org.akaza.openclinica.domain.user.UserAccount; import org.akaza.openclinica.domain.xform.XformContainer; import org.akaza.openclinica.domain.xform.XformGroup; import org.akaza.openclinica.domain.xform.XformItem; import org.akaza.openclinica.domain.xform.XformParser; import org.akaza.openclinica.domain.xform.dto.Html; import org.akaza.openclinica.service.crfdata.XformMetaDataService; import org.akaza.openclinica.service.dto.Crf; import org.akaza.openclinica.service.dto.Version; import org.akaza.openclinica.service.pmanage.ParticipantPortalRegistrar; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItem; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.exception.ExceptionUtils; import org.cdisc.ns.odm.v130_sb.EventType; import org.cdisc.ns.odm.v130_sb.ODM; import org.cdisc.ns.odm.v130_sb.ODMcomplexTypeDefinitionFormDef; import org.cdisc.ns.odm.v130_sb.ODMcomplexTypeDefinitionFormRef; import org.cdisc.ns.odm.v130_sb.ODMcomplexTypeDefinitionGlobalVariables; import org.cdisc.ns.odm.v130_sb.ODMcomplexTypeDefinitionMetaDataVersion; import org.cdisc.ns.odm.v130_sb.ODMcomplexTypeDefinitionStudy; import org.cdisc.ns.odm.v130_sb.ODMcomplexTypeDefinitionStudyEventDef; import org.cdisc.ns.odm.v130_sb.ODMcomplexTypeDefinitionStudyEventRef; import org.cdisc.ns.odm.v130_sb.YesOrNo; import org.openclinica.ns.odm_ext_v130.v31_sb.OCodmComplexTypeDefinitionConfigurationParameters; import org.openclinica.ns.odm_ext_v130.v31_sb.OCodmComplexTypeDefinitionEventDefinitionDetails; import org.openclinica.ns.odm_ext_v130.v31_sb.OCodmComplexTypeDefinitionFormLayoutDef; import org.openclinica.ns.odm_ext_v130.v31_sb.OCodmComplexTypeDefinitionFormLayoutRef; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.DataBinder; import org.springframework.validation.Errors; import org.springframework.web.client.RestTemplate; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class OdmImportServiceImpl implements OdmImportService { private UserAccountDao userAccountDao; private StudyUserRoleDao studyUserRoleDao; private StudyEventDefinitionDao studyEventDefDao; private EventDefinitionCrfDao eventDefinitionCrfDao; private CrfDao crfDao; private CrfVersionDao crfVersionDao; private StudyDao studyDao; private EventDefinitionCrfTagDao eventDefinitionCrfTagDao; private StudyParameterValueDao studyParameterValueDao; private XformParser xformParser; private XformMetaDataService xformService; protected final Logger logger = LoggerFactory.getLogger(getClass().getName()); public OdmImportServiceImpl(DataSource dataSource) { } @Transactional public void importOdmToOC(ODM odm) { UserAccount userAccount = getCurrentUser(); // TODO add validation to all entities ODMcomplexTypeDefinitionStudy odmStudy = odm.getStudy().get(0); Study study = saveOrUpdateStudy(odm, userAccount, odmStudy); ParticipantPortalRegistrar portal = new ParticipantPortalRegistrar(); portal.registerStudy(study.getOc_oid(), study.getOc_oid(), study.getName()); StudyParameterValue spv = getStudyParameterValueDao().findByStudyIdParameter(study.getStudyId(), "participantPortal"); // Update OC Study configuration if (spv == null) { spv = new StudyParameterValue(); spv.setStudy(study); } spv.setValue("enabled"); spv = getStudyParameterValueDao().saveOrUpdate(spv); StudyUserRole studyUserRole = null; StudyUserRoleId studyUserRoleId = null; Crf[] fmCrfs = getCrfsFromFormManager(study); ArrayList<StudyUserRole> surRoles = getStudyUserRoleDao().findAllUserRolesByUserAccount(userAccount, study.getStudyId(), study.getStudyId()); if (surRoles.size() == 0) { studyUserRoleId = new StudyUserRoleId(); studyUserRole = new StudyUserRole(); studyUserRole = getStudyUserRoleDao().saveOrUpdate(populateUserRole(study, userAccount, studyUserRole, studyUserRoleId)); } StudyEventDefinition studyEventDefinition = null; List<ODMcomplexTypeDefinitionMetaDataVersion> odmMetadataVersions = odmStudy.getMetaDataVersion(); List<ODMcomplexTypeDefinitionStudyEventDef> odmStudyEventDefs = saveOrUpdateEvent(userAccount, study, odmMetadataVersions); CrfBean crf = null; CrfVersion crfVersion = null; saveOrUpdateCrf(userAccount, study, odmMetadataVersions, fmCrfs); List<ODMcomplexTypeDefinitionStudyEventRef> odmStudyEventRefs = odmMetadataVersions.get(0).getProtocol().getStudyEventRef(); for (ODMcomplexTypeDefinitionStudyEventRef odmStudyEventRef : odmStudyEventRefs) { for (ODMcomplexTypeDefinitionStudyEventDef odmStudyEventDef : odmStudyEventDefs) { if (odmStudyEventDef.getOID().equals(odmStudyEventRef.getStudyEventOID())) { studyEventDefinition = getStudyEventDefDao().findByOcOID(odmStudyEventDef.getOID()); studyEventDefinition.setOrdinal(odmStudyEventRef.getOrderNumber().intValue()); studyEventDefinition = getStudyEventDefDao().saveOrUpdate(studyEventDefinition); List<EventDefinitionCrf> jsonEventDefCrfList = new ArrayList<>(); EventDefinitionCrf eventDefinitionCrf = null; for (ODMcomplexTypeDefinitionFormRef odmFormRef : odmStudyEventDef.getFormRef()) { crf = getCrfDao().findByOcOID(odmFormRef.getFormOID()); eventDefinitionCrf = getEventDefinitionCrfDao().findByStudyEventDefinitionIdAndCRFIdAndStudyId( studyEventDefinition.getStudyEventDefinitionId(), crf.getCrfId(), study.getStudyId()); String defaultVersionOid = null; OCodmComplexTypeDefinitionConfigurationParameters conf = odmFormRef.getConfigurationParameters(); List<OCodmComplexTypeDefinitionFormLayoutRef> formLayoutRefs = odmFormRef.getFormLayoutRef(); if (formLayoutRefs.size() == 1 && formLayoutRefs.get(0).getIsDefaultVersion() == null) { defaultVersionOid = formLayoutRefs.get(0).getOID(); } else { for (OCodmComplexTypeDefinitionFormLayoutRef formLayoutRef : formLayoutRefs) { if (formLayoutRef.getIsDefaultVersion().equalsIgnoreCase("Yes")) { defaultVersionOid = formLayoutRef.getOID(); } } } if (defaultVersionOid == null) { defaultVersionOid = formLayoutRefs.get(0).getOID(); } crfVersion = getCrfVersionDao().findByOcOID(defaultVersionOid); PopulateEventDefinitionCrfParameter paramObj = new PopulateEventDefinitionCrfParameter(); paramObj.setUserAccount(userAccount); paramObj.setConf(conf); paramObj.setCrf(crf); paramObj.setEventDefinitionCrf(eventDefinitionCrf); paramObj.setOdmFormRef(odmFormRef); paramObj.setStudy(study); paramObj.setCrfVersion(crfVersion); paramObj.setStudyEventDefinition(studyEventDefinition); PopulateEDCTagParameter populateEDCTagParameter = new PopulateEDCTagParameter(); populateEDCTagParameter.setConf(conf); populateEDCTagParameter.setEventDefinitionCrf(eventDefinitionCrf); populateEDCTagParameter.setUserAccount(userAccount); eventDefinitionCrf = saveOrUpdateEventDefnCrf(new PopulateEventDefinitionCrfParameter(paramObj)); saveOrUpdateEDCTag(new PopulateEDCTagParameter(populateEDCTagParameter), studyEventDefinition, crf); jsonEventDefCrfList.add(eventDefinitionCrf); } List<EventDefinitionCrf> ocEventDefCrfList = getEventDefinitionCrfDao() .findAvailableByStudyEventDefStudy(studyEventDefinition.getStudyEventDefinitionId(), study.getStudyId()); for (EventDefinitionCrf ocEventDefCrf : ocEventDefCrfList) { if (!jsonEventDefCrfList.contains(ocEventDefCrf)) { ocEventDefCrf.setStatusId(Status.DELETED.getCode()); getEventDefinitionCrfDao().saveOrUpdate(ocEventDefCrf); } } } } } } private void saveOrUpdateEDCTag(PopulateEDCTagParameter paramObj, StudyEventDefinition studyEventDefinition, CrfBean crf) { EventDefinitionCrfTag eventDefinitionCrfTag; int tagId = 2; // Offline String crfPath = studyEventDefinition.getOc_oid() + "." + crf.getOcOid(); eventDefinitionCrfTag = getEventDefinitionCrfTagDao().findByCrfPathAndTagId(tagId, crfPath); paramObj.setTagId(tagId); paramObj.setCrfPath(crfPath); if (eventDefinitionCrfTag == null) { eventDefinitionCrfTag = new EventDefinitionCrfTag(); paramObj.setEventDefinitionCrfTag(eventDefinitionCrfTag); eventDefinitionCrfTag = getEventDefinitionCrfTagDao().saveOrUpdate(populateEDCTag(new PopulateEDCTagParameter(paramObj))); } else { paramObj.setEventDefinitionCrfTag(eventDefinitionCrfTag); eventDefinitionCrfTag = getEventDefinitionCrfTagDao().saveOrUpdate(updateEDCTag(new PopulateEDCTagParameter(paramObj))); } } private EventDefinitionCrf saveOrUpdateEventDefnCrf(PopulateEventDefinitionCrfParameter paramObj) { EventDefinitionCrf eventDefinitionCrf = paramObj.getEventDefinitionCrf(); if (eventDefinitionCrf == null) { eventDefinitionCrf = new EventDefinitionCrf(); paramObj.setEventDefinitionCrf(eventDefinitionCrf); eventDefinitionCrf = getEventDefinitionCrfDao().saveOrUpdate(populateEventDefinitionCrf(new PopulateEventDefinitionCrfParameter(paramObj))); } else { eventDefinitionCrf = getEventDefinitionCrfDao().saveOrUpdate(updateEventDefinitionCrf(new PopulateEventDefinitionCrfParameter(paramObj))); } return eventDefinitionCrf; } private void saveOrUpdateCrf(UserAccount userAccount, Study study, List<ODMcomplexTypeDefinitionMetaDataVersion> odmMetadataVersions, Crf[] fmCrfs) { CrfBean crf; CrfVersion version; for (ODMcomplexTypeDefinitionFormDef odmFormDef : odmMetadataVersions.get(0).getFormDef()) { crf = getCrfDao().findByOcOID(odmFormDef.getOID()); if (crf == null) { crf = new CrfBean(); crf.setOcOid(odmFormDef.getOID()); crf = getCrfDao().saveOrUpdate(populateCrf(odmFormDef, userAccount, crf, study)); } else { crf = getCrfDao().saveOrUpdate(updateCrf(odmFormDef, userAccount, crf, study)); } version = saveOrUpdateCrfVersion(userAccount, crf, odmFormDef, fmCrfs); if (version.getXform() != null) { try { parseCrfVersion(crf, version, study, userAccount); } catch (Exception e) { e.printStackTrace(); } } } } private CrfVersion saveOrUpdateCrfVersion(UserAccount userAccount, CrfBean crf, ODMcomplexTypeDefinitionFormDef odmFormDef, Crf[] fmCrfs) { CrfVersion crfVersion = null; List<OCodmComplexTypeDefinitionFormLayoutDef> formLayoutDefs = odmFormDef.getFormLayoutDef(); for (OCodmComplexTypeDefinitionFormLayoutDef formLayoutDef : formLayoutDefs) { crfVersion = getCrfVersionDao().findByOcOID(formLayoutDef.getOID()); String url = formLayoutDef.getURL(); PopulateCrfVersionParameter populateCrfVersionParameter = new PopulateCrfVersionParameter(); populateCrfVersionParameter.setCrf(crf); populateCrfVersionParameter.setFmCrfs(fmCrfs); populateCrfVersionParameter.setOdmFormDef(odmFormDef); populateCrfVersionParameter.setUserAccount(userAccount); populateCrfVersionParameter.setUrl(url); if (crfVersion == null) { crfVersion = new CrfVersion(); crfVersion.setOcOid(formLayoutDef.getOID()); populateCrfVersionParameter.setCrfVersion(crfVersion); crfVersion = getCrfVersionDao().saveOrUpdate(populateCrfVersion(new PopulateCrfVersionParameter(populateCrfVersionParameter))); } else { populateCrfVersionParameter.setCrfVersion(crfVersion); crfVersion = getCrfVersionDao().saveOrUpdate(updateCrfVersion(new PopulateCrfVersionParameter(populateCrfVersionParameter))); } } return crfVersion; } private List<ODMcomplexTypeDefinitionStudyEventDef> saveOrUpdateEvent(UserAccount userAccount, Study study, List<ODMcomplexTypeDefinitionMetaDataVersion> odmMetadataVersions) { StudyEventDefinition studyEventDefinition; List<ODMcomplexTypeDefinitionStudyEventDef> odmStudyEventDefs = odmMetadataVersions.get(0).getStudyEventDef(); List<StudyEventDefinition> jsonEventList = new ArrayList<>(); for (ODMcomplexTypeDefinitionStudyEventDef odmStudyEventDef : odmStudyEventDefs) { studyEventDefinition = getStudyEventDefDao().findByOcOID(odmStudyEventDef.getOID()); if (studyEventDefinition == null || studyEventDefinition.getStudyEventDefinitionId() == 0) { studyEventDefinition = new StudyEventDefinition(); studyEventDefinition.setOc_oid(odmStudyEventDef.getOID()); studyEventDefinition = getStudyEventDefDao().saveOrUpdate(populateEvent(odmStudyEventDef, userAccount, studyEventDefinition, study)); } else { studyEventDefinition = getStudyEventDefDao().saveOrUpdate(updateEvent(odmStudyEventDef, userAccount, studyEventDefinition, study)); } jsonEventList.add(studyEventDefinition); } List<StudyEventDefinition> ocEventList = getStudyEventDefDao().findAll(); // findAllNonRemovedEvents for (StudyEventDefinition ocEvent : ocEventList) { if (!jsonEventList.contains(ocEvent)) { ocEvent.setStatus(Status.DELETED); getStudyEventDefDao().saveOrUpdate(ocEvent); } } return odmStudyEventDefs; } private Study saveOrUpdateStudy(ODM odm, UserAccount userAccount, ODMcomplexTypeDefinitionStudy odmStudy) { ODMcomplexTypeDefinitionGlobalVariables odmGlobalVariables = odmStudy.getGlobalVariables(); String studyOid = odm.getStudy().get(0).getOID(); Study study = getStudyDao().findByOcOID(studyOid); if (study == null || study.getStudyId() == 0) { study = new Study(); study.setOc_oid(studyOid); study = getStudyDao().saveOrUpdate(populateStudy(odmGlobalVariables, userAccount, study)); } else { study = getStudyDao().saveOrUpdate(updateStudy(odmGlobalVariables, userAccount, study)); } return study; } private Study populateStudy(ODMcomplexTypeDefinitionGlobalVariables odmGlobalVariables, UserAccount userAccount, Study study) { study.setUniqueIdentifier(odmGlobalVariables.getProtocolName().getValue()); study.setName(odmGlobalVariables.getStudyName().getValue()); // study.setSummary(odmGlobalVariables.getStudyDescription().getValue()); study.setSummary("This is the summary"); study.setStatus(org.akaza.openclinica.domain.Status.AVAILABLE); study.setUserAccount(userAccount); study.setDateCreated(new Date()); return study; } private Study updateStudy(ODMcomplexTypeDefinitionGlobalVariables odmGlobalVariables, UserAccount userAccount, Study study) { study = populateStudy(odmGlobalVariables, userAccount, study); study.setUpdateId(userAccount.getUserId()); study.setDateUpdated(new Date()); return study; } private StudyUserRole populateUserRole(Study study, UserAccount userAccount, StudyUserRole sur, StudyUserRoleId surId) { surId.setUserName(userAccount.getUserName()); surId.setRoleName(Role.STUDYDIRECTOR.getName()); surId.setStudyId(study.getStudyId()); surId.setStatusId(1); surId.setOwnerId(userAccount.getUserId()); surId.setDateCreated(new Date()); sur.setId(surId); return sur; } private StudyEventDefinition populateEvent(ODMcomplexTypeDefinitionStudyEventDef odmStudyEventDef, UserAccount userAccount, StudyEventDefinition studyEventDefinition, Study study) { studyEventDefinition.setName(odmStudyEventDef.getName()); if (odmStudyEventDef.getRepeating().value().equalsIgnoreCase("Yes")) { studyEventDefinition.setRepeating(true); } else { studyEventDefinition.setRepeating(false); } studyEventDefinition.setType(EventType.SCHEDULED.value().toLowerCase()); studyEventDefinition.setStudy(study); studyEventDefinition.setUserAccount(userAccount); studyEventDefinition.setStatus(org.akaza.openclinica.domain.Status.AVAILABLE); // studyEventDefinition.setType(odmStudyEventDef.getType().value()); if (odmStudyEventDef.getStudyEventDefElementExtension().size() != 0) { OCodmComplexTypeDefinitionEventDefinitionDetails eventDetails = odmStudyEventDef.getStudyEventDefElementExtension().get(0); if (eventDetails != null && eventDetails.getCategory() != null) { studyEventDefinition.setCategory(eventDetails.getCategory()); } if (eventDetails != null && eventDetails.getDescription() != null) { studyEventDefinition.setDescription(eventDetails.getDescription()); } } return studyEventDefinition; } private StudyEventDefinition updateEvent(ODMcomplexTypeDefinitionStudyEventDef odmStudyEventDef, UserAccount userAccount, StudyEventDefinition studyEventDefinition, Study study) { studyEventDefinition = populateEvent(odmStudyEventDef, userAccount, studyEventDefinition, study); studyEventDefinition.setUpdateId(userAccount.getUserId()); studyEventDefinition.setDateUpdated(new Date()); return studyEventDefinition; } private CrfBean populateCrf(ODMcomplexTypeDefinitionFormDef odmFormDef, UserAccount userAccount, CrfBean crf, Study study) { crf.setStudy(study); crf.setName(odmFormDef.getName()); crf.setUserAccount(userAccount); crf.setStatus(org.akaza.openclinica.domain.Status.AVAILABLE); return crf; } private CrfBean updateCrf(ODMcomplexTypeDefinitionFormDef odmFormDef, UserAccount userAccount, CrfBean crf, Study study) { crf = populateCrf(odmFormDef, userAccount, crf, study); crf.setUpdateId(userAccount.getUserId()); crf.setDateUpdated(new Date()); return crf; } private CrfVersion populateCrfVersion(PopulateCrfVersionParameter paramObj) { for (Crf fmCrf : paramObj.getFmCrfs()) { if (fmCrf.getOcoid().equals(paramObj.getCrf().getOcOid())) { for (Version version : fmCrf.getVersions()) { if (version.getOcoid().equals(paramObj.getCrfVersion().getOcOid())) { paramObj.getCrfVersion().setDescription("Description"); paramObj.getCrfVersion().setRevisionNotes("Revision"); paramObj.getCrfVersion().setName(version.getName()); if (version.getFileLinks() != null) { List<FileItem> fileItems = new ArrayList<>(); for (String fileLink : version.getFileLinks()) { if (fileLink.endsWith(".xml")) { paramObj.getCrfVersion().setXform(getXFormFromFormManager(fileLink)); paramObj.getCrfVersion().setXformName("default"); } FileItem fileItem = getMediaFileItemFromFormManager(fileLink, paramObj.getCrf(), paramObj.getCrfVersion()); fileItems.add(fileItem); } paramObj.getCrfVersion().setFileItems(fileItems); } } } } } paramObj.getCrfVersion().setCrf(paramObj.getCrf()); paramObj.getCrfVersion().setUrl(paramObj.getUrl()); paramObj.getCrfVersion().setUserAccount(paramObj.getUserAccount()); paramObj.getCrfVersion().setStatus(org.akaza.openclinica.domain.Status.AVAILABLE); return paramObj.getCrfVersion(); } private CrfVersion updateCrfVersion(PopulateCrfVersionParameter paramObj) { CrfVersion crfVersion = paramObj.getCrfVersion(); crfVersion = populateCrfVersion(new PopulateCrfVersionParameter(paramObj)); crfVersion.setUpdateId(paramObj.getUserAccount().getUserId()); crfVersion.setDateUpdated(new Date()); return crfVersion; } private UserAccount getCurrentUser() { UserAccount ub = getUserAccountDao().findById(1); return ub; } private EventDefinitionCrf populateEventDefinitionCrf(PopulateEventDefinitionCrfParameter paramObj) { paramObj.getEventDefinitionCrf().setStudy(paramObj.getStudy()); paramObj.getEventDefinitionCrf().setStudyEventDefinition(paramObj.getStudyEventDefinition()); paramObj.getEventDefinitionCrf().setCrf(paramObj.getCrf()); paramObj.getEventDefinitionCrf().setStatusId(org.akaza.openclinica.domain.Status.AVAILABLE.getCode()); paramObj.getEventDefinitionCrf().setUserAccount(paramObj.getUserAccount()); paramObj.getEventDefinitionCrf().setCrfVersion(paramObj.getCrfVersion()); setConfigurationProperties(paramObj.getConf(), paramObj.getEventDefinitionCrf()); if (paramObj.getOdmFormRef().getMandatory().equals(YesOrNo.YES)) { paramObj.getEventDefinitionCrf().setRequiredCrf(true); } else { paramObj.getEventDefinitionCrf().setRequiredCrf(false); } return paramObj.getEventDefinitionCrf(); } private EventDefinitionCrf updateEventDefinitionCrf(PopulateEventDefinitionCrfParameter paramObj) { EventDefinitionCrf eventDefinitionCrf = paramObj.getEventDefinitionCrf(); eventDefinitionCrf = populateEventDefinitionCrf(new PopulateEventDefinitionCrfParameter(paramObj)); eventDefinitionCrf.setUpdateId(paramObj.getUserAccount().getUserId()); eventDefinitionCrf.setDateUpdated(new Date()); return eventDefinitionCrf; } private EventDefinitionCrf setConfigurationProperties(OCodmComplexTypeDefinitionConfigurationParameters conf, EventDefinitionCrf eventDefinitionCrf) { if (conf.getAllowAnonymousSubmission().equalsIgnoreCase("Yes")) { eventDefinitionCrf.setAllowAnonymousSubmission(true); } else { eventDefinitionCrf.setAllowAnonymousSubmission(false); } if (conf.getParticipantForm().equalsIgnoreCase("Yes")) { eventDefinitionCrf.setParicipantForm(true); } else { eventDefinitionCrf.setParicipantForm(false); } if (conf.getHideCRF().equalsIgnoreCase("Yes")) { eventDefinitionCrf.setHideCrf(true); } else { eventDefinitionCrf.setHideCrf(false); } return eventDefinitionCrf; } private EventDefinitionCrfTag populateEDCTag(PopulateEDCTagParameter paramObj) { if (paramObj.getConf().getOffline().equalsIgnoreCase("Yes")) { paramObj.getEventDefinitionCrfTag().setActive(true); } else { paramObj.getEventDefinitionCrfTag().setActive(false); } paramObj.getEventDefinitionCrfTag().setTagId(paramObj.getTagId()); paramObj.getEventDefinitionCrfTag().setPath(paramObj.getCrfPath()); paramObj.getEventDefinitionCrfTag().setDateCreated(new Date()); paramObj.getEventDefinitionCrfTag().setUserAccount(paramObj.getUserAccount()); return paramObj.getEventDefinitionCrfTag(); } private EventDefinitionCrfTag updateEDCTag(PopulateEDCTagParameter paramObj) { EventDefinitionCrfTag eventDefinitionCrfTag = paramObj.getEventDefinitionCrfTag(); eventDefinitionCrfTag = populateEDCTag(new PopulateEDCTagParameter(paramObj)); eventDefinitionCrfTag.setUpdateId(paramObj.getUserAccount().getUserId()); eventDefinitionCrfTag.setDateUpdated(new Date()); return eventDefinitionCrfTag; } public UserAccountDao getUserAccountDao() { return userAccountDao; } public void setUserAccountDao(UserAccountDao userAccountDao) { this.userAccountDao = userAccountDao; } public StudyUserRoleDao getStudyUserRoleDao() { return studyUserRoleDao; } public void setStudyUserRoleDao(StudyUserRoleDao studyUserRoleDao) { this.studyUserRoleDao = studyUserRoleDao; } public StudyEventDefinitionDao getStudyEventDefDao() { return studyEventDefDao; } public void setStudyEventDefDao(StudyEventDefinitionDao studyEventDefDao) { this.studyEventDefDao = studyEventDefDao; } public EventDefinitionCrfDao getEventDefinitionCrfDao() { return eventDefinitionCrfDao; } public void setEventDefinitionCrfDao(EventDefinitionCrfDao eventDefinitionCrfDao) { this.eventDefinitionCrfDao = eventDefinitionCrfDao; } public CrfDao getCrfDao() { return crfDao; } public void setCrfDao(CrfDao crfDao) { this.crfDao = crfDao; } public CrfVersionDao getCrfVersionDao() { return crfVersionDao; } public void setCrfVersionDao(CrfVersionDao crfVersionDao) { this.crfVersionDao = crfVersionDao; } public StudyDao getStudyDao() { return studyDao; } public void setStudyDao(StudyDao studyDao) { this.studyDao = studyDao; } public EventDefinitionCrfTagDao getEventDefinitionCrfTagDao() { return eventDefinitionCrfTagDao; } public void setEventDefinitionCrfTagDao(EventDefinitionCrfTagDao eventDefinitionCrfTagDao) { this.eventDefinitionCrfTagDao = eventDefinitionCrfTagDao; } public XformParser getXformParser() { return xformParser; } public void setXformParser(XformParser xformParser) { this.xformParser = xformParser; } public XformMetaDataService getXformService() { return xformService; } public void setXformService(XformMetaDataService xformService) { this.xformService = xformService; } public StudyParameterValueDao getStudyParameterValueDao() { return studyParameterValueDao; } public void setStudyParameterValueDao(StudyParameterValueDao studyParameterValueDao) { this.studyParameterValueDao = studyParameterValueDao; } public Crf[] getCrfsFromFormManager(Study study) { String protocolId = study.getUniqueIdentifier(); String url = "http://fm.openclinica.info:8080/api/protocol/" + protocolId + "/forms"; RestTemplate restTemplate = new RestTemplate(); Crf[] crfs = null; try { crfs = (Crf[]) restTemplate.getForObject(url, Crf[].class); } catch (Exception e) { logger.info(e.getMessage()); } return crfs; } public FileItem getMediaFileItemFromFormManager(String fileLink, CrfBean crf, CrfVersion crfVersion) { RestTemplate restTemplate = new RestTemplate(); restTemplate.getMessageConverters().add(new ByteArrayHttpMessageConverter()); HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM)); HttpEntity<String> entity = new HttpEntity<String>(headers); ResponseEntity<byte[]> response = restTemplate.exchange(fileLink, HttpMethod.GET, entity, byte[].class, "1"); FileItem fileItem = null; if (response.getStatusCode() == HttpStatus.OK) { String fileName = ""; FileOutputStream output = null; try { String disposition = response.getHeaders().get("Content-Disposition").get(0); fileName = disposition.replaceFirst("(?i)^.*filename=\"([^\"]+)\".*$", "$1"); String dir = Utils.getCrfMediaFilePath(crf, crfVersion); if (!new File(dir).exists()) { new File(dir).mkdirs(); logger.debug("Made the directory " + dir); } File file = new File(dir + fileName); output = new FileOutputStream(file); IOUtils.write(response.getBody(), output); fileItem = new DiskFileItem("media_file", response.getHeaders().get("Content-Type").get(0), false, fileName, 100000000, file); } catch (IOException e) { e.printStackTrace(); } finally { try { if (output != null) { output.close(); } } catch (IOException e) { e.printStackTrace(); } } } return fileItem; } public File getMediaFilesFromFormManagerOrig(String fileLink) { File file = null; RestTemplate restTemplate = new RestTemplate(); try { file = restTemplate.getForObject(fileLink, File.class); } catch (Exception e) { logger.info(e.getMessage()); } return file; } public String getXFormFromFormManager(String fileLink) { String xform = ""; RestTemplate restTemplate = new RestTemplate(); try { xform = restTemplate.getForObject(fileLink, String.class); } catch (Exception e) { logger.info(e.getMessage()); } return xform; } private void parseCrfVersion(CrfBean crf, CrfVersion version, Study study, UserAccount userAccount) throws Exception { String submittedCrfName = crf.getName(); String submittedCrfVersionName = version.getName(); String submittedCrfVersionDescription = version.getDescription(); String submittedRevisionNotes = version.getRevisionNotes(); String submittedXformText = version.getXform(); // Create container for holding validation errors DataBinder dataBinder = new DataBinder(new CrfVersion()); Errors errors = dataBinder.getBindingResult(); // Validate all upload form fields were populated CRFVersionBean crfVersion = new CRFVersionBean(); crfVersion.setOid(version.getOcOid()); crfVersion.setCrfId(version.getCrf().getCrfId()); ValidateFormFieldsParameter validateFormFieldsParameter = new ValidateFormFieldsParameter(); validateFormFieldsParameter.setErrors(errors); validateFormFieldsParameter.setSubmittedCrfName(submittedCrfName); validateFormFieldsParameter.setSubmittedCrfVersionDescription(submittedCrfVersionDescription); validateFormFieldsParameter.setSubmittedCrfVersionName(submittedCrfVersionName); validateFormFieldsParameter.setSubmittedRevisionNotes(submittedRevisionNotes); validateFormFieldsParameter.setSubmittedXformText(submittedXformText); validateFormFieldsParameter.setVersion(crfVersion); validateFormFields(validateFormFieldsParameter); if (!errors.hasErrors()) { // Parse instance and xform XformContainer container = parseInstance(submittedXformText); Html html = xformParser.unMarshall(submittedXformText); List<FileItem> items = version.getFileItems(); StudyBean currentStudy = new StudyBean(); currentStudy.setId(study.getStudyId()); UserAccountBean ub = new UserAccountBean(); ub.setId(userAccount.getUserId()); ub.setActiveStudyId(currentStudy.getId()); // Save meta-data in database try { xformService.createCRFMetaData(crfVersion, container, currentStudy, ub, html, submittedCrfName, submittedCrfVersionName, submittedCrfVersionDescription, submittedRevisionNotes, submittedXformText, items, errors); } catch (Exception e) { e.printStackTrace(); } } } private XformContainer parseInstance(String xform) throws Exception { // Could use the following xpath to get all leaf nodes in the case // of multiple levels of groups: //*[count(./*) = 0] // For now will assume a structure of /form/item or /form/group/item Document doc = null; try { InputStream stream = new ByteArrayInputStream(xform.getBytes(StandardCharsets.UTF_8)); doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(stream); NodeList instances = doc.getElementsByTagName("instance"); // All whitespace outside tags gets parsed as Text objects and returned // by the various Node methods. We need to ignore these and // focus on actual Elements Element instance = null; // List<XformItem> items = new ArrayList<XformItem>(); List<XformGroup> groups = new ArrayList<XformGroup>(); // Get the primary instance for (int i = 0; i < instances.getLength(); i++) { Element curInstance = (Element) instances.item(i); if (curInstance instanceof Element) { instance = curInstance; break; } } // Get the form element Element form = null; for (int i = 0; i < instance.getChildNodes().getLength(); i++) { Node curNode = instance.getChildNodes().item(i); if (curNode instanceof Element) { form = (Element) curNode; break; } } // Get the groups and grouped items for (int i = 0; i < form.getChildNodes().getLength(); i++) { if (form.getChildNodes().item(i) instanceof Element && ((Element) form.getChildNodes().item(i)).hasChildNodes() && !((Element) form.getChildNodes().item(i)).getTagName().equals("meta")) { Element group = (Element) form.getChildNodes().item(i); XformGroup newGroup = new XformGroup(); newGroup.setGroupName(group.getTagName()); newGroup.setGroupPath("/" + form.getTagName() + "/" + group.getTagName()); groups.add(newGroup); for (int j = 0; j < group.getChildNodes().getLength(); j++) { if (group.getChildNodes().item(j) instanceof Element) { Element item = (Element) group.getChildNodes().item(j); XformItem newItem = new XformItem(); newItem.setItemPath("/" + form.getTagName() + "/" + group.getTagName() + "/" + item.getTagName()); newItem.setItemName(item.getTagName()); // group is null; newGroup.getItems().add(newItem); } } } } XformContainer container = new XformContainer(); container.setGroups(groups); container.setInstanceName(form.getTagName()); return container; } catch (Exception e) { logger.error(e.getMessage()); logger.error(ExceptionUtils.getStackTrace(e)); throw new Exception(e); } } private void validateFormFields(ValidateFormFieldsParameter paramObj) { // Verify CRF Name is populated if (paramObj.getVersion().getCrfId() == 0 && (paramObj.getSubmittedCrfName() == null || paramObj.getSubmittedCrfName().equals(""))) { DataBinder crfDataBinder = new DataBinder(new CrfBean()); Errors crfErrors = crfDataBinder.getBindingResult(); crfErrors.rejectValue("name", "crf_val_crf_name_blank", "CRF Name"); paramObj.getErrors().addAllErrors(crfErrors); } DataBinder crfVersionDataBinder = new DataBinder(new CrfVersion()); Errors crfVersionErrors = crfVersionDataBinder.getBindingResult(); // Verify CRF Version Name is populated if (paramObj.getSubmittedCrfVersionName() == null || paramObj.getSubmittedCrfVersionName().equals("")) { crfVersionErrors.rejectValue("name", "crf_ver_val_name_blank", "Version Name"); } // Verify CRF Version Description is populated if (paramObj.getSubmittedCrfVersionDescription() == null || paramObj.getSubmittedCrfVersionDescription().equals("")) { crfVersionErrors.rejectValue("description", "crf_ver_val_desc_blank", "Version Description"); } // Verify CRF Version Revision Notes is populated if (paramObj.getSubmittedRevisionNotes() == null || paramObj.getSubmittedRevisionNotes().equals("")) { crfVersionErrors.rejectValue("revisionNotes", "crf_ver_val_rev_notes_blank", "Revision Notes"); } // Verify Xform text is populated if (paramObj.getSubmittedXformText() == null || paramObj.getSubmittedXformText().equals("")) { crfVersionErrors.rejectValue("xform", "crf_ver_val_xform_blank", "Xform"); } paramObj.getErrors().addAllErrors(crfVersionErrors); } }