001package jmri.jmrit.display.configurexml;
002
003import java.util.List;
004
005import jmri.configurexml.JmriConfigureXmlException;
006import jmri.jmrit.catalog.NamedIcon;
007import jmri.jmrit.display.*;
008import jmri.jmrit.display.layoutEditor.LayoutEditor;
009import jmri.jmrit.logixng.GlobalVariable;
010import jmri.jmrit.logixng.GlobalVariableManager;
011
012import org.jdom2.Attribute;
013import org.jdom2.Element;
014import org.slf4j.Logger;
015import org.slf4j.LoggerFactory;
016
017/**
018 * Handle configuration for display.GlobalVariableIcon objects.
019 *
020 * @author Bob Jacobsen     Copyright: Copyright (c) 2004
021 * @author Daniel Bergqvist Copyright (C) 2022
022 */
023public class GlobalVariableIconXml extends PositionableLabelXml {
024
025    public GlobalVariableIconXml() {
026    }
027
028    /**
029     * Default implementation for storing the contents of a GlobalVariableIcon
030     *
031     * @param o Object to store, of type GlobalVariableIcon
032     * @return Element containing the complete info
033     */
034    @Override
035    public Element store(Object o) {
036
037        GlobalVariableIcon p = (GlobalVariableIcon) o;
038
039        Element element = new Element("globalVariableIcon");
040
041        // include attributes
042        element.setAttribute("globalVariable", p.getNamedGlobalVariable().getName());
043        storeCommonAttributes(p, element);
044        storeTextInfo(p, element);
045
046        //If the fixed width option is not set and the justification is not left
047        //Then we need to replace the x, y values with the original ones.
048        if (p.getPopupUtility().getFixedWidth() == 0 && p.getPopupUtility().getJustification() != 0) {
049            element.setAttribute("x", "" + p.getOriginalX());
050            element.setAttribute("y", "" + p.getOriginalY());
051        }
052        element.setAttribute("selectable", (p.isSelectable() ? "yes" : "no"));
053
054        element.setAttribute("class", "jmri.jmrit.display.configurexml.GlobalVariableIconXml");
055        if (p.getDefaultIcon() != null) {
056            element.setAttribute("defaulticon", p.getDefaultIcon().getURL());
057        }
058
059        // include contents
060        java.util.HashMap<String, NamedIcon> map = p.getMap();
061        if (map != null) {
062
063            for (java.util.Map.Entry<String, NamedIcon> mi : map.entrySet()) {
064                String key = mi.getKey();
065                String value = mi.getValue().getName();
066
067                Element e2 = new Element("globalVariableState");
068                e2.setAttribute("value", key);
069                e2.setAttribute("icon", value);
070                element.addContent(e2);
071            }
072        }
073
074        storeLogixNG_Data(p, element);
075
076        return element;
077    }
078
079    /**
080     * Load, starting with the globalVariableIcon element, then all the value-icon pairs
081     *
082     * @param element Top level Element to unpack.
083     * @param o       an Editor as an Object
084     * @throws JmriConfigureXmlException when a error prevents creating the objects as as
085     *                   required by the input XML
086     */
087    @Override
088    public void load(Element element, Object o) throws JmriConfigureXmlException {
089
090        Editor ed = null;
091        GlobalVariableIcon l;
092        if (o instanceof LayoutEditor) {
093            ed = (LayoutEditor) o;
094            l = new jmri.jmrit.display.layoutEditor.GlobalVariableIcon("   ", (LayoutEditor) ed);
095        } else if (o instanceof jmri.jmrit.display.Editor) {
096            ed = (Editor) o;
097            l = new GlobalVariableIcon("", ed);
098        } else {
099            log.error("Unrecognizable class - {}", o.getClass().getName());
100            return;
101        }
102
103        String name;
104        Attribute attr = element.getAttribute("globalVariable");
105        if (attr == null) {
106            log.error("incorrect information for a globalVariable location; must use globalVariable name");
107            ed.loadFailed();
108            return;
109        } else {
110            name = attr.getValue();
111        }
112
113        loadTextInfo(l, element);
114
115        GlobalVariable m = jmri.InstanceManager.getDefault(GlobalVariableManager.class).getGlobalVariable(name);
116        if (m != null) {
117            l.setGlobalVariable(name);
118        } else {
119            log.error("GlobalVariable named '{}' not found.", attr.getValue());
120            ed.loadFailed();
121        }
122
123        Attribute a = element.getAttribute("selectable");
124        if (a != null && a.getValue().equals("yes")) {
125            l.setSelectable(true);
126        } else {
127            l.setSelectable(false);
128        }
129
130        a = element.getAttribute("defaulticon");
131        if (a != null) {
132            l.setDefaultIcon(NamedIcon.getIconByName(a.getValue()));
133        }
134
135        // get the icon pairs
136        List<Element> items = element.getChildren("globalVariableState");
137        for (Element item : items) {
138            // get the class, hence the adapter object to do loading
139            String iconName = item.getAttribute("icon").getValue();
140            NamedIcon icon = NamedIcon.getIconByName(iconName);
141            if (icon == null) {
142                icon = ed.loadFailed("GlobalVariable " + name, iconName);
143                if (icon == null) {
144                    log.info("GlobalVariable \"{}\" icon removed for url= {}", name, iconName);
145                }
146            }
147            if (icon != null) {
148                String keyValue = item.getAttribute("value").getValue();
149                l.addKeyAndIcon(icon, keyValue);
150            }
151        }
152        try {
153            ed.putItem(l);
154        } catch (Positionable.DuplicateIdException e) {
155            throw new JmriConfigureXmlException("Positionable id is not unique", e);
156        }
157
158        loadLogixNG_Data(l, element);
159
160        // load individual item's option settings after editor has set its global settings
161        loadCommonAttributes(l, Editor.MEMORIES, element);
162        int x = 0;
163        int y = 0;
164        try {
165            x = element.getAttribute("x").getIntValue();
166            y = element.getAttribute("y").getIntValue();
167        } catch (org.jdom2.DataConversionException e) {
168            log.error("failed to convert positional attribute");
169        }
170        l.setOriginalLocation(x, y);
171        l.displayState();
172    }
173
174    private final static Logger log = LoggerFactory.getLogger(GlobalVariableIconXml.class);
175}