001package jmri.managers.configurexml; 002 003import java.util.ArrayList; 004import java.util.List; 005import java.util.SortedSet; 006 007import jmri.InstanceManager; 008import jmri.Section; 009import jmri.Transit; 010import jmri.Transit.TransitType; 011import jmri.TransitManager; 012import jmri.TransitSection; 013import jmri.TransitSectionAction; 014 015import org.jdom2.DataConversionException; 016import org.jdom2.Element; 017 018/** 019 * Provides the functionality for configuring a TransitManager. 020 * 021 * @author Dave Duchamp Copyright (c) 2008 022 */ 023public class DefaultTransitManagerXml extends jmri.managers.configurexml.AbstractNamedBeanManagerConfigXML { 024 025 public DefaultTransitManagerXml() { 026 } 027 028 /** 029 * Default implementation for storing the contents of a TransitManager. 030 * 031 * @param o Object to store, of type TransitManager 032 * @return Element containing the complete info 033 */ 034 @Override 035 public Element store(Object o) { 036 Element transits = new Element("transits"); 037 setStoreElementClass(transits); 038 TransitManager tm = (TransitManager) o; 039 if (tm != null) { 040 SortedSet<Transit> tstList = tm.getNamedBeanSet(); 041 // don't return an element if there are no Transits to include 042 if (tstList.isEmpty()) { 043 return null; 044 } 045 046 // store the Transit 047 for (Transit transit : tstList) { 048 String tstName = transit.getSystemName(); 049 log.debug("Transit system name is {}", tstName); 050 if (transit.getTransitType() == TransitType.DYNAMICADHOC) { 051 continue; 052 } 053 Element elem = new Element("transit"); 054 elem.addContent(new Element("systemName").addContent(tstName)); 055 056 // As a work-around for backward compatibility, store systemName and username as attribute. 057 // Remove this in e.g. JMRI 4.11.1 and then update all the loadref comparison files 058 elem.setAttribute("systemName", tstName); 059 String uName = transit.getUserName(); 060 if ((uName != null) && !uName.isEmpty()) { 061 elem.setAttribute("userName", uName); 062 } 063 064 ArrayList<TransitSection> tsList = transit.getTransitSectionList(); 065 if ( tsList.isEmpty() ){ 066 log.warn("Not Storing Transit \"{}\" as it has no TransitSections", transit.getDisplayName()); 067 continue; 068 } 069 070 // store common part 071 storeCommon(transit, elem); 072 073 // save child transitsection entries 074 Element tsElem; 075 for (TransitSection ts : tsList) { 076 if ((ts != null) && !ts.isTemporary()) { 077 tsElem = new Element("transitsection"); 078 Section tSection = ts.getSection(); 079 if (tSection != null) { 080 tsElem.setAttribute("sectionname", tSection.getSystemName()); 081 } else { 082 tsElem.setAttribute("sectionname", "null"); 083 } 084 tsElem.setAttribute("sequence", Integer.toString(ts.getSequenceNumber())); 085 tsElem.setAttribute("direction", Integer.toString(ts.getDirection())); 086 tsElem.setAttribute("alternate", "" + (ts.isAlternate() ? "yes" : "no")); 087 tsElem.setAttribute("safe", "" + (ts.isSafe() ? "yes" : "no")); 088 tsElem.setAttribute("stopallocatingsensor", ts.getStopAllocatingSensor()); 089 090 // save child TransitSectionAction entries if any 091 ArrayList<TransitSectionAction> tsaList = ts.getTransitSectionActionList(); 092 if (!tsaList.isEmpty()) { 093 Element tsaElem; 094 for (TransitSectionAction tsa : tsaList) { 095 if (tsa != null) { 096 tsaElem = new Element("transitsectionaction"); 097 tsaElem.setAttribute("whencode", Integer.toString(tsa.getWhenCode())); 098 tsaElem.setAttribute("whatcode", Integer.toString(tsa.getWhatCode())); 099 tsaElem.setAttribute("whendata", Integer.toString(tsa.getDataWhen())); 100 tsaElem.setAttribute("whenstring", tsa.getStringWhen()); 101 tsaElem.setAttribute("whatdata1", Integer.toString(tsa.getDataWhat1())); 102 tsaElem.setAttribute("whatdata2", Integer.toString(tsa.getDataWhat2())); 103 tsaElem.setAttribute("whatstring", tsa.getStringWhat()); 104 tsaElem.setAttribute("whatstring2", tsa.getStringWhat2()); 105 tsElem.addContent(tsaElem); 106 } 107 } 108 } 109 elem.addContent(tsElem); 110 } 111 } 112 transits.addContent(elem); 113 } 114 } 115 return (transits); 116 } 117 118 /** 119 * Subclass provides implementation to create the correct top element, 120 * including the type information. Default implementation is to use the 121 * local class here. 122 * 123 * @param transits The top-level element being created 124 */ 125 public void setStoreElementClass(Element transits) { 126 transits.setAttribute("class", "jmri.configurexml.TransitManagerXml"); 127 } 128 129 /** 130 * Create a TransitManager object of the correct class, then register and 131 * fill it. 132 * 133 * @param sharedTransits Top level Element to unpack. 134 * @param perNodeTransits Per-node top level Element to unpack. 135 * @return true if successful 136 */ 137 @Override 138 public boolean load(Element sharedTransits, Element perNodeTransits) { 139 // load individual Transits 140 loadTransits(sharedTransits, perNodeTransits); 141 return true; 142 } 143 144 /** 145 * Utility method to load the individual Transit objects. If there's no 146 * additional info needed for a specific Transit type, invoke this with the 147 * parent of the set of Transit elements. 148 * 149 * @param sharedTransits Element containing the Transit elements to load. 150 * @param perNodeTransits Per-node Element containing the Transit elements 151 * to load. 152 */ 153 public void loadTransits(Element sharedTransits, Element perNodeTransits) { 154 List<Element> transitList = sharedTransits.getChildren("transit"); 155 log.debug("Found {} transits", transitList.size()); 156 TransitManager tm = InstanceManager.getDefault(TransitManager.class); 157 tm.setPropertyChangesSilenced("beans", true); 158 159 for (Element tst : transitList) { 160 String sysName = getSystemName(tst); 161 String userName = getUserName(tst); 162 Transit x; 163 try { 164 x = tm.createNewTransit(sysName, userName); 165 } catch (IllegalArgumentException ex) { 166 log.error("Continuing following Exception: ", ex); 167 continue; // go to next Element 168 } 169 // load common part 170 loadCommon(x, tst); 171 172 // load transitsection children 173 List<Element> transitTransitSectionList = tst.getChildren("transitsection"); 174 for (Element elem : transitTransitSectionList) { 175 int seq = 0; 176 int dir = Section.UNKNOWN; 177 boolean alt = false; 178 boolean safe = false; 179 String sectionName = elem.getAttribute("sectionname").getValue(); 180 if (sectionName.equals("null")) { 181 log.warn("When loading configuration - missing Section in Transit {}", sysName); 182 } 183 try { 184 seq = elem.getAttribute("sequence").getIntValue(); 185 dir = elem.getAttribute("direction").getIntValue(); 186 } catch (DataConversionException e) { 187 log.error("Data Conversion Exception when loading direction of entry point - ", e); 188 } 189 if (elem.getAttribute("alternate").getValue().equals("yes")) { 190 alt = true; 191 } 192 if (elem.getAttribute("safe") != null) { 193 if (elem.getAttribute("safe").getValue().equals("yes")) { 194 safe = true; 195 } 196 } 197 String stopAllocatingSensor = ""; 198 if (elem.getAttribute("stopallocatingsensor") != null) { // may not exist 199 stopAllocatingSensor = elem.getAttribute("stopallocatingsensor").getValue(); 200 if (stopAllocatingSensor.equals("null")) { 201 log.warn("When loading configuration - missing Section in Transit {}", sysName); 202 stopAllocatingSensor = ""; 203 } 204 } 205 206 TransitSection ts = new TransitSection(sectionName, seq, dir, alt, safe, stopAllocatingSensor ); 207 x.addTransitSection(ts); 208 // load transitsectionaction children, if any 209 List<Element> transitTransitSectionActionList = elem. 210 getChildren("transitsectionaction"); 211 for (Element elemx : transitTransitSectionActionList) { 212 int tWhen = 1; 213 int tWhat = 1; 214 int tWhenData = 0; 215 String tWhenString = elemx.getAttribute("whenstring").getValue(); 216 int tWhatData1 = 0; 217 int tWhatData2 = 0; 218 String tWhatString = elemx.getAttribute("whatstring").getValue(); 219 String tWhatString2 = ""; 220 if (elemx.getAttribute("whatstring").getValue() != null) { 221 tWhatString2=elemx.getAttribute("whatstring").getValue(); 222 } 223 try { 224 tWhen = elemx.getAttribute("whencode").getIntValue(); 225 tWhat = elemx.getAttribute("whatcode").getIntValue(); 226 tWhenData = elemx.getAttribute("whendata").getIntValue(); 227 tWhatData1 = elemx.getAttribute("whatdata1").getIntValue(); 228 tWhatData2 = elemx.getAttribute("whatdata2").getIntValue(); 229 } catch (DataConversionException e) { 230 log.error("Data Conversion Exception when loading transit section action - ", e); 231 } 232 TransitSectionAction tsa = new TransitSectionAction(tWhen, tWhat, tWhenData, 233 tWhatData1, tWhatData2, tWhenString, tWhatString, tWhatString2); 234 ts.addAction(tsa); 235 } 236 } 237 } 238 tm.setPropertyChangesSilenced("beans", false); 239 } 240 241 @Override 242 public int loadOrder() { 243 return InstanceManager.getDefault(TransitManager.class).getXMLOrder(); 244 } 245 246 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DefaultTransitManagerXml.class); 247 248}