Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.osgi/osgi/src/org/osgi/util/tracker/ServiceTracker.java')
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/util/tracker/ServiceTracker.java526
1 files changed, 270 insertions, 256 deletions
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/util/tracker/ServiceTracker.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/util/tracker/ServiceTracker.java
index b4e373b29..bc546e673 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/util/tracker/ServiceTracker.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/util/tracker/ServiceTracker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,9 @@
package org.osgi.util.tracker;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.SortedMap;
+import java.util.TreeMap;
import org.osgi.framework.AllServiceListener;
import org.osgi.framework.BundleContext;
@@ -27,73 +28,74 @@ import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
-import org.osgi.framework.Version;
/**
- * The <code>ServiceTracker</code> class simplifies using services from the
+ * The {@code ServiceTracker} class simplifies using services from the
* Framework's service registry.
* <p>
- * A <code>ServiceTracker</code> object is constructed with search criteria and
- * a <code>ServiceTrackerCustomizer</code> object. A <code>ServiceTracker</code>
- * can use a <code>ServiceTrackerCustomizer</code> to customize the service
- * objects to be tracked. The <code>ServiceTracker</code> can then be opened to
+ * A {@code ServiceTracker} object is constructed with search criteria and
+ * a {@code ServiceTrackerCustomizer} object. A {@code ServiceTracker}
+ * can use a {@code ServiceTrackerCustomizer} to customize the service
+ * objects to be tracked. The {@code ServiceTracker} can then be opened to
* begin tracking all services in the Framework's service registry that match
- * the specified search criteria. The <code>ServiceTracker</code> correctly
- * handles all of the details of listening to <code>ServiceEvent</code>s and
+ * the specified search criteria. The {@code ServiceTracker} correctly
+ * handles all of the details of listening to {@code ServiceEvent}s and
* getting and ungetting services.
* <p>
- * The <code>getServiceReferences</code> method can be called to get references
- * to the services being tracked. The <code>getService</code> and
- * <code>getServices</code> methods can be called to get the service objects for
+ * The {@code getServiceReferences} method can be called to get references
+ * to the services being tracked. The {@code getService} and
+ * {@code getServices} methods can be called to get the service objects for
* the tracked service.
* <p>
- * The <code>ServiceTracker</code> class is thread-safe. It does not call a
- * <code>ServiceTrackerCustomizer</code> while holding any locks.
- * <code>ServiceTrackerCustomizer</code> implementations must also be
+ * The {@code ServiceTracker} class is thread-safe. It does not call a
+ * {@code ServiceTrackerCustomizer} while holding any locks.
+ * {@code ServiceTrackerCustomizer} implementations must also be
* thread-safe.
*
+ * @param <S> The type of the service being tracked.
+ * @param <T> The type of the tracked object.
* @ThreadSafe
- * @version $Revision: 6386 $
+ * @version $Id: b375e1b7075486696b42fc55546375f0546b0d58 $
*/
-public class ServiceTracker implements ServiceTrackerCustomizer {
+public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
/* set this to true to compile in debug messages */
- static final boolean DEBUG = false;
+ static final boolean DEBUG = false;
/**
- * The Bundle Context used by this <code>ServiceTracker</code>.
+ * The Bundle Context used by this {@code ServiceTracker}.
*/
- protected final BundleContext context;
+ protected final BundleContext context;
/**
- * The Filter used by this <code>ServiceTracker</code> which specifies the
+ * The Filter used by this {@code ServiceTracker} which specifies the
* search criteria for the services to track.
*
* @since 1.1
*/
- protected final Filter filter;
+ protected final Filter filter;
/**
- * The <code>ServiceTrackerCustomizer</code> for this tracker.
+ * The {@code ServiceTrackerCustomizer} for this tracker.
*/
- final ServiceTrackerCustomizer customizer;
+ final ServiceTrackerCustomizer<S, T> customizer;
/**
* Filter string for use when adding the ServiceListener. If this field is
* set, then certain optimizations can be taken since we don't have a user
* supplied filter.
*/
- final String listenerFilter;
+ final String listenerFilter;
/**
* Class name to be tracked. If this field is set, then we are tracking by
* class name.
*/
- private final String trackClass;
+ private final String trackClass;
/**
* Reference to be tracked. If this field is set, then we are tracking a
* single ServiceReference.
*/
- private final ServiceReference trackReference;
+ private final ServiceReference<S> trackReference;
/**
- * Tracked services: <code>ServiceReference</code> -> customized Object and
- * <code>ServiceListener</code> object
+ * Tracked services: {@code ServiceReference} -> customized Object and
+ * {@code ServiceListener} object
*/
- private volatile Tracked tracked;
+ private volatile Tracked tracked;
/**
* Accessor method for the current Tracked object. This method is only
@@ -111,49 +113,43 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
*
* This field is volatile since it is accessed by multiple threads.
*/
- private volatile ServiceReference cachedReference;
+ private volatile ServiceReference<S> cachedReference;
/**
* Cached service object for getService.
*
* This field is volatile since it is accessed by multiple threads.
*/
- private volatile Object cachedService;
+ private volatile T cachedService;
/**
- * org.osgi.framework package version which introduced
- * {@link ServiceEvent#MODIFIED_ENDMATCH}
- */
- private static final Version endMatchVersion = new Version(1, 5, 0);
-
- /**
- * Create a <code>ServiceTracker</code> on the specified
- * <code>ServiceReference</code>.
+ * Create a {@code ServiceTracker} on the specified
+ * {@code ServiceReference}.
*
* <p>
- * The service referenced by the specified <code>ServiceReference</code>
- * will be tracked by this <code>ServiceTracker</code>.
+ * The service referenced by the specified {@code ServiceReference}
+ * will be tracked by this {@code ServiceTracker}.
*
- * @param context The <code>BundleContext</code> against which the tracking
+ * @param context The {@code BundleContext} against which the tracking
* is done.
- * @param reference The <code>ServiceReference</code> for the service to be
+ * @param reference The {@code ServiceReference} for the service to be
* tracked.
* @param customizer The customizer object to call when services are added,
- * modified, or removed in this <code>ServiceTracker</code>. If
- * customizer is <code>null</code>, then this
- * <code>ServiceTracker</code> will be used as the
- * <code>ServiceTrackerCustomizer</code> and this
- * <code>ServiceTracker</code> will call the
- * <code>ServiceTrackerCustomizer</code> methods on itself.
+ * modified, or removed in this {@code ServiceTracker}. If
+ * customizer is {@code null}, then this
+ * {@code ServiceTracker} will be used as the
+ * {@code ServiceTrackerCustomizer} and this
+ * {@code ServiceTracker} will call the
+ * {@code ServiceTrackerCustomizer} methods on itself.
*/
public ServiceTracker(final BundleContext context,
- final ServiceReference reference,
- final ServiceTrackerCustomizer customizer) {
+ final ServiceReference<S> reference,
+ final ServiceTrackerCustomizer<S, T> customizer) {
this.context = context;
this.trackReference = reference;
this.trackClass = null;
this.customizer = (customizer == null) ? this : customizer;
this.listenerFilter = "(" + Constants.SERVICE_ID + "="
- + reference.getProperty(Constants.SERVICE_ID).toString() + ")";
+ + reference.getProperty(Constants.SERVICE_ID).toString() + ")";
try {
this.filter = context.createFilter(listenerFilter);
}
@@ -170,32 +166,32 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
}
/**
- * Create a <code>ServiceTracker</code> on the specified class name.
+ * Create a {@code ServiceTracker} on the specified class name.
*
* <p>
* Services registered under the specified class name will be tracked by
- * this <code>ServiceTracker</code>.
+ * this {@code ServiceTracker}.
*
- * @param context The <code>BundleContext</code> against which the tracking
+ * @param context The {@code BundleContext} against which the tracking
* is done.
* @param clazz The class name of the services to be tracked.
* @param customizer The customizer object to call when services are added,
- * modified, or removed in this <code>ServiceTracker</code>. If
- * customizer is <code>null</code>, then this
- * <code>ServiceTracker</code> will be used as the
- * <code>ServiceTrackerCustomizer</code> and this
- * <code>ServiceTracker</code> will call the
- * <code>ServiceTrackerCustomizer</code> methods on itself.
+ * modified, or removed in this {@code ServiceTracker}. If
+ * customizer is {@code null}, then this
+ * {@code ServiceTracker} will be used as the
+ * {@code ServiceTrackerCustomizer} and this
+ * {@code ServiceTracker} will call the
+ * {@code ServiceTrackerCustomizer} methods on itself.
*/
public ServiceTracker(final BundleContext context, final String clazz,
- final ServiceTrackerCustomizer customizer) {
+ final ServiceTrackerCustomizer<S, T> customizer) {
this.context = context;
this.trackReference = null;
this.trackClass = clazz;
this.customizer = (customizer == null) ? this : customizer;
// we call clazz.toString to verify clazz is non-null!
this.listenerFilter = "(" + Constants.OBJECTCLASS + "="
- + clazz.toString() + ")";
+ + clazz.toString() + ")";
try {
this.filter = context.createFilter(listenerFilter);
}
@@ -212,42 +208,31 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
}
/**
- * Create a <code>ServiceTracker</code> on the specified <code>Filter</code>
+ * Create a {@code ServiceTracker} on the specified {@code Filter}
* object.
*
* <p>
- * Services which match the specified <code>Filter</code> object will be
- * tracked by this <code>ServiceTracker</code>.
+ * Services which match the specified {@code Filter} object will be
+ * tracked by this {@code ServiceTracker}.
*
- * @param context The <code>BundleContext</code> against which the tracking
+ * @param context The {@code BundleContext} against which the tracking
* is done.
- * @param filter The <code>Filter</code> to select the services to be
+ * @param filter The {@code Filter} to select the services to be
* tracked.
* @param customizer The customizer object to call when services are added,
- * modified, or removed in this <code>ServiceTracker</code>. If
- * customizer is null, then this <code>ServiceTracker</code> will be
- * used as the <code>ServiceTrackerCustomizer</code> and this
- * <code>ServiceTracker</code> will call the
- * <code>ServiceTrackerCustomizer</code> methods on itself.
+ * modified, or removed in this {@code ServiceTracker}. If
+ * customizer is null, then this {@code ServiceTracker} will be
+ * used as the {@code ServiceTrackerCustomizer} and this
+ * {@code ServiceTracker} will call the
+ * {@code ServiceTrackerCustomizer} methods on itself.
* @since 1.1
*/
public ServiceTracker(final BundleContext context, final Filter filter,
- final ServiceTrackerCustomizer customizer) {
+ final ServiceTrackerCustomizer<S, T> customizer) {
this.context = context;
this.trackReference = null;
this.trackClass = null;
- final Version frameworkVersion = (Version) AccessController
- .doPrivileged(new PrivilegedAction() {
- public Object run() {
- String version = context
- .getProperty(Constants.FRAMEWORK_VERSION);
- return (version == null) ? Version.emptyVersion
- : new Version(version);
- }
- });
- final boolean endMatchSupported = (frameworkVersion
- .compareTo(endMatchVersion) >= 0);
- this.listenerFilter = endMatchSupported ? filter.toString() : null;
+ this.listenerFilter = filter.toString();
this.filter = filter;
this.customizer = (customizer == null) ? this : customizer;
if ((context == null) || (filter == null)) {
@@ -259,13 +244,37 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
}
/**
- * Open this <code>ServiceTracker</code> and begin tracking services.
+ * Create a {@code ServiceTracker} on the specified class.
*
* <p>
- * This implementation calls <code>open(false)</code>.
+ * Services registered under the name of the specified class will be tracked
+ * by this {@code ServiceTracker}.
*
- * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
- * with which this <code>ServiceTracker</code> was created is no
+ * @param context The {@code BundleContext} against which the tracking
+ * is done.
+ * @param clazz The class of the services to be tracked.
+ * @param customizer The customizer object to call when services are added,
+ * modified, or removed in this {@code ServiceTracker}. If
+ * customizer is {@code null}, then this
+ * {@code ServiceTracker} will be used as the
+ * {@code ServiceTrackerCustomizer} and this
+ * {@code ServiceTracker} will call the
+ * {@code ServiceTrackerCustomizer} methods on itself.
+ * @since 1.5
+ */
+ public ServiceTracker(final BundleContext context, final Class<S> clazz,
+ final ServiceTrackerCustomizer<S, T> customizer) {
+ this(context, clazz.getName(), customizer);
+ }
+
+ /**
+ * Open this {@code ServiceTracker} and begin tracking services.
+ *
+ * <p>
+ * This implementation calls {@code open(false)}.
+ *
+ * @throws java.lang.IllegalStateException If the {@code BundleContext}
+ * with which this {@code ServiceTracker} was created is no
* longer valid.
* @see #open(boolean)
*/
@@ -274,22 +283,22 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
}
/**
- * Open this <code>ServiceTracker</code> and begin tracking services.
+ * Open this {@code ServiceTracker} and begin tracking services.
*
* <p>
* Services which match the search criteria specified when this
- * <code>ServiceTracker</code> was created are now tracked by this
- * <code>ServiceTracker</code>.
+ * {@code ServiceTracker} was created are now tracked by this
+ * {@code ServiceTracker}.
*
- * @param trackAllServices If <code>true</code>, then this
- * <code>ServiceTracker</code> will track all matching services
- * regardless of class loader accessibility. If <code>false</code>,
- * then this <code>ServiceTracker</code> will only track matching
+ * @param trackAllServices If {@code true}, then this
+ * {@code ServiceTracker} will track all matching services
+ * regardless of class loader accessibility. If {@code false},
+ * then this {@code ServiceTracker} will only track matching
* services which are class loader accessible to the bundle whose
- * <code>BundleContext</code> is used by this
- * <code>ServiceTracker</code>.
- * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
- * with which this <code>ServiceTracker</code> was created is no
+ * {@code BundleContext} is used by this
+ * {@code ServiceTracker}.
+ * @throws java.lang.IllegalStateException If the {@code BundleContext}
+ * with which this {@code ServiceTracker} was created is no
* longer valid.
* @since 1.3
*/
@@ -300,13 +309,13 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
return;
}
if (DEBUG) {
- System.out.println("ServiceTracker.open: " + filter);
+ System.out.println("ServiceTracker.open: " + filter);
}
t = trackAllServices ? new AllTracked() : new Tracked();
synchronized (t) {
try {
context.addServiceListener(t, listenerFilter);
- ServiceReference[] references = null;
+ ServiceReference<S>[] references = null;
if (trackClass != null) {
references = getInitialReferences(trackAllServices,
trackClass, null);
@@ -314,23 +323,22 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
else {
if (trackReference != null) {
if (trackReference.getBundle() != null) {
- references = new ServiceReference[] {trackReference};
+ ServiceReference<S>[] single = new ServiceReference[] {trackReference};
+ references = single;
}
}
else { /* user supplied filter */
references = getInitialReferences(trackAllServices,
- null,
- (listenerFilter != null) ? listenerFilter
- : filter.toString());
+ null, listenerFilter);
}
}
/* set tracked with the initial references */
- t.setInitial(references);
+ t.setInitial(references);
}
catch (InvalidSyntaxException e) {
throw new RuntimeException(
"unexpected InvalidSyntaxException: "
- + e.getMessage(), e);
+ + e.getMessage(), e);
}
}
tracked = t;
@@ -340,33 +348,33 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
}
/**
- * Returns the list of initial <code>ServiceReference</code>s that will be
- * tracked by this <code>ServiceTracker</code>.
+ * Returns the list of initial {@code ServiceReference}s that will be
+ * tracked by this {@code ServiceTracker}.
*
- * @param trackAllServices If <code>true</code>, use
- * <code>getAllServiceReferences</code>.
+ * @param trackAllServices If {@code true}, use
+ * {@code getAllServiceReferences}.
* @param className The class name with which the service was registered, or
- * <code>null</code> for all services.
- * @param filterString The filter criteria or <code>null</code> for all
+ * {@code null} for all services.
+ * @param filterString The filter criteria or {@code null} for all
* services.
- * @return The list of initial <code>ServiceReference</code>s.
+ * @return The list of initial {@code ServiceReference}s.
* @throws InvalidSyntaxException If the specified filterString has an
* invalid syntax.
*/
- private ServiceReference[] getInitialReferences(boolean trackAllServices,
- String className, String filterString)
+ private ServiceReference<S>[] getInitialReferences(
+ boolean trackAllServices, String className, String filterString)
throws InvalidSyntaxException {
- if (trackAllServices) {
- return context.getAllServiceReferences(className, filterString);
- }
- return context.getServiceReferences(className, filterString);
+ ServiceReference<S>[] result = (ServiceReference<S>[]) ((trackAllServices) ? context
+ .getAllServiceReferences(className, filterString)
+ : context.getServiceReferences(className, filterString));
+ return result;
}
/**
- * Close this <code>ServiceTracker</code>.
+ * Close this {@code ServiceTracker}.
*
* <p>
- * This method should be called when this <code>ServiceTracker</code> should
+ * This method should be called when this {@code ServiceTracker} should
* end the tracking of services.
*
* <p>
@@ -375,14 +383,14 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
*/
public void close() {
final Tracked outgoing;
- final ServiceReference[] references;
+ final ServiceReference<S>[] references;
synchronized (this) {
outgoing = tracked;
if (outgoing == null) {
return;
}
if (DEBUG) {
- System.out.println("ServiceTracker.close: " + filter);
+ System.out.println("ServiceTracker.close: " + filter);
}
outgoing.close();
references = getServiceReferences();
@@ -405,26 +413,25 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
}
if (DEBUG) {
if ((cachedReference == null) && (cachedService == null)) {
- System.out
- .println("ServiceTracker.close[cached cleared]: "
- + filter);
+ System.out.println("ServiceTracker.close[cached cleared]: "
+ + filter);
}
}
}
/**
* Default implementation of the
- * <code>ServiceTrackerCustomizer.addingService</code> method.
+ * {@code ServiceTrackerCustomizer.addingService} method.
*
* <p>
- * This method is only called when this <code>ServiceTracker</code> has been
- * constructed with a <code>null ServiceTrackerCustomizer</code> argument.
+ * This method is only called when this {@code ServiceTracker} has been
+ * constructed with a {@code null ServiceTrackerCustomizer} argument.
*
* <p>
- * This implementation returns the result of calling <code>getService</code>
- * on the <code>BundleContext</code> with which this
- * <code>ServiceTracker</code> was created passing the specified
- * <code>ServiceReference</code>.
+ * This implementation returns the result of calling {@code getService}
+ * on the {@code BundleContext} with which this
+ * {@code ServiceTracker} was created passing the specified
+ * {@code ServiceReference}.
* <p>
* This method can be overridden in a subclass to customize the service
* object to be tracked for the service being added. In that case, take care
@@ -433,22 +440,23 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
* the service.
*
* @param reference The reference to the service being added to this
- * <code>ServiceTracker</code>.
+ * {@code ServiceTracker}.
* @return The service object to be tracked for the service added to this
- * <code>ServiceTracker</code>.
+ * {@code ServiceTracker}.
* @see ServiceTrackerCustomizer#addingService(ServiceReference)
*/
- public Object addingService(ServiceReference reference) {
- return context.getService(reference);
+ public T addingService(ServiceReference<S> reference) {
+ T result = (T) context.getService(reference);
+ return result;
}
/**
* Default implementation of the
- * <code>ServiceTrackerCustomizer.modifiedService</code> method.
+ * {@code ServiceTrackerCustomizer.modifiedService} method.
*
* <p>
- * This method is only called when this <code>ServiceTracker</code> has been
- * constructed with a <code>null ServiceTrackerCustomizer</code> argument.
+ * This method is only called when this {@code ServiceTracker} has been
+ * constructed with a {@code null ServiceTrackerCustomizer} argument.
*
* <p>
* This implementation does nothing.
@@ -457,22 +465,22 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
* @param service The service object for the modified service.
* @see ServiceTrackerCustomizer#modifiedService(ServiceReference, Object)
*/
- public void modifiedService(ServiceReference reference, Object service) {
+ public void modifiedService(ServiceReference<S> reference, T service) {
/* do nothing */
}
/**
* Default implementation of the
- * <code>ServiceTrackerCustomizer.removedService</code> method.
+ * {@code ServiceTrackerCustomizer.removedService} method.
*
* <p>
- * This method is only called when this <code>ServiceTracker</code> has been
- * constructed with a <code>null ServiceTrackerCustomizer</code> argument.
+ * This method is only called when this {@code ServiceTracker} has been
+ * constructed with a {@code null ServiceTrackerCustomizer} argument.
*
* <p>
- * This implementation calls <code>ungetService</code>, on the
- * <code>BundleContext</code> with which this <code>ServiceTracker</code>
- * was created, passing the specified <code>ServiceReference</code>.
+ * This implementation calls {@code ungetService}, on the
+ * {@code BundleContext} with which this {@code ServiceTracker}
+ * was created, passing the specified {@code ServiceReference}.
* <p>
* This method can be overridden in a subclass. If the default
* implementation of {@link #addingService(ServiceReference) addingService}
@@ -482,19 +490,19 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
* @param service The service object for the removed service.
* @see ServiceTrackerCustomizer#removedService(ServiceReference, Object)
*/
- public void removedService(ServiceReference reference, Object service) {
+ public void removedService(ServiceReference<S> reference, T service) {
context.ungetService(reference);
}
/**
* Wait for at least one service to be tracked by this
- * <code>ServiceTracker</code>. This method will also return when this
- * <code>ServiceTracker</code> is closed.
+ * {@code ServiceTracker}. This method will also return when this
+ * {@code ServiceTracker} is closed.
*
* <p>
- * It is strongly recommended that <code>waitForService</code> is not used
- * during the calling of the <code>BundleActivator</code> methods.
- * <code>BundleActivator</code> methods are expected to complete in a short
+ * It is strongly recommended that {@code waitForService} is not used
+ * during the calling of the {@code BundleActivator} methods.
+ * {@code BundleActivator} methods are expected to complete in a short
* period of time.
*
* <p>
@@ -508,11 +516,11 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
* current thread.
* @throws IllegalArgumentException If the value of timeout is negative.
*/
- public Object waitForService(long timeout) throws InterruptedException {
+ public T waitForService(long timeout) throws InterruptedException {
if (timeout < 0) {
- throw new IllegalArgumentException("timeout value is negative");
+ throw new IllegalArgumentException("timeout value is negative");
}
- Object object = getService();
+ T object = getService();
while (object == null) {
final Tracked t = tracked();
if (t == null) { /* if ServiceTracker is not open */
@@ -523,7 +531,7 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
t.wait(timeout);
}
}
- object = getService();
+ object = getService();
if (timeout > 0) {
return object;
}
@@ -532,13 +540,13 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
}
/**
- * Return an array of <code>ServiceReference</code>s for all services being
- * tracked by this <code>ServiceTracker</code>.
+ * Return an array of {@code ServiceReference}s for all services being
+ * tracked by this {@code ServiceTracker}.
*
- * @return Array of <code>ServiceReference</code>s or <code>null</code> if
+ * @return Array of {@code ServiceReference}s or {@code null} if
* no services are being tracked.
*/
- public ServiceReference[] getServiceReferences() {
+ public ServiceReference<S>[] getServiceReferences() {
final Tracked t = tracked();
if (t == null) { /* if ServiceTracker is not open */
return null;
@@ -548,45 +556,45 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
if (length == 0) {
return null;
}
- return (ServiceReference[]) t
- .getTracked(new ServiceReference[length]);
+ ServiceReference<S>[] result = new ServiceReference[length];
+ return t.copyKeys(result);
}
}
/**
- * Returns a <code>ServiceReference</code> for one of the services being
- * tracked by this <code>ServiceTracker</code>.
+ * Returns a {@code ServiceReference} for one of the services being
+ * tracked by this {@code ServiceTracker}.
*
* <p>
* If multiple services are being tracked, the service with the highest
- * ranking (as specified in its <code>service.ranking</code> property) is
+ * ranking (as specified in its {@code service.ranking} property) is
* returned. If there is a tie in ranking, the service with the lowest
- * service ID (as specified in its <code>service.id</code> property); that
+ * service ID (as specified in its {@code service.id} property); that
* is, the service that was registered first is returned. This is the same
- * algorithm used by <code>BundleContext.getServiceReference</code>.
+ * algorithm used by {@code BundleContext.getServiceReference}.
*
* <p>
* This implementation calls {@link #getServiceReferences()} to get the list
* of references for the tracked services.
*
- * @return A <code>ServiceReference</code> or <code>null</code> if no
+ * @return A {@code ServiceReference} or {@code null} if no
* services are being tracked.
* @since 1.1
*/
- public ServiceReference getServiceReference() {
- ServiceReference reference = cachedReference;
+ public ServiceReference<S> getServiceReference() {
+ ServiceReference<S> reference = cachedReference;
if (reference != null) {
if (DEBUG) {
System.out
.println("ServiceTracker.getServiceReference[cached]: "
- + filter);
+ + filter);
}
return reference;
}
if (DEBUG) {
- System.out.println("ServiceTracker.getServiceReference: " + filter);
+ System.out.println("ServiceTracker.getServiceReference: " + filter);
}
- ServiceReference[] references = getServiceReferences();
+ ServiceReference<S>[] references = getServiceReferences();
int length = (references == null) ? 0 : references.length;
if (length == 0) { /* if no service is being tracked */
return null;
@@ -634,15 +642,15 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
/**
* Returns the service object for the specified
- * <code>ServiceReference</code> if the specified referenced service is
- * being tracked by this <code>ServiceTracker</code>.
+ * {@code ServiceReference} if the specified referenced service is
+ * being tracked by this {@code ServiceTracker}.
*
* @param reference The reference to the desired service.
- * @return A service object or <code>null</code> if the service referenced
- * by the specified <code>ServiceReference</code> is not being
+ * @return A service object or {@code null} if the service referenced
+ * by the specified {@code ServiceReference} is not being
* tracked.
*/
- public Object getService(ServiceReference reference) {
+ public T getService(ServiceReference<S> reference) {
final Tracked t = tracked();
if (t == null) { /* if ServiceTracker is not open */
return null;
@@ -654,7 +662,7 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
/**
* Return an array of service objects for all services being tracked by this
- * <code>ServiceTracker</code>.
+ * {@code ServiceTracker}.
*
* <p>
* This implementation calls {@link #getServiceReferences()} to get the list
@@ -662,7 +670,7 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
* {@link #getService(ServiceReference)} for each reference to get the
* tracked service object.
*
- * @return An array of service objects or <code>null</code> if no services
+ * @return An array of service objects or {@code null} if no services
* are being tracked.
*/
public Object[] getServices() {
@@ -671,14 +679,14 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
return null;
}
synchronized (t) {
- ServiceReference[] references = getServiceReferences();
+ ServiceReference<S>[] references = getServiceReferences();
int length = (references == null) ? 0 : references.length;
if (length == 0) {
return null;
}
Object[] objects = new Object[length];
for (int i = 0; i < length; i++) {
- objects[i] = getService(references[i]);
+ objects[i] = getService(references[i]);
}
return objects;
}
@@ -686,46 +694,45 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
/**
* Returns a service object for one of the services being tracked by this
- * <code>ServiceTracker</code>.
+ * {@code ServiceTracker}.
*
* <p>
* If any services are being tracked, this implementation returns the result
- * of calling <code>getService(getServiceReference())</code>.
+ * of calling {@code getService(getServiceReference())}.
*
- * @return A service object or <code>null</code> if no services are being
+ * @return A service object or {@code null} if no services are being
* tracked.
*/
- public Object getService() {
- Object service = cachedService;
+ public T getService() {
+ T service = cachedService;
if (service != null) {
if (DEBUG) {
- System.out
- .println("ServiceTracker.getService[cached]: "
- + filter);
+ System.out.println("ServiceTracker.getService[cached]: "
+ + filter);
}
return service;
}
if (DEBUG) {
- System.out.println("ServiceTracker.getService: " + filter);
+ System.out.println("ServiceTracker.getService: " + filter);
}
- ServiceReference reference = getServiceReference();
+ ServiceReference<S> reference = getServiceReference();
if (reference == null) {
return null;
}
- return cachedService = getService(reference);
+ return cachedService = getService(reference);
}
/**
- * Remove a service from this <code>ServiceTracker</code>.
+ * Remove a service from this {@code ServiceTracker}.
*
* The specified service will be removed from this
- * <code>ServiceTracker</code>. If the specified service was being tracked
- * then the <code>ServiceTrackerCustomizer.removedService</code> method will
+ * {@code ServiceTracker}. If the specified service was being tracked
+ * then the {@code ServiceTrackerCustomizer.removedService} method will
* be called for that service.
*
* @param reference The reference to the service to be removed.
*/
- public void remove(ServiceReference reference) {
+ public void remove(ServiceReference<S> reference) {
final Tracked t = tracked();
if (t == null) { /* if ServiceTracker is not open */
return;
@@ -735,7 +742,7 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
/**
* Return the number of services being tracked by this
- * <code>ServiceTracker</code>.
+ * {@code ServiceTracker}.
*
* @return The number of services being tracked.
*/
@@ -750,24 +757,24 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
}
/**
- * Returns the tracking count for this <code>ServiceTracker</code>.
+ * Returns the tracking count for this {@code ServiceTracker}.
*
* The tracking count is initialized to 0 when this
- * <code>ServiceTracker</code> is opened. Every time a service is added,
- * modified or removed from this <code>ServiceTracker</code>, the tracking
+ * {@code ServiceTracker} is opened. Every time a service is added,
+ * modified or removed from this {@code ServiceTracker}, the tracking
* count is incremented.
*
* <p>
* The tracking count can be used to determine if this
- * <code>ServiceTracker</code> has added, modified or removed a service by
+ * {@code ServiceTracker} has added, modified or removed a service by
* comparing a tracking count value previously collected with the current
* tracking count value. If the value has not changed, then no service has
- * been added, modified or removed from this <code>ServiceTracker</code>
+ * been added, modified or removed from this {@code ServiceTracker}
* since the previous tracking count was collected.
*
* @since 1.2
- * @return The tracking count for this <code>ServiceTracker</code> or -1 if
- * this <code>ServiceTracker</code> is not open.
+ * @return The tracking count for this {@code ServiceTracker} or -1 if
+ * this {@code ServiceTracker} is not open.
*/
public int getTrackingCount() {
final Tracked t = tracked();
@@ -792,17 +799,43 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
cachedReference = null; /* clear cached value */
cachedService = null; /* clear cached value */
if (DEBUG) {
- System.out.println("ServiceTracker.modified: " + filter);
+ System.out.println("ServiceTracker.modified: " + filter);
+ }
+ }
+
+ /**
+ * Return a {@code SortedMap} of the {@code ServiceReference}s and
+ * service objects for all services being tracked by this
+ * {@code ServiceTracker}. The map is sorted in reverse natural order
+ * of {@code ServiceReference}. That is, the first entry is the service
+ * with the highest ranking and the lowest service id.
+ *
+ * @return A {@code SortedMap} with the {@code ServiceReference}s
+ * and service objects for all services being tracked by this
+ * {@code ServiceTracker}. If no services are being tracked,
+ * then the returned map is empty.
+ * @since 1.5
+ */
+ public SortedMap<ServiceReference<S>, T> getTracked() {
+ SortedMap<ServiceReference<S>, T> map = new TreeMap<ServiceReference<S>, T>(
+ Collections.reverseOrder());
+ final Tracked t = tracked();
+ if (t == null) { /* if ServiceTracker is not open */
+ return map;
+ }
+ synchronized (t) {
+ return t.copyEntries(map);
}
}
/**
* Inner class which subclasses AbstractTracked. This class is the
- * <code>ServiceListener</code> object for the tracker.
+ * {@code ServiceListener} object for the tracker.
*
* @ThreadSafe
*/
- class Tracked extends AbstractTracked implements ServiceListener {
+ class Tracked extends AbstractTracked<ServiceReference<S>, T, ServiceEvent>
+ implements ServiceListener {
/**
* Tracked constructor.
*/
@@ -811,11 +844,11 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
}
/**
- * <code>ServiceListener</code> method for the
- * <code>ServiceTracker</code> class. This method must NOT be
+ * {@code ServiceListener} method for the
+ * {@code ServiceTracker} class. This method must NOT be
* synchronized to avoid deadlock potential.
*
- * @param event <code>ServiceEvent</code> object from the framework.
+ * @param event {@code ServiceEvent} object from the framework.
*/
public void serviceChanged(final ServiceEvent event) {
/*
@@ -825,40 +858,21 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
if (closed) {
return;
}
- final ServiceReference reference = event.getServiceReference();
+ final ServiceReference<S> reference = (ServiceReference<S>) event
+ .getServiceReference();
if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.serviceChanged["
- + event.getType() + "]: " + reference);
+ System.out.println("ServiceTracker.Tracked.serviceChanged["
+ + event.getType() + "]: " + reference);
}
switch (event.getType()) {
case ServiceEvent.REGISTERED :
case ServiceEvent.MODIFIED :
- if (listenerFilter != null) { // service listener added with
- // filter
- track(reference, event);
- /*
- * If the customizer throws an unchecked exception, it
- * is safe to let it propagate
- */
- }
- else { // service listener added without filter
- if (filter.match(reference)) {
- track(reference, event);
- /*
- * If the customizer throws an unchecked exception,
- * it is safe to let it propagate
- */
- }
- else {
- untrack(reference, event);
- /*
- * If the customizer throws an unchecked exception,
- * it is safe to let it propagate
- */
- }
- }
+ track(reference, event);
+ /*
+ * If the customizer throws an unchecked exception, it is
+ * safe to let it propagate
+ */
break;
case ServiceEvent.MODIFIED_ENDMATCH :
case ServiceEvent.UNREGISTERING :
@@ -888,12 +902,12 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
*
* @param item Item to be tracked.
* @param related Action related object.
- * @return Customized object for the tracked item or <code>null</code>
+ * @return Customized object for the tracked item or {@code null}
* if the item is not to be tracked.
*/
- Object customizerAdding(final Object item,
- final Object related) {
- return customizer.addingService((ServiceReference) item);
+ T customizerAdding(final ServiceReference<S> item,
+ final ServiceEvent related) {
+ return customizer.addingService(item);
}
/**
@@ -904,9 +918,9 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
* @param related Action related object.
* @param object Customized object for the tracked item.
*/
- void customizerModified(final Object item,
- final Object related, final Object object) {
- customizer.modifiedService((ServiceReference) item, object);
+ void customizerModified(final ServiceReference<S> item,
+ final ServiceEvent related, final T object) {
+ customizer.modifiedService(item, object);
}
/**
@@ -917,9 +931,9 @@ public class ServiceTracker implements ServiceTrackerCustomizer {
* @param related Action related object.
* @param object Customized object for the tracked item.
*/
- void customizerRemoved(final Object item,
- final Object related, final Object object) {
- customizer.removedService((ServiceReference) item, object);
+ void customizerRemoved(final ServiceReference<S> item,
+ final ServiceEvent related, final T object) {
+ customizer.removedService(item, object);
}
}

Back to the top