/* * 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.Arrays; import java.util.Collection; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import org.drugis.addis.entities.Domain; import org.drugis.addis.entities.EntityIdExistsException; import org.drugis.addis.entities.Indication; import org.drugis.addis.entities.OutcomeMeasure; import org.drugis.addis.entities.analysis.BenefitRiskAnalysis; import org.drugis.addis.entities.analysis.DecisionContext; import org.drugis.addis.entities.analysis.BenefitRiskAnalysis.AnalysisType; import org.drugis.addis.presentation.ModifiableHolder; import org.drugis.addis.presentation.ValueHolder; import org.drugis.common.validation.BooleanAndModel; import org.drugis.common.validation.ListMinimumSizeModel; import org.pietschy.wizard.InvalidStateException; import com.jgoodies.binding.list.ArrayListModel; import com.jgoodies.binding.list.ObservableList; import com.jgoodies.binding.value.AbstractConverter; import com.jgoodies.binding.value.ValueModel; public abstract class CriteriaAndAlternativesPresentation<Alternative extends Comparable<Alternative>> { final SelectableOptionsModel<OutcomeMeasure> d_selectedCriteria; final SelectableOptionsModel<Alternative> d_selectedAlternatives; private OptionsEnabledModel<OutcomeMeasure> d_enabledCriteria; final OptionsEnabledModel<Alternative> d_enabledAlternatives; protected final ModifiableHolder<AnalysisType> d_analysisTypeHolder; protected final ModifiableHolder<Alternative> d_baselineModel; protected final ValueHolder<Indication> d_indicationModel; protected final ValueModel d_completeModel; protected final ObservableList<Alternative> d_availableAlternatives; protected final ListDataListener d_resetAlternativeEnabledModelsListener; public CriteriaAndAlternativesPresentation(final ValueHolder<Indication> indication, final ModifiableHolder<AnalysisType> analysisType) { d_indicationModel = indication; d_analysisTypeHolder = analysisType; d_selectedCriteria = new SelectableOptionsModel<OutcomeMeasure>(); d_enabledCriteria = new OptionsEnabledModel<OutcomeMeasure>(d_selectedCriteria, true) { public boolean optionShouldBeEnabled(OutcomeMeasure option) { return getCriterionShouldBeEnabled(option); } }; d_selectedAlternatives = new SelectableOptionsModel<Alternative>(); d_enabledAlternatives = new OptionsEnabledModel<Alternative>(d_selectedAlternatives, true) { public boolean optionShouldBeEnabled(Alternative alt) { return getAlternativeShouldBeEnabled(alt); } }; d_baselineModel = new ModifiableHolder<Alternative>(); d_availableAlternatives = new ArrayListModel<Alternative>(); PropertyChangeListener resetValuesListener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { reset(); } }; d_indicationModel.addValueChangeListener(resetValuesListener); d_analysisTypeHolder.addValueChangeListener(resetValuesListener); d_resetAlternativeEnabledModelsListener = new ListDataListener() { public void contentsChanged(ListDataEvent e) { d_enabledAlternatives.update(); } public void intervalAdded(ListDataEvent e) { d_enabledAlternatives.update(); } public void intervalRemoved(ListDataEvent e) { d_enabledAlternatives.update(); } }; getSelectedCriteria().addListDataListener(d_resetAlternativeEnabledModelsListener); getSelectedAlternatives().addListDataListener(d_resetAlternativeEnabledModelsListener); ListDataListener resetCriteriaEnabledModels = new ListDataListener() { public void contentsChanged(ListDataEvent e) { updateCriteriaEnabled(); } public void intervalAdded(ListDataEvent e) { updateCriteriaEnabled(); } public void intervalRemoved(ListDataEvent e) { updateCriteriaEnabled(); } }; getSelectedCriteria().addListDataListener(resetCriteriaEnabledModels); AbstractConverter baselineValidModel = new AbstractConverter(d_baselineModel) { private static final long serialVersionUID = -8879640617811142054L; @Override public void setValue(Object newValue) { } @Override public Boolean convertFromSubject(Object subjectValue) { return getSelectedAlternatives().contains(subjectValue); } }; d_completeModel = new BooleanAndModel(Arrays.<ValueModel>asList( new ListMinimumSizeModel(getSelectedAlternatives(), 2), new ListMinimumSizeModel(getSelectedCriteria(), 2), baselineValidModel)); } protected abstract void reset(); public abstract ObservableList<OutcomeMeasure> getCriteriaListModel(); public ValueHolder<Boolean> getCriterionSelectedModel(OutcomeMeasure om) { return d_selectedCriteria.getSelectedModel(om); } public ValueHolder<Boolean> getAlternativeSelectedModel(Alternative alternative) { return d_selectedAlternatives.getSelectedModel(alternative); } public ValueHolder<Boolean> getAlternativeEnabledModel(Alternative e) { return d_enabledAlternatives.getEnabledModel(e); } public ValueHolder<Boolean> getCriterionEnabledModel(OutcomeMeasure out) { return d_enabledCriteria.getEnabledModel(out); } public abstract ValueModel getCompleteModel(); public BenefitRiskAnalysis<Alternative> saveAnalysis(Domain domain, String id, DecisionContext context) throws InvalidStateException, EntityIdExistsException { BenefitRiskAnalysis<Alternative> brAnalysis = createAnalysis(id, context); if(domain.getBenefitRiskAnalyses().contains(brAnalysis)) throw new EntityIdExistsException("Benefit Risk Analysis with this ID already exists in domain"); domain.getBenefitRiskAnalyses().add(brAnalysis); return brAnalysis; } public abstract BenefitRiskAnalysis<Alternative> createAnalysis(String id, DecisionContext context) throws InvalidStateException; public ObservableList<Alternative> getSelectedAlternatives() { return d_selectedAlternatives.getSelectedOptions(); } public ObservableList<OutcomeMeasure> getSelectedCriteria() { return d_selectedCriteria.getSelectedOptions(); } public ValueModel getBaselineModel() { return d_baselineModel; } protected void initCriteria() { for (OutcomeMeasure om : getCriteriaListModel()) { d_selectedCriteria.addOption(om, false); } } protected void initAlternatives(Collection<Alternative> alternatives) { d_availableAlternatives.addAll(alternatives); // create alternative selected models for (Alternative alt : alternatives) { d_selectedAlternatives.addOption(alt, false); } } protected boolean getAlternativeShouldBeEnabled(Alternative alt) { if (getAlternativeSelectedModel(alt).getValue() == true) { return true; } if (d_analysisTypeHolder.getValue() == AnalysisType.LyndOBrien) { return getSelectedAlternatives().size() < 2; } return true; } protected boolean getCriterionShouldBeEnabled(OutcomeMeasure crit) { if (getCriterionSelectedModel(crit).getValue() == true) { return true; } if (d_analysisTypeHolder.getValue() == AnalysisType.LyndOBrien) { return getSelectedCriteria().size() < 2; } return true; } private void updateCriteriaEnabled() { d_enabledCriteria.update(); } public ObservableList<Alternative> getAlternativesListModel() { return d_availableAlternatives; } }