001package jmri.jmrit.logixng.implementation.configurexml; 002 003import java.util.List; 004 005import jmri.ConfigureManager; 006import jmri.InstanceManager; 007import jmri.jmrit.logixng.ConditionalNG; 008import jmri.jmrit.logixng.ConditionalNG_Manager; 009import jmri.jmrit.logixng.LogixNG; 010import jmri.jmrit.logixng.LogixNG_Manager; 011import jmri.jmrit.logixng.MaleSocket; 012import jmri.jmrit.logixng.implementation.DefaultConditionalNG; 013import jmri.jmrit.logixng.implementation.DefaultConditionalNGManager; 014import jmri.jmrit.logixng.util.LogixNG_Thread; 015import jmri.util.ThreadingUtil; 016 017import org.jdom2.Element; 018 019/** 020 * Provides the functionality for configuring ConditionalNGManagers 021 * 022 * @author Dave Duchamp Copyright (c) 2007 023 * @author Daniel Bergqvist Copyright (c) 2018 024 * @author Dave Sand Copyright (c) 2021 025 */ 026public class DefaultConditionalNGManagerXml extends jmri.managers.configurexml.AbstractNamedBeanManagerConfigXML { 027 028 public DefaultConditionalNGManagerXml() { 029 } 030 031 /** 032 * Default implementation for storing the contents of a ConditionalNG_Manager 033 * 034 * @param o Object to store, of type ConditionalNG_Manager 035 * @return Element containing the complete info 036 */ 037 @Override 038 public Element store(Object o) { 039 Element conditionalNGs = new Element("LogixNGConditionalNGs"); 040 setStoreElementClass(conditionalNGs); 041 ConditionalNG_Manager tm = (ConditionalNG_Manager) o; 042 LogixNG_Manager lm = InstanceManager.getDefault(LogixNG_Manager.class); 043 if (tm != null) { 044 if (lm.getNamedBeanSet().isEmpty()) return null; 045 for (LogixNG logixNG : lm.getNamedBeanSet()) { 046 for (int i=0; i < logixNG.getNumConditionalNGs(); i++) { 047 ConditionalNG conditionalNG = logixNG.getConditionalNG(i); 048 049 log.debug("ConditionalNG system name is {}", conditionalNG.getSystemName()); // NOI18N 050 boolean enabled = conditionalNG.isEnabled(); 051 boolean executeAtStartup = conditionalNG.isExecuteAtStartup(); 052 Element elem = new Element("ConditionalNG"); // NOI18N 053 elem.addContent(new Element("systemName").addContent(conditionalNG.getSystemName())); // NOI18N 054 055 // store common part 056 storeCommon(conditionalNG, elem); 057 058 elem.addContent(new Element("thread").addContent( 059 Integer.toString(conditionalNG.getStartupThreadId()))); // NOI18N 060 061 Element e2 = new Element("Socket"); 062 e2.addContent(new Element("socketName").addContent(conditionalNG.getChild(0).getName())); 063 MaleSocket socket = conditionalNG.getChild(0).getConnectedSocket(); 064 String socketSystemName; 065 if (socket != null) { 066 socketSystemName = socket.getSystemName(); 067 } else { 068 socketSystemName = ((DefaultConditionalNG)conditionalNG).getSocketSystemName(); 069 } 070 if (socketSystemName != null) { 071 e2.addContent(new Element("systemName").addContent(socketSystemName)); 072 } 073 elem.addContent(e2); 074 075 elem.setAttribute("enabled", enabled ? "yes" : "no"); // NOI18N 076 077 // executeAtStartup is by default true so only store it if it's false 078 if (!executeAtStartup) { 079 elem.setAttribute("executeAtStartup", "no"); // NOI18N 080 } 081 082 conditionalNGs.addContent(elem); 083 } 084 } 085 } 086 return (conditionalNGs); 087 } 088 089 /** 090 * Subclass provides implementation to create the correct top element, 091 * including the type information. Default implementation is to use the 092 * local class here. 093 * 094 * @param logixngs The top-level element being created 095 */ 096 public void setStoreElementClass(Element logixngs) { 097 logixngs.setAttribute("class", this.getClass().getName()); // NOI18N 098 } 099 100 /** 101 * Create a ConditionalNG_Manager object of the correct class, then register and 102 * fill it. 103 * 104 * @param sharedConditionalNG Shared top level Element to unpack. 105 * @param perNodeConditionalNG Per-node top level Element to unpack. 106 * @return true if successful 107 */ 108 @Override 109 public boolean load(Element sharedConditionalNG, Element perNodeConditionalNG) { 110 // create the master object 111 replaceConditionalNGManager(); 112 // load individual sharedLogix 113 loadConditionalNGs(sharedConditionalNG); 114 return true; 115 } 116 117 /** 118 * Utility method to load the individual ConditionalNG objects. If there's no 119 * additional info needed for a specific logixng type, invoke this with the 120 * parent of the set of ConditionalNG elements. 121 * 122 * @param conditionalNGs Element containing the ConditionalNG elements to load. 123 */ 124 public void loadConditionalNGs(Element conditionalNGs) { 125 List<Element> conditionalNGList = conditionalNGs.getChildren("ConditionalNG"); // NOI18N 126 log.debug("Found {} ConditionalNGs", conditionalNGList.size() ); // NOI18N 127 ConditionalNG_Manager tm = InstanceManager.getDefault(jmri.jmrit.logixng.ConditionalNG_Manager.class); 128 129 for (int i = 0; i < conditionalNGList.size(); i++) { 130 131 Element conditionalNG_Element = conditionalNGList.get(i); 132 133 String sysName = getSystemName(conditionalNG_Element); 134 if (sysName == null) { 135 log.warn("unexpected null in systemName {}", conditionalNG_Element); // NOI18N 136 break; 137 } 138 139 String userName = getUserName(conditionalNG_Element); 140 141 int threadId = LogixNG_Thread.DEFAULT_LOGIXNG_THREAD; 142 Element threadElem = conditionalNG_Element.getChild("thread"); 143 if (threadElem != null) threadId = Integer.parseInt(threadElem.getTextTrim()); 144 145 String enabled = ""; 146 if (conditionalNG_Element.getAttribute("enabled") != null) { // NOI18N 147 enabled = conditionalNG_Element.getAttribute("enabled").getValue(); // NOI18N 148 } 149 log.debug("create ConditionalNG: ({})({})", // NOI18N 150 sysName, userName == null ? "<null>" : userName); // NOI18N 151 152 // Create a new ConditionalNG but don't setup the initial tree. 153 LogixNG logixNG = tm.getParentLogixNG(sysName); 154 if (logixNG == null) { 155 log.warn("unexpected null while finding parent logixNG for '{}'", conditionalNG_Element); // NOI18N 156 break; 157 } 158 159 DefaultConditionalNG conditionalNG = 160 (DefaultConditionalNG)tm.createConditionalNG(logixNG, sysName, userName, threadId); 161 162 if (conditionalNG != null) { 163 // load common part 164 loadCommon(conditionalNG, conditionalNG_Element); 165 166 Element socketName = conditionalNG_Element.getChild("Socket").getChild("socketName"); 167 if (socketName != null) { 168 conditionalNG.getFemaleSocket().setName(socketName.getTextTrim()); 169 } 170 Element socketSystemName = conditionalNG_Element.getChild("Socket").getChild("systemName"); 171 if (socketSystemName != null) { 172// log.warn("Socket system name: {}", socketSystemName.getTextTrim()); 173 conditionalNG.setSocketSystemName(socketSystemName.getTextTrim()); 174 } 175 176 // set enabled/disabled if attribute was present 177 if ((enabled != null) && (!enabled.equals(""))) { 178 if (enabled.equals("yes")) { // NOI18N 179 conditionalNG.setEnabled(true); 180 } else if (enabled.equals("no")) { // NOI18N 181 conditionalNG.setEnabled(false); 182 } 183 } 184 185 String executeAtStartup = ""; 186 if (conditionalNG_Element.getAttribute("executeAtStartup") != null) { // NOI18N 187 executeAtStartup = conditionalNG_Element.getAttribute("executeAtStartup").getValue(); // NOI18N 188 } 189 // set enabled/disabled if attribute was present 190 if ((executeAtStartup != null) && (!executeAtStartup.equals(""))) { 191 if (executeAtStartup.equals("yes")) { // NOI18N 192 conditionalNG.setExecuteAtStartup(true); 193 } else if (executeAtStartup.equals("no")) { // NOI18N 194 conditionalNG.setExecuteAtStartup(false); 195 } 196 } 197 } 198 } 199 } 200 201 /** 202 * Replace the current LogixManager, if there is one, with one newly created 203 * during a load operation. This is skipped if they are of the same absolute 204 * type. 205 */ 206 protected void replaceConditionalNGManager() { 207 if (InstanceManager.getDefault(jmri.jmrit.logixng.ConditionalNG_Manager.class).getClass().getName() 208 .equals(DefaultConditionalNGManager.class.getName())) { 209 return; 210 } 211 // if old manager exists, remove it from configuration process 212 if (InstanceManager.getNullableDefault(jmri.jmrit.logixng.ConditionalNG_Manager.class) != null) { 213 ConfigureManager cmOD = InstanceManager.getNullableDefault(jmri.ConfigureManager.class); 214 if (cmOD != null) { 215 cmOD.deregister(InstanceManager.getDefault(jmri.jmrit.logixng.ConditionalNG_Manager.class)); 216 } 217 218 } 219 220 ThreadingUtil.runOnGUI(() -> { 221 // register new one with InstanceManager 222 DefaultConditionalNGManager pManager = DefaultConditionalNGManager.instance(); 223 InstanceManager.store(pManager, ConditionalNG_Manager.class); 224 // register new one for configuration 225 ConfigureManager cmOD = InstanceManager.getNullableDefault(jmri.ConfigureManager.class); 226 if (cmOD != null) { 227 cmOD.registerConfig(pManager, jmri.Manager.LOGIXNGS); 228 } 229 }); 230 } 231 232 @Override 233 public int loadOrder() { 234 return InstanceManager.getDefault(jmri.jmrit.logixng.ConditionalNG_Manager.class).getXMLOrder(); 235 } 236 237 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DefaultConditionalNGManagerXml.class); 238}