package org.apache.felix.dm.tracker;
/*
 * Copyright (c) OSGi Alliance (2007, 2008). 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.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.SynchronousBundleListener;

/**
 * The <code>BundleTracker</code> class simplifies tracking bundles much like
 * the <code>ServiceTracker</code> simplifies tracking services.
 * <p>
 * A <code>BundleTracker</code> is constructed with state criteria and a
 * <code>BundleTrackerCustomizer</code> object. A <code>BundleTracker</code> can
 * use the <code>BundleTrackerCustomizer</code> to select which bundles are
 * tracked and to create a customized object to be tracked with the bundle. The
 * <code>BundleTracker</code> can then be opened to begin tracking all bundles
 * whose state matches the specified state criteria.
 * <p>
 * The <code>getBundles</code> method can be called to get the
 * <code>Bundle</code> objects of the bundles being tracked. The
 * <code>getObject</code> method can be called to get the customized object for
 * a tracked bundle.
 * <p>
 * The <code>BundleTracker</code> class is thread-safe. It does not call a
 * <code>BundleTrackerCustomizer</code> while holding any locks.
 * <code>BundleTrackerCustomizer</code> implementations must also be
 * thread-safe.
 * 
 * @ThreadSafe
 * @version $Revision: 5894 $
 * @since 1.4
 */
public class BundleTracker implements BundleTrackerCustomizer {
	/* set this to true to compile in debug messages */
	static final boolean			DEBUG	= false;

	/**
	 * The Bundle Context used by this <code>BundleTracker</code>.
	 */
	protected final BundleContext	context;

	/**
	 * The <code>BundleTrackerCustomizer</code> object for this tracker.
	 */
	final BundleTrackerCustomizer	customizer;

	/**
	 * Tracked bundles: <code>Bundle</code> object -> customized Object and
	 * <code>BundleListener</code> object
	 */
	private volatile Tracked		tracked;

	/**
	 * Accessor method for the current Tracked object. This method is only
	 * intended to be used by the unsynchronized methods which do not modify the
	 * tracked field.
	 * 
	 * @return The current Tracked object.
	 */
	private Tracked tracked() {
		return tracked;
	}

	/**
	 * State mask for bundles being tracked. This field contains the ORed values
	 * of the bundle states being tracked.
	 */
	final int						mask;

	/**
	 * Create a <code>BundleTracker</code> for bundles whose state is present in
	 * the specified state mask.
	 * 
	 * <p>
	 * Bundles whose state is present on the specified state mask will be
	 * tracked by this <code>BundleTracker</code>.
	 * 
	 * @param context The <code>BundleContext</code> against which the tracking
	 *        is done.
	 * @param stateMask The bit mask of the <code>OR</code>ing of the bundle
	 *        states to be tracked.
	 * @param customizer The customizer object to call when bundles are added,
	 *        modified, or removed in this <code>BundleTracker</code>. If
	 *        customizer is <code>null</code>, then this
	 *        <code>BundleTracker</code> will be used as the
	 *        <code>BundleTrackerCustomizer</code> and this
	 *        <code>BundleTracker</code> will call the
	 *        <code>BundleTrackerCustomizer</code> methods on itself.
	 * @see Bundle#getState()
	 */
	public BundleTracker(BundleContext context, int stateMask,
			BundleTrackerCustomizer customizer) {
		this.context = context;
		this.mask = stateMask;
		this.customizer = (customizer == null) ? this : customizer;
	}

