Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
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.java67
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());

Back to the top