001package jmri.jmrit.display.layoutEditor.configurexml; 002 003import java.util.HashMap; 004import java.util.List; 005 006import jmri.configurexml.JmriConfigureXmlException; 007import jmri.jmrit.catalog.NamedIcon; 008import jmri.jmrit.display.*; 009import jmri.jmrit.display.configurexml.PositionableLabelXml; 010import jmri.jmrit.display.layoutEditor.OutputIndicator; 011 012import org.jdom2.Attribute; 013import org.jdom2.Element; 014import org.slf4j.Logger; 015import org.slf4j.LoggerFactory; 016 017/** 018 * Handle configuration for display.OutputIndicator objects. 019 * 020 * @author Bob Jacobsen Copyright: Copyright (c) 2002 021 */ 022public class OutputIndicatorXml extends PositionableLabelXml { 023 024 static final HashMap<String, String> _nameMap = new HashMap<>(); 025 026 public OutputIndicatorXml() { 027 // map previous store names to property key names 028 _nameMap.put("closed", "TurnoutStateClosed"); 029 _nameMap.put("thrown", "TurnoutStateThrown"); 030 _nameMap.put("unknown", "BeanStateUnknown"); 031 _nameMap.put("inconsistent", "BeanStateInconsistent"); 032 } 033 034 /** 035 * Default implementation for storing the contents of a OutputIndicator 036 * 037 * @param o Object to store, of type OutputIndicator 038 * @return Element containing the complete info 039 */ 040 @Override 041 public Element store(Object o) { 042 043 OutputIndicator p = (OutputIndicator) o; 044 if (!p.isActive()) { 045 return null; // if flagged as inactive, don't store 046 } 047 Element element = new Element("outputindicator"); 048 element.setAttribute("turnout", p.getNamedTurnout().getName()); 049 storeCommonAttributes(p, element); 050 051 element.setAttribute("tristate", p.getTristate() ? "true" : "false"); 052 element.setAttribute("momentary", p.getMomentary() ? "true" : "false"); 053 element.setAttribute("directControl", p.getDirectControl() ? "true" : "false"); 054 055 Element elem = new Element("icons"); 056 elem.addContent(storeIcon("closed", p.getIcon("TurnoutStateClosed"))); 057 elem.addContent(storeIcon("thrown", p.getIcon("TurnoutStateThrown"))); 058 elem.addContent(storeIcon("unknown", p.getIcon("BeanStateUnknown"))); 059 elem.addContent(storeIcon("inconsistent", p.getIcon("BeanStateInconsistent"))); 060 element.addContent(elem); 061 elem = new Element("iconmaps"); 062 String family = p.getFamily(); 063 if (family != null) { 064 elem.setAttribute("family", family); 065 } 066 element.addContent(elem); 067 068 storeLogixNG_Data(p, element); 069 070 element.setAttribute("class", "jmri.jmrit.display.layoutEditor.configurexml.OutputIndicatorXml"); 071 072 return element; 073 } 074 075 /** 076 * Create a PositionableLabel, then add to a target JLayeredPane 077 * 078 * @param element Top level Element to unpack. 079 * @param o Editor as an Object 080 * @throws JmriConfigureXmlException when a error prevents creating the objects as as 081 * required by the input XML 082 */ 083 @Override 084 public void load(Element element, Object o) throws JmriConfigureXmlException { 085 // create the objects 086 Editor p = (Editor) o; 087 088 OutputIndicator l = new OutputIndicator(p); 089 090 String name; 091 try { 092 name = element.getAttribute("turnout").getValue(); 093 } catch (NullPointerException e) { 094 log.error("incorrect information for turnout; must use turnout name"); 095 p.loadFailed(); 096 return; 097 } 098 l.setTurnout(name); 099 100 Attribute a = element.getAttribute("tristate"); 101 if ((a == null) || a.getValue().equals("true")) { 102 l.setTristate(true); 103 } else { 104 l.setTristate(false); 105 } 106 107 a = element.getAttribute("momentary"); 108 if ((a != null) && a.getValue().equals("true")) { 109 l.setMomentary(true); 110 } else { 111 l.setMomentary(false); 112 } 113 114 a = element.getAttribute("directControl"); 115 if ((a != null) && a.getValue().equals("true")) { 116 l.setDirectControl(true); 117 } else { 118 l.setDirectControl(false); 119 } 120 121 List<Element> states = element.getChildren(); 122 if (states.size() > 0) { 123 if (log.isDebugEnabled()) { 124 log.debug("Main element has{} items", states.size()); 125 } 126 Element elem = element; // the element containing the icons 127 Element icons = element.getChild("icons"); 128 if (icons != null) { 129 states = icons.getChildren(); 130 elem = icons; // the element containing the icons 131 if (log.isDebugEnabled()) { 132 log.debug("icons element has{} items", states.size()); 133 } 134 } 135 for (Element value : states) { 136 String state = value.getName(); 137 if (log.isDebugEnabled()) { 138 log.debug("setIcon for state \"{}\" and {}", state, _nameMap.get(state)); 139 } 140 NamedIcon icon = loadIcon(l, state, elem, "TurnoutIcon \"" + name + "\": icon \"" + state + "\" ", p); 141 if (icon != null) { 142 l.setIcon(_nameMap.get(state), icon); 143 } else { 144 log.info("OutputIndicator \"{}\": icon \"{}\" removed", name, state); 145 return; 146 } 147 } 148 log.debug("{} icons loaded for {}", states.size(), l.getNameString()); 149 } else { // case when everything was attributes 150 int rotation = 0; 151 try { 152 rotation = element.getAttribute("rotate").getIntValue(); 153 } catch (org.jdom2.DataConversionException e) { 154 } catch (NullPointerException e) { // considered normal if the attributes are not present 155 } 156 if (loadTurnoutIcon("thrown", rotation, l, element, name, p) == null) { 157 return; 158 } 159 if (loadTurnoutIcon("closed", rotation, l, element, name, p) == null) { 160 return; 161 } 162 if (loadTurnoutIcon("unknown", rotation, l, element, name, p) == null) { 163 return; 164 } 165 if (loadTurnoutIcon("inconsistent", rotation, l, element, name, p) == null) { 166 return; 167 } 168 } 169 Element elem = element.getChild("iconmaps"); 170 if (elem != null) { 171 Attribute attr = elem.getAttribute("family"); 172 if (attr != null) { 173 l.setFamily(attr.getValue()); 174 } 175 } 176 177 try { 178 p.putItem(l); 179 } catch (Positionable.DuplicateIdException e) { 180 throw new JmriConfigureXmlException("Positionable id is not unique", e); 181 } 182 183 loadLogixNG_Data(l, element); 184 185 // load individual item's option settings after editor has set its global settings 186 loadCommonAttributes(l, Editor.TURNOUTS, element); 187 } 188 189 private NamedIcon loadTurnoutIcon(String state, int rotation, TurnoutIcon l, Element element, 190 String name, Editor ed) { 191 NamedIcon icon = null; 192 if (element.getAttribute(state) != null) { 193 String iconName = element.getAttribute(state).getValue(); 194 icon = NamedIcon.getIconByName(iconName); 195 if (icon == null) { 196 icon = ed.loadFailed("Turnout \"" + name + "\" icon \"" + state + "\" ", iconName); 197 if (icon == null) { 198 log.info("Turnout \"{}\" icon \"{}\" removed for url= {}", name, state, iconName); 199 } 200 } else { 201 icon.setRotation(rotation, l); 202 } 203 } else { 204 log.warn("did not locate {} icon file for Turnout {}", state, name); 205 } 206 if (icon == null) { 207 log.info("Turnout Icon \"{}\": icon \"{}\" removed", name, state); 208 } else { 209 l.setIcon(_nameMap.get(state), icon); 210 } 211 return icon; 212 } 213 214 private static final Logger log = LoggerFactory.getLogger(OutputIndicatorXml.class); 215}