13742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman/** 23742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 33742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 43742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanpackage javax.jmdns.impl; 53742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 63742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.EventListener; 73742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.concurrent.ConcurrentHashMap; 83742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.concurrent.ConcurrentMap; 93742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.logging.Logger; 103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.JmDNS; 123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.ServiceEvent; 133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.ServiceInfo; 143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.ServiceListener; 153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.ServiceTypeListener; 163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman/** 183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * This class track the status of listener.<br/> 193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * The main purpose of this class is to collapse consecutive events so that we can guarantee the correct call back sequence. 203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param <T> 223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * listener type 233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanpublic class ListenerStatus<T extends EventListener> { 253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public static class ServiceListenerStatus extends ListenerStatus<ServiceListener> { 273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private static Logger logger = Logger.getLogger(ServiceListenerStatus.class.getName()); 283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final ConcurrentMap<String, ServiceInfo> _addedServices; 303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param listener 333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * listener being tracked. 343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param synch 353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * true if that listener can be called asynchronously 363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public ServiceListenerStatus(ServiceListener listener, boolean synch) { 383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman super(listener, synch); 393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _addedServices = new ConcurrentHashMap<String, ServiceInfo>(32); 403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * A service has been added.<br/> 443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * <b>Note:</b>This event is only the service added event. The service info associated with this event does not include resolution information.<br/> 453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * To get the full resolved information you need to listen to {@link #serviceResolved(ServiceEvent)} or call {@link JmDNS#getServiceInfo(String, String, long)} 463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * <pre> 483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * ServiceInfo info = event.getDNS().getServiceInfo(event.getType(), event.getName()) 493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * </pre> 503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * <p> 513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Please note that service resolution may take a few second to resolve. 523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * </p> 533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param event 553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * The ServiceEvent providing the name and fully qualified type of the service. 563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman void serviceAdded(ServiceEvent event) { 583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String qualifiedName = event.getName() + "." + event.getType(); 593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (null == _addedServices.putIfAbsent(qualifiedName, event.getInfo().clone())) { 603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.getListener().serviceAdded(event); 613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ServiceInfo info = event.getInfo(); 623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((info != null) && (info.hasData())) { 633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.getListener().serviceResolved(event); 643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.finer("Service Added called for a service already added: " + event); 673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * A service has been removed. 723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param event 743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * The ServiceEvent providing the name and fully qualified type of the service. 753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman void serviceRemoved(ServiceEvent event) { 773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String qualifiedName = event.getName() + "." + event.getType(); 783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (_addedServices.remove(qualifiedName, _addedServices.get(qualifiedName))) { 793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.getListener().serviceRemoved(event); 803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.finer("Service Removed called for a service already removed: " + event); 823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * A service has been resolved. Its details are now available in the ServiceInfo record.<br/> 873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * <b>Note:</b>This call back will never be called if the service does not resolve.<br/> 883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param event 903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * The ServiceEvent providing the name, the fully qualified type of the service, and the service info record. 913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman synchronized void serviceResolved(ServiceEvent event) { 933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ServiceInfo info = event.getInfo(); 943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if ((info != null) && (info.hasData())) { 953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String qualifiedName = event.getName() + "." + event.getType(); 963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ServiceInfo previousServiceInfo = _addedServices.get(qualifiedName); 973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (!_sameInfo(info, previousServiceInfo)) { 983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (null == previousServiceInfo) { 993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (null == _addedServices.putIfAbsent(qualifiedName, info.clone())) { 1003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.getListener().serviceResolved(event); 1013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 1033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (_addedServices.replace(qualifiedName, previousServiceInfo, info.clone())) { 1043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.getListener().serviceResolved(event); 1053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 1083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.finer("Service Resolved called for a service already resolved: " + event); 1093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 1113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.warning("Service Resolved called for an unresolved event: " + event); 1123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private static final boolean _sameInfo(ServiceInfo info, ServiceInfo lastInfo) { 1173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (info == null) return false; 1183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (lastInfo == null) return false; 1193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (!info.equals(lastInfo)) return false; 1203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman byte[] text = info.getTextBytes(); 1213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman byte[] lastText = lastInfo.getTextBytes(); 1223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (text.length != lastText.length) return false; 1233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (int i = 0; i < text.length; i++) { 1243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (text[i] != lastText[i]) return false; 1253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return true; 1273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 1303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 1313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see java.lang.Object#toString() 1323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 1343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String toString() { 1353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman StringBuilder aLog = new StringBuilder(2048); 1363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append("[Status for "); 1373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append(this.getListener().toString()); 1383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (_addedServices.isEmpty()) { 1393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append(" no type event "); 1403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 1413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append(" ("); 1423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (String service : _addedServices.keySet()) { 1433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append(service + ", "); 1443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append(") "); 1463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append("]"); 1483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return aLog.toString(); 1493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public static class ServiceTypeListenerStatus extends ListenerStatus<ServiceTypeListener> { 1543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private static Logger logger = Logger.getLogger(ServiceTypeListenerStatus.class.getName()); 1553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final ConcurrentMap<String, String> _addedTypes; 1573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 1593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param listener 1603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * listener being tracked. 1613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param synch 1623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * true if that listener can be called asynchronously 1633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public ServiceTypeListenerStatus(ServiceTypeListener listener, boolean synch) { 1653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman super(listener, synch); 1663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _addedTypes = new ConcurrentHashMap<String, String>(32); 1673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 1703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * A new service type was discovered. 1713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 1723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param event 1733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * The service event providing the fully qualified type of the service. 1743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman void serviceTypeAdded(ServiceEvent event) { 1763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (null == _addedTypes.putIfAbsent(event.getType(), event.getType())) { 1773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.getListener().serviceTypeAdded(event); 1783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 1793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.finest("Service Type Added called for a service type already added: " + event); 1803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 1843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * A new subtype for the service type was discovered. 1853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 1863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * <pre> 1873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * <sub>._sub.<app>.<protocol>.<servicedomain>.<parentdomain>. 1883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * </pre> 1893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 1903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param event 1913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * The service event providing the fully qualified type of the service with subtype. 1923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman void subTypeForServiceTypeAdded(ServiceEvent event) { 1943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (null == _addedTypes.putIfAbsent(event.getType(), event.getType())) { 1953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.getListener().subTypeForServiceTypeAdded(event); 1963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 1973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman logger.finest("Service Sub Type Added called for a service sub type already added: " + event); 1983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 2023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 2033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see java.lang.Object#toString() 2043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String toString() { 2073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman StringBuilder aLog = new StringBuilder(2048); 2083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append("[Status for "); 2093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append(this.getListener().toString()); 2103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (_addedTypes.isEmpty()) { 2113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append(" no type event "); 2123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else { 2133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append(" ("); 2143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (String type : _addedTypes.keySet()) { 2153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append(type + ", "); 2163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append(") "); 2183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append("]"); 2203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return aLog.toString(); 2213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public final static boolean SYNCHONEOUS = true; 2263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public final static boolean ASYNCHONEOUS = false; 2273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final T _listener; 2293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final boolean _synch; 2313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 2333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param listener 2343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * listener being tracked. 2353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param synch 2363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * true if that listener can be called asynchronously 2373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public ListenerStatus(T listener, boolean synch) { 2393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman super(); 2403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _listener = listener; 2413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _synch = synch; 2423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 2453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return the listener 2463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public T getListener() { 2483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _listener; 2493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 2523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Return <cod>true</code> if the listener must be called synchronously. 2533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 2543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return the synch 2553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isSynchronous() { 2573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _synch; 2583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 2613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 2623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see java.lang.Object#hashCode() 2633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public int hashCode() { 2663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.getListener().hashCode(); 2673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 2703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 2713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see java.lang.Object#equals(java.lang.Object) 2723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean equals(Object obj) { 2753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (obj instanceof ListenerStatus) && this.getListener().equals(((ListenerStatus<?>) obj).getListener()); 2763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 2793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 2803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see java.lang.Object#toString() 2813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String toString() { 2843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return "[Status for " + this.getListener().toString() + "]"; 2853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman} 287