001package jmri.jmrit.display.configurexml;
002
003import java.util.List;
004
005import jmri.configurexml.JmriConfigureXmlException;
006import jmri.jmrit.catalog.NamedIcon;
007import jmri.jmrit.display.*;
008
009import org.jdom2.Attribute;
010import org.jdom2.Element;
011import org.slf4j.Logger;
012import org.slf4j.LoggerFactory;
013
014/**
015 * Handle configuration for display.MultiSensorIcon objects
016 *
017 * @author Bob Jacobsen Copyright: Copyright (c) 2002
018 */
019public class MultiSensorIconXml extends PositionableLabelXml {
020
021    public MultiSensorIconXml() {
022    }
023
024    /**
025     * Default implementation for storing the contents of a MultiSensorIcon
026     *
027     * @param o Object to store, of type MultiSensorIcon
028     * @return Element containing the complete info
029     */
030    @Override
031    public Element store(Object o) {
032
033        MultiSensorIcon p = (MultiSensorIcon) o;
034        if (!p.isActive()) {
035            return null;  // if flagged as inactive, don't store
036        }
037        Element element = new Element("multisensoricon");
038        storeCommonAttributes(p, element);
039
040        element.setAttribute("updown", p.getUpDown() ? "true" : "false");
041
042        for (int i = 0; i < p.getNumEntries(); i++) {
043            Element e = storeIcon("active", p.getSensorIcon(i));
044            e.setAttribute("sensor", p.getSensorName(i));
045            element.addContent(e);
046        }
047        element.addContent(storeIcon("inactive", p.getInactiveIcon()));
048        element.addContent(storeIcon("unknown", p.getUnknownIcon()));
049        element.addContent(storeIcon("inconsistent", p.getInconsistentIcon()));
050
051        storeLogixNG_Data(p, element);
052
053        element.setAttribute("class", "jmri.jmrit.display.configurexml.MultiSensorIconXml");
054        return element;
055    }
056
057    /**
058     * Create a PositionableLabel, then add to a target JLayeredPane
059     *
060     * @param element Top level Element to unpack.
061     * @param o       an Editor an Object
062     * @throws JmriConfigureXmlException when a error prevents creating the objects as as
063     *                   required by the input XML
064     */
065    @Override
066    public void load(Element element, Object o) throws JmriConfigureXmlException {
067        Editor pe = (Editor) o;
068        MultiSensorIcon l = new MultiSensorIcon(pe);
069        // create the objects
070        int rotation = 0;
071        try {
072            rotation = element.getAttribute("rotate").getIntValue();
073        } catch (org.jdom2.DataConversionException e) {
074        } catch (NullPointerException e) {  // considered normal if the attributes are not present
075        }
076
077        NamedIcon icon = loadSensorIcon("inactive", rotation, l, element, pe);
078        if (icon != null) {
079            l.setInactiveIcon(icon);
080        } else {
081            return;
082        }
083        icon = loadSensorIcon("unknown", rotation, l, element, pe);
084        if (icon != null) {
085            l.setUnknownIcon(icon);
086        } else {
087            return;
088        }
089        icon = loadSensorIcon("inconsistent", rotation, l, element, pe);
090        if (icon != null) {
091            l.setInconsistentIcon(icon);
092        } else {
093            return;
094        }
095
096        Attribute a = element.getAttribute("updown");
097        if ((a != null) && a.getValue().equals("true")) {
098            l.setUpDown(true);
099        } else {
100            l.setUpDown(false);
101        }
102
103        // get the icon pairs & load
104        List<Element> items = element.getChildren();
105        for (Element item : items) {
106            // get the class, hence the adapter object to do loading
107            if (item.getAttribute("sensor") != null) {
108                String sensor = item.getAttribute("sensor").getValue();
109                if (item.getAttribute("url") != null) {
110                    String name = item.getAttribute("url").getValue();
111                    icon = NamedIcon.getIconByName(name);
112                    if (icon == null) {
113                        icon = pe.loadFailed("MultiSensor \"" + l.getNameString() + "\" ", name);
114                        if (icon == null) {
115                            log.error("MultiSensor \"{}\" removed for url= {}", l.getNameString(), name);
116                            return;
117                        }
118                    }
119                    try {
120                        int deg = 0;
121                        a = item.getAttribute("degrees");
122                        if (a != null) {
123                            deg = a.getIntValue();
124                            double scale = 1.0;
125                            a = item.getAttribute("scale");
126                            if (a != null) {
127                                scale = item.getAttribute("scale").getDoubleValue();
128                            }
129                            icon.setLoad(deg, scale, l);
130                        }
131                        if (deg == 0) {
132                            a = item.getAttribute("rotate");
133                            if (a != null) {
134                                rotation = a.getIntValue();
135                                icon.setRotation(rotation, l);
136                            }
137                        }
138                    } catch (org.jdom2.DataConversionException dce) {
139                    }
140                } else {
141                    String name = item.getAttribute("icon").getValue();
142                    icon = NamedIcon.getIconByName(name);
143                    if (icon == null) {
144                        icon = pe.loadFailed("MultiSensor \"" + l.getNameString(), name);
145                        if (icon == null) {
146                            log.info("MultiSensor \"{} removed for url= {}", l.getNameString(), name);
147                            return;
148                        }
149                    }
150                    if (rotation != 0) {
151                        icon.setRotation(rotation, l);
152                    }
153                }
154
155                l.addEntry(sensor, icon);
156            }
157        }
158        try {
159            pe.putItem(l);
160        } catch (Positionable.DuplicateIdException e) {
161            throw new JmriConfigureXmlException("Positionable id is not unique", e);
162        }
163
164        loadLogixNG_Data(l, element);
165
166        // load individual item's option settings after editor has set its global settings
167        loadCommonAttributes(l, Editor.SENSORS, element);
168    }
169
170    private NamedIcon loadSensorIcon(String state, int rotation, MultiSensorIcon l, Element element, Editor ed) {
171        String msg = "MultiSensor \"" + l.getNameString() + "\": icon \"" + state + "\" ";
172        NamedIcon icon = loadIcon(l, state, element, msg, ed);
173        if (icon == null) {
174            if (element.getAttribute(state) != null) {
175                String iconName = element.getAttribute(state).getValue();
176                icon = NamedIcon.getIconByName(iconName);
177                if (icon == null) {
178                    icon = ed.loadFailed(msg, iconName);
179                    if (icon == null) {
180                        log.info("{} removed for url= {}", msg, iconName);
181                    }
182                } else {
183                    icon.setRotation(rotation, l);
184                }
185            } else {
186                log.warn("did not locate {} for Multisensor icon file", state);
187            }
188        }
189        if (icon == null) {
190            log.info("MultiSensor Icon \"{}\": icon \"{}\" removed", l.getNameString(), state);
191        }
192        return icon;
193    }
194
195    private final static Logger log = LoggerFactory.getLogger(MultiSensorIconXml.class);
196
197}