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