001package jmri.jmrit.logixng.util.configurexml;
002
003import jmri.*;
004import jmri.configurexml.JmriConfigureXmlException;
005import jmri.jmrit.logixng.NamedBeanAddressing;
006import jmri.jmrit.logixng.util.LogixNG_SelectNamedBean;
007import jmri.jmrit.logixng.util.parser.ParserException;
008
009import org.jdom2.Element;
010
011/**
012 * Xml class for jmri.jmrit.logixng.util.LogixNG_SelectNamedBean.
013 *
014 * @param <E> the type of the named bean
015 *
016 * @author Daniel Bergqvist (C) 2022
017 */
018public class LogixNG_SelectNamedBeanXml<E extends NamedBean> {
019
020    public enum StoreNamedBean { Name, SystemName }
021
022    /**
023     * Default implementation for storing the contents of a LogixNG_SelectNamedBean
024     *
025     * @param selectNamedBean the LogixNG_SelectTable object
026     * @param tagName the name of the element
027     * @return Element containing the complete info
028     */
029    public Element store(LogixNG_SelectNamedBean<E> selectNamedBean, String tagName) {
030        return store(selectNamedBean, tagName, StoreNamedBean.Name);
031    }
032
033    public Element store(LogixNG_SelectNamedBean<E> selectNamedBean,
034            String tagName, StoreNamedBean storeNamedBean) {
035        Element namedBeanElement = new Element(tagName);
036
037        LogixNG_SelectTableXml selectTableXml = new LogixNG_SelectTableXml();
038
039        namedBeanElement.addContent(new Element("addressing").addContent(selectNamedBean.getAddressing().name()));
040        NamedBeanHandle<E> namedBeanHandle = selectNamedBean.getNamedBean();
041        if (namedBeanHandle != null) {
042            String name;
043            switch (storeNamedBean) {
044                case Name:
045                    name = namedBeanHandle.getName();
046                    break;
047                case SystemName:
048                    name = namedBeanHandle.getBean() != null
049                            ? namedBeanHandle.getBean().getSystemName() : null;
050                    break;
051                default:
052                    throw new IllegalArgumentException("storeNamedBean has unknown value: "+storeNamedBean.name());
053            }
054            if (name != null) {
055                namedBeanElement.addContent(new Element("name").addContent(name));
056            }
057        }
058        if (selectNamedBean.getReference() != null && !selectNamedBean.getReference().isEmpty()) {
059            namedBeanElement.addContent(new Element("reference").addContent(selectNamedBean.getReference()));
060        }
061        var memory = selectNamedBean.getMemory();
062        if (memory != null) {
063            namedBeanElement.addContent(new Element("memory").addContent(memory.getName()));
064        }
065        // Not used anymore. It's kept to not change old tables and panels files
066        namedBeanElement.addContent(new Element("listenToMemory").addContent("no"));
067        if (selectNamedBean.getLocalVariable() != null && !selectNamedBean.getLocalVariable().isEmpty()) {
068            namedBeanElement.addContent(new Element("localVariable").addContent(selectNamedBean.getLocalVariable()));
069        }
070        if (selectNamedBean.getFormula() != null && !selectNamedBean.getFormula().isEmpty()) {
071            namedBeanElement.addContent(new Element("formula").addContent(selectNamedBean.getFormula()));
072        }
073
074        if (selectNamedBean.getAddressing() == NamedBeanAddressing.Table) {
075            namedBeanElement.addContent(selectTableXml.store(selectNamedBean.getSelectTable(), "table"));
076        }
077
078        return namedBeanElement;
079    }
080
081    public void load(Element namedBeanElement, LogixNG_SelectNamedBean<E> selectNamedBean) throws JmriConfigureXmlException {
082        load(namedBeanElement, selectNamedBean, false);
083    }
084
085    public void load(Element namedBeanElement, LogixNG_SelectNamedBean<E> selectNamedBean, boolean delayedLookup) throws JmriConfigureXmlException {
086
087        if (namedBeanElement != null) {
088
089            LogixNG_SelectTableXml selectTableXml = new LogixNG_SelectTableXml();
090
091            try {
092                Element elem = namedBeanElement.getChild("addressing");
093                if (elem != null) {
094                    selectNamedBean.setAddressing(NamedBeanAddressing.valueOf(elem.getTextTrim()));
095                }
096
097                elem = namedBeanElement.getChild("name");
098                if (elem != null) {
099                    if (delayedLookup) {
100                        selectNamedBean.setDelayedNamedBean(elem.getTextTrim());
101                    } else {
102                        String name = elem.getTextTrim();
103                        E t = selectNamedBean.getManager().getNamedBean(name);
104                        if (t != null) selectNamedBean.setNamedBean(name, t);
105                        else selectNamedBean.removeNamedBean();
106                    }
107                }
108
109                elem = namedBeanElement.getChild("reference");
110                if (elem != null) selectNamedBean.setReference(elem.getTextTrim());
111
112                Element memoryName = namedBeanElement.getChild("memory");
113                if (memoryName != null) {
114                    Memory m = InstanceManager.getDefault(MemoryManager.class).getMemory(memoryName.getTextTrim());
115                    if (m != null) selectNamedBean.setMemory(m);
116                    else selectNamedBean.removeMemory();
117                }
118
119                elem = namedBeanElement.getChild("localVariable");
120                if (elem != null) selectNamedBean.setLocalVariable(elem.getTextTrim());
121
122                elem = namedBeanElement.getChild("formula");
123                if (elem != null) selectNamedBean.setFormula(elem.getTextTrim());
124
125                if (namedBeanElement.getChild("table") != null) {
126                    selectTableXml.load(namedBeanElement.getChild("table"), selectNamedBean.getSelectTable());
127                }
128
129            } catch (ParserException e) {
130                throw new JmriConfigureXmlException(e);
131            }
132        }
133    }
134
135    /**
136     * This method is for backward compability up to and including 4.99.4.Remove this class after 5.0.
137     *
138     * @param shared the shared element
139     * @param selectNamedBean the LogixNG_SelectNamedBean
140     * @param beanElementName the name of the element of the bean, for example "turnout"
141     * @throws JmriConfigureXmlException if an exception occurs
142     */
143    public void loadLegacy(
144            Element shared,
145            LogixNG_SelectNamedBean<E> selectNamedBean,
146            String beanElementName)
147            throws JmriConfigureXmlException {
148        loadLegacy(shared, selectNamedBean, beanElementName, "addressing", "reference", "localVariable", "formula");
149    }
150
151    /**
152     * This method is for backward compability up to and including 4.99.4.Remove this class after 5.0.
153     *
154     * @param shared the shared element
155     * @param selectNamedBean           the LogixNG_SelectNamedBean
156     * @param beanElementName           the name of the element of the bean, for example "turnout"
157     * @param addressingElementName     the name of the element of the addressing, for example "addressing"
158     * @param referenceElementName      the name of the element of the reference, for example "reference"
159     * @param localVariableElementName  the name of the element of the local variable, for example "localVariable"
160     * @param formulaElementName        the name of the element of the formula, for example "formula"
161     * @throws JmriConfigureXmlException if an exception occurs
162     */
163    public void loadLegacy(
164            Element shared,
165            LogixNG_SelectNamedBean<E> selectNamedBean,
166            String beanElementName,
167            String addressingElementName,
168            String referenceElementName,
169            String localVariableElementName,
170            String formulaElementName
171            )
172            throws JmriConfigureXmlException {
173
174        Element beanName = shared.getChild(beanElementName);
175        if (beanName != null) {
176            E t = selectNamedBean.getManager().getNamedBean(beanName.getTextTrim());
177            if (t != null) selectNamedBean.setNamedBean(t);
178            else selectNamedBean.removeNamedBean();
179        }
180
181        try {
182            Element elem;
183
184            if (addressingElementName != null) {
185                elem = shared.getChild(addressingElementName);
186                if (elem != null) {
187                    selectNamedBean.setAddressing(NamedBeanAddressing.valueOf(elem.getTextTrim()));
188                }
189            }
190
191            if (referenceElementName != null) {
192                elem = shared.getChild(referenceElementName);
193                if (elem != null) selectNamedBean.setReference(elem.getTextTrim());
194            }
195
196            if (localVariableElementName != null) {
197                elem = shared.getChild(localVariableElementName);
198                if (elem != null) selectNamedBean.setLocalVariable(elem.getTextTrim());
199            }
200
201            if (formulaElementName != null) {
202                elem = shared.getChild(formulaElementName);
203                if (elem != null) selectNamedBean.setFormula(elem.getTextTrim());
204            }
205
206        } catch (ParserException e) {
207            throw new JmriConfigureXmlException(e);
208        }
209    }
210
211
212    public interface GetNameFromNamedBeanHandle<E extends NamedBean> {
213        public String get(NamedBeanHandle<E> handle);
214    }
215
216}