📄 serviceprovider.java
字号:
public void serviceConnectorUpdate(ServiceConnector source, String data) { // Since we're getting the raw data, it would be quite unpleasant to // parse it right here. Instead, let the device proxies figure it // out. Now, the tough question is how do we know what proxies are // interested in this data... Set proxySet = getProxyByServiceConnector(source); // Now tell them about the data piece... boolean accepted = false; for ( Iterator i = proxySet.iterator(); i.hasNext(); ) { DeviceConnectorProxy dcp = (DeviceConnectorProxy)i.next(); if ( dcp.serviceConnectorUpdate(data) ) { accepted = true; break; } } if ( !accepted ) { //complain(LOG_NOTICE, CH_SP, "No listeners for " + data + ": " + proxySet); } } private Set getProxyByServiceConnector(ServiceConnector connector) { // First, get list of device addresses. Second, resolve them into // device connector proxies. Set proxySet = new TreeSet(); for ( Iterator i = serviceConnectorByAddress.keySet().iterator(); i.hasNext(); ) { String address = i.next().toString(); ServiceConnector target = (ServiceConnector)serviceConnectorByAddress.get(address); if ( target == null ) { complain(LOG_WARNING, CH_SP, "No service connector for " + address + "?"); } else if ( target.equals(connector) ) { // There should be one device connector proxy per address DeviceConnector dc = (DeviceConnector)deviceConnectorByAddress.get(address); if ( dc == null ) { // Quite possible. This means that we don't have the // listener for this device... //complain(LOG_DEBUG, CH_SP, "No proxy for " + address + "?"); //complain(LOG_DEBUG, CH_SP, "Map: " + deviceConnectorByAddress); } else { proxySet.add(dc); } } else { // Oh well, this is not ours... } } return proxySet; } /** * Accept the notification from the dying service connector. * * Also, figure out which devices connectors are affected and broadcast * departure notification to them. Don't forget to remove the dying * service connector from our lists. * * @param connector Connector which is shutting down and is willing to * notify us about its departure. */ synchronized void connectorIsDead(ServiceConnector connector) { // This connector doesn't run at this source address anymore for ( Iterator i = serviceConnectorBySource.keySet().iterator(); i.hasNext(); ) { Object source = i.next(); if ( connector.equals(serviceConnectorBySource.get(source)) ) { // Forget it complain(LOG_NOTICE, CH_SP, "No connector " + connector + " at " + source + " any more"); i.remove(); } } Set departed = getProxyByServiceConnector(connector); complain(LOG_DEBUG, CH_SP, "Devices departed: " + departed); for ( Iterator i = departed.iterator(); i.hasNext(); ) { DeviceConnectorProxy dcp = (DeviceConnectorProxy)i.next(); // This address is not served by this connector anymore serviceConnectorByAddress.remove(dcp.getDeviceAddress()); dcp.broadcast("Not Available"); } } protected class DeviceConnectorProxy implements DeviceConnector, Comparable { private final String deviceAddress; private Set listenerSet = new HashSet(); public DeviceConnectorProxy(String deviceAddress) { if ( deviceAddress == null || "".equals(deviceAddress) ) { throw new IllegalArgumentException("Invalid address: '" + deviceAddress + "'"); } this.deviceAddress = deviceAddress; } public String toString() { return "{proxy " + deviceAddress + "}"; } public final String getDeviceAddress() { return deviceAddress; } public void send(String command) throws IOException { // Since the connectors will be coming and going, we're going to // resolve the proper connector every time. Not necessarily // fast, but reliable. // Need to tell the sender that the device is not currently // available, if so ServiceConnector sc = null; synchronized ( serviceConnectorByAddress ) { sc = (ServiceConnector)serviceConnectorByAddress.get(getDeviceAddress()); if ( sc == null ) { // Don't have a connector at this moment throw new IOException("Not Available"); } } sc.send(getDeviceAddress(), command); } public String sendExclusive(String command) throws IOException { // Since the connectors will be coming and going, we're going to // resolve the proper connector every time. Not necessarily // fast, but reliable. // Need to tell the sender that the device is not currently // available, if so ServiceConnector sc = null; synchronized ( serviceConnectorByAddress ) { sc = (ServiceConnector)serviceConnectorByAddress.get(getDeviceAddress()); if ( sc == null ) { // Don't have a connector at this moment throw new IOException("Not Available"); } } return sc.sendExclusive(getDeviceAddress(), command); } public void addListener(DeviceListener listener) { listenerSet.add(listener); } public boolean serviceConnectorUpdate(String data) { // Figure out if this is ours StringTokenizer st = new StringTokenizer(data, " "); String token = st.nextToken(); boolean accepted = false; if ( getDeviceAddress().equals(token) ) { // Yep, that's ours accepted = true; // Parse the data String value = st.nextToken(); broadcast(value); } return accepted; } void broadcast(String data) { for ( Iterator i = listenerSet.iterator(); i.hasNext(); ) { ((DeviceListener)i.next()).deviceEvent(this, data); } } public int compareTo(Object other) { if ( other == null ) { throw new IllegalArgumentException("Other can't be null"); } if ( !(other instanceof DeviceConnectorProxy) ) { throw new ClassCastException("Expected " + getClass().getName() + ", got " + other.getClass().getName()); } return deviceAddress.compareTo(((DeviceConnectorProxy)other).deviceAddress); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -