geronimo-xbean-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ga...@apache.org
Subject svn commit: r1143986 - /geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/DelegatingBundle.java
Date Thu, 07 Jul 2011 19:18:10 GMT
Author: gawor
Date: Thu Jul  7 19:18:09 2011
New Revision: 1143986

URL: http://svn.apache.org/viewvc?rev=1143986&view=rev
Log:
XBEAN-177: DelegatingBundle optimization take 2. Minimize the use of PackageAdmin

Modified:
    geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/DelegatingBundle.java

Modified: geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/DelegatingBundle.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/DelegatingBundle.java?rev=1143986&r1=1143985&r2=1143986&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/DelegatingBundle.java
(original)
+++ geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/DelegatingBundle.java
Thu Jul  7 19:18:09 2011
@@ -27,8 +27,11 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Dictionary;
 import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -64,44 +67,94 @@ public class DelegatingBundle implements
     }
     
     public Class<?> loadClass(String name) throws ClassNotFoundException {
-        for (Bundle bundle : bundles) {
-            try {
-                return bundle.loadClass(name);
-            } catch (ClassNotFoundException ex) {
-                int index = name.lastIndexOf('.');
-                if (index > 0) {
-                    /*
-                     * We got CNFE and if we are wired to a bundle that exports the 
-                     * given package then there is no hope of loading the class.
-                     */
-                    String packageName = name.substring(0, index);
-                    if (isWired(bundle, packageName)) {
-                        throw ex;
-                    } else {
-                        // ignore - try to load with next bundle
+        try {
+            return bundle.loadClass(name);
+        } catch (ClassNotFoundException ex) {
+            int index = name.lastIndexOf('.');
+            if (index > 0) {
+                // see if there are any bundles exporting the package
+                String packageName = name.substring(0, index);
+                Set<Bundle> packageBundles = getPackageBundles(packageName);
+                if (packageBundles == null) {
+                    // package is NOT exported
+                    
+                    Iterator<Bundle> iterator = bundles.iterator();
+                    // skip first bundle
+                    iterator.next();
+                    // attempt to load the class from the remaining bundles
+                    while (iterator.hasNext()) {
+                        Bundle delegate = iterator.next();
+                        try {
+                            return delegate.loadClass(name);
+                        } catch (ClassNotFoundException e) {
+                            // ignore
+                        }
                     }
-                } else {
-                    // no package name
+                    
                     throw ex;
-                }                
-            }
+                } else {
+                    // package is exported 
+                    
+                    // see if any of our bundles is wired to the exporter 
+                    Bundle delegate = findFirstBundle(packageBundles);
+                    if (delegate == null || delegate == bundle) {
+                        // nope. no static wires but might need to check for dynamic wires
in the future.
+                        throw ex;
+                    } else {
+                        // yes. attempt to load the class from it
+                        return delegate.loadClass(name);
+                    } 
+                }
+            }  else {
+                // no package name
+                throw ex;
+            }  
         }
-        throw new ClassNotFoundException(name);
     }
-
-    private boolean isWired(Bundle importingBundle, String packageName) {
+    
+    private Set<Bundle> getPackageBundles(String packageName) {
         BundleContext context = bundle.getBundleContext();
         ServiceReference reference = context.getServiceReference(PackageAdmin.class.getName());
         PackageAdmin packageAdmin = (PackageAdmin) context.getService(reference);
+        Set<Bundle> bundles = null;
         try {
-            ExportedPackage[] packages = packageAdmin.getExportedPackages(packageName);
-            Bundle exportingBundle = BundleUtils.getWiredBundle(importingBundle, packages);
-            return (exportingBundle != null);
+            ExportedPackage[] exportedPackages = packageAdmin.getExportedPackages(packageName);
+            if (exportedPackages != null && exportedPackages.length > 0) {
+                bundles = new HashSet<Bundle>();
+                for (ExportedPackage exportedPackage : exportedPackages) {
+                    bundles.add(exportedPackage.getExportingBundle());
+                    Bundle[] importingBundles = exportedPackage.getImportingBundles();
+                    if (importingBundles != null) {
+                        for (Bundle importingBundle : importingBundles) {
+                            bundles.add(importingBundle);
+                        }
+                    }
+                }
+            }
+            return bundles;
         } finally {
             context.ungetService(reference);
         }
     }
     
+    private Bundle findFirstBundle(Set<Bundle> packageBundles) {
+        Collection<Bundle> c1 = bundles;
+        Collection<Bundle> c2 = packageBundles;
+        
+        if (bundles instanceof Set<?> && bundles.size() > packageBundles.size())
{
+            c1 = packageBundles;
+            c2 = bundles;
+        }
+        
+        for (Bundle bundle : c1) {
+            if (c2.contains(bundle)) {
+                return bundle;
+            }
+        }
+        
+        return null;
+    }
+    
     public URL getResource(String name) {
         URL resource = null;
         for (Bundle bundle : bundles) {



Mime
View raw message