001package jmri.implementation.configurexml;
002
003import java.util.List;
004import jmri.InstanceManager;
005import jmri.NamedBeanHandle;
006import jmri.SignalHead;
007import jmri.Turnout;
008import jmri.implementation.MergSD2SignalHead;
009import org.jdom2.Element;
010
011/**
012 * Handle XML configuration for MergSD2SignalHead objects.
013 *
014 * This file is part of JMRI.
015 *
016 * JMRI is free software; you can redistribute it and/or modify it under the
017 * terms of version 2 of the GNU General Public License as published by the Free
018 * Software Foundation. See the "COPYING" file for a copy of this license.
019 *
020 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
021 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
022 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
023 *
024 * @author Bob Jacobsen Copyright: Copyright (c) 2003, 2008
025 * @author Kevin Dickerson Copyright: Copyright (c) 2009
026 */
027public class MergSD2SignalHeadXml extends jmri.managers.configurexml.AbstractNamedBeanManagerConfigXML {
028
029    public MergSD2SignalHeadXml() {
030    }
031
032    /**
033     * Default implementation for storing the contents of a MergSD2SignalHead.
034     *
035     * @param o Object to store, of type MergSD2SignalHead
036     * @return Element containing the complete info
037     */
038    @Override
039    public Element store(Object o) {
040        MergSD2SignalHead p = (MergSD2SignalHead) o;
041
042        Element element = new Element("signalhead");
043        element.setAttribute("class", this.getClass().getName());
044
045        element.addContent(new Element("systemName").addContent(p.getSystemName()));
046
047        element.setAttribute("aspects", p.getAspects() + "");
048        if (p.getFeather()) {
049            element.setAttribute("feather", "yes");
050        }
051
052        storeCommon(p, element);
053        int aspects = p.getAspects();
054        //@TODO could re-arange this so that it falls through
055        switch (aspects) {
056            case 2:
057                element.addContent(addTurnoutElement(p.getInput1(), "input1", p));
058                if (!p.getHome()) {
059                    element.setAttribute("home", "no");
060                }
061                break;
062            case 3:
063                element.addContent(addTurnoutElement(p.getInput1(), "input1", p));
064                element.addContent(addTurnoutElement(p.getInput2(), "input2", p));
065                break;
066            case 4:
067                element.addContent(addTurnoutElement(p.getInput1(), "input1", p));
068                element.addContent(addTurnoutElement(p.getInput2(), "input2", p));
069                element.addContent(addTurnoutElement(p.getInput3(), "input3", p));
070                break;
071            default:
072                log.error("incorrect number of aspects {} for Signal {}", aspects, p.getDisplayName());
073        }
074
075        return element;
076    }
077
078    Element addTurnoutElement(NamedBeanHandle<Turnout> to, String which, SignalHead p) {
079        Element el = new Element("turnoutname");
080        el.setAttribute("defines", which);
081        if ( to == null ) {
082            log.error("No Turnout found for MergSD2 Head {}",  p.getDisplayName());
083        } else {
084            el.addContent(to.getName());
085        }
086        return el;
087    }
088
089    @Override
090    public boolean load(Element shared, Element perNode) {
091        int aspects = 2;
092        List<Element> l = shared.getChildren("turnoutname");
093        if (l.isEmpty()) {
094            l = shared.getChildren("turnout");
095            aspects = l.size() + 1;
096        }
097        NamedBeanHandle<Turnout> input1 = null;
098        NamedBeanHandle<Turnout> input2 = null;
099        NamedBeanHandle<Turnout> input3 = null;
100        String yesno = "";
101        boolean feather = false;
102        boolean home = true;
103
104        // put it together
105        String sys = getSystemName(shared);
106        String uname = getUserName(shared);
107
108        if (shared.getAttribute("feather") != null) {
109            yesno = shared.getAttribute("feather").getValue();
110        }
111        if ((yesno != null) && (!yesno.equals(""))) {
112            if (yesno.equals("yes")) {
113                feather = true;
114            } else if (yesno.equals("no")) {
115                feather = false;
116            }
117        }
118
119        if (shared.getAttribute("home") != null) {
120            yesno = shared.getAttribute("home").getValue();
121        }
122        if ((yesno != null) && (!yesno.equals(""))) {
123            if (yesno.equals("yes")) {
124                home = true;
125            } else if (yesno.equals("no")) {
126                home = false;
127            }
128        }
129
130        var aspectsAttr = shared.getAttribute("aspects");
131        if ( aspectsAttr != null ) {
132            try {
133                    aspects = aspectsAttr.getIntValue();
134            } catch (org.jdom2.DataConversionException e) {
135                log.warn("Could not parse aspects attribute! {}", e.getMessage());
136            }
137        }
138
139        //int aspects = l.size()+1;  //Number of aspects is equal to the number of turnouts used plus 1.
140        //@TODO could re-arange this so that it falls through
141        switch (aspects) {
142            case 2:
143                input1 = loadTurnout(l.get(0));
144                break;
145            case 3:
146                input1 = loadTurnout(l.get(0));
147                input2 = loadTurnout(l.get(1));
148                break;
149            case 4:
150                input1 = loadTurnout(l.get(0));
151                input2 = loadTurnout(l.get(1));
152                input3 = loadTurnout(l.get(2));
153                break;
154            default:
155                log.error("incorrect number of aspects {} when loading Signal {}", aspects, sys);
156        }
157
158        SignalHead h;
159        if (uname == null) {
160            h = new MergSD2SignalHead(sys, aspects, input1, input2, input3, feather, home);
161        } else {
162            h = new MergSD2SignalHead(sys, uname, aspects, input1, input2, input3, feather, home);
163        }
164
165        loadCommon(h, shared);
166
167        SignalHead existingBean = InstanceManager.getDefault(jmri.SignalHeadManager.class)
168                        .getBySystemName(sys);
169
170        if ((existingBean != null) && (existingBean != h)) {
171            log.error("systemName is already registered: {}", sys);
172        } else {
173            InstanceManager.getDefault(jmri.SignalHeadManager.class).register(h);
174        }
175
176        return true;
177    }
178
179    NamedBeanHandle<Turnout> loadTurnout(Object o) {
180        Element e = (Element) o;
181
182        if (e.getName().equals("turnout")) {
183            String name = e.getAttribute("systemName").getValue();
184            Turnout t;
185            if (e.getAttribute("userName") != null
186                    && !e.getAttribute("userName").getValue().equals("")) {
187                name = e.getAttribute("userName").getValue();
188                t = InstanceManager.turnoutManagerInstance().getTurnout(name);
189            } else {
190                t = InstanceManager.turnoutManagerInstance().getBySystemName(name);
191            }
192            if (t != null) {
193                return jmri.InstanceManager.getDefault(jmri.NamedBeanHandleManager.class).getNamedBeanHandle(name, t);
194            } else {
195                log.warn("Failed to find turnout {}. Check connection and configuration", name);
196                return null;
197            }
198        } else {
199            String name = e.getText();
200            try {
201                Turnout t = InstanceManager.turnoutManagerInstance().provideTurnout(name);
202                return jmri.InstanceManager.getDefault(jmri.NamedBeanHandleManager.class).getNamedBeanHandle(name, t);
203            } catch (IllegalArgumentException ex) {
204                log.warn("Failed to provide Turnout \"{}\" in loadTurnout", name);
205                return null;
206            }
207        }
208    }
209
210    @Override
211    public void load(Element element, Object o) {
212        log.error("Invalid method called");
213    }
214
215    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MergSD2SignalHeadXml.class);
216
217}