	/**
	 * Open this <code>BundleTracker</code> and begin tracking bundles.
	 * 
	 * <p>
	 * Bundle which match the state criteria specified when this
	 * <code>BundleTracker</code> was created are now tracked by this
	 * <code>BundleTracker</code>.
	 * 
	 * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
	 *         with which this <code>BundleTracker</code> 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]</code>, 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 */
	}

	/**
	 * Close this <code>BundleTracker</code>.
	 * 
	 * <p>
	 * This method should be called when this <code>BundleTracker</code> 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);
			}
		}
	}

	/**
	 * Default implementation of the
	 * <code>BundleTrackerCustomizer.addingBundle</code> method.
	 * 
	 * <p>
	 * This method is only called when this <code>BundleTracker</code> has been
	 * constructed with a <code>null BundleTrackerCustomizer</code> argument.
	 * 
	 * <p>
	 * This implementation simply returns the specified <code>Bundle</code>.
	 * 
	 * <p>
	 * This method can be overridden in a subclass to customize the object to be
	 * tracked for the bundle being added.
	 * 
	 * @param bundle The <code>Bundle</code> being added to this
	 *        <code>BundleTracker</code> object.
	 * @param event The bundle event which caused this customizer method to be
	 *        called or <code>null</code> if there is no bundle event associated
	 *        with the call to this method.
	 * @return The specified bundle.
	 * @see BundleTrackerCustomizer#addingBundle(Bundle, BundleEvent)
	 */
	public Object addingBundle(Bundle bundle, BundleEvent event) {
		return bundle;
	}
	
	public void addedBundle(Bundle bundle, BundleEvent event, Object object) {
		/* do nothing */
	}

	/**
	 * Default implementation of the
	 * <code>BundleTrackerCustomizer.modifiedBundle</code> method.
	 * 
	 * <p>
	 * This method is only called when this <code>BundleTracker</code> has been
	 * constructed with a <code>null BundleTrackerCustomizer</code> argument.
	 * 
	 * <p>
	 * This implementation does nothing.
	 * 
	 * @param bundle The <code>Bundle</code> whose state has been modified.
	 * @param event The bundle event which caused this customizer method to be
	 *        called or <code>null</code> if there is no bundle event associated
	 *        with the call to this method.
	 * @param object The customized object for the specified Bundle.
	 * @see BundleTrackerCustomizer#modifiedBundle(Bundle, BundleEvent, Object)
	 */
	public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
		/* do nothing */
	}

	/**
	 * Default implementation of the
	 * <code>BundleTrackerCustomizer.removedBundle</code> method.
	 * 
	 * <p>
	 * This method is only called when this <code>BundleTracker</code> has been
	 * constructed with a <code>null BundleTrackerCustomizer</code> argument.
	 * 
	 * <p>
	 * This implementation does nothing.
	 * 
	 * @param bundle The <code>Bundle</code> being removed.
	 * @param event The bundle event which caused this customizer method to be
	 *        called or <code>null</code> if there is no bundle event associated
	 *        with the call to this method.
	 * @param object The customized object for the specified bundle.
	 * @see BundleTrackerCustomizer#removedBundle(Bundle, BundleEvent, Object)
	 */
	public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
		/* do nothing */
	}

	/**
	 * Return an array of <code>Bundle</code>s for all bundles being tracked by
	 * this <code>BundleTracker</code>.
	 * 
	 * @return An array of <code>Bundle</code>s or <code>null</code> 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 (Bundle[]) t.getTracked(new Bundle[length]);
		}
	}

	/**
	 * Returns the customized object for the specified <code>Bundle</code> if
	 * the specified bundle is being tracked by this <code>BundleTracker</code>.
	 * 
	 * @param bundle The <code>Bundle</code> being tracked.
	 * @return The customized object for the specified <code>Bundle</code> or
	 *         <code>null</code> if the specified <code>Bundle</code> is not
	 *         being tracked.
	 */
	public Object getObject(Bundle bundle) {
		final Tracked t = tracked();
		if (t == null) { /* if BundleTracker is not open */
			return null;
		}
		synchronized (t) {
			return t.getCustomizedObject(bundle);
		}
	}

	/**
	 * Remove a bundle from this <code>BundleTracker</code>.
	 * 
	 * The specified bundle will be removed from this <code>BundleTracker</code>
	 * . If the specified bundle was being tracked then the
	 * <code>BundleTrackerCustomizer.removedBundle</code> method will be called
	 * for that bundle.
	 * 
	 * @param bundle The <code>Bundle</code> 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 the number of bundles being tracked by this
	 * <code>BundleTracker</code>.
	 * 
	 * @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 tracking count for this <code>BundleTracker</code>.
	 * 
	 * The tracking count is initialized to 0 when this
	 * <code>BundleTracker</code> is opened. Every time a bundle is added,
	 * modified or removed from this <code>BundleTracker</code> the tracking
	 * count is incremented.
	 * 
	 * <p>
	 * The tracking count can be used to determine if this
	 * <code>BundleTracker</code> 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</code>
	 * since the previous tracking count was collected.
	 * 
	 * @return The tracking count for this <code>BundleTracker</code> or -1 if
	 *         this <code>BundleTracker</code> 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();
		}
	}

	/**
	 * Inner class which subclasses AbstractTracked. This class is the
	 * <code>SynchronousBundleListener</code> object for the tracker.
	 * 
	 * @ThreadSafe
	 * @since 1.4
	 */
	class Tracked extends AbstractTracked implements SynchronousBundleListener {
		/**
		 * Tracked constructor.
		 */
		Tracked() {
			super();
		}

		/**
		 * <code>BundleListener</code> method for the <code>BundleTracker</code>
		 * class. This method must NOT be synchronized to avoid deadlock
		 * potential.
		 * 
		 * @param event <code>BundleEvent</code> object from the framework.
		 */
		public void bundleChanged(final BundleEvent event) {
			/*
			 * Check if we had a delayed call (which could happen when we
			 * close).
			 */
			if (closed) {
				return;
			}
			final Bundle bundle = event.getBundle();
			final int state = bundle.getState();
			if (DEBUG) {
				System.out
						.println("BundleTracker.Tracked.bundleChanged[" + state + "]: " + bundle); //$NON-NLS-1$ //$NON-NLS-2$
			}

			if ((state & mask) != 0) {
				track(bundle, event);
				/*
				 * If the customizer throws an unchecked exception, it is safe
				 * to let it propagate
				 */
			}
			else {
				untrack(bundle, event);
				/*
				 * If the customizer throws an unchecked exception, it is safe
				 * to let it propagate
				 */
			}
		}

		/**
		 * Call the specific customizer adding method. This method must not be
		 * called while synchronized on this object.
		 * 
		 * @param item Item to be tracked.
		 * @param related Action related object.
		 * @return Customized object for the tracked item or <code>null</code>
		 *         if the item is not to be tracked.
		 */
		Object customizerAdding(final Object item,
				final Object related) {
			return customizer
					.addingBundle((Bundle) item, (BundleEvent) related);
		}
		
		void customizerAdded(final Object item, final Object related, final Object object) {
			customizer.addedBundle((Bundle) item, (BundleEvent) related, object);
		}

		/**
		 * Call the specific customizer modified method. This method must not be
		 * called while synchronized on this object.
		 * 
		 * @param item Tracked item.
		 * @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.modifiedBundle((Bundle) item, (BundleEvent) related,
					object);
		}

		/**
		 * Call the specific customizer removed method. This method must not be
		 * called while synchronized on this object.
		 * 
		 * @param item Tracked item.
		 * @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.removedBundle((Bundle) item, (BundleEvent) related,
					object);
		}

		@Override
		AbstractCustomizerActionSet createCustomizerActionSet() {
			return new AbstractCustomizerActionSet() {
				
				@Override
				public void addCustomizerAdded(Object item, Object related, Object object) {
					customizerAdded(item, related, object);
				}

				@Override
				public void addCustomizerModified(Object item, Object related,
						Object object) {
					customizerModified(item, related, object);
				}
				@Override
				public void addCustomizerRemoved(Object item, Object related,
						Object object) {
					customizerRemoved(item, related, object);
				}
						
				@Override
				void execute() {
					// nothing to be done here, since this actionSet executes the actions immediately.
				}
			};
		}
	}
}
