You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ch...@apache.org on 2011/01/27 18:12:50 UTC

svn commit: r1064205 - in /activemq/activemq-apollo/trunk: apollo-broker/ apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/osgi/ apollo-util/src/main/scala/org/apache/activemq/apollo/util/

Author: chirino
Date: Thu Jan 27 17:12:50 2011
New Revision: 1064205

URL: http://svn.apache.org/viewvc?rev=1064205&view=rev
Log:
Adding an osgi activator.

Added:
    activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/osgi/
    activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/osgi/Activator.scala
Modified:
    activemq/activemq-apollo/trunk/apollo-broker/pom.xml
    activemq/activemq-apollo/trunk/apollo-util/src/main/scala/org/apache/activemq/apollo/util/ClassFinder.scala

Modified: activemq/activemq-apollo/trunk/apollo-broker/pom.xml
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/pom.xml?rev=1064205&r1=1064204&r2=1064205&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/pom.xml (original)
+++ activemq/activemq-apollo/trunk/apollo-broker/pom.xml Thu Jan 27 17:12:50 2011
@@ -103,7 +103,14 @@
       <optional>true</optional>
     </dependency>
     
-    <!-- Testing Dependencies -->    
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>4.1.0</version>
+      <optional>true</optional>
+    </dependency>
+
+    <!-- Testing Dependencies -->
     <dependency>
       <groupId>org.apache.activemq</groupId>
       <artifactId>apollo-util</artifactId>

Added: activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/osgi/Activator.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/osgi/Activator.scala?rev=1064205&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/osgi/Activator.scala (added)
+++ activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/osgi/Activator.scala Thu Jan 27 17:12:50 2011
@@ -0,0 +1,132 @@
+/**
+ * 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.
+ */
+package org.apache.activemq.apollo.osgi
+
+import java.util.concurrent.ConcurrentHashMap
+import org.osgi.framework._
+import org.apache.activemq.apollo.broker.Broker
+import org.apache.activemq.apollo.broker.store.Store
+import org.apache.activemq.apollo.broker.protocol.Protocol
+import org.apache.activemq.apollo.util.{ClassFinder, Log}
+import java.net.URL
+import collection.mutable.ListBuffer
+
+/**
+ * An OSGi bundle activator for Apollo which tracks Apollo extension
+ * modules.
+ */
+object ApolloActivator extends Log {
+
+  import ClassFinder._
+
+  val bundles = new ConcurrentHashMap[Long, Bundle]
+
+  case class BundleLoader(bundle:Bundle) extends Loader {
+    def getResources(path:String) = bundle.getResources(path).asInstanceOf[java.util.Enumeration[URL]]
+    def loadClass(name:String) = bundle.loadClass(name)
+  }
+
+  def osgi_loader():Array[Loader] = {
+    val builder = ListBuffer[Loader]()
+    import collection.JavaConversions._
+    bundles.values.foreach { bundle=>
+      builder += BundleLoader(bundle)
+    }
+    builder += ClassLoaderLoader(Thread.currentThread.getContextClassLoader)
+    builder.toArray
+  }
+
+
+  // Change the default loaders used by the ClassFinder so
+  // that it can find classes in extension osgi modules.
+  ClassFinder.default_loaders = ()=> osgi_loader
+
+}
+
+class ApolloActivator extends BundleActivator with SynchronousBundleListener {
+
+  import ApolloActivator._
+
+  def start(bundleContext: BundleContext): Unit = this.synchronized {
+    debug("activating")
+    this.bundleContext = bundleContext
+    debug("checking existing bundles")
+    bundleContext.addBundleListener(this)
+    for (bundle <- bundleContext.getBundles) {
+      if (bundle.getState == Bundle.RESOLVED ||
+          bundle.getState == Bundle.STARTING ||
+          bundle.getState == Bundle.ACTIVE ||
+          bundle.getState == Bundle.STOPPING) {
+        register(bundle)
+      }
+    }
+    debug("activated")
+  }
+
+  def stop(bundleContext: BundleContext): Unit = this.synchronized {
+    debug("deactivating")
+    bundleContext.removeBundleListener(this)
+    while (!bundles.isEmpty) {
+      unregister(bundles.keySet.iterator.next)
+    }
+    debug("deactivated")
+    this.bundleContext = null
+  }
+
+  def bundleChanged(event: BundleEvent): Unit = {
+    if (event.getType == BundleEvent.RESOLVED) {
+      register(event.getBundle)
+    }
+    else if (event.getType == BundleEvent.UNRESOLVED || event.getType == BundleEvent.UNINSTALLED) {
+      unregister(event.getBundle.getBundleId)
+    }
+  }
+
+  protected def register(bundle: Bundle): Unit = {
+    debug("checking bundle " + bundle.getBundleId)
+    if (!isImportingUs(bundle)) {
+      debug("The bundle does not import us: " + bundle.getBundleId)
+    } else {
+      bundles.put(bundle.getBundleId, bundle)
+    }
+  }
+
+  /**
+   * @param bundleId
+   */
+  protected def unregister(bundleId: Long): Unit = {
+    bundles.remove(bundleId)
+  }
+
+  private def isImportingUs(bundle: Bundle): Boolean = {
+    isImportingClass(bundle, classOf[Broker]) ||
+    isImportingClass(bundle, classOf[Store]) ||
+    isImportingClass(bundle, classOf[Protocol])
+  }
+
+  private def isImportingClass(bundle: Bundle, clazz: Class[_]): Boolean = {
+    try {
+      bundle.loadClass(clazz.getName) == clazz
+    } catch {
+      case e: ClassNotFoundException => {
+        false
+      }
+    }
+  }
+
+  private var bundleContext: BundleContext = null
+}
\ No newline at end of file

