Author: rsivaram
Date: Fri Feb 22 03:05:14 2008
New Revision: 630153

URL: http://svn.apache.org/viewvc?rev=630153&view=rev
Log:
OSGi Bundle Activator for Tuscany

Added:
    
incubator/tuscany/java/sca/modules/osgi-runtime/src/main/java/org/apache/tuscany/sca/osgi/runtime/OSGiBundleActivator.java

Added: 
incubator/tuscany/java/sca/modules/osgi-runtime/src/main/java/org/apache/tuscany/sca/osgi/runtime/OSGiBundleActivator.java
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/java/sca/modules/osgi-runtime/src/main/java/org/apache/tuscany/sca/osgi/runtime/OSGiBundleActivator.java?rev=630153&view=auto
==============================================================================
--- 
incubator/tuscany/java/sca/modules/osgi-runtime/src/main/java/org/apache/tuscany/sca/osgi/runtime/OSGiBundleActivator.java
 (added)
+++ 
incubator/tuscany/java/sca/modules/osgi-runtime/src/main/java/org/apache/tuscany/sca/osgi/runtime/OSGiBundleActivator.java
 Fri Feb 22 03:05:14 2008
@@ -0,0 +1,234 @@
+package org.apache.tuscany.sca.osgi.runtime;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+
+import org.apache.tuscany.sca.contribution.util.ServiceDiscovery;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+
+/**
+ * OSGi bundle activator, which is run when Tuscany is run inside an OSGi 
runtime.
+ *
+ */
+public class OSGiBundleActivator implements BundleActivator, BundleListener {
+       
+       private static final String TUSCANY_SCA_BUNDLE_PREFIX = 
"org.apache.tuscany.sca";
+       private static final String TUSCANY_3RD_PARTY_BUNDLE_PREFIX = 
"org.apache.tuscany.sca.3rdparty";
+       private OSGiRuntime runtime;
+       private BundleClassLoader serviceDiscoveryClassLoader;
+       private BundleClassLoader threadContextClassLoader;
+       private ClassLoader origTCCL;
+       private Bundle thisBundle;
+
+       public void start(BundleContext bundleContext) throws Exception {
+               
+               initializeTuscanyClassLoaders(bundleContext);
+               
+               runtime = OSGiRuntime.findRuntime();
+               runtime.setBundleContext(bundleContext);
+               runtime.initialize();
+               
+       }
+
+       public void stop(BundleContext bundleContext) throws Exception {
+               runtime.shutdown();
+               
+               Thread.currentThread().setContextClassLoader(origTCCL);
+       }
+       
+       /**
+        * Create a bundle classloader which has visibility of all Tuscany 
related
+        * bundles. Use this classloader as TCCL, and the Tuscany service 
discovery
+        * classloader.
+        * 
+        * @param bundleContext
+        */
+       private void initializeTuscanyClassLoaders(BundleContext bundleContext) 
{
+               
+               thisBundle = bundleContext.getBundle();
+
+               origTCCL = Thread.currentThread().getContextClassLoader();
+               
+               threadContextClassLoader = new BundleClassLoader(thisBundle, 
origTCCL);
+               
+               
Thread.currentThread().setContextClassLoader(threadContextClassLoader);
+               
+               serviceDiscoveryClassLoader = new BundleClassLoader(thisBundle, 
origTCCL);
+
+               Bundle[] bundles = bundleContext.getBundles();
+               for (Bundle bundle : bundles) {
+                       updateBundleClassLoader(bundle);                        
+               }
+               bundleContext.addBundleListener(this);
+               
+               
ServiceDiscovery.getInstance().registerClassLoader(serviceDiscoveryClassLoader);
+               
+               
+               
+       }
+       
+       /**
+        * Add an installed bundle to the list of bundles in the service 
discovery classpath
+        * if the installed bundle is a Tuscany bundle using the same Core-SPI 
bundle.
+        * Since the bundle containing this activator is in Tuscany Runtime, 
this bundle
+        * will provide access to Runtime and its dependencies (SPI, SCA-API). 
Third party
+        * bundles dont need to be in the service discovery classpath, since 
they will be automatically
+        * imported by bundles which require them. That leaves Tuscany 
extension bundles,
+        * which are added to the service discovery classpath here.
+        * 
+        * 3rd party bundle should be explicity added to TCCL since classes 
from these
+        * bundles use TCCL to load other classes from the bundle.
+        * 
+        * Load one class from the bundle to check if the new bundle matches 
this runtime bundle.
+        * 
+        * @param bundle
+        */
+       private void updateBundleClassLoader(Bundle bundle) {
+               
+               if 
(bundle.getSymbolicName().startsWith(TUSCANY_SCA_BUNDLE_PREFIX)) {
+                       
+
+                       // This may be the third party bundle.
+                   if 
(bundle.getSymbolicName().startsWith(TUSCANY_3RD_PARTY_BUNDLE_PREFIX)) {
+                                       
+                               try {
+                                       String xmlInputFactory = 
"javax.xml.stream.XMLInputFactory";
+                                       if 
(thisBundle.loadClass(xmlInputFactory) == bundle.loadClass(xmlInputFactory)) {
+                                                       
+                                           
threadContextClassLoader.addBundle(bundle);
+                                       }
+                               } catch (ClassNotFoundException e) {
+                                       // Ignore
+                               }
+                       } 
+                   else {
+                       
+                           String moduleActivator = 
"org.apache.tuscany.sca.core.ModuleActivator";
+                       
+                           try {
+                                   if (thisBundle.loadClass(moduleActivator) 
== bundle.loadClass(moduleActivator)) {
+                                       
+                                       
serviceDiscoveryClassLoader.addBundle(bundle);
+                                       
threadContextClassLoader.addBundle(bundle);
+                                   }
+                           } catch (ClassNotFoundException e) {
+                                   // Ignore                           
+                           }
+                   }
+               }
+       }
+
+
+       /**
+        * Handle bundle install/uninstall events 
+        */
+       public void bundleChanged(BundleEvent event) {
+               
+               Bundle bundle = event.getBundle();
+               if (event.getType() == BundleEvent.UNINSTALLED) {
+                       serviceDiscoveryClassLoader.removeBundle(bundle);
+                       threadContextClassLoader.removeBundle(bundle);
+               }
+               else if (event.getType() == BundleEvent.INSTALLED) {
+                       updateBundleClassLoader(bundle);
+               }
+       }
+
+
+
+
+       /**
+        * Bundle classloader that searches a bundle classpath consisting of
+        * a list of bundles. The parent classloader is searched only if a class
+        * cannot be loaded from the bundle classpath. Tuscany bundles are
+        * dynamically added and removed from the bundle classpath when the 
bundles
+        * are installed and uninstalled.
+        * 
+        * No ordering of bundles is maintained at the moment.
+        *
+        */
+       private static class BundleClassLoader extends ClassLoader {
+               
+               private HashSet<Bundle> bundles;
+               
+               BundleClassLoader(Bundle bundle, ClassLoader parent) {
+                       super(parent);
+                       this.bundles = new HashSet<Bundle>();
+                       bundles.add(bundle);
+               }
+               
+               private synchronized void addBundle(Bundle bundle) {
+                       bundles.add(bundle);
+               }
+               
+               private synchronized void removeBundle(Bundle bundle) {
+                       if (bundles.contains(bundle))
+                           bundles.remove(bundle);
+               }
+               
+               @Override
+               public Class<?> loadClass(String className) throws 
ClassNotFoundException {
+                       Class<?> clazz = null;
+                       for (Bundle bundle : bundles) {
+                               try {
+                                       clazz = bundle.loadClass(className);
+                                       break;
+                               } catch (ClassNotFoundException e) {
+                               } catch (NoClassDefFoundError e) {
+                               }
+                               
+                       }       
+                       
+                       if (clazz != null) {
+                           return clazz;
+                       }
+                       return super.loadClass(className);
+               }
+               
+               
+
+               @Override
+               @SuppressWarnings("unchecked")
+               public Enumeration<URL> getResources(String resName) throws 
IOException {
+                       HashSet<URL> urlSet = new HashSet<URL>();
+                       Enumeration<URL> urls = null;
+                       for (Bundle bundle : bundles) {
+                           urls = bundle.getResources(resName);                
            
+                           if (urls != null) {
+                               while (urls.hasMoreElements()) {
+                                   urlSet.add(urls.nextElement());
+                               }
+                           }
+                       }
+                       if (urlSet.size() > 0)
+                               return Collections.enumeration(urlSet);
+                       return super.getResources(resName);
+               }
+
+               @Override
+               public URL getResource(String resName) {
+                       URL url = null;
+                       for (Bundle bundle : bundles) {
+                           url = bundle.getResource(resName);
+                           if (url != null)
+                               return url;
+                       }       
+                       return super.getResource(resName);
+               }
+
+               @Override
+               public String toString() {
+                       return "Tuscany BundleClassLoader " + 
bundles.iterator().next();
+           }
+               
+               
+               
+       }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to