/* * This file is part of ADDIS (Aggregate Data Drug Information System). * ADDIS is distributed from http://drugis.org/. * Copyright © 2009 Gert van Valkenhoef, Tommi Tervonen. * Copyright © 2010 Gert van Valkenhoef, Tommi Tervonen, Tijs Zwinkels, * Maarten Jacobs, Hanno Koeslag, Florin Schimbinschi, Ahmad Kamal, Daniel * Reid. * Copyright © 2011 Gert van Valkenhoef, Ahmad Kamal, Daniel Reid, Florin * Schimbinschi. * Copyright © 2012 Gert van Valkenhoef, Daniel Reid, Joël Kuiper, Wouter * Reckman. * Copyright © 2013 Gert van Valkenhoef, Joël Kuiper. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.drugis.addis.presentation.wizard; import java.io.IOException; import java.util.HashSet; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import javax.swing.table.TableModel; import org.drugis.addis.entities.AdverseEvent; import org.drugis.addis.entities.Arm; import org.drugis.addis.entities.BasicStudyCharacteristic; import org.drugis.addis.entities.DependentEntitiesException; import org.drugis.addis.entities.Domain; import org.drugis.addis.entities.Drug; import org.drugis.addis.entities.Endpoint; import org.drugis.addis.entities.Epoch; import org.drugis.addis.entities.Indication; import org.drugis.addis.entities.PopulationCharacteristic; import org.drugis.addis.entities.Source; import org.drugis.addis.entities.Study; import org.drugis.addis.entities.StudyActivity; import org.drugis.addis.entities.StudyActivity.UsedBy; import org.drugis.addis.entities.StudyOutcomeMeasure; import org.drugis.addis.entities.TypeWithNotes; import org.drugis.addis.gui.AddisWindow; import org.drugis.addis.imports.ClinicaltrialsImporter; import org.drugis.addis.presentation.BasicArmPresentation; import org.drugis.addis.presentation.ModifiableHolder; import org.drugis.addis.presentation.MutableCharacteristicHolder; import org.drugis.addis.presentation.PopulationCharTableModel; import org.drugis.addis.presentation.PresentationModelFactory; import org.drugis.addis.presentation.SelectAdverseEventsPresentation; import org.drugis.addis.presentation.SelectEndpointPresentation; import org.drugis.addis.presentation.SelectFromFiniteListPresentation; import org.drugis.addis.presentation.SelectPopulationCharsPresentation; import org.drugis.addis.presentation.StudyMeasurementTableModel; import org.drugis.addis.presentation.StudyPresentation; import org.drugis.addis.presentation.TreatmentActivityPresentation; import org.drugis.addis.presentation.ValueHolder; import org.drugis.common.beans.ContentAwareListModel; import org.drugis.common.beans.SortedSetModel; import com.jgoodies.binding.list.ObservableList; import com.jgoodies.binding.value.AbstractValueModel; import com.jgoodies.binding.value.ValueModel; public class AddStudyWizardPresentation { public static final String CLINICALTRIALS_GOV_BASE = "https://clinicaltrials.gov/show/"; public abstract class OutcomeMeasurementsModel { abstract public TableModel getMeasurementTableModel(); } private Domain d_domain; private PresentationModelFactory d_pmf; private StudyPresentation d_newStudyPM; private SelectAdverseEventsPresentation d_adverseEventSelect; private SelectPopulationCharsPresentation d_populationCharSelect; private SelectEndpointPresentation d_endpointSelect; private AddArmsPresentation d_arms; private AddEpochsPresentation d_epochs; private ValueHolder<Boolean> d_importCTWithResults = new ModifiableHolder<Boolean>(false); private Study d_origStudy = null; private AddisWindow d_mainWindow; private WhenTakenFactory d_wtf; public AddStudyWizardPresentation(final Domain d, final PresentationModelFactory pmf, final AddisWindow mainWindow) { d_domain = d; d_pmf = pmf; d_newStudyPM = new StudyPresentation(new Study(), pmf); d_mainWindow = mainWindow; d_epochs = new AddEpochsPresentation(getNewStudy(), "Epoch", 1); d_wtf = new WhenTakenFactory(d_newStudyPM.getBean()); d_endpointSelect = new SelectEndpointPresentation(d_domain.getEndpoints(), d_wtf, d_mainWindow); d_adverseEventSelect = new SelectAdverseEventsPresentation(d_domain.getAdverseEvents(), d_wtf, d_mainWindow); d_populationCharSelect = new SelectPopulationCharsPresentation(d_domain.getPopulationCharacteristics(), d_wtf, d_mainWindow); d_arms = new AddArmsPresentation(getNewStudy(), "Arm", 2); resetStudy(); } private void updateSelectionHolders() { getAddArmsModel().setStudy(getNewStudy()); getAddEpochsModel().setStudy(getNewStudy()); d_endpointSelect.setSlots(getNewStudy().getEndpoints()); d_adverseEventSelect.setSlots(getNewStudy().getAdverseEvents()); d_populationCharSelect.setSlots(getNewStudy().getPopulationChars()); ListDataListener removeOrphansListener = new ListDataListener() { public void intervalRemoved(final ListDataEvent e) { deleteOrphanUsedBys(); } public void intervalAdded(final ListDataEvent e) { deleteOrphanUsedBys(); } public void contentsChanged(final ListDataEvent e) { deleteOrphanUsedBys(); } }; getAddArmsModel().getList().addListDataListener(removeOrphansListener); getAddEpochsModel().getList().addListDataListener(removeOrphansListener); new ContentAwareListModel<StudyOutcomeMeasure<Endpoint>>(getNewStudy().getEndpoints()); new ContentAwareListModel<StudyOutcomeMeasure<AdverseEvent>>(getNewStudy().getAdverseEvents()); new ContentAwareListModel<StudyOutcomeMeasure<PopulationCharacteristic>>(getNewStudy().getPopulationChars()); } void deleteOrphanUsedBys() { for (StudyActivity sa : getNewStudy().getStudyActivities()) { for (UsedBy ub: sa.getUsedBy()) { if(getNewStudy().findArm(ub.getArm().getName()) == null || getNewStudy().findEpoch(ub.getEpoch().getName()) == null) { HashSet<UsedBy> usedBy = new HashSet<UsedBy>(sa.getUsedBy()); usedBy.remove(ub); sa.setUsedBy(usedBy); } } } } public AddStudyWizardPresentation(final Domain d, final PresentationModelFactory pmf, final AddisWindow mainWindow, final Study origStudy) { this(d, pmf, mainWindow); d_origStudy = origStudy; setNewStudy(origStudy.clone()); } public ValueModel getSourceModel() { return getCharacteristicModel(BasicStudyCharacteristic.SOURCE); } public ValueModel getSourceNoteModel() { return getCharacteristicNoteModel(BasicStudyCharacteristic.SOURCE); } public ValueModel getIdModel() { return d_newStudyPM.getModel(Study.PROPERTY_NAME); } public ValueModel getIdNoteModel() { return new NoteModel(getNewStudy()); } public ValueModel getTitleModel() { return new MutableCharacteristicHolder(getNewStudy(), BasicStudyCharacteristic.TITLE); } public Domain getDomain() { return d_domain; } public ValueHolder<Boolean> shouldImportCTWithResults() { return d_importCTWithResults; } public void importCT() throws IOException { if(getIdModel().getValue().toString().length() != 0) { String studyID = getIdModel().getValue().toString().trim().replace(" ", "%20"); Study clinicaltrialsData; if (d_importCTWithResults.getValue()) { String url = CLINICALTRIALS_GOV_BASE + studyID + "?resultsxml=true"; clinicaltrialsData = ClinicaltrialsImporter.getClinicaltrialsData(url, true); } else { String url = CLINICALTRIALS_GOV_BASE + studyID + "?displayxml=true"; clinicaltrialsData = ClinicaltrialsImporter.getClinicaltrialsData(url, false); } setNewStudy(clinicaltrialsData); } } public void setNewStudy(final Study study) { d_newStudyPM = new StudyPresentation(study, d_pmf); d_wtf.study = study; updateSelectionHolders(); } public SortedSetModel<Indication> getIndicationsModel() { return d_domain.getIndications(); } public ValueModel getIndicationModel() { return d_newStudyPM.getModel(Study.PROPERTY_INDICATION); } public ValueModel getIndicationNoteModel() { return new NoteModel(getNewStudy().getIndicationWithNotes()); } public void resetStudy() { d_newStudyPM = (StudyPresentation) new StudyPresentation(new Study(), d_pmf); getSourceModel().setValue(Source.MANUAL); // Add 2 arms by default: getArms().add(getAddArmsModel().createItem()); getArms().add(getAddArmsModel().createItem()); // Add 1 epoch by default: getEpochs().add(getAddEpochsModel().createItem()); updateSelectionHolders(); d_endpointSelect.addSlot(); // by default have 1 endpoint slot. } public MutableCharacteristicHolder getCharacteristicModel(final BasicStudyCharacteristic c) { return new MutableCharacteristicHolder(getNewStudy(),c); } public ValueModel getCharacteristicNoteModel(final BasicStudyCharacteristic c) { return new NoteModel(getNewStudy().getCharacteristicWithNotes(c)); } public ObservableList<Arm> getArms() { return getNewStudy().getArms(); } public ObservableList<Epoch> getEpochs() { return getNewStudy().getEpochs(); } public SortedSetModel<Drug> getDrugsModel(){ return d_domain.getDrugs(); } public BasicArmPresentation getArmModel(final int armNumber){ return new BasicArmPresentation(getArms().get(armNumber), d_pmf); } public AddArmsPresentation getAddArmsModel() { return d_arms; } public AddEpochsPresentation getAddEpochsModel() { return d_epochs; } public TreatmentActivityPresentation getTreatmentActivityModel(final int armNumber){ Arm arm = getArms().get(armNumber); return new TreatmentActivityPresentation(getNewStudy().getTreatment(arm)); } public ValueModel getArmNoteModel(final int idx) { if(getArms().size() <= idx) return null; return new ArmNoteModel(getArms().get(idx)); } @SuppressWarnings("serial") static class ArmNoteModel extends AbstractValueModel { private final Arm d_arm; public ArmNoteModel(final Arm arm) { d_arm = arm; } public String getValue() { return d_arm.getNotes().size() > 0 ? d_arm.getNotes().get(0).getText() : null; } public void setValue(final Object newValue) { } } @SuppressWarnings("serial") static class NoteModel extends AbstractValueModel { private final TypeWithNotes d_obj; public NoteModel(final TypeWithNotes obj) { d_obj = obj; } public String getValue() { return (d_obj != null && d_obj.getNotes().size() > 0) ? d_obj.getNotes().get(0).getText() : null; } public void setValue(final Object newValue) { } } public StudyMeasurementTableModel getEndpointMeasurementTableModel() { return new StudyMeasurementTableModel(getNewStudy(), d_pmf, Endpoint.class, false); } public Study saveStudy() { if (getArms().isEmpty()) throw new IllegalStateException("No arms selected in study."); if (!isIdAvailable()) throw new IllegalStateException("Study with this ID already exists in domain"); if (isEditing()) { try { d_domain.deleteEntity(d_origStudy); } catch (DependentEntitiesException e) { e.printStackTrace(); } } // Add the study to the domain. d_domain.getStudies().add(getNewStudy()); return getNewStudy(); } public boolean isIdAvailable() { if(getNewStudy().getName() == null) return true; if (!d_domain.getStudies().contains(getNewStudy())) { return true; } if (isEditing()) { return getNewStudy().equals(d_origStudy); } return false; } Study getStudy() { return getNewStudy(); } private Study getNewStudy() { return d_newStudyPM.getBean(); } public StudyPresentation getNewStudyPM() { return d_newStudyPM; } private StudyMeasurementTableModel getAdverseEventMeasurementTableModel() { return new StudyMeasurementTableModel(getNewStudy(),d_pmf, AdverseEvent.class, false); } private PopulationCharTableModel getPopulationCharMeasurementTableModel() { return d_newStudyPM.getPopulationCharTableModel(); } public OutcomeMeasurementsModel getAdverseEventsModel() { return new OutcomeMeasurementsModel() { public StudyMeasurementTableModel getMeasurementTableModel() { return getAdverseEventMeasurementTableModel(); } }; } public OutcomeMeasurementsModel getEndpointsModel() { return new OutcomeMeasurementsModel() { public StudyMeasurementTableModel getMeasurementTableModel() { return getEndpointMeasurementTableModel(); } }; } public OutcomeMeasurementsModel getPopulationCharsModel() { return new OutcomeMeasurementsModel() { public TableModel getMeasurementTableModel() { return getPopulationCharMeasurementTableModel(); } }; } public SelectFromFiniteListPresentation<AdverseEvent> getAdverseEventSelectModel() { return d_adverseEventSelect; } public SelectFromFiniteListPresentation<Endpoint> getEndpointSelectModel() { return d_endpointSelect; } public SelectFromFiniteListPresentation<PopulationCharacteristic> getPopulationCharSelectModel() { return d_populationCharSelect; } public boolean isEditing() { return (d_origStudy != null); } public Study getOldStudy() { return d_origStudy; } }