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}