001package jmri.jmrit.logixng.actions.configurexml;
002
003import jmri.*;
004import jmri.configurexml.JmriConfigureXmlException;
005import jmri.jmrit.logixng.DigitalActionManager;
006import jmri.jmrit.logixng.NamedBeanAddressing;
007import jmri.jmrit.logixng.NamedTable;
008import jmri.jmrit.logixng.NamedTableManager;
009import jmri.jmrit.logixng.actions.ActionLocalVariable;
010import jmri.jmrit.logixng.actions.ActionLocalVariable.ConstantType;
011import jmri.jmrit.logixng.util.configurexml.LogixNG_SelectNamedBeanXml;
012import jmri.jmrit.logixng.util.configurexml.LogixNG_SelectTableXml;
013import jmri.jmrit.logixng.util.parser.ParserException;
014
015import org.jdom2.Element;
016
017/**
018 * Handle XML configuration for ActionLocalVariable objects.
019 *
020 * @author Bob Jacobsen Copyright: Copyright (c) 2004, 2008, 2010
021 * @author Daniel Bergqvist Copyright (C) 2019
022 */
023public class ActionLocalVariableXml extends jmri.managers.configurexml.AbstractNamedBeanManagerConfigXML {
024
025    public ActionLocalVariableXml() {
026    }
027
028    /**
029     * Default implementation for storing the contents of a ActionLocalVariable
030     *
031     * @param o Object to store, of type ActionLocalVariable
032     * @return Element containing the complete info
033     */
034    @Override
035    public Element store(Object o) {
036        ActionLocalVariable p = (ActionLocalVariable) o;
037
038        LogixNG_SelectTableXml selectTableXml = new LogixNG_SelectTableXml();
039
040        Element element = new Element("ActionLocalVariable");   // NOI18N
041        element.setAttribute("class", this.getClass().getName());   // NOI18N
042        element.addContent(new Element("systemName").addContent(p.getSystemName()));    // NOI18N
043
044        storeCommon(p, element);
045
046        var selectMemoryNamedBeanXml = new LogixNG_SelectNamedBeanXml<Memory>();
047        var selectBlockNamedBeanXml = new LogixNG_SelectNamedBeanXml<Block>();
048        var selectReporterNamedBeanXml = new LogixNG_SelectNamedBeanXml<Reporter>();
049
050        String variableName = p.getLocalVariable();
051        if (variableName != null) {
052            element.addContent(new Element("variable").addContent(variableName));   // NOI18N
053        }
054
055        element.addContent(selectMemoryNamedBeanXml.store(p.getSelectMemoryNamedBean(), "memoryNamedBean"));
056        element.addContent(new Element("listenToMemory").addContent(p.getListenToMemory() ? "yes" : "no"));
057
058        element.addContent(selectBlockNamedBeanXml.store(p.getSelectBlockNamedBean(), "blockNamedBean"));
059        element.addContent(new Element("listenToBlock").addContent(p.getListenToBlock() ? "yes" : "no"));
060
061        element.addContent(selectReporterNamedBeanXml.store(p.getSelectReporterNamedBean(), "reporterNamedBean"));
062        element.addContent(new Element("listenToReporter").addContent(p.getListenToReporter() ? "yes" : "no"));
063
064        element.addContent(new Element("variableOperation").addContent(p.getVariableOperation().name()));   // NOI18N
065
066        element.addContent(new Element("constantType").addContent(p.getConstantType().name()));   // NOI18N
067        element.addContent(new Element("constant").addContent(p.getConstantValue()));   // NOI18N
068        element.addContent(new Element("otherVariable").addContent(p.getOtherLocalVariable())); // NOI18N
069        element.addContent(new Element("reference").addContent(p.getReference())); // NOI18N
070        element.addContent(new Element("formula").addContent(p.getFormula()));  // NOI18N
071
072        element.addContent(selectTableXml.store(p.getSelectTable(), "table"));
073
074        return element;
075    }
076
077    @Override
078    public boolean load(Element shared, Element perNode) throws JmriConfigureXmlException {
079        String sys = getSystemName(shared);
080        String uname = getUserName(shared);
081        ActionLocalVariable h = new ActionLocalVariable(sys, uname);
082
083        LogixNG_SelectTableXml selectTableXml = new LogixNG_SelectTableXml();
084
085        loadCommon(h, shared);
086
087        var selectMemoryNamedBeanXml = new LogixNG_SelectNamedBeanXml<Memory>();
088        var selectBlockNamedBeanXml = new LogixNG_SelectNamedBeanXml<Block>();
089        var selectReporterNamedBeanXml = new LogixNG_SelectNamedBeanXml<Reporter>();
090
091        Element variableName = shared.getChild("variable"); // NOI18N
092        if (variableName != null) {
093            h.setLocalVariable(variableName.getTextTrim());
094        }
095
096        selectMemoryNamedBeanXml.load(shared.getChild("memoryNamedBean"), h.getSelectMemoryNamedBean());
097        selectBlockNamedBeanXml.load(shared.getChild("blockNamedBean"), h.getSelectBlockNamedBean());
098        selectReporterNamedBeanXml.load(shared.getChild("reporterNamedBean"), h.getSelectReporterNamedBean());
099
100        Element listenToMemoryElem = shared.getChild("listenToMemory");
101        if (listenToMemoryElem != null) {
102            h.setListenToMemory("yes".equals(listenToMemoryElem.getTextTrim()));
103        }
104
105        Element listenToBlockElem = shared.getChild("listenToBlock");
106        if (listenToBlockElem != null) {
107            h.setListenToBlock("yes".equals(listenToBlockElem.getTextTrim()));
108        }
109
110        Element listenToReporterElem = shared.getChild("listenToReporter");
111        if (listenToReporterElem != null) {
112            h.setListenToReporter("yes".equals(listenToReporterElem.getTextTrim()));
113        }
114
115        //********************************************************
116        // For backwards compability for 4.99.7 and earlier
117        Element memoryName = shared.getChild("memory"); // NOI18N
118        if (memoryName != null) {
119            Memory t = InstanceManager.getDefault(MemoryManager.class).getMemory(memoryName.getTextTrim());
120            if (t != null) h.getSelectMemoryNamedBean().setNamedBean(t);
121            else h.getSelectMemoryNamedBean().removeNamedBean();
122
123            String yesno = "yes";   // Default is "yes" since this attribute is not in panel files before 4.99.3
124            if (memoryName.getAttribute("listen") != null) {  // NOI18N
125                yesno = memoryName.getAttribute("listen").getValue();  // NOI18N
126            }
127            h.setListenToMemory(yesno.equals("yes"));   // NOI18N
128        }
129        Element blockName = shared.getChild("block");   // NOI18N
130        if (blockName != null) {
131            Block t = InstanceManager.getDefault(BlockManager.class).getBlock(blockName.getTextTrim());
132            if (t != null) h.getSelectBlockNamedBean().setNamedBean(t);
133            else h.getSelectBlockNamedBean().removeNamedBean();
134
135            String yesno = "yes";   // Default is "yes" since this attribute is not in panel files before 4.99.3
136            if (blockName.getAttribute("listen") != null) {  // NOI18N
137                yesno = blockName.getAttribute("listen").getValue();  // NOI18N
138            }
139            h.setListenToBlock(yesno.equals("yes"));   // NOI18N
140        }
141        Element reporterName = shared.getChild("reporter"); // NOI18N
142        if (reporterName != null) {
143            Reporter t = InstanceManager.getDefault(ReporterManager.class).getReporter(reporterName.getTextTrim());
144            if (t != null) h.getSelectReporterNamedBean().setNamedBean(t);
145            else h.getSelectReporterNamedBean().removeNamedBean();
146
147            String yesno = "yes";   // Default is "yes" since this attribute is not in panel files before 4.99.3
148            if (reporterName.getAttribute("listen") != null) {  // NOI18N
149                yesno = reporterName.getAttribute("listen").getValue();  // NOI18N
150            }
151            h.setListenToReporter(yesno.equals("yes"));   // NOI18N
152        }
153        // For backwards compability for 4.99.7 and earlier
154        //********************************************************
155
156        Element queryType = shared.getChild("variableOperation");   // NOI18N
157        if (queryType != null) {
158            try {
159                h.setVariableOperation(ActionLocalVariable.VariableOperation.valueOf(queryType.getTextTrim()));
160            } catch (ParserException e) {
161                log.error("cannot set variable operation: {}", queryType.getTextTrim(), e);  // NOI18N
162            }
163        }
164
165        Element constantType = shared.getChild("constantType"); // NOI18N
166        if (constantType != null) {
167            h.setConstantType(ConstantType.valueOf(constantType.getTextTrim()));
168        }
169
170        Element constant = shared.getChild("constant"); // NOI18N
171        if (constant != null) {
172            h.setConstantValue(constant.getTextTrim());
173        }
174
175        Element otherTableCell = shared.getChild("otherTableCell"); // NOI18N
176        if (otherTableCell != null) {
177            boolean result = false;
178            String ref = otherTableCell.getTextTrim();
179            if (!ref.isEmpty()) {
180                String[] refParts = ref.substring(1).split("[\\[\\]]");  // Remove first { and then split on [ and ]
181//                System.out.format("refParts.length: %d, '%s', '%s'%n", refParts.length, refParts[0], refParts[1]);
182                if (refParts.length == 3) {
183                    String table = refParts[0];
184                    String[] rowColumnParts = refParts[1].split(",");
185                    if (rowColumnParts.length == 2) {
186                        String row = rowColumnParts[0];
187                        String column = rowColumnParts[1];
188//                        System.out.format("Table: '%s', row: '%s', column: '%s'%n", table, row, column);
189
190                        h.getSelectTable().setTableNameAddressing(NamedBeanAddressing.Direct);
191                        if (table != null) {
192                            NamedTable t = InstanceManager.getDefault(NamedTableManager.class).getNamedTable(table);
193                            if (t != null) h.getSelectTable().setTable(t);
194                            else h.getSelectTable().removeTable();
195                        }
196                        h.getSelectTable().setTableRowAddressing(NamedBeanAddressing.Direct);
197                        h.getSelectTable().setTableRowName(row);
198                        h.getSelectTable().setTableColumnAddressing(NamedBeanAddressing.Direct);
199                        h.getSelectTable().setTableColumnName(column);
200                        result = true;
201                    }
202                }
203                if (!result) throw new JmriConfigureXmlException("otherTableCell has invalid value: "+ref);
204            }
205        }
206
207        selectTableXml.load(shared.getChild("table"), h.getSelectTable());
208
209        Element otherVariable = shared.getChild("otherVariable");   // NOI18N
210        if (otherVariable != null) {
211            h.setOtherLocalVariable(otherVariable.getTextTrim());
212        }
213
214        Element reference = shared.getChild("reference");   // NOI18N
215        if (reference != null) {
216            h.setReference(reference.getTextTrim());
217        }
218
219        Element formula = shared.getChild("formula");   // NOI18N
220        if (formula != null) {
221            try {
222                h.setFormula(formula.getTextTrim());
223            } catch (ParserException e) {
224                log.error("cannot set data: {}", formula.getTextTrim(), e);  // NOI18N
225            }
226        }
227
228        InstanceManager.getDefault(DigitalActionManager.class).registerAction(h);
229        return true;
230    }
231
232    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ActionLocalVariableXml.class);
233}