001package jmri.managers.configurexml; 002 003import java.util.List; 004import java.util.SortedSet; 005 006import jmri.InstanceManager; 007import jmri.SignalGroup; 008import jmri.SignalGroupManager; 009import jmri.SignalHead; 010 011import org.jdom2.Element; 012 013/** 014 * Handle XML configuration for a DefaultSignalGroupManager objects. 015 * 016 * @author Bob Jacobsen Copyright: Copyright (c) 2009 017 */ 018public class DefaultSignalGroupManagerXml 019 extends jmri.managers.configurexml.AbstractNamedBeanManagerConfigXML { 020 021 public DefaultSignalGroupManagerXml() { 022 } 023 024 /** 025 * Default implementation for storing the contents of a 026 * DefaultSignalGroupManager. 027 * 028 * @param o Object to store, of type SignalGroup 029 * @return Element containing the complete info 030 */ 031 @Override 032 public Element store(Object o) { 033 Element groups = new Element("signalgroups"); 034 groups.setAttribute("class", this.getClass().getName()); 035 SignalGroupManager sgm = (SignalGroupManager) o; 036 if (sgm != null) { 037 SortedSet<SignalGroup> sgList = sgm.getNamedBeanSet(); 038 // don't return an element if there are no SignalGroups to include 039 if (sgList.isEmpty()) { 040 return null; 041 } 042 for (SignalGroup sg : sgList) { 043 // store the signalgroups 044 String sgName = sg.getSystemName(); 045 log.debug("SignalGroup system name is {}", sgName); // NOI18N 046 047 Element e = new Element("signalgroup"); 048 e.addContent(new Element("systemName").addContent(sgName)); 049 storeCommon(sg, e); 050 groups.addContent(e); 051 for (int x = 0; x < sg.getNumSignalMastAspects(); x++) { 052 Element app = new Element("aspect").setAttribute("valid", sg.getSignalMastAspectByIndex(x)); 053 e.addContent(app); 054 } 055 e.setAttribute("signalMast", sg.getSignalMastName()); 056 057 for (int x = 0; x < sg.getNumHeadItems(); x++) { 058 storeSignalHead(e, sg, x); 059 } 060 } 061 } 062 return groups; 063 } 064 065 private void storeSignalHead(Element element, SignalGroup _group, int x) { 066 Element group = new Element("signalHead"); 067 String name = _group.getHeadItemNameByIndex(x); 068 group.setAttribute("name", name); 069 group.setAttribute("onAppearance", getSignalColour(_group.getHeadOnStateByIndex(x))); 070 group.setAttribute("offAppearance", getSignalColour(_group.getHeadOffStateByIndex(x))); 071 if (_group.getSensorTurnoutOperByIndex(x)) { 072 group.setAttribute("sensorTurnoutLogic", "AND"); 073 } else { 074 group.setAttribute("sensorTurnoutLogic", "OR"); 075 } 076 077 for (int i = 0; i < _group.getNumHeadTurnoutsByIndex(x); i++) { 078 storeTurnout(group, _group, x, i); 079 } 080 for (int i = 0; i < _group.getNumHeadSensorsByIndex(x); i++) { 081 storeSensor(group, _group, x, i); 082 } 083 084 element.addContent(group); 085 } 086 087 private void storeTurnout(Element element, SignalGroup _group, int x, int turn) { 088 Element turnout = new Element("turnout").setAttribute("name", _group.getTurnoutNameByIndex(x, turn)); 089 turnout.setAttribute("state", "" + _group.getTurnoutStateByIndex(x, turn)); 090 element.addContent(turnout); 091 } 092 093 private void storeSensor(Element element, SignalGroup _group, int x, int sensor) { 094 Element Sensor = new Element("sensor").setAttribute("name", _group.getSensorNameByIndex(x, sensor)); 095 Sensor.setAttribute("state", "" + _group.getSensorStateByIndex(x, sensor)); 096 element.addContent(Sensor); 097 } 098 099 public void setStoreElementClass(Element signalGroup) { 100 signalGroup.setAttribute("class", this.getClass().getName()); 101 } 102 103 private String getSignalColour(int mAppearance) { 104 switch (mAppearance) { 105 case SignalHead.RED: 106 return "RED"; 107 case SignalHead.FLASHRED: 108 return "FLASHRED"; 109 case SignalHead.YELLOW: 110 return "YELLOW"; 111 case SignalHead.FLASHYELLOW: 112 return "FLASHYELLOW"; 113 case SignalHead.GREEN: 114 return "GREEN"; 115 case SignalHead.FLASHGREEN: 116 return "FLASHGREEN"; 117 case SignalHead.LUNAR: 118 return "LUNAR"; 119 case SignalHead.FLASHLUNAR: 120 return "FLASHLUNAR"; 121 case SignalHead.DARK: 122 return "DARK"; 123 default: 124 log.warn("Unexpected appearance: {}", mAppearance); 125 // go dark 126 return "DARK"; 127 } 128 } 129 130 @Override 131 public boolean load(Element shared, Element perNode) { 132 // loop over contained signalgroup elements 133 List<Element> list = shared.getChildren("signalgroup"); 134 135 SignalGroupManager sgm = InstanceManager.getDefault(jmri.SignalGroupManager.class); 136 137 for (Element e : list) { 138 SignalGroup sg; 139 String primary; 140 String yesno; 141 boolean inverse; 142 int state; 143 144 String sys = getSystemName(e); 145 146 sg = sgm.provideSignalGroup(sys, getUserName(e)); 147 148 //loadCommon(sg, e); // would store comment, now a separate element 149 loadComment(sg, e); 150 151 primary = e.getAttribute("signalMast").getValue(); 152 sg.setSignalMast(primary); 153 154 List<Element> appList = e.getChildren("appearance"); // deprecated 4.7.2 for aspect; warning added 4.19.1 155 for (Element app : appList) { 156 String value = app.getAttribute("valid").getValue(); 157 jmri.util.LoggingUtil.deprecationWarning(log, "appearance elements in file"); 158 sg.addSignalMastAspect(value); 159 } 160 List<Element> aspList = e.getChildren("aspect"); 161 for (Element asp : aspList) { 162 String value = asp.getAttribute("valid").getValue(); 163 sg.addSignalMastAspect(value); 164 } 165 166 List<Element> signalHeadList = e.getChildren("signalHead"); 167 for (Element sh : signalHeadList) { 168 String head = sh.getAttribute("name").getValue(); 169 SignalHead sigHead = jmri.InstanceManager.getDefault(jmri.SignalHeadManager.class).getSignalHead(head); 170 sg.addSignalHead(sigHead); 171 yesno = sh.getAttribute("sensorTurnoutLogic").getValue(); 172 inverse = false; 173 if ((yesno != null) && (!yesno.isEmpty())) { 174 if (yesno.equals("AND")) { 175 inverse = true; 176 // } else if (yesno.equals("OR")) { 177 // inverse = false; // value already assigned as default 178 } 179 } 180 sg.setSensorTurnoutOper(sigHead, inverse); 181 182 try { 183 sg.setHeadOnState(sigHead, getIntFromColour(sh.getAttribute("onAppearance").getValue())); 184 } catch (NullPointerException ex) { // considered normal if the attributes are not present 185 } 186 try { 187 sg.setHeadOffState(sigHead, getIntFromColour(sh.getAttribute("offAppearance").getValue())); 188 } catch (NullPointerException ex) { // considered normal if the attributes are not present 189 } 190 List<Element> signalTurnoutList = sh.getChildren("turnout"); 191 for (Element sgt : signalTurnoutList) { 192 String tName = sgt.getAttribute("name").getValue(); 193 jmri.Turnout turnout = jmri.InstanceManager.turnoutManagerInstance().getTurnout(tName); 194 state = 0; 195 try { 196 state = sgt.getAttribute("state").getIntValue(); 197 } catch (org.jdom2.DataConversionException ex) { 198 log.warn("invalid state attribute value"); 199 } 200 sg.setHeadAlignTurnout(sigHead, turnout, state); 201 } 202 List<Element> signalSensorList = sh.getChildren("sensor"); 203 for (Element sgs: signalSensorList) { 204 String sName = sgs.getAttribute("name").getValue(); 205 jmri.Sensor sensor = jmri.InstanceManager.sensorManagerInstance().getSensor(sName); 206 state = 0; 207 try { 208 state = sgs.getAttribute("state").getIntValue(); 209 } catch (org.jdom2.DataConversionException ex) { 210 log.warn("invalid style attribute value"); 211 } 212 sg.setHeadAlignSensor(sigHead, sensor, state); 213 } 214 } 215 } 216 return true; 217 } 218 219 private int getIntFromColour(String color) { 220 switch (color) { 221 case "RED": 222 return SignalHead.RED; 223 case "YELLOW": 224 return SignalHead.YELLOW; 225 case "GREEN": 226 return SignalHead.GREEN; 227 case "LUNAR": 228 return SignalHead.LUNAR; 229 case "DARK": 230 return SignalHead.DARK; 231 case "FLASHRED": 232 return SignalHead.FLASHRED; 233 case "FLASHYELLOW": 234 return SignalHead.FLASHYELLOW; 235 case "FLASHGREEN": 236 return SignalHead.FLASHGREEN; 237 case "FLASHLUNAR": 238 return SignalHead.FLASHLUNAR; 239 default: 240 log.warn("Unexpected appearance: {}", color); 241 return SignalHead.DARK; 242 } 243 } 244 245 @Override 246 public int loadOrder() { 247 return InstanceManager.getDefault(jmri.SignalGroupManager.class).getXMLOrder(); 248 } 249 250 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DefaultSignalGroupManagerXml.class); 251 252}