001package jmri.jmrit.symbolicprog;
002
003/**
004 * Watches a specific Variable to qualify another object, e.g. another Variable
005 * or a Pane.
006 * <p>
007 * The "qualifier" variable is the one being watched; its properties control
008 * whether the "qualified" Object is available or not.
009 *
010 * @author Bob Jacobsen Copyright (C) 2010, 2014
011 *
012 */
013public abstract class AbstractQualifier implements Qualifier, java.beans.PropertyChangeListener {
014
015    public AbstractQualifier(VariableValue watchedVal) {
016        this.watchedVal = watchedVal;
017
018        // set up listener
019        if (watchedVal != null) {
020            watchedVal.addPropertyChangeListener(this);
021        }
022
023        // subclass ctors are required to qualify on initial value of variable
024        // to get initial qualification state right after listener was added.
025    }
026
027    VariableValue watchedVal;
028    public VariableValue getWatchedVariable() {
029        return this.watchedVal;
030    }
031
032    /**
033     * Process property change from the qualifier Variable (one being watched).
034     * <p>
035     * Follows changes "Value" property, which it assumes is an Integer.
036     * @param e The event that triggered the query
037     */
038    @Override
039    public void propertyChange(java.beans.PropertyChangeEvent e) {
040        if (e.getPropertyName().equals("Value")) {
041            processValueChangeEvent(e);
042        }
043    }
044
045    /**
046     * Process Value property change from the qualifier Variable (one being
047     * watched).
048     * @param e The event that triggered the query
049     */
050    void processValueChangeEvent(java.beans.PropertyChangeEvent e) {
051        // watched value change, check if this changes state of qualified (output) object
052        boolean oldAvailableValue = currentAvailableState();
053        boolean newAvailableValue = availableStateFromEvent(e);
054
055        if (oldAvailableValue != newAvailableValue) {
056            setWatchedAvailable(newAvailableValue);
057        }
058    }
059
060    /**
061     * Calculate whether this PropertyChangeEvent means that the qualified
062     * Object should be set Available or not.
063     * @param e The event that triggered the query
064     * @return true if should be set available
065     */
066    protected boolean availableStateFromEvent(java.beans.PropertyChangeEvent e) {
067        return availableStateFromValue(e.getNewValue());
068    }
069
070    /**
071     * Retrieve the current "available" state from the qualified Object.
072     * @return true if available
073     */
074    abstract protected boolean currentAvailableState();
075
076    /**
077     * Does the current value of qualifier Variable means that the
078     * qualified object should be set Available or not?
079     * @return true if should be set available
080     */
081    @Override
082    abstract public boolean currentDesiredState();
083
084    /**
085     * Calculate whether a particular value for the qualifier Variable means
086     * that the qualified Object should be set Available or not.
087     *
088     * @param value base for the calculation
089     * @return true if should be set available
090     */
091    abstract protected boolean availableStateFromValue(Object value);
092
093    /**
094     * Drive the available or not state of the qualified Object.
095     * <p>
096     * Subclasses implement this to control a specific type of qualified Object,
097     * like a Variable or Pane.
098     * @param enable true if should be enabled
099     */
100    @Override
101    abstract public void setWatchedAvailable(boolean enable);
102
103}