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 @SuppressFBWarnings(value = "UW_UNCOND_WAIT", justification="false postive, guarded by while statement") 063 public void configureManagers() { 064 while(!configured){ 065 // wait for the managers to be configured. 066 synchronized(this){ 067 try { 068 this.wait(); 069 } catch(java.lang.InterruptedException ie){ 070 // just catch the error and re-check our condition. 071 } 072 } 073 } 074 register(); 075 log.debug("Manager configuration complete for bus {}", _bus ); 076 } 077 078 /** 079 * package protected function to get the bus associated with this memo. 080 * 081 * @return integer bus number 082 */ 083 int getBus() { 084 return _bus; 085 } 086 087 /** 088 * Provides access to the Programmer for this particular connection. 089 * <p> 090 * NOTE: Programmer defaults to null 091 * @return programmer manager. 092 */ 093 public SRCPProgrammerManager getProgrammerManager() { 094 return (SRCPProgrammerManager)get(GlobalProgrammerManager.class); 095 } 096 097 public void setProgrammerManager(SRCPProgrammerManager p) { 098 store(p,GlobalProgrammerManager.class); 099 } 100 101 /* 102 * Provides access to the Throttle Manager for this particular connection. 103 * NOTE: Throttle Manager defaults to null 104 */ 105 public ThrottleManager getThrottleManager() { 106 return get(ThrottleManager.class); 107 } 108 109 public void setThrottleManager(ThrottleManager t) { 110 store(t,ThrottleManager.class); 111 } 112 113 /* 114 * Provides access to the Clock Control for this particular connection. 115 * NOTE: May return null if the Clock Control has not been set. 116 */ 117 public ClockControl getClockControl() { 118 return get(ClockControl.class); 119 } 120 121 public void setClockControl(ClockControl t) { 122 store(t,ClockControl.class); 123 InstanceManager.store(t, ClockControl.class); 124 InstanceManager.setDefault(ClockControl.class, t); 125 } 126 127 /* 128 * Provides access to the PowerManager for this particular connection. 129 */ 130 public PowerManager getPowerManager() { 131 return get(PowerManager.class); 132 } 133 134 public void setPowerManager(PowerManager p) { 135 store(p,PowerManager.class); 136 } 137 138 /* 139 * Provides access to the SensorManager for this particular connection. 140 */ 141 public SensorManager getSensorManager() { 142 return get(SensorManager.class); 143 } 144 145 public void setSensorManager(SensorManager s) { 146 store(s,SensorManager.class); 147 } 148 149 /* 150 * Provides access to the TurnoutManager for this particular connection. 151 * NOTE: TurnoutManager defaults to NULL 152 */ 153 public TurnoutManager getTurnoutManager() { 154 return get(TurnoutManager.class); 155 } 156 157 public void setTurnoutManager(TurnoutManager t) { 158 store(t,TurnoutManager.class); 159 } 160 161 @Override 162 protected ResourceBundle getActionModelResourceBundle() { 163 return ResourceBundle.getBundle("jmri.jmrix.srcp.SrcpActionListBundle"); 164 } 165 166 @Override 167 public <B extends NamedBean> Comparator<B> getNamedBeanComparator(Class<B> type) { 168 return new NamedBeanComparator<>(); 169 } 170 171 @Override 172 public void dispose() { 173 if (et != null) { 174 et = null; 175 } 176 InstanceManager.deregister(this, SRCPBusConnectionMemo.class); 177 if (cf != null) { 178 InstanceManager.deregister(cf, jmri.jmrix.swing.ComponentFactory.class); 179 } 180 super.dispose(); 181 } 182 183 // functions for the SRCP Listener interface. 184 @Override 185 public void message(SRCPMessage m) { 186 } 187 188 @Override 189 public void reply(SRCPReply m) { 190 } 191 192 @Override 193 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "NN_NAKED_NOTIFY", justification="Notify passing reply event, not state") 194 public void reply(jmri.jmrix.srcp.parser.SimpleNode n) { 195 log.debug("SimpleNode Reply called with {}", n.toString()); 196 reply(new SRCPReply(n)); 197 if (n.jjtGetChild(1) instanceof ASTinfo) { 198 jmri.jmrix.srcp.parser.SimpleNode infonode 199 = (jmri.jmrix.srcp.parser.SimpleNode) n.jjtGetChild(1); 200 if (!((String) ((SimpleNode) (infonode.jjtGetChild(0))).jjtGetValue()).equals("" + _bus)) { 201 return; // not for this bus. 202 } // Look for description information for this bus, and configure the 203 // managers for this bus. 204 if (infonode.jjtGetChild(1) instanceof jmri.jmrix.srcp.parser.ASTdescription) { 205 SimpleNode descnode = (SimpleNode) infonode.jjtGetChild(1); 206 for (int i = 0; i < descnode.jjtGetNumChildren(); i++) { 207 jmri.jmrix.srcp.parser.SimpleNode child 208 = (jmri.jmrix.srcp.parser.SimpleNode) descnode.jjtGetChild(i); 209 log.debug("child node type {} value {}", child.toString(), child.jjtGetValue()); 210 if (child instanceof jmri.jmrix.srcp.parser.ASTdevicegroup) { 211 String DeviceType = (String) child.jjtGetValue(); 212 switch (DeviceType) { 213 case "FB": 214 setSensorManager(new SRCPSensorManager(this)); 215 InstanceManager.setSensorManager(getSensorManager()); 216 break; 217 case "GA": 218 setTurnoutManager(new SRCPTurnoutManager(this)); 219 InstanceManager.setTurnoutManager(getTurnoutManager()); 220 break; 221 case "SM": 222 setProgrammerManager(new SRCPProgrammerManager(new SRCPProgrammer(this), this)); 223 InstanceManager.store(getProgrammerManager(), GlobalProgrammerManager.class); 224 break; 225 case "POWER": 226 setPowerManager(new SRCPPowerManager(this, _bus)); 227 InstanceManager.store(getPowerManager(), PowerManager.class); 228 break; 229 case "GL": 230 setThrottleManager(new SRCPThrottleManager(this)); 231 InstanceManager.setThrottleManager(getThrottleManager()); 232 break; 233 case "TIME": 234 setClockControl(new SRCPClockControl(this)); 235 break; 236 default: 237 log.warn("unexpected DeviceType"); 238 break; 239 } 240 } 241 } 242 configured = true; 243 synchronized(this) { 244 this.notifyAll(); // wake up any thread that called configureManagers(). 245 } 246 } 247 } 248 } 249 250 private final static Logger log = LoggerFactory.getLogger(SRCPBusConnectionMemo.class); 251 252}