You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ni...@apache.org on 2009/09/24 05:22:23 UTC

svn commit: r818354 - in /camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi: Activator.java tracker/AbstractTracked.java tracker/BundleTracker.java tracker/BundleTrackerCustomizer.java

Author: ningjiang
Date: Thu Sep 24 03:22:21 2009
New Revision: 818354

URL: http://svn.apache.org/viewvc?rev=818354&view=rev
Log:
Fixed the CS errors of camel-osgi

Modified:
    camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/Activator.java
    camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/tracker/AbstractTracked.java
    camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/tracker/BundleTracker.java
    camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/tracker/BundleTrackerCustomizer.java

Modified: camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/Activator.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/Activator.java?rev=818354&r1=818353&r2=818354&view=diff
==============================================================================
--- camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/Activator.java (original)
+++ camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/Activator.java Thu Sep 24 03:22:21 2009
@@ -74,26 +74,26 @@
         Set<String> converterPackages;
     }
     
-	public Object addingBundle(Bundle bundle, BundleEvent event) {
-		modifiedBundle(bundle, event, null);
-		return bundle;
-	}
+    public Object addingBundle(Bundle bundle, BundleEvent event) {
+        modifiedBundle(bundle, event, null);
+        return bundle;
+    }
 
-	public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
+    public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
         if (LOG.isDebugEnabled()) {
             LOG.debug("Bundle started: " + bundle.getSymbolicName());
         }
-        mayBeAddComponentAndLanguageFor(bundle);                
+        mayBeAddComponentAndLanguageFor(bundle);
         mayBeAddTypeConverterFor(bundle);
-	}
+    }
 
-	public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
+    public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
         if (LOG.isDebugEnabled()) {
             LOG.debug("Bundle stopped: " + bundle.getSymbolicName());
         }
-        mayBeRemoveComponentAndLanguageFor(bundle);                
+        mayBeRemoveComponentAndLanguageFor(bundle);
         mayBeRemoveTypeConverterFor(bundle);
