001package jmri.jmrit.display.configurexml;
002
003import java.util.ArrayList;
004import java.util.HashMap;
005import java.util.Iterator;
006import java.util.List;
007import java.util.Map.Entry;
008
009import jmri.NamedBeanHandle;
010import jmri.Sensor;
011import jmri.configurexml.JmriConfigureXmlException;
012import jmri.jmrit.catalog.NamedIcon;
013import jmri.jmrit.display.*;
014import jmri.jmrit.logix.OBlock;
015
016import org.jdom2.Attribute;
017import org.jdom2.Element;
018import org.slf4j.Logger;
019import org.slf4j.LoggerFactory;
020
021/**
022 * Handle configuration for display.IndicatorTrackIconXml objects.
023 *
024 * @author Pete Cressman Copyright: Copyright (c) 2010
025 */
026public class IndicatorTrackIconXml extends PositionableLabelXml {
027
028    public IndicatorTrackIconXml() {
029    }
030
031    /**
032     * Default implementation for storing the contents of a IndicatorTrackIcon
033     *
034     * @param o Object to store, of type IndicatorTrackIcon
035     * @return Element containing the complete info
036     */
037    @Override
038    public Element store(Object o) {
039
040        IndicatorTrackIcon p = (IndicatorTrackIcon) o;
041        if (!p.isActive()) {
042            return null;  // if flagged as inactive, don't store
043        }
044        Element element = new Element("indicatortrackicon");
045        storeCommonAttributes(p, element);
046
047        NamedBeanHandle<OBlock> b = p.getNamedOccBlock();
048        if (b != null) {
049            element.addContent(storeNamedBean("occupancyblock", b));
050            // additional OBlock information for web server is extracted by ControlPanelServlet at runtime, not stored
051        }
052        NamedBeanHandle<Sensor> s = p.getNamedOccSensor();
053        if (b == null && s != null) {  // only write sensor if no OBlock, don't write double sensing
054            element.addContent(storeNamedBean("occupancysensor", s));
055        }
056
057        Element elem = new Element("showTrainName");
058        String show = "no";
059        if (p.showTrain()) {
060            show = "yes";
061        }
062        
063        elem.addContent(show);
064        element.addContent(elem);
065
066        HashMap<String, NamedIcon> iconMap = p.getIconMap();
067        Iterator<Entry<String, NamedIcon>> it = iconMap.entrySet().iterator();
068        elem = new Element("iconmap");
069        String family = p.getFamily();
070        if (family != null) {
071            elem.setAttribute("family", family);
072        }
073        while (it.hasNext()) {
074            Entry<String, NamedIcon> entry = it.next();
075            elem.addContent(storeIcon(entry.getKey(), entry.getValue()));
076        }
077        element.addContent(elem);
078
079        elem = new Element("paths");
080        ArrayList<String> paths = p.getPaths();
081        if (paths != null) {
082            for (String path : paths) {
083                Element e = new Element("path");
084                e.addContent(path);
085                elem.addContent(e);
086
087            }
088            element.addContent(elem);
089        }
090
091        storeLogixNG_Data(p, element);
092
093        element.setAttribute("class", "jmri.jmrit.display.configurexml.IndicatorTrackIconXml");
094
095        return element;
096    }
097
098    static Element storeNamedBean(String elemName, NamedBeanHandle<?> nb) {
099        Element elem = new Element(elemName);
100        elem.addContent(nb.getName());
101        return elem;
102    }
103
104    /**
105     * Create a IndicatorTrackIcon, then add to a target JLayeredPane
106     *
107     * @param element Top level Element to unpack.
108     * @param o       Editor as an Object
109     * @throws JmriConfigureXmlException when a error prevents creating the objects as as
110     *                   required by the input XML
111     */
112    @Override
113    public void load(Element element, Object o) throws JmriConfigureXmlException {
114        // create the objects
115        Editor p = (Editor) o;
116
117        IndicatorTrackIcon l = new IndicatorTrackIcon(p);
118
119        Element elem = element.getChild("iconmap");
120        if (elem != null) {
121            List<Element> status = elem.getChildren();
122            if (status.size() > 0) {
123                for (Element value : status) {
124                    String msg = "IndicatorTrack \"" + l.getNameString() + "\" icon \"" + value.getName() + "\" ";
125                    NamedIcon icon = loadIcon(l, value.getName(), elem, msg, p);
126                    if (icon != null) {
127                        l.setIcon(value.getName(), icon);
128                    } else {
129                        log.info("{} removed for url= {}", msg, value.getName());
130                        return;
131                    }
132                }
133            }
134            Attribute attr = elem.getAttribute("family");
135            if (attr != null) {
136                l.setFamily(attr.getValue());
137            }
138        }
139        Element name = element.getChild("occupancyblock");
140        if (name != null) {
141            l.setOccBlock(name.getText());
142        } else {        // only write sensor if no OBlock, don't write double sensing
143            name = element.getChild("occupancysensor");
144            if (name != null) {
145                l.setOccSensor(name.getText());
146            }            
147        }
148
149        l.setShowTrain(false);
150        name = element.getChild("showTrainName");
151        if (name != null) {
152            if ("yes".equals(name.getText())) {
153                l.setShowTrain(true);
154            }
155        }
156
157        elem = element.getChild("paths");
158        if (elem != null) {
159            ArrayList<String> paths = new ArrayList<>();
160            List<Element> pth = elem.getChildren();
161            for (Element value : pth) {
162                paths.add(value.getText());
163            }
164            l.setPaths(paths);
165        }
166
167        l.displayState(l.getStatus());
168        l.updateSize();
169        try {
170            p.putItem(l);
171        } catch (Positionable.DuplicateIdException e) {
172            throw new JmriConfigureXmlException("Positionable id is not unique", e);
173        }
174
175        loadLogixNG_Data(l, element);
176
177        // load individual item's option settings after editor has set its global settings
178        loadCommonAttributes(l, Editor.TURNOUTS, element);
179    }
180
181    private final static Logger log = LoggerFactory.getLogger(IndicatorTrackIconXml.class);
182}