001package jmri.managers.configurexml;
002
003import java.util.List;
004import java.util.SortedSet;
005
006import jmri.InstanceManager;
007import jmri.JmriException;
008import jmri.SignalMast;
009import jmri.configurexml.XmlAdapter;
010import jmri.implementation.SignalMastRepeater;
011import jmri.managers.DefaultSignalMastManager;
012import org.jdom2.Element;
013import org.slf4j.Logger;
014import org.slf4j.LoggerFactory;
015
016/**
017 * Handle XML configuration for a DefaultSignalMastManager objects.
018 *
019 * @author Bob Jacobsen Copyright: Copyright (c) 2009
020 */
021public class DefaultSignalMastManagerXml
022        extends jmri.managers.configurexml.AbstractNamedBeanManagerConfigXML {
023
024    public DefaultSignalMastManagerXml() {
025    }
026
027    /**
028     * Default implementation for storing the contents of a
029     * DefaultSignalMastManager.
030     *
031     * @param o Object to store
032     * @return Element containing the complete info
033     */
034    @Override
035    public Element store(Object o) {
036        Element signalmasts = new Element("signalmasts");
037        signalmasts.setAttribute("class", this.getClass().getName());
038        DefaultSignalMastManager smm = (DefaultSignalMastManager) o;
039        if (smm != null) {
040            SortedSet<SignalMast> smList = smm.getNamedBeanSet();
041            // don't return an element if there are no SignalMasts to include
042            if (smList.isEmpty()) {
043                return null;
044            }
045            // include contents
046            for (SignalMast sm : smList) {
047                Element e = jmri.configurexml.ConfigXmlManager.elementFromObject(sm);
048                if (e != null) {
049                    signalmasts.addContent(e);
050                }
051            }
052            List<SignalMastRepeater> repeaterList = smm.getRepeaterList();
053            if (repeaterList.size() > 0) {
054                for (SignalMastRepeater smr : repeaterList) {
055                    Element e = new Element("signalmastrepeater");
056                    e.addContent(new Element("masterMast").addContent(smr.getMasterMastName()));
057                    e.addContent(new Element("slaveMast").addContent(smr.getSlaveMastName()));
058                    e.addContent(new Element("enabled").addContent(smr.getEnabled() ? "true" : "false"));
059                    switch (smr.getDirection()) {
060                        case 1:
061                            e.addContent(new Element("update").addContent("MasterToSlave"));
062                            break;
063                        case 2:
064                            e.addContent(new Element("update").addContent("SlaveToMaster"));
065                            break;
066                        default:
067                            e.addContent(new Element("update").addContent("BothWay"));
068                            break;
069                    }
070                    signalmasts.addContent(e);
071                }
072            }
073        }
074        return signalmasts;
075    }
076
077    /**
078     * Create a DefaultSignalMastManager.
079     *
080     * @param shared Top level Element to unpack.
081     * @param perNode Top level Element that is per-node.
082     * @return true if successful
083     */
084    @Override
085    public boolean load(Element shared, Element perNode) {
086        // loop over contained signalmast elements
087        List<Element> mastList = shared.getChildren("signalmast");
088        boolean result = true;
089
090        for (Element e : mastList) {
091            if (e.getAttribute("class") == null) {
092                SignalMast m;
093                String sys = getSystemName(e);
094                try {
095                    m = InstanceManager.getDefault(jmri.SignalMastManager.class)
096                            .provideSignalMast(sys);
097
098                    if (getUserName(e) != null) {
099                        m.setUserName(getUserName(e));
100                    }
101
102                    loadCommon(m, e);
103                } catch (IllegalArgumentException ex) {
104                    log.warn("Failed to provide SignalMast \"{}\" in load", sys);
105                }
106            } else {
107                String adapterName = e.getAttribute("class").getValue();
108                log.debug("load via {}", adapterName);
109                try {
110                    XmlAdapter adapter = (XmlAdapter) Class.forName(adapterName).getDeclaredConstructor().newInstance();
111                    // and do it
112                    adapter.load(e, null);
113                } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException
114                            | IllegalAccessException | java.lang.reflect.InvocationTargetException
115                            | jmri.configurexml.JmriConfigureXmlException ex) {
116                    log.error("Exception while loading {}: {}", e.getName(), ex, ex);
117                }
118            }
119        }
120
121        loadSignalMastClass(shared, "turnoutsignalmast");
122        loadSignalMastClass(shared, "virtualsignalmast");
123        loadSignalMastClass(shared, "mqttsignalmast");
124        loadSignalMastClass(shared, "matrixsignalmast");
125        loadSignalMastClass(shared, "dccsignalmast");
126        loadSignalMastClass(shared, "olcbsignalmast");
127
128        mastList = shared.getChildren("signalmastrepeater");
129        if (mastList != null) {
130            DefaultSignalMastManager m = (DefaultSignalMastManager) InstanceManager.getDefault(jmri.SignalMastManager.class);
131            for (Element e : mastList) {
132                String masterName = e.getChild("masterMast").getText();
133                String slaveName = e.getChild("slaveMast").getText();
134                SignalMast masterMast = m.getSignalMast(masterName);
135                if (masterMast == null) {
136                    log.error("Unable to add mast repeater {}: {}. Master mast must exist.", masterName, slaveName);
137                    result = false;
138                    continue;
139                }
140                SignalMast slaveMast = m.getSignalMast(slaveName);
141                if (slaveMast == null) {
142                    log.error("Unable to add mast repeater {}: {}. Slave mast must exist.", masterName, slaveName);
143                    result = false;
144                    continue;
145                }
146
147                SignalMastRepeater smr = null;
148                try {
149                    smr = m.provideRepeater(masterMast, slaveMast);
150                } catch (JmriException e1) {
151                    log.error("Unable to add mast repeater {}: {}", masterName, slaveName, e1);
152                    result = false;
153                    continue;
154                }
155                if (e.getChild("enabled") != null && e.getChild("enabled").getText().equals("false")) {
156                    smr.setEnabled(false);
157                }
158                if (e.getChild("update") != null) {
159                    if (e.getChild("update").getText().equals("MasterToSlave")) {
160                        smr.setDirection(SignalMastRepeater.MASTERTOSLAVE);
161                    } else if (e.getChild("update").getText().equals("SlaveToMaster")) {
162                        smr.setDirection(SignalMastRepeater.SLAVETOMASTER);
163                    }
164                }
165            }
166            m.initialiseRepeaters();
167        }
168        return result;
169    }
170
171    private void loadSignalMastClass(Element shared, String signalMastClass) {
172        List<Element> mastClassList = shared.getChildren(signalMastClass);
173        log.debug("Found {} signal masts", mastClassList.size());
174        // load the contents
175        boolean result = loadInAdapter(mastClassList, null);
176        if (!result) {
177            log.warn("error loading signalmasts");
178        }
179    }
180
181    @Override
182    public void load(Element element, Object o) {
183        log.error("Invalid method called");
184    }
185
186    @Override
187    public int loadOrder() {
188        return InstanceManager.getDefault(jmri.SignalMastManager.class).getXMLOrder();
189    }
190
191    private final static Logger log = LoggerFactory.getLogger(DefaultSignalMastManagerXml.class);
192
193}