You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ga...@apache.org on 2010/01/14 21:42:09 UTC

svn commit: r899403 - in /geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi: BundleClassFinder.java BundleResourceFinder.java

Author: gawor
Date: Thu Jan 14 20:42:08 2010
New Revision: 899403

URL: http://svn.apache.org/viewvc?rev=899403&view=rev
Log:
GERONIMO-5026: first stab at bundle resource finder

Added:
    geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleResourceFinder.java   (with props)
Modified:
    geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleClassFinder.java

Modified: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleClassFinder.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleClassFinder.java?rev=899403&r1=899402&r2=899403&view=diff
==============================================================================
--- geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleClassFinder.java (original)
+++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleClassFinder.java Thu Jan 14 20:42:08 2010
@@ -25,7 +25,6 @@
 import java.util.Collection;
 import java.util.Enumeration;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
@@ -90,7 +89,7 @@
      * 
      * @return classes visible to the bundle. Not all classes returned might be loadable. 
      */
-    public Set<String> findAll() {    
+    public Set<String> find() {    
         Set<String> classes = new LinkedHashSet<String>();
         
         classMap = new HashMap<Bundle, Set<String>>();
@@ -117,15 +116,12 @@
         if (!scanImportPackages) {
             return;
         }
-        BundleDescription description = new BundleDescription(fragment.getHeaders());
-        
+        BundleDescription description = new BundleDescription(fragment.getHeaders());        
         List<BundleDescription.ImportPackage> imports = description.getExternalImports();
-        HashSet<Bundle> wiredBundles = new HashSet<Bundle>();
         for (BundleDescription.ImportPackage packageImport : imports) {
             ExportedPackage[] exports = packageAdmin.getExportedPackages(packageImport.getName());
             Bundle wiredBundle = isWired(host, exports);
             if (wiredBundle != null) {
-                wiredBundles.add(wiredBundle);
                 Set<String> allClasses = findAllClasses(wiredBundle);
                 addMatchingClasses(classes, allClasses, packageImport.getName());
             }
@@ -137,7 +133,7 @@
         if (allClasses == null) {
             BundleClassFinder finder = new BundleClassFinder(packageAdmin, bundle);
             finder.setScanImportPackages(false);
-            allClasses = finder.findAll();
+            allClasses = finder.find();
             classMap.put(bundle, allClasses);
         }
         return allClasses;
@@ -192,9 +188,7 @@
     }    
     
     private void scanDirectory(Collection<String> classes, Bundle bundle, String basePath) {
-        if (!basePath.endsWith("/")) {
-            basePath = basePath + "/";
-        }
+        basePath = addSlash(basePath);
         Enumeration e = bundle.findEntries(basePath, PATTERN, true);
         if (e != null) {
             while (e.hasMoreElements()) {
@@ -235,6 +229,13 @@
         return name;
     }
     
+    private static String addSlash(String name) {
+        if (!name.endsWith("/")) {
+            name = name + "/";
+        }
+        return name;
+    }
+    
     private static Bundle isWired(Bundle bundle, ExportedPackage[] exports) {
         if (exports != null) {
             for (ExportedPackage exportedPackage : exports) {

Added: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleResourceFinder.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleResourceFinder.java?rev=899403&view=auto
==============================================================================
--- geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleResourceFinder.java (added)
+++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleResourceFinder.java Thu Jan 14 20:42:08 2010
@@ -0,0 +1,170 @@
+/*
+ * 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.geronimo.kernel.osgi;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.apache.geronimo.kernel.osgi.BundleDescription.HeaderEntry;
+import org.osgi.framework.Bundle;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+/**
+ * Finds all available resources to a bundle by scanning Bundle-ClassPath header 
+ * of the given bundle and its fragments.
+ * DynamicImport-Package header is not considered during scanning.
+ * 
+ * @version $Rev$ $Date$
+ */
+public class BundleResourceFinder {
+   
+    private Bundle bundle;
+    private PackageAdmin packageAdmin;
+    private String prefix;
+    private String suffix;
+    
+    public BundleResourceFinder(PackageAdmin packageAdmin, Bundle bundle, String prefix, String suffix) {
+        this.packageAdmin = packageAdmin;
+        this.bundle = bundle;
+        this.prefix = prefix.trim();
+        this.suffix = suffix.trim();
+    }
+    
+    public Set<URL> find() {
+        Set<URL> resources = new LinkedHashSet<URL>();
+
+        scanBundleClassPath(resources, bundle);
+        
+        Bundle[] fragments = packageAdmin.getFragments(bundle);
+        if (fragments != null) {
+            for (Bundle fragment : fragments) {
+                scanBundleClassPath(resources, fragment);
+            }
+        }
+        
+        return resources;
+    }
+    
+    private void scanBundleClassPath(Collection<URL> resources, Bundle bundle) {
+        BundleDescription desc = new BundleDescription(bundle.getHeaders());
+        List<HeaderEntry> paths = desc.getBundleClassPath();
+        if (paths.isEmpty()) {
+            scanDirectory(resources, bundle, prefix);
+        } else {
+            for (HeaderEntry path : paths) {
+                String name = path.getName();
+                if (name.equals(".") || name.equals("/")) {
+                    // scan root
+                    scanDirectory(resources, bundle, prefix);
+                } else if (name.endsWith(".jar") || name.endsWith(".zip")) {
+                    // scan embedded jar/zip
+                    scanZip(resources, bundle, name);
+                } else {
+                    // assume it's a directory
+                    scanDirectory(resources, bundle, addSlash(prefix) + name);
+                }
+            }
+        }
+    }
+    
+    private void scanDirectory(Collection<URL> resources, Bundle bundle, String basePath) {
+        Enumeration e = bundle.findEntries(basePath, "*" + suffix, true);
+        if (e != null) {
+            while (e.hasMoreElements()) {
+                resources.add((URL) e.nextElement());
+            }
+        }
+    }
+    
+    private void scanZip(Collection<URL> resources, Bundle bundle, String zipName) {   
+        URL zipEntry = bundle.getEntry(zipName);
+        if (zipEntry == null) {
+            return;
+        }
+        try {
+            ZipInputStream in = new ZipInputStream(zipEntry.openStream());
+            ZipEntry entry;
+            while ((entry = in.getNextEntry()) != null) {
+                String name = entry.getName();
+                if (prefixMatches(name) && suffixMatches(name)) {
+                    /**
+                     * XXX: The bundle.getResource() uses bundle class loader to find the resource.
+                     * That means that the returned URL might actually come from another bundle
+                     * that also has a resource with the same name.
+                     * 
+                     * Possible solution 1:
+                     *  Build the URL to the right resource.
+                     *   - Pros: Would not use bundle classloader
+                     *   - Cons: The "bundle" url is not standardized so the implementation might be
+                     *     very framework specific.  
+                     * 
+                     * Possible solution 2:
+                     *   Use bundle.getResources() and find the right resource by comparing urls.
+                     *   - Pros: 
+                     *   - Cons: Uses bundle classloader to find the resources
+                     *           Might need to understand the "bundle" url to compare the returned
+                     *           urls.  
+                     */
+                    URL u = getRightResource(name);
+                    resources.add(u);
+                }
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+    
+    private boolean prefixMatches(String name) {
+        if (prefix.length() == 0 || prefix.equals(".") || prefix.equals("/")) {
+            return true;
+        } else if (prefix.startsWith("/")) {
+            return name.startsWith(prefix, 1);
+        } else {
+            return name.startsWith(prefix);
+        }
+    }
+    
+    private boolean suffixMatches(String name) {
+        return (suffix.length() == 0) ? true : name.endsWith(suffix);
+    }
+        
+    private URL getRightResource(String name) throws IOException {
+        Enumeration e = bundle.getResources(name);
+        URL firstResource = (URL) e.nextElement();
+        if (e.hasMoreElements()) {
+            // TODO: multiple resources found - must pick right one
+        }
+        return firstResource;
+    }
+       
+    private static String addSlash(String name) {
+        if (!name.endsWith("/")) {
+            name = name + "/";
+        }
+        return name;
+    }
+}

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleResourceFinder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleResourceFinder.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/BundleResourceFinder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain