001package jmri.jmris; 002 003import java.beans.PropertyChangeEvent; 004import java.beans.PropertyChangeListener; 005import java.io.IOException; 006import java.util.HashMap; 007import java.util.Map; 008import jmri.InstanceManager; 009import jmri.JmriException; 010import jmri.Light; 011import org.slf4j.Logger; 012import org.slf4j.LoggerFactory; 013 014/** 015 * Abstract interface between the a JMRI Light and a network connection 016 * 017 * @author Paul Bender Copyright (C) 2010 018 * @author Randall Wood Copyright (C) 2013, 2014 019 */ 020abstract public class AbstractLightServer { 021 022 private final HashMap<String, LightListener> lights; 023 private final static Logger log = LoggerFactory.getLogger(AbstractLightServer.class); 024 025 public AbstractLightServer() { 026 lights = new HashMap<>(); 027 } 028 029 /* 030 * Protocol Specific Abstract Functions 031 */ 032 abstract public void sendStatus(String lightName, int Status) throws IOException; 033 034 abstract public void sendErrorStatus(String lightName) throws IOException; 035 036 abstract public void parseStatus(String statusString) throws JmriException, IOException; 037 038 synchronized protected void addLightToList(String lightName) { 039 if (!lights.containsKey(lightName)) { 040 Light li = InstanceManager.lightManagerInstance().getLight(lightName); 041 if (li != null) { 042 lights.put(lightName, new LightListener(lightName)); 043 li.addPropertyChangeListener(lights.get(lightName)); 044 } else { 045 log.error("Failed to get light {}", lightName); 046 } 047 } 048 } 049 050 synchronized protected void removeLightFromList(String lightName) { 051 if (lights.containsKey(lightName)) { 052 Light li = InstanceManager.lightManagerInstance().getLight(lightName); 053 if (li != null) { 054 li.removePropertyChangeListener(lights.get(lightName)); 055 lights.remove(lightName); 056 } else { 057 log.error("Failed to get light {}", lightName); 058 } 059 } 060 } 061 062 public Light initLight(String lightName) throws IllegalArgumentException { 063 Light light = InstanceManager.lightManagerInstance().provideLight(lightName); 064 this.addLightToList(lightName); 065 return light; 066 } 067 068 public void lightOff(String lightName) { 069 Light light; 070 // load address from switchAddrTextField 071 try { 072 073 addLightToList(lightName); 074 light = InstanceManager.lightManagerInstance().getLight(lightName); 075 if (light == null) { 076 log.error("Light {} is not available", lightName); 077 } else { 078 log.debug("about to command OFF"); 079 // and set state to OFF 080 light.setState(Light.OFF); 081 } 082 } catch (Exception ex) { 083 log.error("light off", ex); 084 } 085 } 086 087 public void lightOn(String lightName) { 088 Light light; 089 // load address from switchAddrTextField 090 try { 091 addLightToList(lightName); 092 light = InstanceManager.lightManagerInstance().getLight(lightName); 093 094 if (light == null) { 095 log.error("Light {} is not available", lightName); 096 } else { 097 log.debug("about to command ON"); 098 // and set state to ON 099 light.setState(Light.ON); 100 } 101 } catch (Exception ex) { 102 log.error("light on", ex); 103 } 104 } 105 106 public void dispose() { 107 for (Map.Entry<String, LightListener> light : this.lights.entrySet()) { 108 Light li = InstanceManager.lightManagerInstance().getLight(light.getKey()); 109 if (li != null) { 110 li.removePropertyChangeListener(light.getValue()); 111 } 112 } 113 this.lights.clear(); 114 } 115 116 class LightListener implements PropertyChangeListener { 117 118 LightListener(String lightName) { 119 name = lightName; 120 light = InstanceManager.lightManagerInstance().getLight(lightName); 121 } 122 123 // update state as state of light changes 124 @Override 125 public void propertyChange(PropertyChangeEvent e) { 126 // If the Commanded State changes, show transition state as "<inconsistent>" 127 if (e.getPropertyName().equals("KnownState")) { 128 int now = ((Integer) e.getNewValue()).intValue(); 129 try { 130 sendStatus(name, now); 131 } catch (IOException ie) { 132 log.debug("Error Sending Status"); 133 // if we get an error, de-register 134 light.removePropertyChangeListener(this); 135 removeLightFromList(name); 136 } 137 } 138 } 139 Light light = null; 140 String name = null; 141 } 142}