/* * 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.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import org.drugis.addis.entities.Arm; import org.drugis.addis.entities.Domain; import org.drugis.addis.entities.OutcomeMeasure; import org.drugis.addis.entities.Study; import org.drugis.addis.entities.StudyArmsEntry; import org.drugis.addis.entities.analysis.MetaAnalysis; import org.drugis.addis.entities.analysis.RandomEffectsMetaAnalysis; import org.drugis.addis.entities.treatment.TreatmentDefinition; import org.drugis.addis.presentation.ModifiableHolder; import org.drugis.addis.presentation.PairWiseMetaAnalysisPresentation; import org.drugis.addis.presentation.PresentationModelFactory; import org.drugis.addis.presentation.SelectableTreatmentDefinitionsGraphModel; import org.drugis.common.EqualsUtil; import com.jgoodies.binding.list.ObservableList; import com.jgoodies.binding.value.AbstractValueModel; import com.jgoodies.binding.value.ValueModel; public class PairWiseMetaAnalysisWizardPresentation extends NetworkMetaAnalysisWizardPM { private static final String TEMPLATE_DEFINITIONS_DESCRIPTION = "Select the %1$s to be used for the meta-analysis. " + "To continue, (1) at least %2$s must be selected, and (2) the selected %1$s must be connected."; private final ModifiableHolder<TreatmentDefinition> d_rawFirstDefinitionHolder = new ModifiableHolder<TreatmentDefinition>(); private final ModifiableHolder<TreatmentDefinition> d_rawSecondDefinitionHolder = new ModifiableHolder<TreatmentDefinition>(); private final ModifiableHolder<TreatmentDefinition> d_refinedFirstDefinitionHolder = new ModifiableHolder<TreatmentDefinition>(); private final ModifiableHolder<TreatmentDefinition> d_refinedSecondDefinitionHolder = new ModifiableHolder<TreatmentDefinition>(); private MetaAnalysisCompleteListener d_metaAnalysisCompleteListener; private PairWiseMetaAnalysisPresentation d_pm; public PairWiseMetaAnalysisWizardPresentation(Domain d, PresentationModelFactory pmm) { super(d, pmm); d_metaAnalysisCompleteListener = new MetaAnalysisCompleteListener(); d_selectableStudyListPm.getSelectedStudiesModel().addListDataListener(d_metaAnalysisCompleteListener); d_rawFirstDefinitionHolder.addValueChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { commitRawSelectionToGraph(); } }); d_rawSecondDefinitionHolder.addValueChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { commitRawSelectionToGraph(); } }); d_refinedFirstDefinitionHolder.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { if (evt.getNewValue() != null && evt.getNewValue().equals(d_refinedSecondDefinitionHolder.getValue())) { d_refinedSecondDefinitionHolder.setValue(null); } commitRefinedSelectionToGraph(); } }); d_refinedSecondDefinitionHolder.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { if (evt.getNewValue() != null && evt.getNewValue().equals(d_refinedFirstDefinitionHolder.getValue())) { d_refinedFirstDefinitionHolder.setValue(null); } commitRefinedSelectionToGraph(); } }); d_outcomeHolder.addPropertyChangeListener(new ClearValueModelsOnPropertyChangeListener(new ModifiableHolder[]{d_rawFirstDefinitionHolder, d_rawSecondDefinitionHolder})); } @Override public boolean rebuildRawAlternativesGraph() { if (super.rebuildRawAlternativesGraph()) { commitRawSelectionToGraph(); return true; } return false; } @Override public boolean rebuildRefinedAlternativesGraph() { if (super.rebuildRefinedAlternativesGraph()) { propagateRawToRefined(getRawFirstDefinitionModel(), getRefinedFirstDefinitionModel()); propagateRawToRefined(getRawSecondDefinitionModel(), getRefinedSecondDefinitionModel()); commitRefinedSelectionToGraph(); return true; } return false; } private void propagateRawToRefined( ModifiableHolder<TreatmentDefinition> rawModel, ModifiableHolder<TreatmentDefinition> refinedModel) { if (getRefinedAlternativesGraph().getDefinitions().contains(rawModel.getValue())) { refinedModel.setValue(rawModel.getValue()); } else { refinedModel.setValue(null); } } protected void commitRefinedSelectionToGraph() { commitSelection(getSelectedRefinedTreatmentDefinitions(), d_refinedFirstDefinitionHolder.getValue(), d_refinedSecondDefinitionHolder.getValue()); } private void commitRawSelectionToGraph() { commitSelection(getSelectedRawTreatmentDefinitions(), d_rawFirstDefinitionHolder.getValue(), d_rawSecondDefinitionHolder.getValue()); } private void commitSelection(ObservableList<TreatmentDefinition> list, TreatmentDefinition firstDef, TreatmentDefinition secondDef) { if (firstDef == null) { // ensure the first is never null unless both are null firstDef = secondDef; secondDef = null; } if (firstDef == null) { // both null list.clear(); } else if (EqualsUtil.equal(firstDef, secondDef)) { // both equal, non-null replaceOrInsert(list, 0, firstDef); trim(list, 1); } else { // both different, second one may be null replaceOrInsert(list, 0, firstDef); // first is non-null if (secondDef != null) { replaceOrInsert(list, 1, secondDef); trim(list, 2); } else { trim(list, 1); } } } private void trim(List<TreatmentDefinition> list, int size) { while (list.size() > size) { list.remove(size); } } private void replaceOrInsert(List<TreatmentDefinition> list, int index, TreatmentDefinition element) { if (list.size() > index) { if (list.get(index) != element) { list.set(index, element); } } else { list.add(index, element); } } public ModifiableHolder<TreatmentDefinition> getRawFirstDefinitionModel() { return d_rawFirstDefinitionHolder; } public ModifiableHolder<TreatmentDefinition> getRawSecondDefinitionModel() { return d_rawSecondDefinitionHolder; } public ModifiableHolder<TreatmentDefinition> getRefinedFirstDefinitionModel() { return d_refinedFirstDefinitionHolder; } public ModifiableHolder<TreatmentDefinition> getRefinedSecondDefinitionModel() { return d_refinedSecondDefinitionHolder; } public RandomEffectsMetaAnalysis buildMetaAnalysis() { List<StudyArmsEntry> studyArms = new ArrayList <StudyArmsEntry>(); TreatmentDefinition base = d_refinedFirstDefinitionHolder.getValue(); TreatmentDefinition subj = d_refinedSecondDefinitionHolder.getValue(); for (Study s : getSelectableStudyListPM().getSelectedStudiesModel()) { Arm left = d_selectedArms.get(s).get(base).getValue(); Arm right = d_selectedArms.get(s).get(subj).getValue(); studyArms.add(new StudyArmsEntry(s, left, right)); } OutcomeMeasure om = (OutcomeMeasure) getOutcomeMeasureModel().getValue(); return new RandomEffectsMetaAnalysis("", om, base, subj, studyArms, false); } public ValueModel getMetaAnalysisCompleteModel() { return d_metaAnalysisCompleteListener; } @SuppressWarnings("serial") public class MetaAnalysisCompleteListener extends AbstractValueModel implements ListDataListener { private void fireChange() { firePropertyChange(PROPERTYNAME_VALUE, null, getValue()); } public Object getValue() { return new Boolean(!d_selectableStudyListPm.getSelectedStudiesModel().isEmpty()); } public void setValue(Object newValue) { } public void contentsChanged(ListDataEvent e) { fireChange(); } public void intervalAdded(ListDataEvent e) { fireChange(); } public void intervalRemoved(ListDataEvent e) { fireChange(); } } @Override protected SelectableTreatmentDefinitionsGraphModel buildRawAlternativesGraph() { return new SelectableTreatmentDefinitionsGraphModel(getStudiesEndpointAndIndication(), d_rawTreatmentDefinitions, d_outcomeHolder, 1, 2); } @Override protected SelectableTreatmentDefinitionsGraphModel buildRefinedAlternativesGraph() { return new SelectableTreatmentDefinitionsGraphModel(getStudiesEndpointAndIndication(), d_refinedTreatmentDefinitions, d_outcomeHolder, 2, 2); } public PairWiseMetaAnalysisPresentation getMetaAnalysisModel() { RandomEffectsMetaAnalysis buildMetaAnalysis = buildMetaAnalysis(); d_pm = (PairWiseMetaAnalysisPresentation) d_pmf.getModel(buildMetaAnalysis); return d_pm; } public MetaAnalysis createAnalysis(String name) { RandomEffectsMetaAnalysis ma = null; if (d_pm == null) { ma = buildMetaAnalysis(); } else { ma = d_pm.getBean(); } ma.setName(name); return ma; } @Override protected String getDescriptionTemplate() { return TEMPLATE_DEFINITIONS_DESCRIPTION; } }