incubator-aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lin...@apache.org
Subject svn commit: r931955 - in /incubator/aries/trunk/subsystem/subsystem-core: ./ src/main/java/org/apache/aries/subsystem/core/internal/
Date Thu, 08 Apr 2010 14:27:10 GMT
Author: linsun
Date: Thu Apr  8 14:27:09 2010
New Revision: 931955

URL: http://svn.apache.org/viewvc?rev=931955&view=rev
Log:
ARIES-278 Provide subsystem event dispatcher to dispatch events to Subsystem listener, based
on blueprint event dispatcher without event admin notification

Added:
    incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java
  (with props)
Modified:
    incubator/aries/trunk/subsystem/subsystem-core/pom.xml
    incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
    incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java

Modified: incubator/aries/trunk/subsystem/subsystem-core/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/pom.xml?rev=931955&r1=931954&r2=931955&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/pom.xml (original)
+++ incubator/aries/trunk/subsystem/subsystem-core/pom.xml Thu Apr  8 14:27:09 2010
@@ -60,6 +60,15 @@
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.utils</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>

Modified: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java?rev=931955&r1=931954&r2=931955&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
(original)
+++ incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
Thu Apr  8 14:27:09 2010
@@ -39,9 +39,12 @@ public class Activator implements Bundle
 
     private BundleContext context;
     private List<ServiceRegistration> registrations = new ArrayList<ServiceRegistration>();
