Go to the documentation of this file.00001
00004 package javax.jmdns.impl;
00005
00006 import java.util.EventListener;
00007 import java.util.concurrent.ConcurrentHashMap;
00008 import java.util.concurrent.ConcurrentMap;
00009 import java.util.logging.Logger;
00010
00011 import javax.jmdns.JmDNS;
00012 import javax.jmdns.ServiceEvent;
00013 import javax.jmdns.ServiceInfo;
00014 import javax.jmdns.ServiceListener;
00015 import javax.jmdns.ServiceTypeListener;
00016
00024 public class ListenerStatus<T extends EventListener> {
00025
00026 public static class ServiceListenerStatus extends ListenerStatus<ServiceListener> {
00027 private static Logger logger = Logger.getLogger(ServiceListenerStatus.class.getName());
00028
00029 private final ConcurrentMap<String, ServiceInfo> _addedServices;
00030
00037 public ServiceListenerStatus(ServiceListener listener, boolean synch) {
00038 super(listener, synch);
00039 _addedServices = new ConcurrentHashMap<String, ServiceInfo>(32);
00040 }
00041
00057 void serviceAdded(ServiceEvent event) {
00058 String qualifiedName = event.getName() + "." + event.getType();
00059 if (null == _addedServices.putIfAbsent(qualifiedName, event.getInfo().clone())) {
00060 this.getListener().serviceAdded(event);
00061 ServiceInfo info = event.getInfo();
00062 if ((info != null) && (info.hasData())) {
00063 this.getListener().serviceResolved(event);
00064 }
00065 } else {
00066 logger.finer("Service Added called for a service already added: " + event);
00067 }
00068 }
00069
00076 void serviceRemoved(ServiceEvent event) {
00077 String qualifiedName = event.getName() + "." + event.getType();
00078 if (_addedServices.remove(qualifiedName, _addedServices.get(qualifiedName))) {
00079 this.getListener().serviceRemoved(event);
00080 } else {
00081 logger.finer("Service Removed called for a service already removed: " + event);
00082 }
00083 }
00084
00092 synchronized void serviceResolved(ServiceEvent event) {
00093 ServiceInfo info = event.getInfo();
00094 if ((info != null) && (info.hasData())) {
00095 String qualifiedName = event.getName() + "." + event.getType();
00096 ServiceInfo previousServiceInfo = _addedServices.get(qualifiedName);
00097 if (!_sameInfo(info, previousServiceInfo)) {
00098 if (null == previousServiceInfo) {
00099 if (null == _addedServices.putIfAbsent(qualifiedName, info.clone())) {
00100 this.getListener().serviceResolved(event);
00101 }
00102 } else {
00103 if (_addedServices.replace(qualifiedName, previousServiceInfo, info.clone())) {
00104 this.getListener().serviceResolved(event);
00105 }
00106 }
00107 } else {
00108 logger.finer("Service Resolved called for a service already resolved: " + event);
00109 }
00110 } else {
00111 logger.warning("Service Resolved called for an unresolved event: " + event);
00112
00113 }
00114 }
00115
00116 private static final boolean _sameInfo(ServiceInfo info, ServiceInfo lastInfo) {
00117 if (info == null) return false;
00118 if (lastInfo == null) return false;
00119 if (!info.equals(lastInfo)) return false;
00120 byte[] text = info.getTextBytes();
00121 byte[] lastText = lastInfo.getTextBytes();
00122 if (text.length != lastText.length) return false;
00123 for (int i = 0; i < text.length; i++) {
00124 if (text[i] != lastText[i]) return false;
00125 }
00126 return true;
00127 }
00128
00129
00130
00131
00132
00133 @Override
00134 public String toString() {
00135 StringBuilder aLog = new StringBuilder(2048);
00136 aLog.append("[Status for ");
00137 aLog.append(this.getListener().toString());
00138 if (_addedServices.isEmpty()) {
00139 aLog.append(" no type event ");
00140 } else {
00141 aLog.append(" (");
00142 for (String service : _addedServices.keySet()) {
00143 aLog.append(service + ", ");
00144 }
00145 aLog.append(") ");
00146 }
00147 aLog.append("]");
00148 return aLog.toString();
00149 }
00150
00151 }
00152
00153 public static class ServiceTypeListenerStatus extends ListenerStatus<ServiceTypeListener> {
00154 private static Logger logger = Logger.getLogger(ServiceTypeListenerStatus.class.getName());
00155
00156 private final ConcurrentMap<String, String> _addedTypes;
00157
00164 public ServiceTypeListenerStatus(ServiceTypeListener listener, boolean synch) {
00165 super(listener, synch);
00166 _addedTypes = new ConcurrentHashMap<String, String>(32);
00167 }
00168
00175 void serviceTypeAdded(ServiceEvent event) {
00176 if (null == _addedTypes.putIfAbsent(event.getType(), event.getType())) {
00177 this.getListener().serviceTypeAdded(event);
00178 } else {
00179 logger.finest("Service Type Added called for a service type already added: " + event);
00180 }
00181 }
00182
00193 void subTypeForServiceTypeAdded(ServiceEvent event) {
00194 if (null == _addedTypes.putIfAbsent(event.getType(), event.getType())) {
00195 this.getListener().subTypeForServiceTypeAdded(event);
00196 } else {
00197 logger.finest("Service Sub Type Added called for a service sub type already added: " + event);
00198 }
00199 }
00200
00201
00202
00203
00204
00205 @Override
00206 public String toString() {
00207 StringBuilder aLog = new StringBuilder(2048);
00208 aLog.append("[Status for ");
00209 aLog.append(this.getListener().toString());
00210 if (_addedTypes.isEmpty()) {
00211 aLog.append(" no type event ");
00212 } else {
00213 aLog.append(" (");
00214 for (String type : _addedTypes.keySet()) {
00215 aLog.append(type + ", ");
00216 }
00217 aLog.append(") ");
00218 }
00219 aLog.append("]");
00220 return aLog.toString();
00221 }
00222
00223 }
00224
00225 public final static boolean SYNCHONEOUS = true;
00226 public final static boolean ASYNCHONEOUS = false;
00227
00228 private final T _listener;
00229
00230 private final boolean _synch;
00231
00238 public ListenerStatus(T listener, boolean synch) {
00239 super();
00240 _listener = listener;
00241 _synch = synch;
00242 }
00243
00247 public T getListener() {
00248 return _listener;
00249 }
00250
00256 public boolean isSynchronous() {
00257 return _synch;
00258 }
00259
00260
00261
00262
00263
00264 @Override
00265 public int hashCode() {
00266 return this.getListener().hashCode();
00267 }
00268
00269
00270
00271
00272
00273 @Override
00274 public boolean equals(Object obj) {
00275 return (obj instanceof ListenerStatus) && this.getListener().equals(((ListenerStatus<?>) obj).getListener());
00276 }
00277
00278
00279
00280
00281
00282 @Override
00283 public String toString() {
00284 return "[Status for " + this.getListener().toString() + "]";
00285 }
00286 }