001package jmri.jmrix.srcp; 002 003import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 004 005import java.util.Comparator; 006import java.util.ResourceBundle; 007 008import jmri.*; 009import jmri.jmrix.ConfiguringSystemConnectionMemo; 010import jmri.jmrix.DefaultSystemConnectionMemo; 011import jmri.jmrix.srcp.parser.ASTinfo; 012import jmri.jmrix.srcp.parser.SimpleNode; 013import jmri.util.NamedBeanComparator; 014 015import org.slf4j.Logger; 016import org.slf4j.LoggerFactory; 017 018/** 019 * Lightweight class to denote that a system is active, and provide general 020 * information. 021 * <p> 022 * Objects of specific subtypes are registered in the instance manager to 023 * activate their particular system. 024 * 025 * @author Bob Jacobsen Copyright (C) 2010 026 */ 027public class SRCPBusConnectionMemo extends DefaultSystemConnectionMemo implements SRCPListener, ConfiguringSystemConnectionMemo { 028 029 private int _bus = 0; 030 private boolean configured = false; 031 032 public SRCPBusConnectionMemo(SRCPTrafficController et, String Prefix, int bus) { 033 super(Prefix + bus, "SRCP:" + bus); 034 this.et = et; 035 _bus = bus; 036 log.debug("Created SRCPBusConnectionMemo for bus {}", bus); 037 et.addSRCPListener(this); 038 et.sendSRCPMessage(new SRCPMessage("GET " + bus + " DESCRIPTION\n"), null); 039 configured = false; 040 } 041 042 private jmri.jmrix.swing.ComponentFactory cf = null; 043 044 /** 045 * Provides access to the TrafficController for this particular connection. 046 * @return SRCP Traffic Controller. 047 */ 048 public SRCPTrafficController getTrafficController() { 049 return et; 050 } 051 052 public void setTrafficController(SRCPTrafficController et) { 053 this.et = et; 054 } 055 056 private SRCPTrafficController et; 057 058 /** 059 * Configure the common managers for Internal connections. This puts the 060 * common manager config in one place. 061 */ 062 @Override 063 @SuppressFBWarnings(value = "UW_UNCOND_WAIT", justification="false postive, guarded by while statement") 064 public void configureManagers() { 065 while(!configured){ 066 // wait for the managers to be configured. 067 synchronized(this){ 068 try { 069 this.wait(); 070 } catch(java.lang.InterruptedException ie){ 071 // just catch the error and re-check our condition. 072 } 073 } 074 } 075 register(); 076 log.debug("Manager configuration complete for bus {}", _bus ); 077 } 078 079 /** 080 * package protected function to get the bus associated with this memo. 081 * 082 * @return integer bus number 083 */ 084 int getBus() { 085 return _bus; 086 } 087 088 /** 089 * Provides access to the Programmer for this particular connection. 090 * <p> 091 * NOTE: Programmer defaults to null 092 * @return programmer manager. 093 */ 094 public SRCPProgrammerManager getProgrammerManager() { 095 return (SRCPProgrammerManager)get(GlobalProgrammerManager.class); 096 } 097 098 public void setProgrammerManager(SRCPProgrammerManager p) { 099 store(p,GlobalProgrammerManager.class); 100 } 101 102 /* 103 * Provides access to the Throttle Manager for this particular connection. 104 * NOTE: Throttle Manager defaults to null 105 */ 106 public ThrottleManager getThrottleManager() { 107 return get(ThrottleManager.class); 108 } 109 110 public void setThrottleManager(ThrottleManager t) { 111 store(t,ThrottleManager.class); 112 } 113 114 /* 115 * Provides access to the Clock Control for this particular connection. 116 * NOTE: May return null if the Clock Control has not been set. 117 */ 118 public ClockControl getClockControl() { 119 return get(ClockControl.class); 120 } 121 122 public void setClockControl(ClockControl t) { 123 store(t,ClockControl.class); 124 InstanceManager.store(t, ClockControl.class); 125 InstanceManager.setDefault(ClockControl.class, t); 126 } 127 128 /* 129 * Provides access to the PowerManager for this particular connection. 130 */ 131 public PowerManager getPowerManager() { 132 return get(PowerManager.class); 133 } 134 135 public void setPowerManager(PowerManager p) { 136 store(p,PowerManager.class); 137 } 138 139 /* 140 * Provides access to the SensorManager for this particular connection. 141 */ 142 public SensorManager getSensorManager() { 143 return get(SensorManager.class); 144 } 145 146 public void setSensorManager(SensorManager s) { 147 store(s,SensorManager.class); 148 } 149 150 /* 151 * Provides access to the TurnoutManager for this particular connection. 152 * NOTE: TurnoutManager defaults to NULL 153 */ 154 public TurnoutManager getTurnoutManager() { 155 return get(TurnoutManager.class); 156 } 157 158 public void setTurnoutManager(TurnoutManager t) { 159 store(t,TurnoutManager.class); 160 } 161 162 @Override 163 protected ResourceBundle getActionModelResourceBundle() { 164 return ResourceBundle.getBundle("jmri.jmrix.srcp.SrcpActionListBundle"); 165 } 166 167 @Override 168 public <B extends NamedBean> Comparator<B> getNamedBeanComparator(Class<B> type) { 169 return new NamedBeanComparator<>(); 170 } 171 172 @Override 173 public void dispose() { 174 if (et != null) { 175 et = null; 176 } 177 InstanceManager.deregister(this, SRCPBusConnectionMemo.class); 178 if (cf != null) { 179 InstanceManager.deregister(cf, jmri.jmrix.swing.ComponentFactory.class); 180 } 181 super.dispose(); 182 } 183 184 // functions for the SRCP Listener interface. 185 @Override 186 public void message(SRCPMessage m) { 187 } 188 189 @Override 190 public void reply(SRCPReply m) { 191 } 192 193 @Override 194 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "NN_NAKED_NOTIFY", justification="Notify passing reply event, not state") 195 public void reply(jmri.jmrix.srcp.parser.SimpleNode n) { 196 log.debug("SimpleNode Reply called with {}", n.toString()); 197 reply(new SRCPReply(n)); 198 if (n.jjtGetChild(1) instanceof ASTinfo) { 199 jmri.jmrix.srcp.parser.SimpleNode infonode 200 = (jmri.jmrix.srcp.parser.SimpleNode) n.jjtGetChild(1); 201 if (!((String) ((SimpleNode) (infonode.jjtGetChild(0))).jjtGetValue()).equals("" + _bus)) { 202 return; // not for this bus. 203 } // Look for description information for this bus, and configure the 204 // managers for this bus. 205 if (infonode.jjtGetChild(1) instanceof jmri.jmrix.srcp.parser.ASTdescription) { 206 SimpleNode descnode = (SimpleNode) infonode.jjtGetChild(1); 207 for (int i = 0; i < descnode.jjtGetNumChildren(); i++) { 208 jmri.jmrix.srcp.parser.SimpleNode child 209 = (jmri.jmrix.srcp.parser.SimpleNode) descnode.jjtGetChild(i); 210 log.debug("child node type {} value {}", child.toString(), child.jjtGetValue()); 211 if (child instanceof jmri.jmrix.srcp.parser.ASTdevicegroup) { 212 String DeviceType = (String) child.jjtGetValue(); 213 switch (DeviceType) { 214 case "FB": 215 setSensorManager(new SRCPSensorManager(this)); 216 InstanceManager.setSensorManager(getSensorManager()); 217 break; 218 case "GA": 219 setTurnoutManager(new SRCPTurnoutManager(this)); 220 InstanceManager.setTurnoutManager(getTurnoutManager()); 221 break; 222 case "SM": 223 setProgrammerManager(new SRCPProgrammerManager(new SRCPProgrammer(this), this)); 224 InstanceManager.store(getProgrammerManager(), GlobalProgrammerManager.class); 225 break; 226 case "POWER": 227 setPowerManager(new SRCPPowerManager(this, _bus)); 228 InstanceManager.store(getPowerManager(), PowerManager.class); 229 break; 230 case "GL": 231 setThrottleManager(new SRCPThrottleManager(this)); 232 InstanceManager.setThrottleManager(getThrottleManager()); 233 break; 234 case "TIME": 235 setClockControl(new SRCPClockControl(this)); 236 break; 237 default: 238 log.warn("unexpected DeviceType"); 239 break; 240 } 241 } 242 } 243 configured = true; 244 synchronized(this) { 245 this.notifyAll(); // wake up any thread that called configureManagers(). 246 } 247 } 248 } 249 } 250 251 private final static Logger log = LoggerFactory.getLogger(SRCPBusConnectionMemo.class); 252 253}