+    private static SubsystemEventDispatcher eventDispatcher;
 
     public void start(BundleContext context) throws Exception {
         this.context = context;
+        eventDispatcher = new SubsystemEventDispatcher(context);
+        
         register(SubsystemAdmin.class, new SubsystemAdminFactory(), null);
         register(ResourceResolver.class,
                  new NoOpResolver(),
@@ -83,7 +86,7 @@ public class Activator implements Bundle
             SubsystemAdminImpl admin = admins.get(systemBundleContext);
             long ref = 0;
             if (admin == null) {
-                admin = new SubsystemAdminImpl(systemBundleContext);
+                admin = new SubsystemAdminImpl(systemBundleContext, eventDispatcher);
                 admins.put(systemBundleContext, admin);
             } else {
                 ref = references.get(admin);

Modified: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java?rev=931955&r1=931954&r2=931955&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java
(original)
+++ incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java
Thu Apr  8 14:27:09 2010
@@ -48,9 +48,11 @@ public class SubsystemAdminImpl implemen
     final Map<Long, Subsystem> subsystems = new HashMap<Long, Subsystem>();
     final ServiceTracker compositeAdminTracker;
     final ServiceTracker resourceResolverTracker;
+    final SubsystemEventDispatcher eventDispatcher;
 
-    public SubsystemAdminImpl(BundleContext context) {
+    public SubsystemAdminImpl(BundleContext context, SubsystemEventDispatcher eventDispatcher)
{
         this.context = context;
+        this.eventDispatcher = eventDispatcher;
         this.compositeAdminTracker = new ServiceTracker(context, CompositeAdmin.class.getName(),
null);
         this.compositeAdminTracker.open();
         this.resourceResolverTracker = new ServiceTracker(context, ResourceResolver.class.getName(),
null);

Added: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java?rev=931955&view=auto
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java
(added)
+++ incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java
Thu Apr  8 14:27:09 2010
@@ -0,0 +1,152 @@
+package org.apache.aries.subsystem.core.internal;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.aries.subsystem.Subsystem;
+import org.apache.aries.subsystem.SubsystemEvent;
+import org.apache.aries.subsystem.SubsystemListener;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * this event dispatcher dispatches subsystem events to subsystem listeners.
+ *
+ */
+public class SubsystemEventDispatcher implements SubsystemListener, SynchronousBundleListener
{
+
+    private static final Logger LOGGER = LoggerFactory
+            .getLogger(SubsystemEventDispatcher.class);
+    private final Set<SubsystemListener> listeners = new CopyOnWriteArraySet<SubsystemListener>();
+    private final Map<Subsystem, SubsystemEvent> states = new ConcurrentHashMap<Subsystem,
SubsystemEvent>();
+    private final ExecutorService executor = Executors
+            .newSingleThreadExecutor();
+    private final ServiceTracker containerListenerTracker;
+
+    SubsystemEventDispatcher(final BundleContext bundleContext) {
+
+        assert bundleContext != null;
+
+        this.containerListenerTracker = new ServiceTracker(bundleContext,
+                SubsystemListener.class.getName(),
+                new ServiceTrackerCustomizer() {
+                    public Object addingService(ServiceReference reference) {
+                        SubsystemListener listener = (SubsystemListener) bundleContext
+                                .getService(reference);
+
+                        synchronized (listeners) {
+                            sendInitialEvents(listener);
+                            listeners.add(listener);
+                        }
+
+                        return listener;
+                    }
+
+                    public void modifiedService(ServiceReference reference,
+                            Object service) {
+                    }
+
+                    public void removedService(ServiceReference reference,
+                            Object service) {
+                        listeners.remove(service);
+                        bundleContext.ungetService(reference);
+                    }
+                });
+        this.containerListenerTracker.open();
+    }
+
+    private void sendInitialEvents(SubsystemListener listener) {
+        for (Map.Entry<Subsystem, SubsystemEvent> entry : states.entrySet()) {
+            try {
+                callListener(listener, entry.getValue());
+            } catch (RejectedExecutionException ree) {
+                LOGGER.warn("Executor shut down", ree);
+                break;
+            }
+        }
+    }
+
+    private void callListeners(SubsystemEvent event) {
+        for (final SubsystemListener listener : listeners) {
+            try {
+                callListener(listener, event);
+            } catch (RejectedExecutionException ree) {
+                LOGGER.warn("Executor shut down", ree);
+                break;
+            }
+        }
+    }
+
+    private void callListener(final SubsystemListener listener,
+            final SubsystemEvent event) throws RejectedExecutionException {
+        try {
+            executor.invokeAny(Collections
+                    .<Callable<Void>> singleton(new Callable<Void>() {
+                        public Void call() throws Exception {
+                            listener.subsystemEvent(event);
+                            return null;
+                        }
+                    }), 60L, TimeUnit.SECONDS);
+        } catch (InterruptedException ie) {
+            LOGGER.warn("Thread interrupted", ie);
+            Thread.currentThread().interrupt();
+        } catch (TimeoutException te) {
+            LOGGER.warn("Listener timed out, will be ignored", te);
+            listeners.remove(listener);
+        } catch (ExecutionException ee) {
+            LOGGER.warn("Listener caused an exception, will be ignored", ee);
+            listeners.remove(listener);
+        }
+    }
+
+    public void subsystemEvent(SubsystemEvent event) {
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug("Sending Subsystem event {} for subsystem {}",
+                    toString(event), event.getSubsystem().getSymbolicName());
+        }
+
+        synchronized (listeners) {
+            callListeners(event);
+            states.put(event.getSubsystem(), event);
+        }
+    }
+
+    @SuppressWarnings( { "ThrowableResultOfMethodCallIgnored" })
+    private static String toString(SubsystemEvent event) {
+        return "SubsystemEvent[subsystem=" + event.getSubsystem().getScope()
+                + " type=" + event.getType() + "]";
+    }
+
+    void destroy() {
+        executor.shutdown();
+        // wait for the queued tasks to execute
+        try {
+            executor.awaitTermination(60, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            // ignore
+        }
+        containerListenerTracker.close();
+    }
+
+    public void bundleChanged(BundleEvent event) {
+        if (BundleEvent.STOPPING == event.getType()) {
+            states.remove(event.getBundle());
+        }
+    }
+}

Propchange: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message