001package jmri.jmrit.symbolicprog;
002
003import java.util.ArrayList;
004import java.util.List;
005import org.jdom2.Element;
006import org.jdom2.Parent;
007import org.slf4j.Logger;
008import org.slf4j.LoggerFactory;
009
010/**
011 * Abstract base for adding qualifiers to objects
012 *
013 * @see jmri.jmrit.symbolicprog.Qualifier
014 * @see jmri.jmrit.symbolicprog.ArithmeticQualifier
015 * @see jmri.jmrit.symbolicprog.tabbedframe.PaneProgFrame
016 *
017 * @author Bob Jacobsen Copyright (C) 2014
018 *
019 */
020public abstract class QualifierAdder {
021
022    /**
023     * Invoked to create the qualifier object and connect as needed. If extra
024     * state is needed, provide it via the subclass constructor.
025     *
026     * @param var      The variable that qualifies this, e.g. the one that's
027     *                 watched
028     * @param relation The relation term from the qualifier definition, e.g.
029     *                 greater than
030     * @param value    The value for the comparison
031     * @return the new Qualifier object for this request.
032     */
033    // e.g. return new PaneQualifier(pane, var, Integer.parseInt(value), relation, tabPane, index);
034    abstract protected Qualifier createQualifier(VariableValue var, String relation, String value);
035
036    // e.g. arrange for this to be sent a property change event on change of the qualified object
037    abstract protected void addListener(java.beans.PropertyChangeListener qc);
038
039    public void processModifierElements(Element e, VariableTableModel model) {
040
041        ArrayList<Qualifier> lq = new ArrayList<Qualifier>();
042
043        List<Element> le = e.getChildren("qualifier"); // we assign to this to allow us to suppress unchecked error
044        processList(le, lq, model);
045
046        // search for enclosing element so we can find all relevant qualifiers
047        Parent p = e;
048        while ((p = p.getParent()) != null && p instanceof Element) {
049            Element el = (Element) p;
050            if (el.getName().equals("pane")) {
051                break;  // stop when we get to an enclosing pane element
052            }
053            List<Element> le2 = el.getChildren("qualifier");  // we assign to this to allow us to suppress unchecked error
054            processList(le2, lq, model);
055        }
056
057        // Add the AND logic - listen for change and ensure result correct
058        if (lq.size() > 1) {
059            new QualifierCombiner(lq);
060        }
061    }
062
063    void processList(List<Element> le, ArrayList<Qualifier> lq, VariableTableModel model) {
064        for (Element q : le) {
065            processElement(q, lq, model);
066        }
067    }
068
069    void processElement(Element q, ArrayList<Qualifier> lq, VariableTableModel model) {
070        if (q.getChild("variableref") == null) {
071            log.error("Pane qualifier element 'variableref' is NULL");
072            return;
073        }
074        String variableRef = q.getChild("variableref").getText();
075        if (q.getChild("relation") == null) {
076            log.error("Pane qualifier element 'relation' is NULL");
077            return;
078        }
079        String relation = q.getChild("relation").getText();
080        if (q.getChild("value") == null) {
081            log.error("Pane qualifier element 'value' is NULL");
082            return;
083        }
084        String value = q.getChild("value").getText();
085
086        // find the variable
087        VariableValue var = model.findVar(variableRef);
088
089        if (var != null || relation.equals("exists")) {
090            // found, attach the qualifier object through creating it
091            log.debug("Attached {} variable for {} {} qualifier", variableRef, relation, value);
092        } else {
093            log.debug("Didn't find {} variable for {} {} qualifier", variableRef, relation, value);
094        }
095
096        // create qualifier
097        Qualifier qual = createQualifier(var, relation, value);
098        qual.update();
099        lq.add(qual);
100    }
101
102    private final static Logger log = LoggerFactory.getLogger(QualifierAdder.class);
103
104}