001package jmri.jmrit.symbolicprog;
002
003import java.util.ArrayList;
004import java.util.List;
005
006/**
007 * Force a set of Qualifiers to work in an AND relationship.
008 * <p>
009 * On transition, the qualifiers are evaluated in order, stopping when the
010 * outcome is known.
011 *
012 * @author Bob Jacobsen Copyright (C) 2011
013 */
014public class QualifierCombiner implements Qualifier, java.beans.PropertyChangeListener {
015
016    public QualifierCombiner(List<Qualifier> qualifiers) {
017        this.qualifiers = qualifiers;
018
019        // handle the change events here so
020        // add a listener for each VariableValue used by the component qualifiers
021        // and remove the listeners for the component qualifiers
022        ArrayList<VariableValue> lv = new ArrayList<VariableValue>();
023        for (Qualifier q : qualifiers) {
024            AbstractQualifier aq = (AbstractQualifier)q;
025            VariableValue v = aq.getWatchedVariable();
026            if (v != null) {
027                // only add one listener for any given VariableValue
028                if (!lv.contains(v)) {
029                    lv.add(v);
030                    v.addPropertyChangeListener(this);
031                }
032                // remove listener from component qualifier
033                v.removePropertyChangeListener(aq);
034            }
035        }
036
037        setWatchedAvailable(currentDesiredState());
038    }
039
040    List<Qualifier> qualifiers;
041
042    @Override
043    public void propertyChange(java.beans.PropertyChangeEvent e) {
044        if (e.getPropertyName().equals("Value")) {
045            setWatchedAvailable(currentDesiredState());  // relies on non-propagation of null changes
046        }
047    }
048
049    @Override
050    public void setWatchedAvailable(boolean enable) {
051        qualifiers.get(0).setWatchedAvailable(enable);
052    }
053
054    @Override
055    public boolean currentDesiredState() {
056        for (Qualifier q : qualifiers) {
057            if (!q.currentDesiredState()) {
058                return false;
059            }
060        }
061        return true;
062    }
063
064    @Override
065    public void update() {
066        setWatchedAvailable(currentDesiredState());
067    }
068}