comparison org.eclipse.osgi/osgi/src/org/osgi/util/tracker/ServiceTracker.d @ 105:bbe49769ec18

...
author Frank Benoit <benoit@tionex.de>
date Sun, 08 Nov 2009 12:42:30 +0100
parents 12b890a6392a
children
comparison
equal deleted inserted replaced
104:88652073d1c2 105:bbe49769ec18
1 /* 1 /*
2 * $Header: /cvshome/build/org.osgi.util.tracker/src/org/osgi/util/tracker/ServiceTracker.java,v 1.22 2006/07/20 16:14:43 hargrave Exp $ 2 * $Header: /cvshome/build/org.osgi.util.tracker/src/org/osgi/util/tracker/ServiceTracker.java,v 1.22 2006/07/20 16:14:43 hargrave Exp $
3 * 3 *
4 * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved. 4 * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
5 * 5 *
6 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License. 7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at 8 * You may obtain a copy of the License at
9 * 9 *
10 * http://www.apache.org/licenses/LICENSE-2.0 10 * http://www.apache.org/licenses/LICENSE-2.0
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and 15 * See the License for the specific language governing permissions and
16 * limitations under the License. 16 * limitations under the License.
17 */ 17 */
18 18
19 // Port to the D programming language:
20 // Frank Benoit <benoit@tionex.de>
19 module org.osgi.util.tracker.ServiceTracker; 21 module org.osgi.util.tracker.ServiceTracker;
20 import org.osgi.util.tracker.ServiceTrackerCustomizer;
21 22
22 import java.lang.all; 23 import java.lang.all;
24
25 import org.osgi.util.tracker.ServiceTrackerCustomizer; // packageimport
26
23 import java.util.ArrayList; 27 import java.util.ArrayList;
24 import java.util.Enumeration; 28 import java.util.Enumeration;
25 import java.util.Hashtable; 29 import java.util.Hashtable;
26 import java.util.LinkedList; 30 import java.util.LinkedList;
27 31
28 //FIXME tmp remove: import org.eclipse.osgi.framework.internal.core.FilterImpl; 32 import org.eclipse.osgi.framework.internal.core.FilterImpl;
29 //FIXME tmp remove: import org.osgi.framework.AllServiceListener; 33 import org.osgi.framework.AllServiceListener;
30 import org.osgi.framework.BundleContext; 34 import org.osgi.framework.BundleContext;
31 //FIXME tmp remove: import org.osgi.framework.Constants; 35 import org.osgi.framework.Constants;
32 import org.osgi.framework.Filter; 36 import org.osgi.framework.Filter;
33 //FIXME tmp remove: import org.osgi.framework.InvalidSyntaxException; 37 import org.osgi.framework.InvalidSyntaxException;
34 import org.osgi.framework.ServiceEvent; 38 import org.osgi.framework.ServiceEvent;
35 import org.osgi.framework.ServiceListener; 39 import org.osgi.framework.ServiceListener;
36 import org.osgi.framework.ServiceReference; 40 import org.osgi.framework.ServiceReference;
37 41
38 /** 42 /**
56 * <p> 60 * <p>
57 * The <code>ServiceTracker</code> class is thread-safe. It does not call a 61 * The <code>ServiceTracker</code> class is thread-safe. It does not call a
58 * <code>ServiceTrackerCustomizer</code> object while holding any locks. 62 * <code>ServiceTrackerCustomizer</code> object while holding any locks.
59 * <code>ServiceTrackerCustomizer</code> implementations must also be 63 * <code>ServiceTrackerCustomizer</code> implementations must also be
60 * thread-safe. 64 * thread-safe.
61 * 65 *
62 * @ThreadSafe 66 * @ThreadSafe
63 * @version $Revision: 1.29 $ 67 * @version $Revision: 1.29 $
64 */ 68 */
65 69
66 /* 70 /*
68 * In all cases a filter string containing objectClass is passed to BundleContext.addServiceListener 72 * In all cases a filter string containing objectClass is passed to BundleContext.addServiceListener
69 * to take advantage of the ServiceEvent delivery optimizations. 73 * to take advantage of the ServiceEvent delivery optimizations.
70 */ 74 */
71 75
72 public class ServiceTracker : ServiceTrackerCustomizer { 76 public class ServiceTracker : ServiceTrackerCustomizer {
73 public this(BundleContext context, ServiceReference reference, ServiceTrackerCustomizer customizer) { 77 /* set this to true to compile in_ debug_ messages */
74 implMissing(__FILE__,__LINE__); 78 static final bool DEBUG = false;
75 }
76 public this(BundleContext context, String clazz, ServiceTrackerCustomizer customizer) {
77 implMissing(__FILE__,__LINE__);
78 }
79 public this(BundleContext context, Filter filter, ServiceTrackerCustomizer customizer) {
80 implMissing(__FILE__,__LINE__);
81 }
82 public Object addingService(ServiceReference reference){
83 implMissing(__FILE__,__LINE__);
84 return null;
85 }
86 public void modifiedService(ServiceReference reference, Object service){
87 implMissing(__FILE__,__LINE__);
88 }
89 public void removedService(ServiceReference reference, Object service){
90 implMissing(__FILE__,__LINE__);
91 }
92 public void open() {
93 implMissing(__FILE__,__LINE__);
94 }
95 public void open( bool trackAll) {
96 implMissing(__FILE__,__LINE__);
97 }
98 public synchronized void close() {
99 implMissing(__FILE__,__LINE__);
100 }
101 public Object getService(ServiceReference reference) {
102 implMissing(__FILE__,__LINE__);
103 return null;
104 }
105 public Object getService() {
106 implMissing(__FILE__,__LINE__);
107 return null;
108 }
109 }
110 //FIXME Dummy class
111 /+++
112 public class ServiceTracker : ServiceTrackerCustomizer {
113 /* set this to true to compile in debug messages */
114 static final bool DEBUG = false;
115 /** 79 /**
116 * Bundle context against which this <code>ServiceTracker</code> object is 80 * Bundle context against which this <code>ServiceTracker</code> object is
117 * tracking. 81 * tracking.
118 */ 82 */
119 protected final BundleContext context; 83 protected final BundleContext context;
120 /** 84 /**
121 * Filter specifying search criteria for the services to track. 85 * Filter specifying search criteria for the services to track.
122 * 86 *
123 * @since 1.1 87 * @since 1.1
124 */ 88 */
125 protected final Filter filter; 89 protected final Filter filter;
126 /** 90 /**
127 * <code>ServiceTrackerCustomizer</code> object for this tracker. 91 * <code>ServiceTrackerCustomizer</code> object for this tracker.
143 private final ServiceReference trackReference; 107 private final ServiceReference trackReference;
144 /** 108 /**
145 * True if no Filter object was supplied in a constructor or we are not 109 * True if no Filter object was supplied in a constructor or we are not
146 * using the supplied filter. 110 * using the supplied filter.
147 */ 111 */
148 final bool noUserFilter; 112 final bool noUserFilter;
149 /** 113 /**
150 * Tracked services: <code>ServiceReference</code> object -> customized 114 * Tracked services: <code>ServiceReference</code> object -> customized
151 * Object and <code>ServiceListener</code> object 115 * Object and <code>ServiceListener</code> object
152 */ 116 */
153 private volatile Tracked tracked; 117 private /+volatile+/ Tracked tracked;
154 /** 118 /**
155 * Modification count. This field is initialized to zero by open, set to -1 119 * Modification count. This field is initialized to zero by open, set to -1
156 * by close and incremented by modified. 120 * by close and incremented by modified.
157 * 121 *
158 * This field is volatile since it is accessed by multiple threads. 122 * This field is volatile since it is accessed by multiple threads.
159 */ 123 */
160 private volatile int trackingCount = -1; 124 private /+volatile+/ int trackingCount = -1;
161 /** 125 /**
162 * Cached ServiceReference for getServiceReference. 126 * Cached ServiceReference for getServiceReference.
163 * 127 *
164 * This field is volatile since it is accessed by multiple threads. 128 * This field is volatile since it is accessed by multiple threads.
165 */ 129 */
166 private volatile ServiceReference cachedReference; 130 private /+volatile+/ ServiceReference cachedReference;
167 /** 131 /**
168 * Cached service object for getService. 132 * Cached service object for getService.
169 * 133 *
170 * This field is volatile since it is accessed by multiple threads. 134 * This field is volatile since it is accessed by multiple threads.
171 */ 135 */
172 private volatile Object cachedService; 136 private /+volatile+/ Object cachedService;
173 137
174 /** 138 /**
175 * Create a <code>ServiceTracker</code> object on the specified 139 * Create a <code>ServiceTracker</code> object on the specified
176 * <code>ServiceReference</code> object. 140 * <code>ServiceReference</code> object.
177 * 141 *
178 * <p> 142 * <p>
179 * The service referenced by the specified <code>ServiceReference</code> 143 * The service referenced by the specified <code>ServiceReference</code>
180 * object will be tracked by this <code>ServiceTracker</code> object. 144 * object will be tracked by this <code>ServiceTracker</code> object.
181 * 145 *
182 * @param context <code>BundleContext</code> object against which the 146 * @param context <code>BundleContext</code> object against which the
183 * tracking is done. 147 * tracking is done.
184 * @param reference <code>ServiceReference</code> object for the service 148 * @param reference <code>ServiceReference</code> object for the service
185 * to be tracked. 149 * to be tracked.
186 * @param customizer The customizer object to call when services are added, 150 * @param customizer The customizer object to call when services are added,
194 public this(BundleContext context, ServiceReference reference, 158 public this(BundleContext context, ServiceReference reference,
195 ServiceTrackerCustomizer customizer) { 159 ServiceTrackerCustomizer customizer) {
196 this.context = context; 160 this.context = context;
197 this.trackReference = reference; 161 this.trackReference = reference;
198 this.trackClass = null; 162 this.trackClass = null;
199 this.customizer = (customizer == null) ? this : customizer; 163 this.customizer = (customizer is null) ? this : customizer;
200 this.listenerFilter = "(&(" + Constants.OBJECTCLASS + "=" + ((String[]) reference.getProperty(Constants.OBJECTCLASS))[0] //$NON-NLS-1$ //$NON-NLS-2$ 164 this.listenerFilter = "(&(" + Constants.OBJECTCLASS + "=" + (stringcast( reference.getProperty(Constants.OBJECTCLASS)))[0] //$NON-NLS-1$ //$NON-NLS-2$
201 + ")(" + Constants.SERVICE_ID + "=" + reference.getProperty(Constants.SERVICE_ID).toString() + "))" ; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 165 + ")(" + Constants.SERVICE_ID + "=" + reference.getProperty(Constants.SERVICE_ID).toString() + "))" ; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
202 this.noUserFilter = true; 166 this.noUserFilter = true;
203 try { 167 try {
204 this.filter = context.createFilter(listenerFilter); 168 this.filter = context.createFilter(listenerFilter);
205 } 169 }
212 } 176 }
213 177
214 /** 178 /**
215 * Create a <code>ServiceTracker</code> object on the specified class 179 * Create a <code>ServiceTracker</code> object on the specified class
216 * name. 180 * name.
217 * 181 *
218 * <p> 182 * <p>
219 * Services registered under the specified class name will be tracked by 183 * Services registered under the specified class name will be tracked by
220 * this <code>ServiceTracker</code> object. 184 * this <code>ServiceTracker</code> object.
221 * 185 *
222 * @param context <code>BundleContext</code> object against which the 186 * @param context <code>BundleContext</code> object against which the
223 * tracking is done. 187 * tracking is done.
224 * @param clazz Class name of the services to be tracked. 188 * @param clazz Class name of the services to be tracked.
225 * @param customizer The customizer object to call when services are added, 189 * @param customizer The customizer object to call when services are added,
226 * modified, or removed in this <code>ServiceTracker</code> object. 190 * modified, or removed in this <code>ServiceTracker</code> object.
233 public this(BundleContext context, String clazz, 197 public this(BundleContext context, String clazz,
234 ServiceTrackerCustomizer customizer) { 198 ServiceTrackerCustomizer customizer) {
235 this.context = context; 199 this.context = context;
236 this.trackReference = null; 200 this.trackReference = null;
237 this.trackClass = clazz; 201 this.trackClass = clazz;
238 this.customizer = (customizer == null) ? this : customizer; 202 this.customizer = (customizer is null) ? this : customizer;
239 this.listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz.toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 203 this.listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz.toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
240 this.noUserFilter = true; 204 this.noUserFilter = true;
241 try { 205 try {
242 this.filter = context.createFilter(listenerFilter); 206 this.filter = context.createFilter(listenerFilter);
243 } 207 }
250 } 214 }
251 215
252 /** 216 /**
253 * Create a <code>ServiceTracker</code> object on the specified 217 * Create a <code>ServiceTracker</code> object on the specified
254 * <code>Filter</code> object. 218 * <code>Filter</code> object.
255 * 219 *
256 * <p> 220 * <p>
257 * Services which match the specified <code>Filter</code> object will be 221 * Services which match the specified <code>Filter</code> object will be
258 * tracked by this <code>ServiceTracker</code> object. 222 * tracked by this <code>ServiceTracker</code> object.
259 * 223 *
260 * @param context <code>BundleContext</code> object against which the 224 * @param context <code>BundleContext</code> object against which the
261 * tracking is done. 225 * tracking is done.
262 * @param filter <code>Filter</code> object to select the services to be 226 * @param filter <code>Filter</code> object to select the services to be
263 * tracked. 227 * tracked.
264 * @param customizer The customizer object to call when services are added, 228 * @param customizer The customizer object to call when services are added,
273 ServiceTrackerCustomizer customizer) { 237 ServiceTrackerCustomizer customizer) {
274 this.context = context; 238 this.context = context;
275 this.trackReference = null; 239 this.trackReference = null;
276 240
277 // obtain a required objectClass from the user supplied filter 241 // obtain a required objectClass from the user supplied filter
278 if (filter instanceof FilterImpl) { 242 if ( null !is cast(FilterImpl)filter ) {
279 this.trackClass = ((FilterImpl)filter).getRequiredObjectClass(); 243 this.trackClass = (cast(FilterImpl)filter).getRequiredObjectClass();
280 } else { 244 } else {
281 this.trackClass = null; 245 this.trackClass = null;
282 } 246 }
283 247
284 if (this.trackClass != null) { 248 if (this.trackClass !is null) {
285 this.listenerFilter = FilterImpl.getObjectClassFilterString(this.trackClass); 249 this.listenerFilter = FilterImpl.getObjectClassFilterString(this.trackClass);
286 //convert to track by class instead of filter if the user filter is in the form (objectClass=some.Clazz) 250 //convert to track by class instead of filter if the user filter is in the form (objectClass=some.Clazz)
287 this.noUserFilter = this.listenerFilter.equals(filter.toString()); 251 this.noUserFilter = this.listenerFilter.opEquals(filter.toString());
288 } else { 252 } else {
289 this.listenerFilter = null; 253 this.listenerFilter = null;
290 this.noUserFilter = false; 254 this.noUserFilter = false;
291 } 255 }
292 256
293 this.filter = filter; 257 this.filter = filter;
294 this.customizer = (customizer == null) ? this : customizer; 258 this.customizer = (customizer is null) ? this : customizer;
295 if ((context == null) || (filter == null)) { // we throw a NPE here 259 if ((context is null) || (filter is null)) { // we throw a NPE here
296 // to 260 // to
297 // be consistent with the 261 // be consistent with the
298 // other constructors 262 // other constructors
299 throw new NullPointerException(); 263 throw new NullPointerException();
300 } 264 }
301 } 265 }
302 266
303 /** 267 /**
304 * Open this <code>ServiceTracker</code> object and begin tracking 268 * Open this <code>ServiceTracker</code> object and begin tracking
305 * services. 269 * services.
306 * 270 *
307 * <p> 271 * <p>
308 * This method calls <code>open(false)</code>. 272 * This method calls <code>open(false)</code>.
309 * 273 *
310 * @throws java.lang.IllegalStateException if the <code>BundleContext</code> 274 * @throws java.lang.IllegalStateException if the <code>BundleContext</code>
311 * object with which this <code>ServiceTracker</code> object was 275 * object with which this <code>ServiceTracker</code> object was
312 * created is no longer valid. 276 * created is no longer valid.
313 * @see #open(bool) 277 * @see #open(boolean)
314 */ 278 */
315 public void open() { 279 public void open() {
316 open(false); 280 open(false);
317 } 281 }
318 282
319 /** 283 /**
320 * Open this <code>ServiceTracker</code> object and begin tracking 284 * Open this <code>ServiceTracker</code> object and begin tracking
321 * services. 285 * services.
322 * 286 *
323 * <p> 287 * <p>
324 * Services which match the search criteria specified when this 288 * Services which match the search criteria specified when this
325 * <code>ServiceTracker</code> object was created are now tracked by this 289 * <code>ServiceTracker</code> object was created are now tracked by this
326 * <code>ServiceTracker</code> object. 290 * <code>ServiceTracker</code> object.
327 * 291 *
328 * @param trackAllServices If <code>true</code>, then this 292 * @param trackAllServices If <code>true</code>, then this
329 * <code>ServiceTracker</code> will track all matching services 293 * <code>ServiceTracker</code> will track all matching services
330 * regardless of class loader accessibility. If <code>false</code>, 294 * regardless of class loader accessibility. If <code>false</code>,
331 * then this <code>ServiceTracker</code> will only track matching 295 * then this <code>ServiceTracker</code> will only track matching
332 * services which are class loader accessibile to the bundle whose 296 * services which are class loader accessibile to the bundle whose
336 * object with which this <code>ServiceTracker</code> object was 300 * object with which this <code>ServiceTracker</code> object was
337 * created is no longer valid. 301 * created is no longer valid.
338 * @since 1.3 302 * @since 1.3
339 */ 303 */
340 public synchronized void open(bool trackAllServices) { 304 public synchronized void open(bool trackAllServices) {
341 if (tracked != null) { 305 if (tracked !is null) {
342 return; 306 return;
343 } 307 }
344 if (DEBUG) { 308 if (DEBUG) {
345 System.out.println("ServiceTracker.open: " + filter); //$NON-NLS-1$ 309 System.out_.println("ServiceTracker.open: " + filter); //$NON-NLS-1$
346 } 310 }
347 tracked = trackAllServices ? new AllTracked() : new Tracked(); 311 tracked = trackAllServices ? new AllTracked() : new Tracked();
348 trackingCount = 0; 312 trackingCount = 0;
349 synchronized (tracked) { 313 synchronized (tracked) {
350 try { 314 try {
351 context.addServiceListener(tracked, listenerFilter); 315 context.addServiceListener(tracked, listenerFilter);
352 ServiceReference[] references; 316 ServiceReference[] references;
353 317
354 if (trackReference != null) { // tracking a single reference 318 if (trackReference !is null) { // tracking a single reference
355 references = new ServiceReference[] {trackReference}; 319 references = [ cast(ServiceReference)trackReference];
356 } 320 }
357 else { // tracking a set of references 321 else { // tracking a set of references
358 references = getInitialReferences(trackAllServices, trackClass, 322 references = getInitialReferences(trackAllServices, trackClass,
359 noUserFilter ? null: filter.toString()); 323 noUserFilter ? null: filter.toString());
360 } 324 }
361 325
362 tracked.setInitialServices(references); // set tracked with 326 tracked.setInitialServices(references); // set tracked with_
363 // the initial 327 // the initial
364 // references 328 // references
365 } 329 }
366 catch (InvalidSyntaxException e) { 330 catch (InvalidSyntaxException e) {
367 throw new RuntimeException( 331 throw new RuntimeException(
373 } 337 }
374 338
375 /** 339 /**
376 * Returns the list of initial <code>ServiceReference</code> objects that 340 * Returns the list of initial <code>ServiceReference</code> objects that
377 * will be tracked by this <code>ServiceTracker</code> object. 341 * will be tracked by this <code>ServiceTracker</code> object.
378 * 342 *
379 * @param trackAllServices If true, use getAllServiceReferences. 343 * @param trackAllServices If true, use getAllServiceReferences.
380 * @param trackClass the class name with which the service was registered, 344 * @param trackClass the class name with which the service was registered,
381 * or null for all services. 345 * or null for all services.
382 * @param filterString the filter criteria or null for all services. 346 * @param filterString the filter criteria or null for all services.
383 * @return the list of initial <code>ServiceReference</code> objects. 347 * @return the list of initial <code>ServiceReference</code> objects.
384 * @throws InvalidSyntaxException if the filter uses an invalid syntax. 348 * @throws InvalidSyntaxException if the filter uses an invalid syntax.
385 */ 349 */
386 private ServiceReference[] getInitialReferences(bool trackAllServices, 350 private ServiceReference[] getInitialReferences(bool trackAllServices,
387 String trackClass, String filterString) 351 String trackClass, String filterString) {
388 throws InvalidSyntaxException {
389 if (trackAllServices) { 352 if (trackAllServices) {
390 return context.getAllServiceReferences(trackClass, filterString); 353 return context.getAllServiceReferences(trackClass, filterString);
391 } 354 }
392 else { 355 else {
393 return context.getServiceReferences(trackClass, filterString); 356 return context.getServiceReferences(trackClass, filterString);
394 } 357 }
395 } 358 }
396 359
397 /** 360 /**
398 * Close this <code>ServiceTracker</code> object. 361 * Close this <code>ServiceTracker</code> object.
399 * 362 *
400 * <p> 363 * <p>
401 * This method should be called when this <code>ServiceTracker</code> 364 * This method should be called when this <code>ServiceTracker</code>
402 * object should end the tracking of services. 365 * object should end the tracking of services.
403 */ 366 */
404 public synchronized void close() { 367 public synchronized void close() {
405 if (tracked == null) { 368 if (tracked is null) {
406 return; 369 return;
407 } 370 }
408 if (DEBUG) { 371 if (DEBUG) {
409 System.out.println("ServiceTracker.close: " + filter); //$NON-NLS-1$ 372 System.out_.println("ServiceTracker.close: " + filter); //$NON-NLS-1$
410 } 373 }
411 tracked.close(); 374 tracked.close();
412 ServiceReference[] references = getServiceReferences(); 375 ServiceReference[] references = getServiceReferences();
413 Tracked outgoing = tracked; 376 Tracked outgoing = tracked;
414 tracked = null; 377 tracked = null;
416 context.removeServiceListener(outgoing); 379 context.removeServiceListener(outgoing);
417 } 380 }
418 catch (IllegalStateException e) { 381 catch (IllegalStateException e) {
419 /* In case the context was stopped. */ 382 /* In case the context was stopped. */
420 } 383 }
421 if (references != null) { 384 if (references !is null) {
422 for (int i = 0; i < references.length; i++) { 385 for (int i = 0; i < references.length_; i++) {
423 outgoing.untrack(references[i]); 386 outgoing.untrack(references[i]);
424 } 387 }
425 } 388 }
426 trackingCount = -1; 389 trackingCount = -1;
427 if (DEBUG) { 390 if (DEBUG) {
428 if ((cachedReference == null) && (cachedService == null)) { 391 if ((cachedReference is null) && (cachedService is null)) {
429 System.out 392 System.out_
430 .println("ServiceTracker.close[cached cleared]: " + filter); //$NON-NLS-1$ 393 .println("ServiceTracker.close[cached cleared]: " + filter); //$NON-NLS-1$
431 } 394 }
432 } 395 }
433 } 396 }
434 397
435 /** 398 /**
436 * Default implementation of the 399 * Default implementation of the
437 * <code>ServiceTrackerCustomizer.addingService</code> method. 400 * <code>ServiceTrackerCustomizer.addingService</code> method.
438 * 401 *
439 * <p> 402 * <p>
440 * This method is only called when this <code>ServiceTracker</code> object 403 * This method is only called when this <code>ServiceTracker</code> object
441 * has been constructed with a <code>null ServiceTrackerCustomizer</code> 404 * has been constructed with a <code>null ServiceTrackerCustomizer</code>
442 * argument. 405 * argument.
443 * 406 *
444 * The default implementation returns the result of calling 407 * The default implementation returns the result of calling
445 * <code>getService</code>, on the <code>BundleContext</code> object 408 * <code>getService</code>, on the <code>BundleContext</code> object
446 * with which this <code>ServiceTracker</code> object was created, passing 409 * with which this <code>ServiceTracker</code> object was created, passing
447 * the specified <code>ServiceReference</code> object. 410 * the specified <code>ServiceReference</code> object.
448 * <p> 411 * <p>
449 * This method can be overridden in a subclass to customize the service 412 * This method can be overridden in a subclass to customize the service
450 * object to be tracked for the service being added. In that case, take care 413 * object to be tracked for the service being added. In that case, take care
451 * not to rely on the default implementation of removedService that will 414 * not to rely on the default implementation of removedService that will
452 * unget the service. 415 * unget the service.
453 * 416 *
454 * @param reference Reference to service being added to this 417 * @param reference Reference to service being added to this
455 * <code>ServiceTracker</code> object. 418 * <code>ServiceTracker</code> object.
456 * @return The service object to be tracked for the service added to this 419 * @return The service object to be tracked for the service added to this
457 * <code>ServiceTracker</code> object. 420 * <code>ServiceTracker</code> object.
458 * @see ServiceTrackerCustomizer 421 * @see ServiceTrackerCustomizer
462 } 425 }
463 426
464 /** 427 /**
465 * Default implementation of the 428 * Default implementation of the
466 * <code>ServiceTrackerCustomizer.modifiedService</code> method. 429 * <code>ServiceTrackerCustomizer.modifiedService</code> method.
467 * 430 *
468 * <p> 431 * <p>
469 * This method is only called when this <code>ServiceTracker</code> object 432 * This method is only called when this <code>ServiceTracker</code> object
470 * has been constructed with a <code>null ServiceTrackerCustomizer</code> 433 * has been constructed with a <code>null ServiceTrackerCustomizer</code>
471 * argument. 434 * argument.
472 * 435 *
473 * The default implementation does nothing. 436 * The default implementation does nothing.
474 * 437 *
475 * @param reference Reference to modified service. 438 * @param reference Reference to modified service.
476 * @param service The service object for the modified service. 439 * @param service The service object for the modified service.
477 * @see ServiceTrackerCustomizer 440 * @see ServiceTrackerCustomizer
478 */ 441 */
479 public void modifiedService(ServiceReference reference, Object service) { 442 public void modifiedService(ServiceReference reference, Object service) {
480 } 443 }
481 444
482 /** 445 /**
483 * Default implementation of the 446 * Default implementation of the
484 * <code>ServiceTrackerCustomizer.removedService</code> method. 447 * <code>ServiceTrackerCustomizer.removedService</code> method.
485 * 448 *
486 * <p> 449 * <p>
487 * This method is only called when this <code>ServiceTracker</code> object 450 * This method is only called when this <code>ServiceTracker</code> object
488 * has been constructed with a <code>null ServiceTrackerCustomizer</code> 451 * has been constructed with a <code>null ServiceTrackerCustomizer</code>
489 * argument. 452 * argument.
490 * 453 *
491 * The default implementation calls <code>ungetService</code>, on the 454 * The default implementation calls <code>ungetService</code>, on the
492 * <code>BundleContext</code> object with which this 455 * <code>BundleContext</code> object with which this
493 * <code>ServiceTracker</code> object was created, passing the specified 456 * <code>ServiceTracker</code> object was created, passing the specified
494 * <code>ServiceReference</code> object. 457 * <code>ServiceReference</code> object.
495 * <p> 458 * <p>
496 * This method can be overridden in a subclass. If the default 459 * This method can be overridden in a subclass. If the default
497 * implementation of <code>addingService</code> method was used, this 460 * implementation of <code>addingService</code> method was used, this
498 * method must unget the service. 461 * method must unget the service.
499 * 462 *
500 * @param reference Reference to removed service. 463 * @param reference Reference to removed service.
501 * @param service The service object for the removed service. 464 * @param service The service object for the removed service.
502 * @see ServiceTrackerCustomizer 465 * @see ServiceTrackerCustomizer
503 */ 466 */
504 public void removedService(ServiceReference reference, Object service) { 467 public void removedService(ServiceReference reference, Object service) {
511 * <p> 474 * <p>
512 * It is strongly recommended that <code>waitForService</code> is not used 475 * It is strongly recommended that <code>waitForService</code> is not used
513 * during the calling of the <code>BundleActivator</code> methods. 476 * during the calling of the <code>BundleActivator</code> methods.
514 * <code>BundleActivator</code> methods are expected to complete in a 477 * <code>BundleActivator</code> methods are expected to complete in a
515 * short period of time. 478 * short period of time.
516 * 479 *
517 * @param timeout time interval in milliseconds to wait. If zero, the method 480 * @param timeout time interval in milliseconds to wait. If zero, the method
518 * will wait indefinately. 481 * will wait indefinately.
519 * @return Returns the result of <code>getService()</code>. 482 * @return Returns the result of <code>getService()</code>.
520 * @throws InterruptedException If another thread has interrupted the 483 * @throws InterruptedException If another thread has interrupted the
521 * current thread. 484 * current thread.
522 * @throws IllegalArgumentException If the value of timeout is negative. 485 * @throws IllegalArgumentException If the value of timeout is negative.
523 */ 486 */
524 public Object waitForService(long timeout) throws InterruptedException { 487 public Object waitForService(long timeout) {
525 if (timeout < 0) { 488 if (timeout < 0) {
526 throw new IllegalArgumentException("timeout value is negative"); //$NON-NLS-1$ 489 throw new IllegalArgumentException("timeout value is_ negative"); //$NON-NLS-1$
527 } 490 }
528 Object object = getService(); 491 Object object = getService();
529 while (object == null) { 492 while (object is null) {
530 Tracked tracked = this.tracked; /* 493 Tracked tracked = this.tracked; /*
531 * use local var since we are not 494 * use local var since we are not
532 * synchronized 495 * synchronized
533 */ 496 */
534 if (tracked == null) { /* if ServiceTracker is not open */ 497 if (tracked is null) { /* if ServiceTracker is_ not open */
535 return null; 498 return null;
536 } 499 }
537 synchronized (tracked) { 500 synchronized (tracked) {
538 if (tracked.size() == 0) { 501 if (tracked.size() is 0) {
539 tracked.wait(timeout); 502 tracked.wait(timeout);
540 } 503 }
541 } 504 }
542 object = getService(); 505 object = getService();
543 if (timeout > 0) { 506 if (timeout > 0) {
548 } 511 }
549 512
550 /** 513 /**
551 * Return an array of <code>ServiceReference</code> objects for all 514 * Return an array of <code>ServiceReference</code> objects for all
552 * services being tracked by this <code>ServiceTracker</code> object. 515 * services being tracked by this <code>ServiceTracker</code> object.
553 * 516 *
554 * @return Array of <code>ServiceReference</code> objects or 517 * @return Array of <code>ServiceReference</code> objects or
555 * <code>null</code> if no service are being tracked. 518 * <code>null</code> if no service are being tracked.
556 */ 519 */
557 public ServiceReference[] getServiceReferences() { 520 public ServiceReference[] getServiceReferences() {
558 Tracked tracked = this.tracked; /* 521 Tracked tracked = this.tracked; /*
559 * use local var since we are not 522 * use local var since we are not
560 * synchronized 523 * synchronized
561 */ 524 */
562 if (tracked == null) { /* if ServiceTracker is not open */ 525 if (tracked is null) { /* if ServiceTracker is_ not open */
563 return null; 526 return null;
564 } 527 }
565 synchronized (tracked) { 528 synchronized (tracked) {
566 int length = tracked.size(); 529 int length_ = tracked.size();
567 if (length == 0) { 530 if (length_ is 0) {
568 return null; 531 return null;
569 } 532 }
570 ServiceReference[] references = new ServiceReference[length]; 533 ServiceReference[] references = new ServiceReference[length_];
571 Enumeration keys = tracked.keys(); 534 Enumeration keys = tracked.keys();
572 for (int i = 0; i < length; i++) { 535 for (int i = 0; i < length_; i++) {
573 references[i] = (ServiceReference) keys.nextElement(); 536 references[i] = cast(ServiceReference) keys.nextElement();
574 } 537 }
575 return references; 538 return references;
576 } 539 }
577 } 540 }
578 541
579 /** 542 /**
580 * Returns a <code>ServiceReference</code> object for one of the services 543 * Returns a <code>ServiceReference</code> object for one of the services
581 * being tracked by this <code>ServiceTracker</code> object. 544 * being tracked by this <code>ServiceTracker</code> object.
582 * 545 *
583 * <p> 546 * <p>
584 * If multiple services are being tracked, the service with the highest 547 * If multiple services are being tracked, the service with the highest
585 * ranking (as specified in its <code>service.ranking</code> property) is 548 * ranking (as specified in its <code>service.ranking</code> property) is
586 * returned. 549 * returned.
587 * 550 *
588 * <p> 551 * <p>
589 * If there is a tie in ranking, the service with the lowest service ID (as 552 * If there is a tie in ranking, the service with the lowest service ID (as
590 * specified in its <code>service.id</code> property); that is, the 553 * specified in its <code>service.id</code> property); that is, the
591 * service that was registered first is returned. 554 * service that was registered first is returned.
592 * <p> 555 * <p>
593 * This is the same algorithm used by 556 * This is the same algorithm used by
594 * <code>BundleContext.getServiceReference</code>. 557 * <code>BundleContext.getServiceReference</code>.
595 * 558 *
596 * @return <code>ServiceReference</code> object or <code>null</code> if 559 * @return <code>ServiceReference</code> object or <code>null</code> if
597 * no service is being tracked. 560 * no service is being tracked.
598 * @since 1.1 561 * @since 1.1
599 */ 562 */
600 public ServiceReference getServiceReference() { 563 public ServiceReference getServiceReference() {
601 ServiceReference reference = cachedReference; 564 ServiceReference reference = cachedReference;
602 if (reference != null) { 565 if (reference !is null) {
603 if (DEBUG) { 566 if (DEBUG) {
604 System.out 567 System.out_
605 .println("ServiceTracker.getServiceReference[cached]: " + filter); //$NON-NLS-1$ 568 .println("ServiceTracker.getServiceReference[cached]: " + filter); //$NON-NLS-1$
606 } 569 }
607 return reference; 570 return reference;
608 } 571 }
609 if (DEBUG) { 572 if (DEBUG) {
610 System.out.println("ServiceTracker.getServiceReference: " + filter); //$NON-NLS-1$ 573 System.out_.println("ServiceTracker.getServiceReference: " + filter); //$NON-NLS-1$
611 } 574 }
612 ServiceReference[] references = getServiceReferences(); 575 ServiceReference[] references = getServiceReferences();
613 int length = (references == null) ? 0 : references.length; 576 int length_ = (references is null) ? 0 : references.length_;
614 if (length == 0) /* if no service is being tracked */ 577 if (length_ is 0) /* if no service is_ being tracked */
615 { 578 {
616 return null; 579 return null;
617 } 580 }
618 int index = 0; 581 int index = 0;
619 if (length > 1) /* if more than one service, select highest ranking */ 582 if (length_ > 1) /* if more than one service, select highest ranking */
620 { 583 {
621 int rankings[] = new int[length]; 584 int rankings[] = new int[length_];
622 int count = 0; 585 int count = 0;
623 int maxRanking = Integer.MIN_VALUE; 586 int maxRanking = Integer.MIN_VALUE;
624 for (int i = 0; i < length; i++) { 587 for (int i = 0; i < length_; i++) {
625 Object property = references[i] 588 Object property = references[i]
626 .getProperty(Constants.SERVICE_RANKING); 589 .getProperty(Constants.SERVICE_RANKING);
627 int ranking = (property instanceof Integer) ? ((Integer) property) 590 int ranking = ( null !is cast(Integer)property ) ? (cast(Integer) property)
628 .intValue() 591 .intValue()
629 : 0; 592 : 0;
630 rankings[i] = ranking; 593 rankings[i] = ranking;
631 if (ranking > maxRanking) { 594 if (ranking > maxRanking) {
632 index = i; 595 index = i;
633 maxRanking = ranking; 596 maxRanking = ranking;
634 count = 1; 597 count = 1;
635 } 598 }
636 else { 599 else {
637 if (ranking == maxRanking) { 600 if (ranking is maxRanking) {
638 count++; 601 count++;
639 } 602 }
640 } 603 }
641 } 604 }
642 if (count > 1) /* if still more than one service, select lowest id */ 605 if (count > 1) /* if still more than one service, select lowest id */
643 { 606 {
644 long minId = Long.MAX_VALUE; 607 long minId = Long.MAX_VALUE;
645 for (int i = 0; i < length; i++) { 608 for (int i = 0; i < length_; i++) {
646 if (rankings[i] == maxRanking) { 609 if (rankings[i] is maxRanking) {
647 long id = ((Long) (references[i] 610 long id = (cast(Long) (references[i]
648 .getProperty(Constants.SERVICE_ID))) 611 .getProperty(Constants.SERVICE_ID)))
649 .longValue(); 612 .longValue();
650 if (id < minId) { 613 if (id < minId) {
651 index = i; 614 index = i;
652 minId = id; 615 minId = id;
660 623
661 /** 624 /**
662 * Returns the service object for the specified 625 * Returns the service object for the specified
663 * <code>ServiceReference</code> object if the referenced service is being 626 * <code>ServiceReference</code> object if the referenced service is being
664 * tracked by this <code>ServiceTracker</code> object. 627 * tracked by this <code>ServiceTracker</code> object.
665 * 628 *
666 * @param reference Reference to the desired service. 629 * @param reference Reference to the desired service.
667 * @return Service object or <code>null</code> if the service referenced 630 * @return Service object or <code>null</code> if the service referenced
668 * by the specified <code>ServiceReference</code> object is not 631 * by the specified <code>ServiceReference</code> object is not
669 * being tracked. 632 * being tracked.
670 */ 633 */
671 public Object getService(ServiceReference reference) { 634 public Object getService(ServiceReference reference) {
672 Tracked tracked = this.tracked; /* 635 Tracked tracked = this.tracked; /*
673 * use local var since we are not 636 * use local var since we are not
674 * synchronized 637 * synchronized
675 */ 638 */
676 if (tracked == null) { /* if ServiceTracker is not open */ 639 if (tracked is null) { /* if ServiceTracker is_ not open */
677 return null; 640 return null;
678 } 641 }
679 synchronized (tracked) { 642 synchronized (tracked) {
680 return tracked.get(reference); 643 return tracked.get(reference);
681 } 644 }
682 } 645 }
683 646
684 /** 647 /**
685 * Return an array of service objects for all services being tracked by this 648 * Return an array of service objects for all services being tracked by this
686 * <code>ServiceTracker</code> object. 649 * <code>ServiceTracker</code> object.
687 * 650 *
688 * @return Array of service objects or <code>null</code> if no service are 651 * @return Array of service objects or <code>null</code> if no service are
689 * being tracked. 652 * being tracked.
690 */ 653 */
691 public Object[] getServices() { 654 public Object[] getServices() {
692 Tracked tracked = this.tracked; /* 655 Tracked tracked = this.tracked; /*
693 * use local var since we are not 656 * use local var since we are not
694 * synchronized 657 * synchronized
695 */ 658 */
696 if (tracked == null) { /* if ServiceTracker is not open */ 659 if (tracked is null) { /* if ServiceTracker is_ not open */
697 return null; 660 return null;
698 } 661 }
699 synchronized (tracked) { 662 synchronized (tracked) {
700 ServiceReference[] references = getServiceReferences(); 663 ServiceReference[] references = getServiceReferences();
701 int length = (references == null) ? 0 : references.length; 664 int length_ = (references is null) ? 0 : references.length_;
702 if (length == 0) { 665 if (length_ is 0) {
703 return null; 666 return null;
704 } 667 }
705 Object[] objects = new Object[length]; 668 Object[] objects = new Object[length_];
706 for (int i = 0; i < length; i++) { 669 for (int i = 0; i < length_; i++) {
707 objects[i] = getService(references[i]); 670 objects[i] = getService(references[i]);
708 } 671 }
709 return objects; 672 return objects;
710 } 673 }
711 } 674 }
712 675
713 /** 676 /**
714 * Returns a service object for one of the services being tracked by this 677 * Returns a service object for one of the services being tracked by this
715 * <code>ServiceTracker</code> object. 678 * <code>ServiceTracker</code> object.
716 * 679 *
717 * <p> 680 * <p>
718 * If any services are being tracked, this method returns the result of 681 * If any services are being tracked, this method returns the result of
719 * calling <code>getService(getServiceReference())</code>. 682 * calling <code>getService(getServiceReference())</code>.
720 * 683 *
721 * @return Service object or <code>null</code> if no service is being 684 * @return Service object or <code>null</code> if no service is being
722 * tracked. 685 * tracked.
723 */ 686 */
724 public Object getService() { 687 public Object getService() {
725 Object service = cachedService; 688 Object service = cachedService;
726 if (service != null) { 689 if (service !is null) {
727 if (DEBUG) { 690 if (DEBUG) {
728 System.out 691 System.out_
729 .println("ServiceTracker.getService[cached]: " + filter); //$NON-NLS-1$ 692 .println("ServiceTracker.getService[cached]: " + filter); //$NON-NLS-1$
730 } 693 }
731 return service; 694 return service;
732 } 695 }
733 if (DEBUG) { 696 if (DEBUG) {
734 System.out.println("ServiceTracker.getService: " + filter); //$NON-NLS-1$ 697 System.out_.println("ServiceTracker.getService: " + filter); //$NON-NLS-1$
735 } 698 }
736 ServiceReference reference = getServiceReference(); 699 ServiceReference reference = getServiceReference();
737 if (reference == null) { 700 if (reference is null) {
738 return null; 701 return null;
739 } 702 }
740 return cachedService = getService(reference); 703 return cachedService = getService(reference);
741 } 704 }
742 705
743 /** 706 /**
744 * Remove a service from this <code>ServiceTracker</code> object. 707 * Remove a service from this <code>ServiceTracker</code> object.
745 * 708 *
746 * The specified service will be removed from this 709 * The specified service will be removed from this
747 * <code>ServiceTracker</code> object. If the specified service was being 710 * <code>ServiceTracker</code> object. If the specified service was being
748 * tracked then the <code>ServiceTrackerCustomizer.removedService</code> 711 * tracked then the <code>ServiceTrackerCustomizer.removedService</code>
749 * method will be called for that service. 712 * method will be called for that service.
750 * 713 *
751 * @param reference Reference to the service to be removed. 714 * @param reference Reference to the service to be removed.
752 */ 715 */
753 public void remove(ServiceReference reference) { 716 public void remove(ServiceReference reference) {
754 Tracked tracked = this.tracked; /* 717 Tracked tracked = this.tracked; /*
755 * use local var since we are not 718 * use local var since we are not
756 * synchronized 719 * synchronized
757 */ 720 */
758 if (tracked == null) { /* if ServiceTracker is not open */ 721 if (tracked is null) { /* if ServiceTracker is_ not open */
759 return; 722 return;
760 } 723 }
761 tracked.untrack(reference); 724 tracked.untrack(reference);
762 } 725 }
763 726
764 /** 727 /**
765 * Return the number of services being tracked by this 728 * Return the number of services being tracked by this
766 * <code>ServiceTracker</code> object. 729 * <code>ServiceTracker</code> object.
767 * 730 *
768 * @return Number of services being tracked. 731 * @return Number of services being tracked.
769 */ 732 */
770 public int size() { 733 public int size() {
771 Tracked tracked = this.tracked; /* 734 Tracked tracked = this.tracked; /*
772 * use local var since we are not 735 * use local var since we are not
773 * synchronized 736 * synchronized
774 */ 737 */
775 if (tracked == null) { /* if ServiceTracker is not open */ 738 if (tracked is null) { /* if ServiceTracker is_ not open */
776 return 0; 739 return 0;
777 } 740 }
778 return tracked.size(); 741 return tracked.size();
779 } 742 }
780 743
781 /** 744 /**
782 * Returns the tracking count for this <code>ServiceTracker</code> object. 745 * Returns the tracking count for this <code>ServiceTracker</code> object.
783 * 746 *
784 * The tracking count is initialized to 0 when this 747 * The tracking count is initialized to 0 when this
785 * <code>ServiceTracker</code> object is opened. Every time a service is 748 * <code>ServiceTracker</code> object is opened. Every time a service is
786 * added, modified or removed from this <code>ServiceTracker</code> object 749 * added, modified or removed from this <code>ServiceTracker</code> object
787 * the tracking count is incremented. 750 * the tracking count is incremented.
788 * 751 *
789 * <p> 752 * <p>
790 * The tracking count can be used to determine if this 753 * The tracking count can be used to determine if this
791 * <code>ServiceTracker</code> object has added, modified or removed a 754 * <code>ServiceTracker</code> object has added, modified or removed a
792 * service by comparing a tracking count value previously collected with the 755 * service by comparing a tracking count value previously collected with the
793 * current tracking count value. If the value has not changed, then no 756 * current tracking count value. If the value has not changed, then no
794 * service has been added, modified or removed from this 757 * service has been added, modified or removed from this
795 * <code>ServiceTracker</code> object since the previous tracking count 758 * <code>ServiceTracker</code> object since the previous tracking count
796 * was collected. 759 * was collected.
797 * 760 *
798 * @since 1.2 761 * @since 1.2
799 * @return The tracking count for this <code>ServiceTracker</code> object 762 * @return The tracking count for this <code>ServiceTracker</code> object
800 * or -1 if this <code>ServiceTracker</code> object is not open. 763 * or -1 if this <code>ServiceTracker</code> object is not open.
801 */ 764 */
802 public int getTrackingCount() { 765 public int getTrackingCount() {
804 } 767 }
805 768
806 /** 769 /**
807 * Called by the Tracked object whenever the set of tracked services is 770 * Called by the Tracked object whenever the set of tracked services is
808 * modified. Increments the tracking count and clears the cache. 771 * modified. Increments the tracking count and clears the cache.
809 * 772 *
810 * @GuardedBy tracked 773 * @GuardedBy tracked
811 */ 774 */
812 /* 775 /*
813 * This method must not be synchronized since it is called by Tracked while 776 * This method must not be synchronized since it is called by Tracked while
814 * Tracked is synchronized. We don't want synchronization interactions 777 * Tracked is synchronized. We don't want synchronization interactions
817 void modified() { 780 void modified() {
818 trackingCount++; /* increment modification count */ 781 trackingCount++; /* increment modification count */
819 cachedReference = null; /* clear cached value */ 782 cachedReference = null; /* clear cached value */
820 cachedService = null; /* clear cached value */ 783 cachedService = null; /* clear cached value */
821 if (DEBUG) { 784 if (DEBUG) {
822 System.out.println("ServiceTracker.modified: " + filter); //$NON-NLS-1$ 785 System.out_.println("ServiceTracker.modified: " + filter); //$NON-NLS-1$
823 } 786 }
824 } 787 }
825 788
826 789
827 /** 790 /**
830 * class is a hashtable mapping <code>ServiceReference</code> object -> 793 * class is a hashtable mapping <code>ServiceReference</code> object ->
831 * customized Object. This class is the <code>ServiceListener</code> 794 * customized Object. This class is the <code>ServiceListener</code>
832 * object for the tracker. This class is used to synchronize access to the 795 * object for the tracker. This class is used to synchronize access to the
833 * tracked services. This is not a public class. It is only for use by the 796 * tracked services. This is not a public class. It is only for use by the
834 * implementation of the <code>ServiceTracker</code> class. 797 * implementation of the <code>ServiceTracker</code> class.
835 * 798 *
836 * @ThreadSafe 799 * @ThreadSafe
837 */ 800 */
838 class Tracked extends Hashtable implements ServiceListener { 801 class Tracked : Hashtable , ServiceListener {
839 static final long serialVersionUID = -7420065199791006079L; 802 static final long serialVersionUID = -7420065199791006079L;
840 /** 803 /**
841 * List of ServiceReferences in the process of being added. This is used 804 * List of ServiceReferences in the process of being added. This is used
842 * to deal with nesting of ServiceEvents. Since ServiceEvents are 805 * to deal with nesting of ServiceEvents. Since ServiceEvents are
843 * synchronously delivered, ServiceEvents can be nested. For example, 806 * synchronously delivered, ServiceEvents can be nested. For example,
844 * when processing the adding of a service and the customizer causes the 807 * when processing the adding of a service and the customizer causes the
845 * service to be unregistered, notification to the nested call to 808 * service to be unregistered, notification to the nested call to
846 * untrack that the service was unregistered can be made to the track 809 * untrack that the service was unregistered can be made to the track
847 * method. 810 * method.
848 * 811 *
849 * Since the ArrayList implementation is not synchronized, all access to 812 * Since the ArrayList implementation is not synchronized, all access to
850 * this list must be protected by the same synchronized object for 813 * this list must be protected by the same synchronized object for
851 * thread-safety. 814 * thread-safety.
852 * 815 *
853 * @GuardedBy this 816 * @GuardedBy this
854 */ 817 */
855 private final ArrayList adding; 818 private final ArrayList adding;
856 819
857 /** 820 /**
858 * true if the tracked object is closed. 821 * true if the tracked object is closed.
859 * 822 *
860 * This field is volatile because it is set by one thread and read by 823 * This field is volatile because it is set by one thread and read by
861 * another. 824 * another.
862 */ 825 */
863 private volatile bool closed; 826 private /+volatile+/ bool closed;
864 827
865 /** 828 /**
866 * Initial list of ServiceReferences for the tracker. This is used to 829 * Initial list of ServiceReferences for the tracker. This is used to
867 * correctly process the initial services which could become 830 * correctly process the initial services which could become
868 * unregistered before they are tracked. This is necessary since the 831 * unregistered before they are tracked. This is necessary since the
869 * initial set of tracked services are not "announced" by ServiceEvents 832 * initial set of tracked services are not "announced" by ServiceEvents
870 * and therefore the ServiceEvent for unregistration could be delivered 833 * and therefore the ServiceEvent for unregistration could be delivered
871 * before we track the service. 834 * before we track the service.
872 * 835 *
873 * A service must not be in both the initial and adding lists at the 836 * A service must not be in both the initial and adding lists at the
874 * same time. A service must be moved from the initial list to the 837 * same time. A service must be moved from the initial list to the
875 * adding list "atomically" before we begin tracking it. 838 * adding list "atomically" before we begin tracking it.
876 * 839 *
877 * Since the LinkedList implementation is not synchronized, all access 840 * Since the LinkedList implementation is not synchronized, all access
878 * to this list must be protected by the same synchronized object for 841 * to this list must be protected by the same synchronized object for
879 * thread-safety. 842 * thread-safety.
880 * 843 *
881 * @GuardedBy this 844 * @GuardedBy this
882 */ 845 */
883 private final LinkedList initial; 846 private final LinkedList initial;
884 847
885 /** 848 /**
886 * Tracked constructor. 849 * Tracked constructor.
887 */ 850 */
888 protected Tracked() { 851 protected this() {
889 super(); 852 super();
890 closed = false; 853 closed = false;
891 adding = new ArrayList(6); 854 adding = new ArrayList(6);
892 initial = new LinkedList(); 855 initial = new LinkedList();
893 } 856 }
894 857
895 /** 858 /**
896 * Set initial list of services into tracker before ServiceEvents begin 859 * Set initial list of services into tracker before ServiceEvents begin
897 * to be received. 860 * to be received.
898 * 861 *
899 * This method must be called from ServiceTracker.open while 862 * This method must be called from ServiceTracker.open while
900 * synchronized on this object in the same synchronized block as the 863 * synchronized on this object in the same synchronized block as the
901 * addServiceListener call. 864 * addServiceListener call.
902 * 865 *
903 * @param references The initial list of services to be tracked. 866 * @param references The initial list of services to be tracked.
904 * @GuardedBy this 867 * @GuardedBy this
905 */ 868 */
906 protected void setInitialServices(ServiceReference[] references) { 869 protected void setInitialServices(ServiceReference[] references) {
907 if (references == null) { 870 if (references is null) {
908 return; 871 return;
909 } 872 }
910 int size = references.length; 873 int size = references.length_;
911 for (int i = 0; i < size; i++) { 874 for (int i = 0; i < size; i++) {
912 if (DEBUG) { 875 if (DEBUG) {
913 System.out 876 System.out_
914 .println("ServiceTracker.Tracked.setInitialServices: " + references[i]); //$NON-NLS-1$ 877 .println("ServiceTracker.Tracked.setInitialServices: " + references[i]); //$NON-NLS-1$
915 } 878 }
916 initial.add(references[i]); 879 initial.add(references[i]);
917 } 880 }
918 } 881 }
919 882
920 /** 883 /**
921 * Track the initial list of services. This is called after 884 * Track the initial list of services. This is called after
922 * ServiceEvents can begin to be received. 885 * ServiceEvents can begin to be received.
923 * 886 *
924 * This method must be called from ServiceTracker.open while not 887 * This method must be called from ServiceTracker.open while not
925 * synchronized on this object after the addServiceListener call. 888 * synchronized on this object after the addServiceListener call.
926 * 889 *
927 */ 890 */
928 protected void trackInitialServices() { 891 protected void trackInitialServices() {
929 while (true) { 892 while (true) {
930 ServiceReference reference; 893 ServiceReference reference;
931 synchronized (this) { 894 synchronized (this) {
932 if (initial.size() == 0) { 895 if (initial.size() is 0) {
933 /* 896 /*
934 * if there are no more inital services 897 * if there are no more inital services
935 */ 898 */
936 return; /* we are done */ 899 return; /* we are done */
937 } 900 }
938 /* 901 /*
939 * move the first service from the initial list to the 902 * move the first service from the initial list to the
940 * adding list within this synchronized block. 903 * adding list within this synchronized block.
941 */ 904 */
942 reference = (ServiceReference) initial.removeFirst(); 905 reference = cast(ServiceReference) initial.removeFirst();
943 if (this.get(reference) != null) { 906 if (this.get(reference) !is null) {
944 /* if we are already tracking this service */ 907 /* if we are already tracking this service */
945 if (DEBUG) { 908 if (DEBUG) {
946 System.out 909 System.out_
947 .println("ServiceTracker.Tracked.trackInitialServices[already tracked]: " + reference); //$NON-NLS-1$ 910 .println("ServiceTracker.Tracked.trackInitialServices[already tracked]: " + reference); //$NON-NLS-1$
948 } 911 }
949 continue; /* skip this service */ 912 continue; /* skip this service */
950 } 913 }
951 if (adding.contains(reference)) { 914 if (adding.contains(reference)) {
952 /* 915 /*
953 * if this service is already in the process of being 916 * if this service is already in the process of being
954 * added. 917 * added.
955 */ 918 */
956 if (DEBUG) { 919 if (DEBUG) {
957 System.out 920 System.out_
958 .println("ServiceTracker.Tracked.trackInitialServices[already adding]: " + reference); //$NON-NLS-1$ 921 .println("ServiceTracker.Tracked.trackInitialServices[already adding]: " + reference); //$NON-NLS-1$
959 } 922 }
960 continue; /* skip this service */ 923 continue; /* skip this service */
961 } 924 }
962 adding.add(reference); 925 adding.add(reference);
963 } 926 }
964 if (DEBUG) { 927 if (DEBUG) {
965 System.out 928 System.out_
966 .println("ServiceTracker.Tracked.trackInitialServices: " + reference); //$NON-NLS-1$ 929 .println("ServiceTracker.Tracked.trackInitialServices: " + reference); //$NON-NLS-1$
967 } 930 }
968 trackAdding(reference); /* 931 trackAdding(reference); /*
969 * Begin tracking it. We call 932 * Begin tracking it. We call
970 * trackAdding since we have already put 933 * trackAdding since we have already put
983 946
984 /** 947 /**
985 * <code>ServiceListener</code> method for the 948 * <code>ServiceListener</code> method for the
986 * <code>ServiceTracker</code> class. This method must NOT be 949 * <code>ServiceTracker</code> class. This method must NOT be
987 * synchronized to avoid deadlock potential. 950 * synchronized to avoid deadlock potential.
988 * 951 *
989 * @param event <code>ServiceEvent</code> object from the framework. 952 * @param event <code>ServiceEvent</code> object from the framework.
990 */ 953 */
991 public void serviceChanged(ServiceEvent event) { 954 public void serviceChanged(ServiceEvent event) {
992 /* 955 /*
993 * Check if we had a delayed call (which could happen when we 956 * Check if we had a delayed call (which could happen when we
996 if (closed) { 959 if (closed) {
997 return; 960 return;
998 } 961 }
999 ServiceReference reference = event.getServiceReference(); 962 ServiceReference reference = event.getServiceReference();
1000 if (DEBUG) { 963 if (DEBUG) {
1001 System.out 964 System.out_
1002 .println("ServiceTracker.Tracked.serviceChanged[" + event.getType() + "]: " + reference); //$NON-NLS-1$ //$NON-NLS-2$ 965 .println("ServiceTracker.Tracked.serviceChanged[" + event.getType() + "]: " + reference); //$NON-NLS-1$ //$NON-NLS-2$
1003 } 966 }
1004 967
1005 switch (event.getType()) { 968 switch (event.getType()) {
1006 case ServiceEvent.REGISTERED : 969 case ServiceEvent.REGISTERED :
1039 } 1002 }
1040 } 1003 }
1041 1004
1042 /** 1005 /**
1043 * Begin to track the referenced service. 1006 * Begin to track the referenced service.
1044 * 1007 *
1045 * @param reference Reference to a service to be tracked. 1008 * @param reference Reference to a service to be tracked.
1046 */ 1009 */
1047 private void track(ServiceReference reference) { 1010 private void track(ServiceReference reference) {
1048 Object object; 1011 Object object;
1049 synchronized (this) { 1012 synchronized (this) {
1050 object = this.get(reference); 1013 object = this.get(reference);
1051 } 1014 }
1052 if (object != null) /* we are already tracking the service */ 1015 if (object !is null) /* we are already tracking the service */
1053 { 1016 {
1054 if (DEBUG) { 1017 if (DEBUG) {
1055 System.out 1018 System.out_
1056 .println("ServiceTracker.Tracked.track[modified]: " + reference); //$NON-NLS-1$ 1019 .println("ServiceTracker.Tracked.track[modified]: " + reference); //$NON-NLS-1$
1057 } 1020 }
1058 synchronized (this) { 1021 synchronized (this) {
1059 modified(); /* increment modification count */ 1022 modified(); /* increment modification count */
1060 } 1023 }
1071 * if this service is 1034 * if this service is
1072 * already in the process of 1035 * already in the process of
1073 * being added. 1036 * being added.
1074 */ 1037 */
1075 if (DEBUG) { 1038 if (DEBUG) {
1076 System.out 1039 System.out_
1077 .println("ServiceTracker.Tracked.track[already adding]: " + reference); //$NON-NLS-1$ 1040 .println("ServiceTracker.Tracked.track[already adding]: " + reference); //$NON-NLS-1$
1078 } 1041 }
1079 return; 1042 return;
1080 } 1043 }
1081 adding.add(reference); /* mark this service is being added */ 1044 adding.add(reference); /* mark this service is_ being added */
1082 } 1045 }
1083 1046
1084 trackAdding(reference); /* 1047 trackAdding(reference); /*
1085 * call trackAdding now that we have put the 1048 * call trackAdding now that we have put the
1086 * reference in the adding list 1049 * reference in the adding list
1089 1052
1090 /** 1053 /**
1091 * Common logic to add a service to the tracker used by track and 1054 * Common logic to add a service to the tracker used by track and
1092 * trackInitialServices. The specified reference must have been placed 1055 * trackInitialServices. The specified reference must have been placed
1093 * in the adding list before calling this method. 1056 * in the adding list before calling this method.
1094 * 1057 *
1095 * @param reference Reference to a service to be tracked. 1058 * @param reference Reference to a service to be tracked.
1096 */ 1059 */
1097 private void trackAdding(ServiceReference reference) { 1060 private void trackAdding(ServiceReference reference) {
1098 if (DEBUG) { 1061 if (DEBUG) {
1099 System.out 1062 System.out_
1100 .println("ServiceTracker.Tracked.trackAdding: " + reference); //$NON-NLS-1$ 1063 .println("ServiceTracker.Tracked.trackAdding: " + reference); //$NON-NLS-1$
1101 } 1064 }
1102 Object object = null; 1065 Object object = null;
1103 bool becameUntracked = false; 1066 bool becameUntracked = false;
1104 /* Call customizer outside of synchronized region */ 1067 /* Call customizer outside of synchronized region */
1114 if (adding.remove(reference)) { /* 1077 if (adding.remove(reference)) { /*
1115 * if the service was not 1078 * if the service was not
1116 * untracked during the 1079 * untracked during the
1117 * customizer callback 1080 * customizer callback
1118 */ 1081 */
1119 if (object != null) { 1082 if (object !is null) {
1120 this.put(reference, object); 1083 this.put(reference, object);
1121 modified(); /* increment modification count */ 1084 modified(); /* increment modification count */
1122 notifyAll(); /* 1085 notifyAll(); /*
1123 * notify any waiters in 1086 * notify any waiters in
1124 * waitForService 1087 * waitForService
1133 /* 1096 /*
1134 * The service became untracked during the customizer callback. 1097 * The service became untracked during the customizer callback.
1135 */ 1098 */
1136 if (becameUntracked) { 1099 if (becameUntracked) {
1137 if (DEBUG) { 1100 if (DEBUG) {
1138 System.out 1101 System.out_
1139 .println("ServiceTracker.Tracked.trackAdding[removed]: " + reference); //$NON-NLS-1$ 1102 .println("ServiceTracker.Tracked.trackAdding[removed]: " + reference); //$NON-NLS-1$
1140 } 1103 }
1141 /* Call customizer outside of synchronized region */ 1104 /* Call customizer outside of synchronized region */
1142 customizer.removedService(reference, object); 1105 customizer.removedService(reference, object);
1143 /* 1106 /*
1147 } 1110 }
1148 } 1111 }
1149 1112
1150 /** 1113 /**
1151 * Discontinue tracking the referenced service. 1114 * Discontinue tracking the referenced service.
1152 * 1115 *
1153 * @param reference Reference to the tracked service. 1116 * @param reference Reference to the tracked service.
1154 */ 1117 */
1155 protected void untrack(ServiceReference reference) { 1118 protected void untrack(ServiceReference reference) {
1156 Object object; 1119 Object object;
1157 synchronized (this) { 1120 synchronized (this) {
1160 * already in the list of 1123 * already in the list of
1161 * initial references to 1124 * initial references to
1162 * process 1125 * process
1163 */ 1126 */
1164 if (DEBUG) { 1127 if (DEBUG) {
1165 System.out 1128 System.out_
1166 .println("ServiceTracker.Tracked.untrack[removed from initial]: " + reference); //$NON-NLS-1$ 1129 .println("ServiceTracker.Tracked.untrack[removed from initial]: " + reference); //$NON-NLS-1$
1167 } 1130 }
1168 return; /* 1131 return; /*
1169 * we have removed it from the list and it will not 1132 * we have removed it from the list and it will not
1170 * be processed 1133 * be processed
1174 if (adding.remove(reference)) { /* 1137 if (adding.remove(reference)) { /*
1175 * if the service is in the 1138 * if the service is in the
1176 * process of being added 1139 * process of being added
1177 */ 1140 */
1178 if (DEBUG) { 1141 if (DEBUG) {
1179 System.out 1142 System.out_
1180 .println("ServiceTracker.Tracked.untrack[being added]: " + reference); //$NON-NLS-1$ 1143 .println("ServiceTracker.Tracked.untrack[being added]: " + reference); //$NON-NLS-1$
1181 } 1144 }
1182 return; /* 1145 return; /*
1183 * in case the service is untracked while in the 1146 * in case the service is untracked while in the
1184 * process of adding 1147 * process of adding
1187 object = this.remove(reference); /* 1150 object = this.remove(reference); /*
1188 * must remove from tracker 1151 * must remove from tracker
1189 * before calling customizer 1152 * before calling customizer
1190 * callback 1153 * callback
1191 */ 1154 */
1192 if (object == null) { /* are we actually tracking the service */ 1155 if (object is null) { /* are we actually tracking the service */
1193 return; 1156 return;
1194 } 1157 }
1195 modified(); /* increment modification count */ 1158 modified(); /* increment modification count */
1196 } 1159 }
1197 if (DEBUG) { 1160 if (DEBUG) {
1198 System.out 1161 System.out_
1199 .println("ServiceTracker.Tracked.untrack[removed]: " + reference); //$NON-NLS-1$ 1162 .println("ServiceTracker.Tracked.untrack[removed]: " + reference); //$NON-NLS-1$
1200 } 1163 }
1201 /* Call customizer outside of synchronized region */ 1164 /* Call customizer outside of synchronized region */
1202 customizer.removedService(reference, object); 1165 customizer.removedService(reference, object);
1203 /* 1166 /*
1208 } 1171 }
1209 1172
1210 /** 1173 /**
1211 * Subclass of Tracked which implements the AllServiceListener interface. 1174 * Subclass of Tracked which implements the AllServiceListener interface.
1212 * This class is used by the ServiceTracker if open is called with true. 1175 * This class is used by the ServiceTracker if open is called with true.
1213 * 1176 *
1214 * @since 1.3 1177 * @since 1.3
1215 * @ThreadSafe 1178 * @ThreadSafe
1216 */ 1179 */
1217 class AllTracked extends Tracked implements AllServiceListener { 1180 class AllTracked : Tracked , AllServiceListener {
1218 static final long serialVersionUID = 4050764875305137716L; 1181 static final long serialVersionUID = 4050764875305137716L;
1219 1182
1220 /** 1183 /**
1221 * AllTracked constructor. 1184 * AllTracked constructor.
1222 */ 1185 */
1223 protected AllTracked() { 1186 protected this() {
1224 super(); 1187 super();
1225 } 1188 }
1226 } 1189 }
1227 } 1190 }
1228 +++/
1229
1230