diff --git a/src/main/java/org/broadinstitute/consent/http/models/draft/AccessManagement.java b/src/main/java/org/broadinstitute/consent/http/models/draft/AccessManagement.java new file mode 100644 index 0000000000..ba52129f69 --- /dev/null +++ b/src/main/java/org/broadinstitute/consent/http/models/draft/AccessManagement.java @@ -0,0 +1,22 @@ +package org.broadinstitute.consent.http.models.draft; + +public enum AccessManagement { + OPEN("open"), + CONTROLLED("controlled"), + EXTERNAL("external"); + private final String value; + + AccessManagement(String value) { + this.value = value; + } + + @Override + public String toString() { + return this.value; + } + + public String value() { + return this.value; + } + +} diff --git a/src/main/java/org/broadinstitute/consent/http/models/draft/AlternativeDataSharingPlanAccessManagement.java b/src/main/java/org/broadinstitute/consent/http/models/draft/AlternativeDataSharingPlanAccessManagement.java new file mode 100644 index 0000000000..18d0848cca --- /dev/null +++ b/src/main/java/org/broadinstitute/consent/http/models/draft/AlternativeDataSharingPlanAccessManagement.java @@ -0,0 +1,22 @@ +package org.broadinstitute.consent.http.models.draft; + +public enum AlternativeDataSharingPlanAccessManagement { + CONTROLLED_ACCESS("Controlled Access"), + OPEN_ACCESS("Open Access"), + EXTERNAL_ACCESS("External Access"); + private final String value; + + AlternativeDataSharingPlanAccessManagement(String value) { + this.value = value; + } + + @Override + public String toString() { + return this.value; + } + + public String value() { + return this.value; + } + +} diff --git a/src/main/java/org/broadinstitute/consent/http/models/draft/AlternativeDataSharingPlanDataSubmitted.java b/src/main/java/org/broadinstitute/consent/http/models/draft/AlternativeDataSharingPlanDataSubmitted.java new file mode 100644 index 0000000000..1ff8f7641b --- /dev/null +++ b/src/main/java/org/broadinstitute/consent/http/models/draft/AlternativeDataSharingPlanDataSubmitted.java @@ -0,0 +1,24 @@ +package org.broadinstitute.consent.http.models.draft; + +public enum AlternativeDataSharingPlanDataSubmitted { + + WITHIN_3_MONTHS_OF_THE_LAST_DATA_GENERATED_OR_LAST_CLINICAL_VISIT( + "Within 3 months of the last data generated or last clinical visit"), + BY_BATCHES_OVER_STUDY_TIMELINE_E_G_BASED_ON_CLINICAL_TRIAL_ENROLLMENT_BENCHMARKS( + "By batches over Study Timeline (e.g. based on clinical trial enrollment benchmarks)"); + private final String value; + + AlternativeDataSharingPlanDataSubmitted(String value) { + this.value = value; + } + + @Override + public String toString() { + return this.value; + } + + public String value() { + return this.value; + } + +} diff --git a/src/main/java/org/broadinstitute/consent/http/models/draft/AlternativeDataSharingPlanReason.java b/src/main/java/org/broadinstitute/consent/http/models/draft/AlternativeDataSharingPlanReason.java new file mode 100644 index 0000000000..36eb06a9d4 --- /dev/null +++ b/src/main/java/org/broadinstitute/consent/http/models/draft/AlternativeDataSharingPlanReason.java @@ -0,0 +1,31 @@ +package org.broadinstitute.consent.http.models.draft; + +public enum AlternativeDataSharingPlanReason { + + LEGAL_RESTRICTIONS("Legal Restrictions"), + INFORMED_CONSENT_PROCESSES_ARE_INADEQUATE_TO_SUPPORT_DATA_FOR_SHARING_FOR_THE_FOLLOWING_REASONS( + "Informed consent processes are inadequate to support data for sharing for the following reasons:"), + THE_CONSENT_FORMS_ARE_UNAVAILABLE_OR_NON_EXISTENT_FOR_SAMPLES_COLLECTED_AFTER_JANUARY_25_2015( + "The consent forms are unavailable or non-existent for samples collected after January 25, 2015"), + THE_CONSENT_PROCESS_DID_NOT_SPECIFICALLY_ADDRESS_FUTURE_USE_OR_BROAD_DATA_SHARING_FOR_SAMPLES_COLLECTED_AFTER_JANUARY_25_2015( + "The consent process did not specifically address future use or broad data sharing for samples collected after January 25, 2015"), + THE_CONSENT_PROCESS_INADEQUATELY_ADDRESSES_RISKS_RELATED_TO_FUTURE_USE_OR_BROAD_DATA_SHARING_FOR_SAMPLES_COLLECTED_AFTER_JANUARY_25_2015( + "The consent process inadequately addresses risks related to future use or broad data sharing for samples collected after January 25, 2015"), + THE_CONSENT_PROCESS_SPECIFICALLY_PRECLUDES_FUTURE_USE_OR_BROAD_DATA_SHARING_INCLUDING_A_STATEMENT_THAT_USE_OF_DATA_WILL_BE_LIMITED_TO_THE_ORIGINAL_RESEARCHERS( + "The consent process specifically precludes future use or broad data sharing (including a statement that use of data will be limited to the original researchers)"), + OTHER_INFORMED_CONSENT_LIMITATIONS_OR_CONCERNS("Other informed consent limitations or concerns"), + OTHER("Other"); + private final String value; + AlternativeDataSharingPlanReason(String value) { + this.value = value; + } + + @Override + public String toString() { + return this.value; + } + + public String value() { + return this.value; + } +} diff --git a/src/main/java/org/broadinstitute/consent/http/models/draft/ConsentGroup.java b/src/main/java/org/broadinstitute/consent/http/models/draft/ConsentGroup.java new file mode 100644 index 0000000000..4c0bf43b20 --- /dev/null +++ b/src/main/java/org/broadinstitute/consent/http/models/draft/ConsentGroup.java @@ -0,0 +1,31 @@ +package org.broadinstitute.consent.http.models.draft; + +import java.net.URI; +import java.util.List; + +public record ConsentGroup( + Integer datasetId, + String datasetIdentifier, + String consentGroupName, + AccessManagement accessManagement, + Boolean generalResearchUse, + Boolean hmb, + List diseaseSpecificUse, + Boolean poa, + String otherPrimary, + Boolean nmds, + Boolean gso, + Boolean pub, + Boolean col, + Boolean irb, + String gs, + Boolean mor, + String morDate, + Boolean npu, + String otherSecondary, + Integer dataAccessCommitteeId, + DataLocation dataLocation, + URI url, + Integer numberOfParticipants, + List fileTypes +) {} diff --git a/src/main/java/org/broadinstitute/consent/http/models/draft/DataLocation.java b/src/main/java/org/broadinstitute/consent/http/models/draft/DataLocation.java new file mode 100644 index 0000000000..4bcbc62c36 --- /dev/null +++ b/src/main/java/org/broadinstitute/consent/http/models/draft/DataLocation.java @@ -0,0 +1,24 @@ +package org.broadinstitute.consent.http.models.draft; + +public enum DataLocation { + + AN_VIL_WORKSPACE("AnVIL Workspace"), + TERRA_WORKSPACE("Terra Workspace"), + TDR_LOCATION("TDR Location"), + NOT_DETERMINED("Not Determined"); + private final String value; + + DataLocation(String value) { + this.value = value; + } + + @Override + public String toString() { + return this.value; + } + + public String value() { + return this.value; + } + +} diff --git a/src/main/java/org/broadinstitute/consent/http/models/draft/FileType.java b/src/main/java/org/broadinstitute/consent/http/models/draft/FileType.java new file mode 100644 index 0000000000..27b17e333d --- /dev/null +++ b/src/main/java/org/broadinstitute/consent/http/models/draft/FileType.java @@ -0,0 +1,25 @@ +package org.broadinstitute.consent.http.models.draft; + +public enum FileType { + + ARRAYS("Arrays"), + GENOME("Genome"), + EXOME("Exome"), + SURVEY("Survey"), + PHENOTYPE("Phenotype"); + private final String value; + + FileType(String value) { + this.value = value; + } + + @Override + public String toString() { + return this.value; + } + + public String value() { + return this.value; + } + +} diff --git a/src/main/java/org/broadinstitute/consent/http/models/draft/FileTypeObject.java b/src/main/java/org/broadinstitute/consent/http/models/draft/FileTypeObject.java new file mode 100644 index 0000000000..63b380857c --- /dev/null +++ b/src/main/java/org/broadinstitute/consent/http/models/draft/FileTypeObject.java @@ -0,0 +1,6 @@ +package org.broadinstitute.consent.http.models.draft; + +public record FileTypeObject( + FileType fileType, + String functionalEquivalence +) {} \ No newline at end of file diff --git a/src/main/java/org/broadinstitute/consent/http/models/draft/LegacyRegistration.java b/src/main/java/org/broadinstitute/consent/http/models/draft/LegacyRegistration.java new file mode 100644 index 0000000000..1fc0d45592 --- /dev/null +++ b/src/main/java/org/broadinstitute/consent/http/models/draft/LegacyRegistration.java @@ -0,0 +1,43 @@ +package org.broadinstitute.consent.http.models.draft; + +import java.util.List; + +public record LegacyRegistration( + Integer studyId, + String studyName, + String studyDescription, + List dataTypes, + Boolean publicVisibility, + String piName, + String phenotypeIndication, + StudyType studyType, + String species, + Integer dataSubmitterUserId, + List dataCustodianEmail, + NihAnvilUse nihAnvilUse, + Boolean submittingToAnvil, + String dbGaPPhsID, + String dbGaPStudyRegistrationName, + String embargoReleaseDate, + String sequencingCenter, + Integer piInstitution, + String nihGrantContractNumber, + List nihICsSupportingStudy, + String nihProgramOfficerName, + NihInstitutionCenterSubmission nihInstitutionCenterSubmission, + String nihGenomicProgramAdministratorName, + Boolean multiCenterStudy, + List collaboratingSites, + Boolean controlledAccessRequiredForGenomicSummaryResultsGSR, + String controlledAccessRequiredForGenomicSummaryResultsGSRRequiredExplanation, + Boolean alternativeDataSharingPlan, + List alternativeDataSharingPlanReasons, + String alternativeDataSharingPlanExplanation, + String alternativeDataSharingPlanFileName, + AlternativeDataSharingPlanDataSubmitted alternativeDataSharingPlanDataSubmitted, + Boolean alternativeDataSharingPlanDataReleased, + String alternativeDataSharingPlanTargetDeliveryDate, + String alternativeDataSharingPlanTargetPublicReleaseDate, + AlternativeDataSharingPlanAccessManagement alternativeDataSharingPlanAccessManagement, + List consentGroups +) {} diff --git a/src/main/java/org/broadinstitute/consent/http/models/draft/NihAnvilUse.java b/src/main/java/org/broadinstitute/consent/http/models/draft/NihAnvilUse.java new file mode 100644 index 0000000000..ded2a660cc --- /dev/null +++ b/src/main/java/org/broadinstitute/consent/http/models/draft/NihAnvilUse.java @@ -0,0 +1,24 @@ +package org.broadinstitute.consent.http.models.draft; + +public enum NihAnvilUse { + + I_AM_NHGRI_FUNDED_AND_I_HAVE_A_DB_GA_P_PHS_ID_ALREADY( + "I am NHGRI funded and I have a dbGaP PHS ID already"), + I_AM_NHGRI_FUNDED_AND_I_DO_NOT_HAVE_A_DB_GA_P_PHS_ID( + "I am NHGRI funded and I do not have a dbGaP PHS ID"), + I_AM_NOT_NHGRI_FUNDED_BUT_I_AM_SEEKING_TO_SUBMIT_DATA_TO_AN_VIL( + "I am not NHGRI funded but I am seeking to submit data to AnVIL"), + I_AM_NOT_NHGRI_FUNDED_AND_DO_NOT_PLAN_TO_STORE_DATA_IN_AN_VIL( + "I am not NHGRI funded and do not plan to store data in AnVIL"); + private final String value; + + @Override + public String toString() { + return this.value; + } + + NihAnvilUse(String value) { + this.value = value; + } + +} diff --git a/src/main/java/org/broadinstitute/consent/http/models/draft/NihICsSupportingStudy.java b/src/main/java/org/broadinstitute/consent/http/models/draft/NihICsSupportingStudy.java new file mode 100644 index 0000000000..2c13d6d89a --- /dev/null +++ b/src/main/java/org/broadinstitute/consent/http/models/draft/NihICsSupportingStudy.java @@ -0,0 +1,47 @@ +package org.broadinstitute.consent.http.models.draft; + +public enum NihICsSupportingStudy { + + NCI("NCI"), + NEI("NEI"), + NHLBI("NHLBI"), + NHGRI("NHGRI"), + NIA("NIA"), + NIAAA("NIAAA"), + NIAID("NIAID"), + NIAMS("NIAMS"), + NIBIB("NIBIB"), + NICHD("NICHD"), + NIDCD("NIDCD"), + NIDCR("NIDCR"), + NIDDK("NIDDK"), + NIDA("NIDA"), + NIEHS("NIEHS"), + NIGMS("NIGMS"), + NIMH("NIMH"), + NIMHD("NIMHD"), + NINDS("NINDS"), + NINR("NINR"), + NLM("NLM"), + CC("CC"), + CIT("CIT"), + CSR("CSR"), + FIC("FIC"), + NCATS("NCATS"), + NCCIH("NCCIH"); + private final String value; + + NihICsSupportingStudy(String value) { + this.value = value; + } + + @Override + public String toString() { + return this.value; + } + + public String value() { + return this.value; + } + +} diff --git a/src/main/java/org/broadinstitute/consent/http/models/draft/NihInstitutionCenterSubmission.java b/src/main/java/org/broadinstitute/consent/http/models/draft/NihInstitutionCenterSubmission.java new file mode 100644 index 0000000000..b6fe3d50cf --- /dev/null +++ b/src/main/java/org/broadinstitute/consent/http/models/draft/NihInstitutionCenterSubmission.java @@ -0,0 +1,46 @@ +package org.broadinstitute.consent.http.models.draft; + +public enum NihInstitutionCenterSubmission { + + NCI("NCI"), + NEI("NEI"), + NHLBI("NHLBI"), + NHGRI("NHGRI"), + NIA("NIA"), + NIAAA("NIAAA"), + NIAID("NIAID"), + NIAMS("NIAMS"), + NIBIB("NIBIB"), + NICHD("NICHD"), + NIDCD("NIDCD"), + NIDCR("NIDCR"), + NIDDK("NIDDK"), + NIDA("NIDA"), + NIEHS("NIEHS"), + NIGMS("NIGMS"), + NIMH("NIMH"), + NIMHD("NIMHD"), + NINDS("NINDS"), + NINR("NINR"), + NLM("NLM"), + CC("CC"), + CIT("CIT"), + CSR("CSR"), + FIC("FIC"), + NCATS("NCATS"), + NCCIH("NCCIH"); + private final String value; + NihInstitutionCenterSubmission(String value) { + this.value = value; + } + + @Override + public String toString() { + return this.value; + } + + public String value() { + return this.value; + } + +} diff --git a/src/main/java/org/broadinstitute/consent/http/models/draft/StudyBuilder.java b/src/main/java/org/broadinstitute/consent/http/models/draft/StudyBuilder.java new file mode 100644 index 0000000000..458e0550cc --- /dev/null +++ b/src/main/java/org/broadinstitute/consent/http/models/draft/StudyBuilder.java @@ -0,0 +1,242 @@ +package org.broadinstitute.consent.http.models.draft; + +import com.google.gson.Gson; +import java.util.List; +import java.util.Optional; +import org.broadinstitute.consent.http.enumeration.FileCategory; +import org.broadinstitute.consent.http.enumeration.PropertyType; +import org.broadinstitute.consent.http.models.DataUse; +import org.broadinstitute.consent.http.models.Dataset; +import org.broadinstitute.consent.http.models.DatasetProperty; +import org.broadinstitute.consent.http.models.DraftStudyDataset; +import org.broadinstitute.consent.http.models.Study; +import org.broadinstitute.consent.http.models.StudyProperty; +import org.broadinstitute.consent.http.util.ConsentLogger; +import org.broadinstitute.consent.http.util.gson.GsonUtil; + +public class StudyBuilder implements ConsentLogger { + + // Study Fields + protected static final String ALTERNATIVE_DATA_SHARING_PLAN = "alternativeDataSharingPlan"; + protected static final String ALTERNATIVE_DATA_SHARING_PLAN_REASONS = "alternativeDataSharingPlanReasons"; + protected static final String ALTERNATIVE_DATA_SHARING_PLAN_EXPLANATION = "alternativeDataSharingPlanExplanation"; + protected static final String ALTERNATIVE_DATA_SHARING_PLAN_FILE_NAME = "alternativeDataSharingPlanFileName"; + protected static final String ALTERNATIVE_DATA_SHARING_PLAN_DATA_SUBMITTED = "alternativeDataSharingPlanDataSubmitted"; + protected static final String ALTERNATIVE_DATA_SHARING_PLAN_DATA_RELEASED = "alternativeDataSharingPlanDataReleased"; + protected static final String ALTERNATIVE_DATA_SHARING_PLAN_TARGET_DELIVERY_DATE = "alternativeDataSharingPlanTargetDeliveryDate"; + protected static final String ALTERNATIVE_DATA_SHARING_PLAN_TARGET_PUBLIC_RELEASE_DATE = "alternativeDataSharingPlanTargetPublicReleaseDate"; + protected static final String ALTERNATIVE_DATA_SHARING_PLAN_ACCESS_MANAGEMENT = "alternativeDataSharingPlanAccessManagement"; + protected static final String COLLABORATING_SITES = "collaboratingSites"; + protected static final String CONTROLLED_ACCESS_REQUIRED_FOR_GENOMIC_SUMMARY_RESULTS_GSR = "controlledAccessRequiredForGenomicSummaryResultsGSR"; + protected static final String CONTROLLED_ACCESS_REQUIRED_FOR_GENOMIC_SUMMARY_RESULTS_GSR_REQUIRED_EXPLANATION = "controlledAccessRequiredForGenomicSummaryResultsGSRRequiredExplanation"; + protected static final String DATA_CUSTODIAN_EMAIL = "dataCustodianEmail"; + protected static final String DB_GAP_PHS_ID = "dbGaPPhsID"; + protected static final String DB_GAP_STUDY_REGISTRATION_NAME = "dbGaPStudyRegistrationName"; + protected static final String EMBARGO_RELEASE_DATE = "embargoReleaseDate"; + protected static final String MULTI_CENTER_STUDY = "multiCenterStudy"; + protected static final String NIH_ANVIL_USE = "nihAnvilUse"; + protected static final String NIH_GRANT_CONTRACT_NUMBER = "nihGrantContractNumber"; + protected static final String NIH_ICS_SUPPORTING_STUDY = "nihICsSupportingStudy"; + protected static final String NIH_PROGRAM_OFFICER_NAME = "nihProgramOfficerName"; + protected static final String NIH_INSTITUTION_CENTER_SUBMISSION = "nihInstitutionCenterSubmission"; + protected static final String NIH_GENOMIC_PROGRAM_ADMINISTRATOR_NAME = "nihGenomicProgramAdministratorName"; + protected static final String PHENOTYPE_INDICATION = "phenotypeIndication"; + protected static final String PI_INSTITUTION = "piInstitution"; + protected static final String SEQUENCING_CENTER = "sequencingCenter"; + protected static final String SPECIES = "species"; + protected static final String STUDY_TYPE = "studyType"; + protected static final String SUBMITTING_TO_ANVIL = "submittingToAnvil"; + // Dataset Fields + protected static final String ACCESS_MANAGEMENT = "accessManagement"; + protected static final String DATA_LOCATION = "dataLocation"; + protected static final String URL = "url"; + protected static final String NUMBER_OF_PARTICIPANTS = "numberOfParticipants"; + protected static final String FILE_TYPES = "fileTypes"; + + protected static final Gson gson = GsonUtil.getInstance(); + + public Study buildStudyFromDraftLegacyRegistration(DraftStudyDataset draft) { + // Set draft related fields + Study study = new Study(); + study.setCreateDate(draft.getCreateDate()); + study.setUpdateDate(draft.getUpdateDate()); + study.setName(draft.getName()); + study.setUuid(draft.getUUID()); + study.setCreateUserId(draft.getCreateUser().getUserId()); + study.setCreateUserEmail(draft.getCreateUser().getEmail()); + study.setUpdateUserId(draft.getUpdateUser().getUserId()); + draft.getStoredFiles() + .stream() + .filter(f -> f.getCategory().equals(FileCategory.ALTERNATIVE_DATA_SHARING_PLAN)) + .findFirst() + .ifPresent(study::setAlternativeDataSharingPlan); + // Set legacy registration related fields + LegacyRegistration lr = gson.fromJson(draft.getJson(), LegacyRegistration.class); + study.setDescription(lr.studyDescription()); + study.setDataTypes(lr.dataTypes()); + study.setPublicVisibility(lr.publicVisibility()); + study.setPiName(lr.piName()); + if (lr.studyId() != null) { + study.setStudyId(lr.studyId()); + } + studyProp(PHENOTYPE_INDICATION, lr.phenotypeIndication(), PropertyType.String).ifPresent( + study::addProperty); + studyProp(STUDY_TYPE, lr.studyType(), PropertyType.String).ifPresent(study::addProperty); + studyProp(SPECIES, lr.species(), PropertyType.String).ifPresent(study::addProperty); + studyProp(DATA_CUSTODIAN_EMAIL, lr.dataCustodianEmail(), PropertyType.Json).ifPresent( + study::addProperty); + studyProp(NIH_ANVIL_USE, lr.nihAnvilUse(), PropertyType.String).ifPresent(study::addProperty); + studyProp(SUBMITTING_TO_ANVIL, lr.submittingToAnvil(), PropertyType.Boolean).ifPresent( + study::addProperty); + studyProp(DB_GAP_PHS_ID, lr.dbGaPPhsID(), PropertyType.String).ifPresent(study::addProperty); + studyProp(DB_GAP_STUDY_REGISTRATION_NAME, lr.dbGaPStudyRegistrationName(), + PropertyType.String).ifPresent(study::addProperty); + studyProp(EMBARGO_RELEASE_DATE, lr.embargoReleaseDate(), PropertyType.String).ifPresent( + study::addProperty); + studyProp(SEQUENCING_CENTER, lr.sequencingCenter(), PropertyType.String).ifPresent( + study::addProperty); + studyProp(PI_INSTITUTION, lr.piInstitution(), PropertyType.Number).ifPresent(study::addProperty); + studyProp(NIH_GRANT_CONTRACT_NUMBER, lr.nihGrantContractNumber(), PropertyType.String).ifPresent( + study::addProperty); + studyProp(NIH_ICS_SUPPORTING_STUDY, lr.nihICsSupportingStudy(), PropertyType.Json).ifPresent( + study::addProperty); + studyProp(NIH_PROGRAM_OFFICER_NAME, lr.nihProgramOfficerName(), PropertyType.String).ifPresent( + study::addProperty); + studyProp(NIH_INSTITUTION_CENTER_SUBMISSION, lr.nihInstitutionCenterSubmission(), + PropertyType.String).ifPresent(study::addProperty); + studyProp(NIH_GENOMIC_PROGRAM_ADMINISTRATOR_NAME, lr.nihGenomicProgramAdministratorName(), + PropertyType.String).ifPresent(study::addProperty); + studyProp(MULTI_CENTER_STUDY, lr.multiCenterStudy(), PropertyType.Boolean).ifPresent( + study::addProperty); + studyProp(COLLABORATING_SITES, lr.collaboratingSites(), PropertyType.Json).ifPresent( + study::addProperty); + studyProp(CONTROLLED_ACCESS_REQUIRED_FOR_GENOMIC_SUMMARY_RESULTS_GSR, + lr.controlledAccessRequiredForGenomicSummaryResultsGSR(), PropertyType.Boolean).ifPresent( + study::addProperty); + studyProp(CONTROLLED_ACCESS_REQUIRED_FOR_GENOMIC_SUMMARY_RESULTS_GSR_REQUIRED_EXPLANATION, + lr.controlledAccessRequiredForGenomicSummaryResultsGSRRequiredExplanation(), + PropertyType.String) + .ifPresent(study::addProperty); + studyProp(ALTERNATIVE_DATA_SHARING_PLAN, lr.alternativeDataSharingPlan(), + PropertyType.Boolean).ifPresent(study::addProperty); + studyProp(ALTERNATIVE_DATA_SHARING_PLAN_REASONS, lr.alternativeDataSharingPlanReasons(), + PropertyType.Json).ifPresent(study::addProperty); + studyProp(ALTERNATIVE_DATA_SHARING_PLAN_EXPLANATION, + lr.alternativeDataSharingPlanExplanation(), PropertyType.String).ifPresent( + study::addProperty); + studyProp(ALTERNATIVE_DATA_SHARING_PLAN_FILE_NAME, + lr.alternativeDataSharingPlanFileName(), PropertyType.String).ifPresent(study::addProperty); + studyProp(ALTERNATIVE_DATA_SHARING_PLAN_DATA_SUBMITTED, + lr.alternativeDataSharingPlanDataSubmitted(), PropertyType.String).ifPresent( + study::addProperty); + studyProp(ALTERNATIVE_DATA_SHARING_PLAN_DATA_RELEASED, + lr.alternativeDataSharingPlanDataReleased(), PropertyType.Boolean).ifPresent( + study::addProperty); + studyProp(ALTERNATIVE_DATA_SHARING_PLAN_TARGET_DELIVERY_DATE, + lr.alternativeDataSharingPlanTargetDeliveryDate(), PropertyType.String).ifPresent( + study::addProperty); + studyProp(ALTERNATIVE_DATA_SHARING_PLAN_TARGET_PUBLIC_RELEASE_DATE, + lr.alternativeDataSharingPlanTargetPublicReleaseDate(), PropertyType.String).ifPresent( + study::addProperty); + studyProp(ALTERNATIVE_DATA_SHARING_PLAN_ACCESS_MANAGEMENT, + lr.alternativeDataSharingPlanAccessManagement(), PropertyType.String).ifPresent( + study::addProperty); + + if (lr.consentGroups() != null) { + study.addDatasets(getDatasetsFromConsentGroups(lr.consentGroups())); + } + return study; + } + + private Optional studyProp(String name, Object value, PropertyType type) { + if (value != null) { + return Optional.of(new StudyProperty(name, value, type)); + } + return Optional.empty(); + } + + public List getDatasetsFromConsentGroups(List consentGroups) { + if (consentGroups != null) { + return consentGroups.stream().map(this::mapConsentGroupObjectToV1SchemaDataset).toList(); + } + return List.of(); + } + + protected Dataset mapConsentGroupObjectToV1SchemaDataset(ConsentGroup cg) { + Dataset dataset = new Dataset(); + dataset.setName(cg.consentGroupName()); + dataset.setDacId(cg.dataAccessCommitteeId()); + if (cg.datasetIdentifier() != null) { + dataset.setAlias(Dataset.parseIdentifierToAlias(cg.datasetIdentifier())); + } + datasetProp(ACCESS_MANAGEMENT, cg.accessManagement(), PropertyType.String) + .ifPresent(dataset::addProperty); + datasetProp(DATA_LOCATION, cg.dataLocation(), PropertyType.String).ifPresent(dataset::addProperty); + datasetProp(URL, cg.url(), PropertyType.String).ifPresent(dataset::addProperty); + datasetProp(NUMBER_OF_PARTICIPANTS, cg.numberOfParticipants(), PropertyType.Number) + .ifPresent(dataset::addProperty); + datasetProp(FILE_TYPES, cg.fileTypes(), PropertyType.Json).ifPresent(dataset::addProperty); + dataset.setDataUse(populateDataUse(cg)); + return dataset; + } + + private Optional datasetProp(String name, Object value, PropertyType type) { + if (value != null) { + DatasetProperty prop = new DatasetProperty(); + prop.setPropertyName(name); + prop.setPropertyValue(value); + prop.setPropertyType(type); + return Optional.of(prop); + } + return Optional.empty(); + } + + private DataUse populateDataUse(ConsentGroup cg) { + DataUse dataUse = new DataUse(); + if (cg.generalResearchUse() != null && cg.generalResearchUse()) { + dataUse.setGeneralUse(true); + } + if (cg.hmb() != null && cg.hmb()) { + dataUse.setHmbResearch(true); + } + if (cg.diseaseSpecificUse() != null && !cg.diseaseSpecificUse().isEmpty()) { + dataUse.setDiseaseRestrictions(cg.diseaseSpecificUse()); + } + if (cg.poa() != null && cg.poa()) { + dataUse.setPopulationOriginsAncestry(true); + } + if (cg.otherPrimary() != null) { + dataUse.setOther(cg.otherPrimary()); + } + if (cg.nmds() != null && cg.nmds()) { + dataUse.setMethodsResearch(true); + } + if (cg.gso() != null && cg.gso()) { + dataUse.setGeneticStudiesOnly(true); + } + if (cg.pub() != null && cg.pub()) { + dataUse.setPublicationResults(true); + } + if (cg.col() != null && cg.col()) { + dataUse.setCollaboratorRequired(true); + } + if (cg.irb() != null && cg.irb()) { + dataUse.setEthicsApprovalRequired(true); + } + if (cg.gs() != null) { + dataUse.setGeographicalRestrictions(cg.gs()); + } + if (cg.mor() != null && cg.mor()) { + if (cg.morDate() != null) { + dataUse.setPublicationMoratorium(cg.morDate()); + } + } + if (cg.npu() != null && cg.npu()) { + dataUse.setNonProfitUse(true); + } + if (cg.otherSecondary() != null) { + dataUse.setSecondaryOther(cg.otherSecondary()); + } + return dataUse; + } +} diff --git a/src/main/java/org/broadinstitute/consent/http/models/draft/StudyType.java b/src/main/java/org/broadinstitute/consent/http/models/draft/StudyType.java new file mode 100644 index 0000000000..4d20ef56dd --- /dev/null +++ b/src/main/java/org/broadinstitute/consent/http/models/draft/StudyType.java @@ -0,0 +1,30 @@ +package org.broadinstitute.consent.http.models.draft; + +public enum StudyType { + + OBSERVATIONAL("Observational"), + INTERVENTIONAL("Interventional"), + DESCRIPTIVE("Descriptive"), + ANALYTICAL("Analytical"), + PROSPECTIVE("Prospective"), + RETROSPECTIVE("Retrospective"), + CASE_REPORT("Case report"), + CASE_SERIES("Case series"), + CROSS_SECTIONAL("Cross-sectional"), + COHORT_STUDY("Cohort study"); + private final String value; + + StudyType(String value) { + this.value = value; + } + + @Override + public String toString() { + return this.value; + } + + public String value() { + return this.value; + } + +} \ No newline at end of file diff --git a/src/test/java/org/broadinstitute/consent/http/models/draft/StudyBuilderTest.java b/src/test/java/org/broadinstitute/consent/http/models/draft/StudyBuilderTest.java new file mode 100644 index 0000000000..51e50b8faa --- /dev/null +++ b/src/test/java/org/broadinstitute/consent/http/models/draft/StudyBuilderTest.java @@ -0,0 +1,153 @@ +package org.broadinstitute.consent.http.models.draft; + +import static org.broadinstitute.consent.http.models.draft.StudyBuilder.SPECIES; +import static org.broadinstitute.consent.http.models.draft.StudyBuilder.STUDY_TYPE; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.broadinstitute.consent.http.models.DraftStudyDataset; +import org.broadinstitute.consent.http.models.Study; +import org.broadinstitute.consent.http.models.User; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class StudyBuilderTest { + + // TODO Flesh out more test values + String draftJson = """ + { + "studyId": 6077, + "studyName": "All of Us (Controlled+ Tier)", + "studyType": "Descriptive", + "studyDescription": "This study and dataset(s) represents the All of Us controlled+ tier data", + "dataTypes": [ + "Whole Genome (WGS)" + ], + "phenotypeIndication": "NA", + "species": "Human", + "piName": "Paul Harris, Melissa Basford", + "dataSubmitterUserId": 3396, + "dataCustodianEmail": ["email@test.com"], + "publicVisibility": true, + "nihAnvilUse": "I_AM_NOT_NHGRI_FUNDED_AND_DO_NOT_PLAN_TO_STORE_DATA_IN_AN_VIL", + "submittingToAnvil": null, + "dbGaPPhsID": null, + "dbGaPStudyRegistrationName": null, + "embargoReleaseDate": null, + "sequencingCenter": null, + "piInstitution": null, + "nihGrantContractNumber": null, + "nihICsSupportingStudy": [], + "nihProgramOfficerName": null, + "nihInstitutionCenterSubmission": null, + "nihGenomicProgramAdministratorName": null, + "multiCenterStudy": null, + "collaboratingSites": [], + "controlledAccessRequiredForGenomicSummaryResultsGSR": null, + "controlledAccessRequiredForGenomicSummaryResultsGSRRequiredExplanation": null, + "alternativeDataSharingPlan": null, + "alternativeDataSharingPlanReasons": [], + "alternativeDataSharingPlanExplanation": null, + "alternativeDataSharingPlanFileName": null, + "alternativeDataSharingPlanDataSubmitted": null, + "alternativeDataSharingPlanDataReleased": null, + "alternativeDataSharingPlanTargetDeliveryDate": null, + "alternativeDataSharingPlanTargetPublicReleaseDate": null, + "alternativeDataSharingPlanAccessManagement": null, + "consentGroups": [ + { + "datasetId": 2583, + "datasetIdentifier": "DUOS-001078", + "consentGroupName": "All of Us (Controlled+ Tier) - Set 1", + "accessManagement": "OPEN", + "generalResearchUse": true, + "hmb": false, + "diseaseSpecificUse": ["https://disease-ontology.org/term/DOID:162/"], + "poa": true, + "otherPrimary": "String", + "nmds": true, + "gso": false, + "pub": false, + "col": false, + "irb": false, + "gs": "GS", + "mor": true, + "morDate": "More Date", + "npu": false, + "otherSecondary": "String", + "dataAccessCommitteeId": 99, + "dataLocation": "TDR_LOCATION", + "url": "https://abcnews.com", + "numberOfParticipants": 2, + "fileTypes": [ + { + "fileType": null, + "functionalEquivalence": null + } + ] + }, + { + "consentGroupName": "All of Us (Controlled+ Tier) - Set 2", + "accessManagement": "OPEN", + "generalResearchUse": true, + "hmb": false, + "diseaseSpecificUse": ["https://disease-ontology.org/term/DOID:162/"], + "poa": true, + "otherPrimary": "String", + "nmds": true, + "gso": false, + "pub": false, + "col": false, + "irb": false, + "gs": "GS", + "mor": true, + "morDate": "More Date", + "npu": false, + "otherSecondary": "String", + "dataAccessCommitteeId": 99, + "dataLocation": "TDR_LOCATION", + "url": "https://abcnews.com", + "numberOfParticipants": 2, + "fileTypes": [ + { + "fileType": null, + "functionalEquivalence": null + } + ] + } + ] + } + """; + + @Test + void testBuildStudy() { + User user = new User(); + user.setUserId(1); + user.setEmail("email"); + StudyBuilder studyBuilder = new StudyBuilder(); + DraftStudyDataset draft = new DraftStudyDataset(draftJson, user); + Study study = studyBuilder.buildStudyFromDraftLegacyRegistration(draft); + assertNotNull(study); + assertEquals(6077, study.getStudyId()); + assertEquals(draft.getName(), study.getName()); + assertEquals(draft.getCreateDate(), study.getCreateDate()); + assertEquals(draft.getUUID(), study.getUuid()); + assertEquals(user.getUserId(), study.getCreateUserId()); + assertEquals(user.getUserId(), study.getUpdateUserId()); + + assertEquals("This study and dataset(s) represents the All of Us controlled+ tier data", + study.getDescription()); + assertTrue(study.getDataTypes().contains("Whole Genome (WGS)")); + assertEquals(true, study.getPublicVisibility()); + assertEquals("Paul Harris, Melissa Basford", study.getPiName()); + assertTrue(study.getProperties().stream() + .anyMatch(p -> p.getKey().equals(SPECIES) && p.getValue().equals("Human"))); + assertTrue(study.getProperties().stream().anyMatch( + p -> p.getKey().equals(STUDY_TYPE) && p.getValue().equals(StudyType.DESCRIPTIVE))); + // TODO Flesh out testing + } + +}