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