FELIX-3511 - Use java.concurrent from Java 6

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1612809 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/handler/EventHandlerProxy.java b/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/handler/EventHandlerProxy.java
index 158f9b9..3f00e50 100644
--- a/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/handler/EventHandlerProxy.java
+++ b/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/handler/EventHandlerProxy.java
@@ -43,7 +43,7 @@
 public class EventHandlerProxy {
 
     /** The service reference for the event handler. */
-    private final ServiceReference reference;
+    private final ServiceReference<EventHandler> reference;
 
     /** The handler context. */
     private final EventHandlerTracker.HandlerContext handlerContext;
@@ -73,7 +73,7 @@
      * @param reference Reference to the EventHandler
      */
     public EventHandlerProxy(final EventHandlerTracker.HandlerContext context,
-                    final ServiceReference reference)
+                    final ServiceReference<EventHandler> reference)
     {
         this.handlerContext = context;
         this.reference = reference;
@@ -283,7 +283,7 @@
         {
             try
             {
-                this.handler = (EventHandler)this.handlerContext.bundleContext.getService(this.reference);
+                this.handler = this.handlerContext.bundleContext.getService(this.reference);
                 if ( this.handler != null )
                 {
                     this.checkTimeout(this.handler.getClass().getName());
diff --git a/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/handler/EventHandlerTracker.java b/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/handler/EventHandlerTracker.java
index 38205de..cf76a7c 100644
--- a/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/handler/EventHandlerTracker.java
+++ b/eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/handler/EventHandlerTracker.java
@@ -18,13 +18,13 @@
  */
 package org.apache.felix.eventadmin.impl.handler;
 
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
@@ -40,17 +40,17 @@
 public class EventHandlerTracker extends ServiceTracker<EventHandler, EventHandlerProxy> {
 
     /** The proxies in this list match all events. */
-	private volatile List<EventHandlerProxy> matchingAllEvents;
+	private final List<EventHandlerProxy> matchingAllEvents;
 
     /** This is a map for exact topic matches. The key is the topic,
      * the value is a list of proxies.
      */
-    private volatile Map<String, List<EventHandlerProxy>> matchingTopic;
+    private final Map<String, List<EventHandlerProxy>> matchingTopic;
 
 	/** This is a map for wildcard topics. The key is the prefix of the topic,
 	 * the value is a list of proxies
 	 */
-	private volatile Map<String, List<EventHandlerProxy>> matchingPrefixTopic;
+	private final Map<String, List<EventHandlerProxy>> matchingPrefixTopic;
 
 
 	/** The context for the proxies. */
@@ -60,9 +60,9 @@
 		super(context, EventHandler.class.getName(), null);
 
 		// we start with empty collections
-		this.matchingAllEvents = new ArrayList<EventHandlerProxy>();
-		this.matchingTopic = new HashMap<String, List<EventHandlerProxy>>();
-		this.matchingPrefixTopic = new HashMap<String, List<EventHandlerProxy>>();
+		this.matchingAllEvents = new CopyOnWriteArrayList<EventHandlerProxy>();
+		this.matchingTopic = new ConcurrentHashMap<String, List<EventHandlerProxy>>();
+		this.matchingPrefixTopic = new ConcurrentHashMap<String, List<EventHandlerProxy>>();
 	}
 
     /**
@@ -109,7 +109,7 @@
 	 * @see org.osgi.util.tracker.ServiceTracker#addingService(org.osgi.framework.ServiceReference)
 	 */
 	@Override
-    public EventHandlerProxy addingService(final ServiceReference reference) {
+    public EventHandlerProxy addingService(final ServiceReference<EventHandler> reference) {
 		final EventHandlerProxy proxy = new EventHandlerProxy(this.handlerContext, reference);
 		if ( proxy.update() ) {
 			this.put(proxy);
@@ -121,7 +121,7 @@
 	 * @see org.osgi.util.tracker.ServiceTracker#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
 	 */
 	@Override
-    public void modifiedService(final ServiceReference reference, final EventHandlerProxy proxy) {
+    public void modifiedService(final ServiceReference<EventHandler> reference, final EventHandlerProxy proxy) {
 	    this.remove(proxy);
 	    if ( proxy.update() ) {
             this.put(proxy);
@@ -132,22 +132,23 @@
 	 * @see org.osgi.util.tracker.ServiceTracker#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
 	 */
 	@Override
-    public void removedService(final ServiceReference reference, final EventHandlerProxy proxy) {
+    public void removedService(final ServiceReference<EventHandler> reference, final EventHandlerProxy proxy) {
         this.remove(proxy);
         proxy.dispose();
 	}
 
 	private void updateMap(final Map<String, List<EventHandlerProxy>> proxyListMap, final String key, final EventHandlerProxy proxy, final boolean add) {
         List<EventHandlerProxy> proxies = proxyListMap.get(key);
-        if (proxies == null) {
+        if (proxies == null)
+        {
             if ( !add )
             {
                 return;
             }
-            proxies = new ArrayList<EventHandlerProxy>();
-        } else {
-            proxies = new ArrayList<EventHandlerProxy>(proxies);
+            proxies = new CopyOnWriteArrayList<EventHandlerProxy>();
+            proxyListMap.put(key, proxies);
         }
+
         if ( add )
         {
             proxies.add(proxy);
@@ -155,120 +156,68 @@
         else
         {
             proxies.remove(proxy);
-        }
-        if ( proxies.size() == 0 )
-        {
-            proxyListMap.remove(key);
-        }
-        else
-        {
-            proxyListMap.put(key, proxies);
+            if ( proxies.size() == 0 )
+            {
+                proxyListMap.remove(key);
+            }
         }
 	}
 
 	/**
 	 * Check the topics of the event handler and put it into the
 	 * corresponding collections.
-	 * We always create new collections - while this is "expensive"
-	 * it allows us to read from them unsynced
 	 */
 	private synchronized void put(final EventHandlerProxy proxy) {
 		final String[] topics = proxy.getTopics();
 		if ( topics == null )
 		{
-		    final List<EventHandlerProxy> newMatchingAllEvents = new ArrayList<EventHandlerProxy>(this.matchingAllEvents);
-		    newMatchingAllEvents.add(proxy);
-		    this.matchingAllEvents = newMatchingAllEvents;
+		    this.matchingAllEvents.add(proxy);
 		}
 		else
 		{
-		    Map<String, List<EventHandlerProxy>> newMatchingTopic = null;
-		    Map<String, List<EventHandlerProxy>> newMatchingPrefixTopic = null;
     		for(int i = 0; i < topics.length; i++) {
     			final String topic = topics[i];
 
     			if ( topic.endsWith("/*") )
     			{
                     // prefix topic: we remove the /*
-    			    if ( newMatchingPrefixTopic == null )
-    			    {
-    			        newMatchingPrefixTopic = new HashMap<String, List<EventHandlerProxy>>(this.matchingPrefixTopic);
-    			    }
-
     				final String prefix = topic.substring(0, topic.length() - 2);
-                    this.updateMap(newMatchingPrefixTopic, prefix, proxy, true);
+                    this.updateMap(this.matchingPrefixTopic, prefix, proxy, true);
     			}
     			else
     			{
     			    // exact match
-                    if ( newMatchingTopic == null )
-                    {
-                        newMatchingTopic = new HashMap<String, List<EventHandlerProxy>>(this.matchingTopic);
-                    }
-
-                    this.updateMap(newMatchingTopic, topic, proxy, true);
+                    this.updateMap(this.matchingTopic, topic, proxy, true);
     			}
     		}
-    		if ( newMatchingTopic != null )
-    		{
-    		    this.matchingTopic = newMatchingTopic;
-    		}
-    		if ( newMatchingPrefixTopic != null )
-    		{
-    		    this.matchingPrefixTopic = newMatchingPrefixTopic;
-    		}
 		}
 	}
 
     /**
      * Check the topics of the event handler and remove it from the
      * corresponding collections.
-     * We always create new collections - while this is "expensive"
-     * it allows us to read from them unsynced
      */
 	private synchronized void remove(final EventHandlerProxy proxy) {
         final String[] topics = proxy.getTopics();
         if ( topics == null )
         {
-            final List<EventHandlerProxy> newMatchingAllEvents = new ArrayList<EventHandlerProxy>(this.matchingAllEvents);
-            newMatchingAllEvents.remove(proxy);
-            this.matchingAllEvents = newMatchingAllEvents;
+            this.matchingAllEvents.remove(proxy);
         } else {
-            Map<String, List<EventHandlerProxy>> newMatchingTopic = null;
-            Map<String, List<EventHandlerProxy>> newMatchingPrefixTopic = null;
             for(int i = 0; i < topics.length; i++) {
                 final String topic = topics[i];
 
                 if ( topic.endsWith("/*") )
                 {
                     // prefix topic: we remove the /*
-                    if ( newMatchingPrefixTopic == null )
-                    {
-                        newMatchingPrefixTopic = new HashMap<String, List<EventHandlerProxy>>(this.matchingPrefixTopic);
-                    }
-
                     final String prefix = topic.substring(0, topic.length() - 2);
-                    this.updateMap(newMatchingPrefixTopic, prefix, proxy, false);
+                    this.updateMap(this.matchingPrefixTopic, prefix, proxy, false);
                 }
                 else
                 {
                     // exact match
-                    if ( newMatchingTopic == null )
-                    {
-                        newMatchingTopic = new HashMap<String, List<EventHandlerProxy>>(this.matchingTopic);
-                    }
-
-                    this.updateMap(newMatchingTopic, topic, proxy, false);
+                    this.updateMap(this.matchingTopic, topic, proxy, false);
                 }
             }
-            if ( newMatchingTopic != null )
-            {
-                this.matchingTopic = newMatchingTopic;
-            }
-            if ( newMatchingPrefixTopic != null )
-            {
-                this.matchingPrefixTopic = newMatchingPrefixTopic;
-            }
         }
 	}
 
@@ -284,13 +233,7 @@
 		final Set<EventHandlerProxy> handlers = new HashSet<EventHandlerProxy>();
 
 		// Add all handlers matching everything
-		for(final EventHandlerProxy p : this.matchingAllEvents)
-		{
-		    if ( p.canDeliver(event) )
-		    {
-		        handlers.add(p);
-		    }
-		}
+        this.checkHandlerAndAdd(handlers, this.matchingAllEvents, event);
 
 		// Now check for prefix matches
 		if ( !this.matchingPrefixTopic.isEmpty() )
@@ -299,26 +242,28 @@
 			while (pos != -1)
 			{
 			    final String prefix = topic.substring(0, pos);
-				List<EventHandlerProxy> proxies = this.matchingPrefixTopic.get(prefix);
-				if (proxies != null)
-				{
-			        for(final EventHandlerProxy p : proxies)
-			        {
-			            if ( p.canDeliver(event) )
-			            {
-			                handlers.add(p);
-			            }
-			        }
-				}
+		        this.checkHandlerAndAdd(handlers, this.matchingPrefixTopic.get(prefix), event);
 
 				pos = prefix.lastIndexOf('/');
 			}
 		}
 
 		// Add the handlers for matching topic names
-		List<EventHandlerProxy> proxies = this.matchingTopic.get(topic);
-		if (proxies != null)
-		{
+		this.checkHandlerAndAdd(handlers, this.matchingTopic.get(topic), event);
+
+		return handlers;
+	}
+
+	/**
+	 * Checks each handler from the proxy list if it can deliver the event
+	 * If the event can be delivered, the proxy is added to the handlers.
+	 */
+	private void checkHandlerAndAdd( final Set<EventHandlerProxy> handlers,
+	        final List<EventHandlerProxy> proxies,
+	        final Event event)
+	{
+	    if ( proxies != null )
+	    {
             for(final EventHandlerProxy p : proxies)
             {
                 if ( p.canDeliver(event) )
@@ -326,9 +271,7 @@
                     handlers.add(p);
                 }
             }
-		}
-
-		return handlers;
+	    }
 	}
 
     /**