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        namedBeanElement.addContent(new Element("listenToMemory").addContent(selectNamedBean.getListenToMemory() ? "yes" : "no"));
066        if (selectNamedBean.getLocalVariable() != null && !selectNamedBean.getLocalVariable().isEmpty()) {
067            namedBeanElement.addContent(new Element("localVariable").addContent(selectNamedBean.getLocalVariable()));
068        }
069        if (selectNamedBean.getFormula() != null && !selectNamedBean.getFormula().isEmpty()) {
070            namedBeanElement.addContent(new Element("formula").addContent(selectNamedBean.getFormula()));
071        }
072
073        if (selectNamedBean.getAddressing() == NamedBeanAddressing.Table) {
074            namedBeanElement.addContent(selectTableXml.store(selectNamedBean.getSelectTable(), "table"));
075        }
076
077        return namedBeanElement;
078    }
079
080    public void load(Element namedBeanElement, LogixNG_SelectNamedBean<E> selectNamedBean) throws JmriConfigureXmlException {
081        load(namedBeanElement, selectNamedBean, false);
082    }
083
084    public void load(Element namedBeanElement, LogixNG_SelectNamedBean<E> selectNamedBean, boolean delayedLookup) throws JmriConfigureXmlException {
085
086        if (namedBeanElement != null) {
087
088            LogixNG_SelectTableXml selectTableXml = new LogixNG_SelectTableXml();
089
090            try {
091                Element elem = namedBeanElement.getChild("addressing");
092                if (elem != null) {
093                    selectNamedBean.setAddressing(NamedBeanAddressing.valueOf(elem.getTextTrim()));
094                }
095
096                elem = namedBeanElement.getChild("name");
097                if (elem != null) {
098                    if (delayedLookup) {
099                        selectNamedBean.setDelayedNamedBean(elem.getTextTrim());
100                    } else {
101                        String name = elem.getTextTrim();
102                        E t = selectNamedBean.getManager().getNamedBean(name);
103                        if (t != null) selectNamedBean.setNamedBean(name, t);
104                        else selectNamedBean.removeNamedBean();
105                    }
106                }
107
108                elem = namedBeanElement.getChild("reference");
109                if (elem != null) selectNamedBean.setReference(elem.getTextTrim());
110
111                Element memoryName = namedBeanElement.getChild("memory");
112                if (memoryName != null) {
113                    Memory m = InstanceManager.getDefault(MemoryManager.class).getMemory(memoryName.getTextTrim());
114                    if (m != null) selectNamedBean.setMemory(m);
115                    else selectNamedBean.removeMemory();
116                }
117
118                Element listenToMemoryElem = namedBeanElement.getChild("listenToMemory");
119                if (listenToMemoryElem != null) {
120                    selectNamedBean.setListenToMemory("yes".equals(listenToMemoryElem.getTextTrim()));
121                }
122
123                elem = namedBeanElement.getChild("localVariable");
124                if (elem != null) selectNamedBean.setLocalVariable(elem.getTextTrim());
125
126                elem = namedBeanElement.getChild("formula");
127                if (elem != null) selectNamedBean.setFormula(elem.getTextTrim());
128
129                if (namedBeanElement.getChild("table") != null) {
130                    selectTableXml.load(namedBeanElement.getChild("table"), selectNamedBean.getSelectTable());
131                }
132
133            } catch (ParserException e) {
134                throw new JmriConfigureXmlException(e);
135            }
136        }
137    }
138
139    /**
140     * This method is for backward compability up to and including 4.99.4.Remove this class after 5.0.
141     *
142     * @param shared the shared element
143     * @param selectNamedBean the LogixNG_SelectNamedBean
144     * @param beanElementName the name of the element of the bean, for example "turnout"
145     * @throws JmriConfigureXmlException if an exception occurs
146     */
147    public void loadLegacy(
148            Element shared,
149            LogixNG_SelectNamedBean<E> selectNamedBean,
150            String beanElementName)
151            throws JmriConfigureXmlException {
152        loadLegacy(shared, selectNamedBean, beanElementName, "addressing", "reference", "localVariable", "formula");
153    }
154
155    /**
156     * This method is for backward compability up to and including 4.99.4.Remove this class after 5.0.
157     *
158     * @param shared the shared element
159     * @param selectNamedBean           the LogixNG_SelectNamedBean
160     * @param beanElementName           the name of the element of the bean, for example "turnout"
161     * @param addressingElementName     the name of the element of the addressing, for example "addressing"
162     * @param referenceElementName      the name of the element of the reference, for example "reference"
163     * @param localVariableElementName  the name of the element of the local variable, for example "localVariable"
164     * @param formulaElementName        the name of the element of the formula, for example "formula"
165     * @throws JmriConfigureXmlException if an exception occurs
166     */
167    public void loadLegacy(
168            Element shared,
169            LogixNG_SelectNamedBean<E> selectNamedBean,
170            String beanElementName,
171            String addressingElementName,
172            String referenceElementName,
173            String localVariableElementName,
174            String formulaElementName
175            )
176            throws JmriConfigureXmlException {
177
178        Element beanName = shared.getChild(beanElementName);
179        if (beanName != null) {
180            E t = selectNamedBean.getManager().getNamedBean(beanName.getTextTrim());
181            if (t != null) selectNamedBean.setNamedBean(t);
182            else selectNamedBean.removeNamedBean();
183        }
184
185        try {
186            Element elem;
187
188            if (addressingElementName != null) {
189                elem = shared.getChild(addressingElementName);
190                if (elem != null) {
191                    selectNamedBean.setAddressing(NamedBeanAddressing.valueOf(elem.getTextTrim()));
192                }
193            }
194
195            if (referenceElementName != null) {
196                elem = shared.getChild(referenceElementName);
197                if (elem != null) selectNamedBean.setReference(elem.getTextTrim());
198            }
199
200            if (localVariableElementName != null) {
201                elem = shared.getChild(localVariableElementName);
202                if (elem != null) selectNamedBean.setLocalVariable(elem.getTextTrim());
203            }
204
205            if (formulaElementName != null) {
206                elem = shared.getChild(formulaElementName);
207                if (elem != null) selectNamedBean.setFormula(elem.getTextTrim());
208            }
209
210        } catch (ParserException e) {
211            throw new JmriConfigureXmlException(e);
212        }
213    }
214
215
216    public interface GetNameFromNamedBeanHandle<E extends NamedBean> {
217        public String get(NamedBeanHandle<E> handle);
218    }
219
220}