package org.ws4d.java.dispatch; import org.ws4d.java.dispatch.ServiceListenerQueue.ServiceEvent; import org.ws4d.java.service.Service; import org.ws4d.java.service.reference.ServiceListener; import org.ws4d.java.service.reference.ServiceReference; import org.ws4d.java.structures.Iterator; import org.ws4d.java.structures.LockedMap; /** * Registry to manage all listeners to service changes, who implement the * {@link ServiceListener} interface. */ public class ServiceReferenceEventRegistry { private static ServiceReferenceEventRegistry instance = new ServiceReferenceEventRegistry(); public static ServiceReferenceEventRegistry getInstance() { return instance; } // ServiceListener --> ListenerQueue private LockedMap listeners = new LockedMap(); private ServiceReferenceEventRegistry() { } /** * Register listener (callback) for service reference changes. Listeners get * get information about service changes. * * @param listener listener (callback) to register. */ public void registerServiceListening(ServiceListener listener) { if (listeners == null) { listeners = new LockedMap(); } listeners.exclusiveLock(); try { if (listeners.containsKey(listener)) { // no need to create new listener queue return; } listeners.put(listener, new ServiceListenerQueue(listener)); } finally { listeners.releaseExclusiveLock(); } } /** * Unregisters listener for service reference listening. This method should * be called, if holder of reference is no more interested in this * reference. * * @param listener listener to remove. */ public void unregisterServiceListening(ServiceListener listener) { listeners.exclusiveLock(); try { listeners.remove(listener); } finally { listeners.releaseExclusiveLock(); } } private void announceServiceListenerEvent(byte eventType, ServiceReference servRef, Service service) { listeners.sharedLock(); try { ServiceEvent event = new ServiceEvent(eventType, servRef, service); for (Iterator it = listeners.values().iterator(); it.hasNext();) { ServiceListenerQueue queue = (ServiceListenerQueue) it.next(); queue.announce(event); } } finally { listeners.releaseSharedLock(); } } protected void announceServiceChanged(ServiceReference servRef, Service service) { announceServiceListenerEvent(ServiceListenerQueue.SERVICE_CHANGED_EVENT, servRef, service); } protected void announceServiceCreated(ServiceReference servRef, Service service) { announceServiceListenerEvent(ServiceListenerQueue.SERVICE_CREATED_EVENT, servRef, service); } protected void announceServiceDisposed(ServiceReference servRef) { announceServiceListenerEvent(ServiceListenerQueue.SERVICE_DISPOSED_EVENT, servRef, null); } }