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;
+ }
}
/**