diff options
Diffstat (limited to 'framework/bundles/org.eclipse.ecf.discovery/src/org/eclipse/ecf/discovery/AbstractDiscoveryContainerAdapter.java')
-rw-r--r-- | framework/bundles/org.eclipse.ecf.discovery/src/org/eclipse/ecf/discovery/AbstractDiscoveryContainerAdapter.java | 67 |
1 files changed, 62 insertions, 5 deletions
diff --git a/framework/bundles/org.eclipse.ecf.discovery/src/org/eclipse/ecf/discovery/AbstractDiscoveryContainerAdapter.java b/framework/bundles/org.eclipse.ecf.discovery/src/org/eclipse/ecf/discovery/AbstractDiscoveryContainerAdapter.java index 53f9be01b..c84bc936d 100644 --- a/framework/bundles/org.eclipse.ecf.discovery/src/org/eclipse/ecf/discovery/AbstractDiscoveryContainerAdapter.java +++ b/framework/bundles/org.eclipse.ecf.discovery/src/org/eclipse/ecf/discovery/AbstractDiscoveryContainerAdapter.java @@ -84,9 +84,34 @@ public abstract class AbstractDiscoveryContainerAdapter extends * org.eclipse.ecf.discovery.IDiscoveryContainerAdapter#addServiceListener * (org.eclipse.ecf.discovery.IServiceListener) */ - public void addServiceListener(IServiceListener aListener) { + public void addServiceListener(final IServiceListener aListener) { Assert.isNotNull(aListener); - allServiceListeners.add(aListener); + + if (aListener.triggerDiscovery()) { + final IExecutor executor = new ThreadsExecutor(); + executor.execute(new IProgressRunnable() { + public Object run(final IProgressMonitor arg0) throws Exception { + final IServiceInfo[] services = getServices(); + + for (int i = 0; i < services.length; i++) { + final IServiceInfo iServiceInfo = services[i]; + aListener.serviceDiscovered(getServiceEvent( + iServiceInfo, getConfig().getID())); + } + allServiceListeners.add(aListener); + return null; + } + }, null); + } else { + allServiceListeners.add(aListener); + } + } + + /** + * @since 5.0 + */ + protected IServiceEvent getServiceEvent(IServiceInfo iServiceInfo, ID id) { + return new ServiceContainerEvent(iServiceInfo, id); } /* @@ -97,11 +122,43 @@ public abstract class AbstractDiscoveryContainerAdapter extends * (org.eclipse.ecf.discovery.identity.IServiceTypeID, * org.eclipse.ecf.discovery.IServiceListener) */ - public void addServiceListener(IServiceTypeID aType, - IServiceListener aListener) { + public void addServiceListener(final IServiceTypeID aType, + final IServiceListener aListener) { Assert.isNotNull(aListener); Assert.isNotNull(aType); - synchronized (serviceListeners) { // put-if-absent idiom race condition + + if (aListener.triggerDiscovery()) { + final IExecutor executor = new ThreadsExecutor(); + executor.execute(new IProgressRunnable() { + public Object run(final IProgressMonitor arg0) throws Exception { + final IServiceInfo[] services = getServices(aType); + + for (int i = 0; i < services.length; i++) { + final IServiceInfo iServiceInfo = services[i]; + aListener.serviceDiscovered(getServiceEvent( + iServiceInfo, getConfig().getID())); + } + // Add the listener _after_ explicitly discovering services + // to _reduce_ the chance of notifying the listener more + // than once. This happens, if the background discovery job + // runs interleaved with explicit discovery here. However, + // ECF discovery -at the API level- does not guarantee that + // it won't send out notifications for the same logical + // discovery event at-most once/exactly once. It provides + // at-least-once instead/best-effort. + addServiceListener0(aType, aListener); + return null; + } + }, null); + } else { + addServiceListener0(aType, aListener); + } + } + + private void addServiceListener0(final IServiceTypeID aType, + final IServiceListener aListener) { + synchronized (serviceListeners) { // put-if-absent idiom race + // condition Collection v = (Collection) serviceListeners.get(aType); if (v == null) { v = Collections.synchronizedSet(new HashSet()); |