-	}
+    }
 
     protected void addComponentEntry(String entryPath, Bundle bundle, Map<String, ComponentEntry> entries, Class clazz) {
         // Check bundle compatibility

Modified: camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/tracker/AbstractTracked.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/tracker/AbstractTracked.java?rev=818354&r1=818353&r2=818354&view=diff
==============================================================================
--- camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/tracker/AbstractTracked.java (original)
+++ camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/tracker/AbstractTracked.java Thu Sep 24 03:22:21 2009
@@ -1,3 +1,20 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 /*
  * Copyright (c) OSGi Alliance (2007, 2008). All Rights Reserved.
  * 
@@ -35,415 +52,388 @@
  * @since 1.4
  */
 abstract class AbstractTracked {
-	/* set this to true to compile in debug messages */
-	static final boolean		DEBUG	= false;
-
-	/**
-	 * Map of tracked items to customized objects.
-	 * 
-	 * @GuardedBy this
-	 */
-	private final Map			tracked;
-
-	/**
-	 * Modification count. This field is initialized to zero and incremented by
-	 * modified.
-	 * 
-	 * @GuardedBy this
-	 */
-	private int					trackingCount;
-
-	/**
-	 * List of items in the process of being added. This is used to deal with
-	 * nesting of events. Since events may be synchronously delivered, events
-	 * can be nested. For example, when processing the adding of a service and
-	 * the customizer causes the service to be unregistered, notification to the
-	 * nested call to untrack that the service was unregistered can be made to
-	 * the track method.
-	 * 
-	 * Since the ArrayList implementation is not synchronized, all access to
-	 * this list must be protected by the same synchronized object for
-	 * thread-safety.
-	 * 
-	 * @GuardedBy this
-	 */
-	private final List			adding;
-
-	/**
-	 * true if the tracked object is closed.
-	 * 
-	 * This field is volatile because it is set by one thread and read by
-	 * another.
-	 */
-	volatile boolean			closed;
-
-	/**
-	 * Initial list of items for the tracker. This is used to correctly process
-	 * the initial items which could be modified before they are tracked. This
-	 * is necessary since the initial set of tracked items are not "announced"
-	 * by events and therefore the event which makes the item untracked could be
-	 * delivered before we track the item.
-	 * 
-	 * An item must not be in both the initial and adding lists at the same
-	 * time. An item must be moved from the initial list to the adding list
-	 * "atomically" before we begin tracking it.
-	 * 
-	 * Since the LinkedList implementation is not synchronized, all access to
-	 * this list must be protected by the same synchronized object for
-	 * thread-safety.
-	 * 
-	 * @GuardedBy this
-	 */
-	private final LinkedList	initial;
-
-	/**
-	 * AbstractTracked constructor.
-	 */
-	AbstractTracked() {
-		tracked = new HashMap();
-		trackingCount = 0;
-		adding = new ArrayList(6);
-		initial = new LinkedList();
-		closed = false;
-	}
-
-	/**
-	 * Set initial list of items into tracker before events begin to be
-	 * received.
-	 * 
-	 * This method must be called from Tracker's open method while synchronized
-	 * on this object in the same synchronized block as the add listener call.
-	 * 
-	 * @param list The initial list of items to be tracked. <code>null</code>
-	 *        entries in the list are ignored.
-	 * @GuardedBy this
-	 */
-	void setInitial(Object[] list) {
-		if (list == null) {
-			return;
-		}
-		int size = list.length;
-		for (int i = 0; i < size; i++) {
-			Object item = list[i];
-			if (item == null) {
-				continue;
-			}
-			if (DEBUG) {
-				System.out.println("AbstractTracked.setInitial: " + item); //$NON-NLS-1$
-			}
-			initial.add(item);
-		}
-	}
-
-	/**
-	 * Track the initial list of items. This is called after events can begin to
-	 * be received.
-	 * 
-	 * This method must be called from Tracker's open method while not
-	 * synchronized on this object after the add listener call.
-	 * 
-	 */
-	void trackInitial() {
-		while (true) {
-			Object item;
-			synchronized (this) {
-				if (closed || (initial.size() == 0)) {
-					/*
-					 * if there are no more initial items
-					 */
-					return; /* we are done */
-				}
-				/*
-				 * move the first item from the initial list to the adding list
-				 * within this synchronized block.
-				 */
-				item = initial.removeFirst();
-				if (tracked.get(item) != null) {
-					/* if we are already tracking this item */
-					if (DEBUG) {
-						System.out
-								.println("AbstractTracked.trackInitial[already tracked]: " + item); //$NON-NLS-1$
-					}
-					continue; /* skip this item */
-				}
-				if (adding.contains(item)) {
-					/*
-					 * if this item is already in the process of being added.
-					 */
-					if (DEBUG) {
-						System.out
-								.println("AbstractTracked.trackInitial[already adding]: " + item); //$NON-NLS-1$
-					}
-					continue; /* skip this item */
-				}
-				adding.add(item);
-			}
-			if (DEBUG) {
-				System.out.println("AbstractTracked.trackInitial: " + item); //$NON-NLS-1$
-			}
-			trackAdding(item, null); /*
-									 * Begin tracking it. We call trackAdding
-									 * since we have already put the item in the
-									 * adding list.
-									 */
-		}
-	}
-
-	/**
-	 * Called by the owning Tracker object when it is closed.
-	 */
-	void close() {
-		closed = true;
-	}
-
-	/**
-	 * Begin to track an item.
-	 * 
-	 * @param item Item to be tracked.
-	 * @param related Action related object.
-	 */
-	void track(final Object item, final Object related) {
-		final Object object;
-		synchronized (this) {
-			if (closed) {
-				return;
-			}
-			object = tracked.get(item);
-			if (object == null) { /* we are not tracking the item */
-				if (adding.contains(item)) {
-					/* if this item is already in the process of being added. */
-					if (DEBUG) {
-						System.out
-								.println("AbstractTracked.track[already adding]: " + item); //$NON-NLS-1$
-					}
-					return;
-				}
-				adding.add(item); /* mark this item is being added */
-			}
-			else { /* we are currently tracking this item */
-				if (DEBUG) {
-					System.out
-							.println("AbstractTracked.track[modified]: " + item); //$NON-NLS-1$
-				}
-				modified(); /* increment modification count */
-			}
-		}
-
-		if (object == null) { /* we are not tracking the item */
-			trackAdding(item, related);
-		}
-		else {
-			/* Call customizer outside of synchronized region */
-			customizerModified(item, related, object);
-			/*
-			 * If the customizer throws an unchecked exception, it is safe to
-			 * let it propagate
-			 */
-		}
-	}
-
-	/**
-	 * Common logic to add an item to the tracker used by track and
-	 * trackInitial. The specified item must have been placed in the adding list
-	 * before calling this method.
-	 * 
-	 * @param item Item to be tracked.
-	 * @param related Action related object.
-	 */
-	private void trackAdding(final Object item, final Object related) {
-		if (DEBUG) {
-			System.out.println("AbstractTracked.trackAdding: " + item); //$NON-NLS-1$
-		}
-		Object object = null;
-		boolean becameUntracked = false;
-		/* Call customizer outside of synchronized region */
-		try {
-			object = customizerAdding(item, related);
-			/*
-			 * If the customizer throws an unchecked exception, it will
-			 * propagate after the finally
-			 */
-		}
-		finally {
-			synchronized (this) {
-				if (adding.remove(item) && !closed) {
-					/*
-					 * if the item was not untracked during the customizer
-					 * callback
-					 */
-					if (object != null) {
-						tracked.put(item, object);
-						modified(); /* increment modification count */
-						notifyAll(); /* notify any waiters */
-					}
-				}
-				else {
-					becameUntracked = true;
-				}
-			}
-		}
-		/*
-		 * The item became untracked during the customizer callback.
-		 */
-		if (becameUntracked && (object != null)) {
-			if (DEBUG) {
-				System.out
-						.println("AbstractTracked.trackAdding[removed]: " + item); //$NON-NLS-1$
-			}
-			/* Call customizer outside of synchronized region */
-			customizerRemoved(item, related, object);
-			/*
-			 * If the customizer throws an unchecked exception, it is safe to
-			 * let it propagate
-			 */
-		}
-	}
-
-	/**
-	 * Discontinue tracking the item.
-	 * 
-	 * @param item Item to be untracked.
-	 * @param related Action related object.
-	 */
-	void untrack(final Object item, final Object related) {
-		final Object object;
-		synchronized (this) {
-			if (initial.remove(item)) { /*
-										 * if this item is already in the list
-										 * of initial references to process
-										 */
-				if (DEBUG) {
-					System.out
-							.println("AbstractTracked.untrack[removed from initial]: " + item); //$NON-NLS-1$
-				}
-				return; /*
-						 * we have removed it from the list and it will not be
-						 * processed
-						 */
-			}
-
-			if (adding.remove(item)) { /*
-										 * if the item is in the process of
-										 * being added
-										 */
-				if (DEBUG) {
-					System.out
-							.println("AbstractTracked.untrack[being added]: " + item); //$NON-NLS-1$
-				}
-				return; /*
-						 * in case the item is untracked while in the process of
-						 * adding
-						 */
-			}
-			object = tracked.remove(item); /*
-											 * must remove from tracker before
-											 * calling customizer callback
-											 */
-			if (object == null) { /* are we actually tracking the item */
-				return;
-			}
-			modified(); /* increment modification count */
-		}
-		if (DEBUG) {
-			System.out.println("AbstractTracked.untrack[removed]: " + item); //$NON-NLS-1$
-		}
-		/* Call customizer outside of synchronized region */
-		customizerRemoved(item, related, object);
-		/*
-		 * If the customizer throws an unchecked exception, it is safe to let it
-		 * propagate
-		 */
-	}
-
-	/**
-	 * Returns the number of tracked items.
-	 * 
-	 * @return The number of tracked items.
-	 * 
-	 * @GuardedBy this
-	 */
-	int size() {
-		return tracked.size();
-	}
-
-	/**
-	 * Return the customized object for the specified item
-	 * 
-	 * @param item The item to lookup in the map
-	 * @return The customized object for the specified item.
-	 * 
-	 * @GuardedBy this
-	 */
-	Object getCustomizedObject(final Object item) {
-		return tracked.get(item);
-	}
-
-	/**
-	 * Return the list of tracked items.
-	 * 
-	 * @param list An array to contain the tracked items.
-	 * @return The specified list if it is large enough to hold the tracked
-	 *         items or a new array large enough to hold the tracked items.
-	 * @GuardedBy this
-	 */
-	Object[] getTracked(final Object[] list) {
-		return tracked.keySet().toArray(list);
-	}
-
-	/**
-	 * Increment the modification count. If this method is overridden, the
-	 * overriding method MUST call this method to increment the tracking count.
-	 * 
-	 * @GuardedBy this
-	 */
-	void modified() {
-		trackingCount++;
-	}
-
-	/**
-	 * Returns the tracking count for this <code>ServiceTracker</code> object.
-	 * 
-	 * The tracking count is initialized to 0 when this object is opened. Every
-	 * time an item is added, modified or removed from this object the tracking
-	 * count is incremented.
-	 * 
-	 * @GuardedBy this
-	 * @return The tracking count for this object.
-	 */
-	int getTrackingCount() {
-		return trackingCount;
-	}
-
-	/**
-	 * 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.
-	 */
-	abstract Object customizerAdding(final Object item, final Object related);
-
-	/**
-	 * 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.
-	 */
-	abstract void customizerModified(final Object item, final Object related,
-			final Object 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.
-	 */
-	abstract void customizerRemoved(final Object item, final Object related,
-			final Object object);
+    /* set this to true to compile in debug messages */
+    static final boolean DEBUG = false;
+    
+    /**
+     * true if the tracked object is closed. This field is volatile because it
+     * is set by one thread and read by another.
+     */
+    volatile boolean closed;
+
+    /**
+     * Map of tracked items to customized objects.
+     * 
+     * @GuardedBy this
+     */
+    private final Map tracked;
+
+    /**
+     * Modification count. This field is initialized to zero and incremented by
+     * modified.
+     * 
+     * @GuardedBy this
+     */
+    private int trackingCount;
+
+    /**
+     * List of items in the process of being added. This is used to deal with
+     * nesting of events. Since events may be synchronously delivered, events
+     * can be nested. For example, when processing the adding of a service and
+     * the customizer causes the service to be unregistered, notification to the
+     * nested call to untrack that the service was unregistered can be made to
+     * the track method. Since the ArrayList implementation is not synchronized,
+     * all access to this list must be protected by the same synchronized object
+     * for thread-safety.
+     * 
+     * @GuardedBy this
+     */
+    private final List adding;    
+
+    /**
+     * Initial list of items for the tracker. This is used to correctly process
+     * the initial items which could be modified before they are tracked. This
+     * is necessary since the initial set of tracked items are not "announced"
+     * by events and therefore the event which makes the item untracked could be
+     * delivered before we track the item. An item must not be in both the
+     * initial and adding lists at the same time. An item must be moved from the
+     * initial list to the adding list "atomically" before we begin tracking it.
+     * Since the LinkedList implementation is not synchronized, all access to
+     * this list must be protected by the same synchronized object for
+     * thread-safety.
+     * 
+     * @GuardedBy this
+     */
+    private final LinkedList initial;
+
+    /**
+     * AbstractTracked constructor.
+     */
+    AbstractTracked() {
+        tracked = new HashMap();
+        trackingCount = 0;
+        adding = new ArrayList(6);
+        initial = new LinkedList();
+        closed = false;
+    }
+
+    /**
+     * Set initial list of items into tracker before events begin to be
+     * received. This method must be called from Tracker's open method while
+     * synchronized on this object in the same synchronized block as the add
+     * listener call.
+     * 
+     * @param list The initial list of items to be tracked. <code>null</code>
+     *            entries in the list are ignored.
+     * @GuardedBy this
+     */
+    void setInitial(Object[] list) {
+        if (list == null) {
+            return;
+        }
+        int size = list.length;
+        for (int i = 0; i < size; i++) {
+            Object item = list[i];
+            if (item == null) {
+                continue;
+            }
+            if (DEBUG) {
+                System.out.println("AbstractTracked.setInitial: " + item); //$NON-NLS-1$
+            }
+            initial.add(item);
+        }
+    }
+
+    /**
+     * Track the initial list of items. This is called after events can begin to
+     * be received. This method must be called from Tracker's open method while
+     * not synchronized on this object after the add listener call.
+     */
+    void trackInitial() {
+        while (true) {
+            Object item;
+            synchronized (this) {
+                if (closed || (initial.size() == 0)) {
+                    /*
+                     * if there are no more initial items
+                     */
+                    return; /* we are done */
+                }
+                /*
+                 * move the first item from the initial list to the adding list
+                 * within this synchronized block.
+                 */
+                item = initial.removeFirst();
+                if (tracked.get(item) != null) {
+                    /* if we are already tracking this item */
+                    if (DEBUG) {
+                        System.out.println("AbstractTracked.trackInitial[already tracked]: " + item); //$NON-NLS-1$
+                    }
+                    continue; /* skip this item */
+                }
+                if (adding.contains(item)) {
+                    /*
+                     * if this item is already in the process of being added.
+                     */
+                    if (DEBUG) {
+                        System.out.println("AbstractTracked.trackInitial[already adding]: " + item); //$NON-NLS-1$
+                    }
+                    continue; /* skip this item */
+                }
+                adding.add(item);
+            }
+            if (DEBUG) {
+                System.out.println("AbstractTracked.trackInitial: " + item); //$NON-NLS-1$
+            }
+            trackAdding(item, null); /*
+                                      * Begin tracking it. We call trackAdding
+                                      * since we have already put the item in
+                                      * the adding list.
+                                      */
+        }
+    }
+
+    /**
+     * Called by the owning Tracker object when it is closed.
+     */
+    void close() {
+        closed = true;
+    }
+
+    /**
+     * Begin to track an item.
+     * 
+     * @param item Item to be tracked.
+     * @param related Action related object.
+     */
+    void track(final Object item, final Object related) {
+        final Object object;
+        synchronized (this) {
+            if (closed) {
+                return;
+            }
+            object = tracked.get(item);
+            if (object == null) { /* we are not tracking the item */
+                if (adding.contains(item)) {
+                    /* if this item is already in the process of being added. */
+                    if (DEBUG) {
+                        System.out.println("AbstractTracked.track[already adding]: " + item); //$NON-NLS-1$
+                    }
+                    return;
+                }
+                adding.add(item); /* mark this item is being added */
+            } else { /* we are currently tracking this item */
+                if (DEBUG) {
+                    System.out.println("AbstractTracked.track[modified]: " + item); //$NON-NLS-1$
+                }
+                modified(); /* increment modification count */
+            }
+        }
+
+        if (object == null) { /* we are not tracking the item */
+            trackAdding(item, related);
+        } else {
+            /* Call customizer outside of synchronized region */
+            customizerModified(item, related, object);
+            /*
+             * If the customizer throws an unchecked exception, it is safe to
+             * let it propagate
+             */
+        }
+    }
+
+    /**
+     * Common logic to add an item to the tracker used by track and
+     * trackInitial. The specified item must have been placed in the adding list
+     * before calling this method.
+     * 
+     * @param item Item to be tracked.
+     * @param related Action related object.
+     */
+    private void trackAdding(final Object item, final Object related) {
+        if (DEBUG) {
+            System.out.println("AbstractTracked.trackAdding: " + item); //$NON-NLS-1$
+        }
+        Object object = null;
+        boolean becameUntracked = false;
+        /* Call customizer outside of synchronized region */
+        try {
+            object = customizerAdding(item, related);
+            /*
+             * If the customizer throws an unchecked exception, it will
+             * propagate after the finally
+             */
+        } finally {
+            synchronized (this) {
+                if (adding.remove(item) && !closed) {
+                    /*
+                     * if the item was not untracked during the customizer
+                     * callback
+                     */
+                    if (object != null) {
+                        tracked.put(item, object);
+                        modified(); /* increment modification count */
+                        notifyAll(); /* notify any waiters */
+                    }
+                } else {
+                    becameUntracked = true;
+                }
+            }
+        }
+        /*
+         * The item became untracked during the customizer callback.
+         */
+        if (becameUntracked && (object != null)) {
+            if (DEBUG) {
+                System.out.println("AbstractTracked.trackAdding[removed]: " + item); //$NON-NLS-1$
+            }
+            /* Call customizer outside of synchronized region */
+            customizerRemoved(item, related, object);
+            /*
+             * If the customizer throws an unchecked exception, it is safe to
+             * let it propagate
+             */
+        }
+    }
+
+    /**
+     * Discontinue tracking the item.
+     * 
+     * @param item Item to be untracked.
+     * @param related Action related object.
+     */
+    void untrack(final Object item, final Object related) {
+        final Object object;
+        synchronized (this) {
+            if (initial.remove(item)) { /*
+                                         * if this item is already in the list
+                                         * of initial references to process
+                                         */
+                if (DEBUG) {
+                    System.out.println("AbstractTracked.untrack[removed from initial]: " + item); //$NON-NLS-1$
+                }
+                return; /*
+                         * we have removed it from the list and it will not be
+                         * processed
+                         */
+            }
+
+            if (adding.remove(item)) { /*
+                                        * if the item is in the process of being
+                                        * added
+                                        */
+                if (DEBUG) {
+                    System.out.println("AbstractTracked.untrack[being added]: " + item); //$NON-NLS-1$
+                }
+                return; /*
+                         * in case the item is untracked while in the process of
+                         * adding
+                         */
+            }
+            object = tracked.remove(item); /*
+                                            * must remove from tracker before
+                                            * calling customizer callback
+                                            */
+            if (object == null) { /* are we actually tracking the item */
+                return;
+            }
+            modified(); /* increment modification count */
+        }
+        if (DEBUG) {
+            System.out.println("AbstractTracked.untrack[removed]: " + item); //$NON-NLS-1$
+        }
+        /* Call customizer outside of synchronized region */
+        customizerRemoved(item, related, object);
+        /*
+         * If the customizer throws an unchecked exception, it is safe to let it
+         * propagate
+         */
+    }
+
+    /**
+     * Returns the number of tracked items.
+     * 
+     * @return The number of tracked items.
+     * @GuardedBy this
+     */
+    int size() {
+        return tracked.size();
+    }
+
+    /**
+     * Return the customized object for the specified item
+     * 
+     * @param item The item to lookup in the map
+     * @return The customized object for the specified item.
+     * @GuardedBy this
+     */
+    Object getCustomizedObject(final Object item) {
+        return tracked.get(item);
+    }
+
+    /**
+     * Return the list of tracked items.
+     * 
+     * @param list An array to contain the tracked items.
+     * @return The specified list if it is large enough to hold the tracked
+     *         items or a new array large enough to hold the tracked items.
+     * @GuardedBy this
+     */
+    Object[] getTracked(final Object[] list) {
+        return tracked.keySet().toArray(list);
+    }
+
+    /**
+     * Increment the modification count. If this method is overridden, the
+     * overriding method MUST call this method to increment the tracking count.
+     * 
+     * @GuardedBy this
+     */
+    void modified() {
+        trackingCount++;
+    }
+
+    /**
+     * Returns the tracking count for this <code>ServiceTracker</code> object.
+     * The tracking count is initialized to 0 when this object is opened. Every
+     * time an item is added, modified or removed from this object the tracking
+     * count is incremented.
+     * 
+     * @GuardedBy this
+     * @return The tracking count for this object.
+     */
+    int getTrackingCount() {
+        return trackingCount;
+    }
+
+    /**
+     * 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.
+     */
+    abstract Object customizerAdding(final Object item, final Object related);
+
+    /**
+     * 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.
+     */
+    abstract void customizerModified(final Object item, final Object related, final Object 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.
+     */
+    abstract void customizerRemoved(final Object item, final Object related, final Object object);
 }

Modified: camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/tracker/BundleTracker.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/tracker/BundleTracker.java?rev=818354&r1=818353&r2=818354&view=diff
==============================================================================
--- camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/tracker/BundleTracker.java (original)
+++ camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/tracker/BundleTracker.java Thu Sep 24 03:22:21 2009
@@ -1,3 +1,20 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 /*
  * Copyright (c) OSGi Alliance (2007, 2008). All Rights Reserved.
  * 
@@ -47,425 +64,401 @@
  * @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;
-	}
-
-	/**
-	 * 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);
-		}
-
-		/**
-		 * 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);
-		}
-	}
+    /* 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;
+    
+    /**
+     * State mask for bundles being tracked. This field contains the ORed values
+     * of the bundle states being tracked.
+     */
+    final int mask;
+    
+    /**
+     * 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;
+
+    /**
+     * 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;
+    }
+    
+    /**
+     * 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;
+    }
+
+
+    /**
+     * 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;
+    }
+
+    /**
+     * 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);
+        }
+
+        /**
+         * 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);
+        }
+    }
 }

Modified: camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/tracker/BundleTrackerCustomizer.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/tracker/BundleTrackerCustomizer.java?rev=818354&r1=818353&r2=818354&view=diff
==============================================================================
--- camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/tracker/BundleTrackerCustomizer.java (original)
+++ camel/trunk/components/camel-osgi/src/main/java/org/apache/camel/osgi/tracker/BundleTrackerCustomizer.java Thu Sep 24 03:22:21 2009
@@ -1,3 +1,20 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
 /*
  * Copyright (c) OSGi Alliance (2007, 2008). All Rights Reserved.
  * 
@@ -48,57 +65,52 @@
  * @since 1.4
  */
 public interface BundleTrackerCustomizer {
-	/**
-	 * A bundle is being added to the <code>BundleTracker</code>.
-	 * 
-	 * <p>
-	 * This method is called before a bundle which matched the search parameters
-	 * of the <code>BundleTracker</code> is added to the
-	 * <code>BundleTracker</code>. This method should return the object to be
-	 * tracked for the specified <code>Bundle</code>. The returned object is
-	 * stored in the <code>BundleTracker</code> and is available from the
-	 * {@link BundleTracker#getObject(Bundle) getObject} method.
-	 * 
-	 * @param bundle The <code>Bundle</code> being added to the
-	 *        <code>BundleTracker</code>.
-	 * @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 object to be tracked for the specified <code>Bundle</code>
-	 *         object or <code>null</code> if the specified <code>Bundle</code>
-	 *         object should not be tracked.
-	 */
-	public Object addingBundle(Bundle bundle, BundleEvent event);
-
-	/**
-	 * A bundle tracked by the <code>BundleTracker</code> has been modified.
-	 * 
-	 * <p>
-	 * This method is called when a bundle being tracked by the
-	 * <code>BundleTracker</code> has had its state modified.
-	 * 
-	 * @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 tracked object for the specified bundle.
-	 */
-	public void modifiedBundle(Bundle bundle, BundleEvent event,
-			Object object);
-
-	/**
-	 * A bundle tracked by the <code>BundleTracker</code> has been removed.
-	 * 
-	 * <p>
-	 * This method is called after a bundle is no longer being tracked by the
-	 * <code>BundleTracker</code>.
-	 * 
-	 * @param bundle The <code>Bundle</code> that has been 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 tracked object for the specified bundle.
-	 */
-	public void removedBundle(Bundle bundle, BundleEvent event,
-			Object object);
+    /**
+     * A bundle is being added to the <code>BundleTracker</code>.
+     * <p>
+     * This method is called before a bundle which matched the search parameters
+     * of the <code>BundleTracker</code> is added to the
+     * <code>BundleTracker</code>. This method should return the object to be
+     * tracked for the specified <code>Bundle</code>. The returned object is
+     * stored in the <code>BundleTracker</code> and is available from the
+     * {@link BundleTracker#getObject(Bundle) getObject} method.
+     * 
+     * @param bundle The <code>Bundle</code> being added to the
+     *            <code>BundleTracker</code>.
+     * @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 object to be tracked for the specified <code>Bundle</code>
+     *         object or <code>null</code> if the specified <code>Bundle</code>
+     *         object should not be tracked.
+     */
+    Object addingBundle(Bundle bundle, BundleEvent event);
+
+    /**
+     * A bundle tracked by the <code>BundleTracker</code> has been modified.
+     * <p>
+     * This method is called when a bundle being tracked by the
+     * <code>BundleTracker</code> has had its state modified.
+     * 
+     * @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 tracked object for the specified bundle.
+     */
+    void modifiedBundle(Bundle bundle, BundleEvent event, Object object);
+
+    /**
+     * A bundle tracked by the <code>BundleTracker</code> has been removed.
+     * <p>
+     * This method is called after a bundle is no longer being tracked by the
+     * <code>BundleTracker</code>.
+     * 
+     * @param bundle The <code>Bundle</code> that has been 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 tracked object for the specified bundle.
+     */
+    void removedBundle(Bundle bundle, BundleEvent event, Object object);
 }