$search
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 * (non-Javadoc) 00131 * @see java.lang.Object#toString() 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 * (non-Javadoc) 00203 * @see java.lang.Object#toString() 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 * (non-Javadoc) 00262 * @see java.lang.Object#hashCode() 00263 */ 00264 @Override 00265 public int hashCode() { 00266 return this.getListener().hashCode(); 00267 } 00268 00269 /* 00270 * (non-Javadoc) 00271 * @see java.lang.Object#equals(java.lang.Object) 00272 */ 00273 @Override 00274 public boolean equals(Object obj) { 00275 return (obj instanceof ListenerStatus) && this.getListener().equals(((ListenerStatus<?>) obj).getListener()); 00276 } 00277 00278 /* 00279 * (non-Javadoc) 00280 * @see java.lang.Object#toString() 00281 */ 00282 @Override 00283 public String toString() { 00284 return "[Status for " + this.getListener().toString() + "]"; 00285 } 00286 }