001package jmri.jmrix.openlcb.configurexml; 002 003import java.util.List; 004import jmri.InstanceManager; 005import jmri.JmriException; 006import jmri.SignalAppearanceMap; 007import jmri.jmrix.openlcb.OlcbSignalMast; 008 009import org.jdom2.Element; 010 011import org.openlcb.EventID; 012 013import javax.annotation.Nonnull; 014 015/** 016 * Handle XML configuration for OlcbSignalMast objects. 017 * 018 * @author Bob Jacobsen Copyright: Copyright (c) 2017, 2018 019 * 020 */ 021public class OlcbSignalMastXml 022 extends jmri.managers.configurexml.AbstractNamedBeanManagerConfigXML { 023 024 public OlcbSignalMastXml() { 025 } 026 027 /** 028 * Default implementation for storing the contents of a 029 * DefaultSignalMastManager 030 * 031 * @param o Object to store, of type OlcbSignalMast 032 * @return Element containing the complete info 033 */ 034 @Override 035 public Element store(Object o) { 036 OlcbSignalMast p = (OlcbSignalMast) o; 037 Element e = new Element("olcbsignalmast"); 038 e.setAttribute("class", this.getClass().getName()); 039 e.addContent(new Element("systemName").addContent(p.getSystemName())); 040 041 storeCommon(p, e); 042 043 Element lit = new Element("lit"); 044 lit.addContent(new Element("lit").addContent(nullToEmpty(p.getLitEventId()))); 045 lit.addContent(new Element("notlit").addContent(nullToEmpty(p.getNotLitEventId()))); 046 e.addContent(lit); 047 048 Element held = new Element("held"); 049 held.addContent(new Element("held").addContent(nullToEmpty(p.getHeldEventId()))); 050 held.addContent(new Element("notheld").addContent(nullToEmpty(p.getNotHeldEventId()))); 051 e.addContent(held); 052 053 SignalAppearanceMap appMap = p.getAppearanceMap(); 054 if (appMap != null) { 055 java.util.Enumeration<String> aspects = appMap.getAspects(); 056 while (aspects.hasMoreElements()) { 057 String key = aspects.nextElement(); 058 Element el = new Element("aspect"); 059 el.setAttribute("defines", key); 060 el.addContent(new Element("event").addContent(nullToEmpty(p.getOutputForAppearance(key)))); 061 e.addContent(el); 062 } 063 } 064 List<String> disabledAspects = p.getDisabledAspects(); 065 if (disabledAspects != null) { 066 Element el = new Element("disabledAspects"); 067 for (String aspect : disabledAspects) { 068 Element ele = new Element("disabledAspect"); 069 ele.addContent(aspect); 070 el.addContent(ele); 071 } 072 if (disabledAspects.size() != 0) { 073 e.addContent(el); 074 } 075 } 076 return e; 077 } 078 079 @Override 080 public boolean load(@Nonnull Element shared, Element perNode) { 081 OlcbSignalMast m; 082 String sys = getSystemName(shared); 083 try { 084 m = (OlcbSignalMast) InstanceManager.getDefault(jmri.SignalMastManager.class) 085 .provideCustomSignalMast(sys, OlcbSignalMast.class); 086 } catch (JmriException e) { 087 log.error("Failed to load OlcbSignalMast {}", sys, e); 088 return false; 089 } 090 091 if (getUserName(shared) != null) { 092 m.setUserName(getUserName(shared)); 093 } 094 095 return loadCommonOlcbMast(m, shared); 096 } 097 098 /** 099 * If the input string is a zero Event ID, replace it 100 * with the empty String 101 * @param event an event ID read from an element 102 * @param m the relevant signal mast, used for a warning message 103 * @return the event ID or the empty String 104 */ 105 private String convertZeroEvent(String event, OlcbSignalMast m) { 106 if ("".equals(event)) { 107 return ""; 108 } 109 if (event == null) { 110 return ""; 111 } 112 try { 113 var eventID = new EventID(event); 114 if (eventID.getContents()[0] == 0) { 115 // migrate starting-with-zero event ID to blank 116 log.warn("Migrating zero-initial-value event {} to a blank entry in signal mast \"{}\"", event, m.getDisplayName()); 117 return ""; 118 } else { 119 // non-zero-starting event ID, normal case 120 return event; 121 } 122 } catch (IllegalArgumentException ex) { 123 // not dotted-hex, assume this is a event name 124 return event; 125 } 126 127 } 128 129 protected boolean loadCommonOlcbMast(OlcbSignalMast m, Element element) { 130 loadCommon(m, element); 131 132 if (element.getChild("lit") != null) { 133 Element lit = element.getChild("lit"); 134 m.setLitEventId(convertZeroEvent(childValue(lit, "lit"), m)); 135 m.setNotLitEventId(convertZeroEvent(childValue(lit, "notlit"), m)); 136 } 137 138 if (element.getChild("held") != null) { 139 Element held = element.getChild("held"); 140 m.setHeldEventId(convertZeroEvent(childValue(held, "held"), m)); 141 m.setNotHeldEventId(convertZeroEvent(childValue(held, "notheld"), m)); 142 } 143 144 List<Element> list = element.getChildren("aspect"); 145 for (Element e : list) { 146 String aspect = e.getAttribute("defines").getValue(); 147 String event = convertZeroEvent(childValue(e, "event"), m); 148 m.setOutputForAppearance(aspect, event); 149 } 150 Element e = element.getChild("disabledAspects"); 151 if (e != null) { 152 list = e.getChildren("disabledAspect"); 153 for (Element aspect : list) { 154 m.setAspectDisabled(aspect.getText()); 155 } 156 } 157 158 return true; 159 160 } 161 162 @Override 163 public void load(Element element, Object o) { 164 log.error("Invalid method called"); 165 } 166 167 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(OlcbSignalMastXml.class); 168}