/** * Close this {@code BundleTracker}. * * <p>This method should be called when this {@code BundleTracker} should end the tracking of * bundles. * * <p>This implementation calls {@link #getBundles()} to get the list of tracked bundles to * remove. */ public void close() { final Bundle[] bundles; final Tracked outgoing; synchronized (this) { outgoing = tracked; if (outgoing == null) { return; } if (DEBUG) { System.out.println("BundleTracker.close"); // $NON-NLS-1$ } outgoing.close(); bundles = getBundles(); tracked = null; try { context.removeBundleListener(outgoing); } catch (IllegalStateException e) { /* In case the context was stopped. */ } } if (bundles != null) { for (int i = 0; i < bundles.length; i++) { outgoing.untrack(bundles[i], null); } } }
/** * Open this {@code BundleTracker} and begin tracking bundles. * * <p>Bundle which match the state criteria specified when this {@code BundleTracker} was created * are now tracked by this {@code BundleTracker}. * * @throws java.lang.IllegalStateException If the {@code BundleContext} with which this {@code * BundleTracker} was created is no longer valid. * @throws java.lang.SecurityException If the caller and this class do not have the appropriate * {@code AdminPermission[context bundle,LISTENER]}, and the Java Runtime Environment supports * permissions. */ public void open() { final Tracked t; synchronized (this) { if (tracked != null) { return; } if (DEBUG) { System.out.println("BundleTracker.open"); // $NON-NLS-1$ } t = new Tracked(); synchronized (t) { context.addBundleListener(t); Bundle[] bundles = context.getBundles(); if (bundles != null) { int length = bundles.length; for (int i = 0; i < length; i++) { int state = bundles[i].getState(); if ((state & mask) == 0) { /* null out bundles whose states are not interesting */ bundles[i] = null; } } /* set tracked with the initial bundles */ t.setInitial(bundles); } } tracked = t; } /* Call tracked outside of synchronized region */ t.trackInitial(); /* process the initial references */ }
/** * Remove a bundle from this {@code BundleTracker}. * * <p>The specified bundle will be removed from this {@code BundleTracker} . If the specified * bundle was being tracked then the {@code BundleTrackerCustomizer.removedBundle} method will be * called for that bundle. * * @param bundle The {@code Bundle} to be removed. */ public void remove(Bundle bundle) { final Tracked t = tracked(); if (t == null) { /* if BundleTracker is not open */ return; } t.untrack(bundle, null); }
/** * Return if this {@code BundleTracker} is empty. * * @return {@code true} if this {@code BundleTracker} is not tracking any bundles. * @since 1.5 */ public boolean isEmpty() { final Tracked t = tracked(); if (t == null) { /* if BundleTracker is not open */ return true; } synchronized (t) { return t.isEmpty(); } }
/** * Returns the tracking count for this {@code BundleTracker}. * * <p>The tracking count is initialized to 0 when this {@code BundleTracker} is opened. Every time * a bundle is added, modified or removed from this {@code BundleTracker} the tracking count is * incremented. * * <p>The tracking count can be used to determine if this {@code BundleTracker} has added, * modified or removed a bundle by comparing a tracking count value previously collected with the * current tracking count value. If the value has not changed, then no bundle has been added, * modified or removed from this {@code BundleTracker} since the previous tracking count was * collected. * * @return The tracking count for this {@code BundleTracker} or -1 if this {@code BundleTracker} * is not open. */ public int getTrackingCount() { final Tracked t = tracked(); if (t == null) { /* if BundleTracker is not open */ return -1; } synchronized (t) { return t.getTrackingCount(); } }
/** * Return the number of bundles being tracked by this {@code BundleTracker}. * * @return The number of bundles being tracked. */ public int size() { final Tracked t = tracked(); if (t == null) { /* if BundleTracker is not open */ return 0; } synchronized (t) { return t.size(); } }
/** * Returns the customized object for the specified {@code Bundle} if the specified bundle is being * tracked by this {@code BundleTracker}. * * @param bundle The {@code Bundle} being tracked. * @return The customized object for the specified {@code Bundle} or {@code null} if the specified * {@code Bundle} is not being tracked. */ public T getObject(Bundle bundle) { final Tracked t = tracked(); if (t == null) { /* if BundleTracker is not open */ return null; } synchronized (t) { return t.getCustomizedObject(bundle); } }
/** * Return a {@code Map} with the {@code Bundle}s and customized objects for all bundles being * tracked by this {@code BundleTracker}. * * @return A {@code Map} with the {@code Bundle}s and customized objects for all services being * tracked by this {@code BundleTracker}. If no bundles are being tracked, then the returned * map is empty. * @since 1.5 */ public Map<Bundle, T> getTracked() { Map<Bundle, T> map = new HashMap<Bundle, T>(); final Tracked t = tracked(); if (t == null) { /* if BundleTracker is not open */ return map; } synchronized (t) { return t.copyEntries(map); } }
/** * Return an array of {@code Bundle}s for all bundles being tracked by this {@code BundleTracker}. * * @return An array of {@code Bundle}s or {@code null} if no bundles are being tracked. */ public Bundle[] getBundles() { final Tracked t = tracked(); if (t == null) { /* if BundleTracker is not open */ return null; } synchronized (t) { int length = t.size(); if (length == 0) { return null; } return t.copyKeys(new Bundle[length]); } }