Modified: activemq/activemq-apollo/trunk/apollo-util/src/main/scala/org/apache/activemq/apollo/util/ClassFinder.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-util/src/main/scala/org/apache/activemq/apollo/util/ClassFinder.scala?rev=1064205&r1=1064204&r2=1064205&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-util/src/main/scala/org/apache/activemq/apollo/util/ClassFinder.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-util/src/main/scala/org/apache/activemq/apollo/util/ClassFinder.scala Thu Jan 27 17:12:50 2011
@@ -19,9 +19,30 @@ package org.apache.activemq.apollo.util
 import java.io.InputStream
 import java.util.Properties
 import scala.collection.mutable.ListBuffer
+import java.net.URL
 
 
-object ClassFinder extends Log
+object ClassFinder extends Log {
+
+  trait Loader {
+    def getResources(path:String):java.util.Enumeration[URL]
+    def loadClass(name:String):Class[_]
+  }
+
+  case class ClassLoaderLoader(cl:ClassLoader) extends Loader {
+    def getResources(path:String) = cl.getResources(path)
+    def loadClass(name:String) = cl.loadClass(name)
+  }
+
+  def standalone_loader():Array[Loader] = {
+    Array(ClassLoaderLoader(Thread.currentThread.getContextClassLoader))
+  }
+
+  var default_loaders = ()=>standalone_loader
+}
+
+import ClassFinder._
+
 
 /**
  * <p>
@@ -30,16 +51,16 @@ object ClassFinder extends Log
  *
  * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
  */
-class ClassFinder[T](val path:String, val loaders:Array[ClassLoader]) {
-  import ClassFinder._
+class ClassFinder[T](val path:String, val loaders: ()=>Array[Loader]) {
 
-  def this(path:String) = this(path, Array(Thread.currentThread.getContextClassLoader))
+  def this(path:String) = this(path, default_loaders)
+//  def this(path:String, loaders:Array[ClassLoader]) = this(path, ()=>{loaders.map(ClassLoaderLoader _) })
 
   def findArray(): Array[Class[T]] = find.toArray
 
   def find(): List[Class[T]] = {
     var classes = List[Class[T]]()
-    loaders.foreach { loader=>
+    loaders().foreach { loader=>
 
       val resources = loader.getResources(path)
       var classNames: List[String] = Nil
@@ -53,10 +74,15 @@ class ClassFinder[T](val path:String, va
       }
       classNames = classNames.distinct
 
-      classes :::= classNames.map { name=>
-        loader.loadClass(name).asInstanceOf[Class[T]]
+      classes :::= classNames.flatMap { name=>
+        try {
+          Some(loader.loadClass(name).asInstanceOf[Class[T]])
+        } catch {
+          case e:Throwable =>
+            debug(e, "Could not load class %s", name)
+            None
+        }
       }
-
     }
 
     return classes.distinct