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