You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by at...@apache.org on 2010/01/11 20:35:04 UTC

svn commit: r898026 - in /incubator/aries/trunk/jmx/jmx-core/src: main/java/org/apache/aries/jmx/util/FrameworkUtils.java test/java/org/apache/aries/jmx/codec/BundleDataTest.java test/java/org/apache/aries/jmx/util/FrameworkUtilsTest.java

Author: atk
Date: Mon Jan 11 19:35:03 2010
New Revision: 898026

URL: http://svn.apache.org/viewvc?rev=898026&view=rev
Log:
ARIES-113 consider headers when performing dependency resolution

Modified:
    incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/util/FrameworkUtils.java
    incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleDataTest.java
    incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/util/FrameworkUtilsTest.java

Modified: incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/util/FrameworkUtils.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/util/FrameworkUtils.java?rev=898026&r1=898025&r2=898026&view=diff
==============================================================================
--- incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/util/FrameworkUtils.java (original)
+++ incubator/aries/trunk/jmx/jmx-core/src/main/java/org/apache/aries/jmx/util/FrameworkUtils.java Mon Jan 11 19:35:03 2010
@@ -25,6 +25,7 @@
 import static org.osgi.jmx.framework.BundleStateMBean.UNKNOWN;
 
 import java.util.ArrayList;
+import java.util.Dictionary;
 import java.util.List;
 
 import org.osgi.framework.Bundle;
@@ -49,7 +50,7 @@
 
     /**
      * 
-     * Returns the Bundle object for a given id 
+     * Returns the Bundle object for a given id
      * 
      * @param bundleContext
      * @param bundleId
@@ -99,7 +100,8 @@
         }
         ServiceReference result = null;
         try {
-            ServiceReference[] references = bundleContext.getAllServiceReferences(null, "(" + Constants.SERVICE_ID + "=" + serviceId + ")");
+            ServiceReference[] references = bundleContext.getAllServiceReferences(null, "(" + Constants.SERVICE_ID
+                    + "=" + serviceId + ")");
             if (references == null || references.length < 1) {
                 throw new IllegalArgumentException("Service with id [" + serviceId + "] Not Found");
             } else {
@@ -107,10 +109,10 @@
             }
         } catch (InvalidSyntaxException e) {
             throw new IllegalStateException("Failure when resolving service ", e);
-        } 
+        }
         return result;
     }
-    
+
     /**
      * Returns an array of service.id values
      * 
@@ -210,16 +212,20 @@
 
     /**
      * Returns the resolved package imports for the given bundle
-     * @param localBundleContext BundleContext object of this bundle/caller
-     * @param bundle target Bundle object to query imported packages for
+     * 
+     * @param localBundleContext
+     *            BundleContext object of this bundle/caller
+     * @param bundle
+     *            target Bundle object to query imported packages for
      * @param packageAdmin
      * 
      * @return
      * @throws IllegalArgumentException
      *             if fragment or packageAdmin are null
      */
-    public static String[] getBundleImportedPackages(BundleContext localBundleContext, Bundle bundle, PackageAdmin packageAdmin)
-            throws IllegalArgumentException {
+    @SuppressWarnings("unchecked")
+    public static String[] getBundleImportedPackages(BundleContext localBundleContext, Bundle bundle,
+            PackageAdmin packageAdmin) throws IllegalArgumentException {
         if (bundle == null) {
             throw new IllegalArgumentException("Argument bundle cannot be null");
         }
@@ -227,23 +233,46 @@
             throw new IllegalArgumentException("Argument packageAdmin cannot be null");
         }
         List<String> result = new ArrayList<String>();
-        // TODO - Is there an easier way to achieve this? Unable to find a direct way through Framework
-        // API to find the actual package wiring
-        Bundle[] bundles = localBundleContext.getBundles();
-        for (Bundle candidate : bundles) {
-            if (candidate.equals(bundle)) {
-                continue;
+        Dictionary<String, String> bundleHeaders = bundle.getHeaders();
+        String dynamicImportHeader = bundleHeaders.get(Constants.DYNAMICIMPORT_PACKAGE);
+        // if DynamicImport-Package used, then do full iteration
+        if (dynamicImportHeader != null && dynamicImportHeader.contains("*")) {
+            Bundle[] bundles = localBundleContext.getBundles();
+            for (Bundle candidate : bundles) {
+                if (candidate.equals(bundle)) {
+                    continue;
+                }
+                ExportedPackage[] candidateExports = packageAdmin.getExportedPackages(candidate);
+                if (candidateExports != null) {
+                    for (ExportedPackage exportedPackage : candidateExports) {
+                        Bundle[] userBundles = exportedPackage.getImportingBundles();
+                        if (userBundles != null && arrayContains(userBundles, bundle)) {
+                            result.add(exportedPackage.getName() + ";" + exportedPackage.getVersion().toString());
+                        }
+                    }// end for candidateExports
+                }
+            }// end for bundles
+        } else { // only query ExportPackage for package names declared as imported
+            List<String> importPackages = new ArrayList<String>();
+            String importPackageHeader = bundleHeaders.get(Constants.IMPORT_PACKAGE);
+            if (importPackageHeader != null && importPackageHeader.length() > 0) {
+                importPackages.addAll(extractHeaderDeclaration(importPackageHeader));
             }
-            ExportedPackage[] candidateExports = packageAdmin.getExportedPackages(candidate);
-            if (candidateExports != null) {
-                for (ExportedPackage exportedPackage : candidateExports) {
-                    Bundle[] userBundles = exportedPackage.getImportingBundles();
-                    if (userBundles != null && arrayContains(userBundles, bundle)) {
-                        result.add(exportedPackage.getName() + ";" + exportedPackage.getVersion().toString());
-                    }
-                }// end for candidateExports
+            if (dynamicImportHeader != null) {
+                importPackages.addAll(extractHeaderDeclaration(dynamicImportHeader));
+            }
+            for (String packageName : importPackages) {
+                ExportedPackage[] candidateExports = packageAdmin.getExportedPackages(packageName);
+                if (candidateExports != null) {
+                    for (ExportedPackage exportedPackage : candidateExports) {
+                        Bundle[] userBundles = exportedPackage.getImportingBundles();
+                        if (userBundles != null && arrayContains(userBundles, bundle)) {
+                            result.add(exportedPackage.getName() + ";" + exportedPackage.getVersion().toString());
+                        }
+                    }// end for candidateExports
+                }
             }
-        }// end for bundles
+        }
         return result.toArray(new String[result.size()]);
     }
 
@@ -367,16 +396,20 @@
 
     /**
      * Returns an array of ids of bundles the given bundle depends on
-     * @param localBundleContext BundleContext object of this bundle/caller 
-     * @param bundle target Bundle object to query dependencies for
+     * 
+     * @param localBundleContext
+     *            BundleContext object of this bundle/caller
+     * @param bundle
+     *            target Bundle object to query dependencies for
      * @param packageAdmin
      * 
      * @return
      * @throws IllegalArgumentException
      *             if bundle or packageAdmin are null
      */
-    public static long[] getBundleDependencies(BundleContext localBundleContext, Bundle bundle, PackageAdmin packageAdmin)
-            throws IllegalArgumentException {
+    @SuppressWarnings("unchecked")
+    public static long[] getBundleDependencies(BundleContext localBundleContext, Bundle bundle,
+            PackageAdmin packageAdmin) throws IllegalArgumentException {
         if (bundle == null) {
             throw new IllegalArgumentException("Argument bundle cannot be null");
         }
@@ -384,20 +417,20 @@
             throw new IllegalArgumentException("Argument packageAdmin cannot be null");
         }
         List<Bundle> dependencies = new ArrayList<Bundle>();
-        // TODO - Is there an easier way to achieve this? Unable to find a direct way through Framework
-        // API to resolve the current dependencies
-        for (Bundle candidate : localBundleContext.getBundles()) {
-            if (candidate.equals(bundle)) {
-                continue;
-            }
-            RequiredBundle[] candidateRequiredBundles = packageAdmin.getRequiredBundles(candidate.getSymbolicName());
-            if (candidateRequiredBundles == null) {
-                continue;
-            } else {
-                for (RequiredBundle candidateRequiredBundle : candidateRequiredBundles) {
-                    Bundle[] bundlesRequiring = candidateRequiredBundle.getRequiringBundles();
-                    if (bundlesRequiring != null && arrayContains(bundlesRequiring, bundle)) {
-                        dependencies.add(candidateRequiredBundle.getBundle());
+        Dictionary<String, String> bundleHeaders = bundle.getHeaders();
+        String requireBundleHeader = bundleHeaders.get(Constants.REQUIRE_BUNDLE);
+        if (requireBundleHeader != null) { // only check if Require-Bundle is used
+            List<String> bundleSymbolicNames = extractHeaderDeclaration(requireBundleHeader);
+            for (String bundleSymbolicName: bundleSymbolicNames) {
+                RequiredBundle[] candidateRequiredBundles = packageAdmin.getRequiredBundles(bundleSymbolicName);
+                if (candidateRequiredBundles == null) {
+                    continue;
+                } else {
+                    for (RequiredBundle candidateRequiredBundle : candidateRequiredBundles) {
+                        Bundle[] bundlesRequiring = candidateRequiredBundle.getRequiringBundles();
+                        if (bundlesRequiring != null && arrayContains(bundlesRequiring, bundle)) {
+                            dependencies.add(candidateRequiredBundle.getBundle());
+                        }
                     }
                 }
             }
@@ -479,4 +512,17 @@
         }
         return result;
     }
+
+    /*
+     * Will parse a header value, strip out trailing attributes and return a list of declarations
+     */
+    public static List<String> extractHeaderDeclaration(String headerStatement) {
+        List<String> result = new ArrayList<String>();
+        for (String headerDeclaration : headerStatement.split("\\s*,\\s*")) {
+            String name = headerDeclaration.contains(";") ? headerDeclaration.substring(0, headerDeclaration
+                    .indexOf(";")) : headerDeclaration;
+            result.add(name);
+        }
+        return result;
+    }
 }

Modified: incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleDataTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleDataTest.java?rev=898026&r1=898025&r2=898026&view=diff
==============================================================================
--- incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleDataTest.java (original)
+++ incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/codec/BundleDataTest.java Mon Jan 11 19:35:03 2010
@@ -123,6 +123,7 @@
         when(ep2.getImportingBundles()).thenReturn(new Bundle[] { bundle, b3 });
         when(ep2.getName()).thenReturn("org.apache.aries.jmx.b2");
         when(ep2.getVersion()).thenReturn(Version.parseVersion("2.0.1"));
+        headers.put(Constants.DYNAMICIMPORT_PACKAGE, "*");
   
         when(packageAdmin.getExportedPackages(b1)).thenReturn(new ExportedPackage[] { ep1 });
         when(packageAdmin.getExportedPackages(b2)).thenReturn(new ExportedPackage[] { ep2 });
@@ -138,7 +139,7 @@
         RequiredBundle rb3 = mock(RequiredBundle.class);
         when(rb3.getBundle()).thenReturn(b3);
         when(rb3.getRequiringBundles()).thenReturn(new Bundle[] { bundle, b1, b2 });
-        
+        headers.put(Constants.REQUIRE_BUNDLE, "b1;bundle-version=\"1.0.0\",b3;bundle-version=\"2.0.0\"");
         when(packageAdmin.getRequiredBundles("b1")).thenReturn(new RequiredBundle[] { rb1 });
         when(packageAdmin.getRequiredBundles("b2")).thenReturn(new RequiredBundle[] { rb2 });
         when(packageAdmin.getRequiredBundles("b3")).thenReturn(new RequiredBundle[] { rb3 });
@@ -159,7 +160,7 @@
         assertEquals("test", compositeData.get(SYMBOLIC_NAME));
         assertEquals("0.0.0", (String) compositeData.get(VERSION));
         TabularData headerTable = (TabularData) compositeData.get(HEADERS);
-        assertEquals(2, headerTable.values().size());
+        assertEquals(4, headerTable.values().size());
         assertArrayEquals(new String[] { "org.apache.aries.jmx;1.0.0"} , (String[]) compositeData.get(EXPORTED_PACKAGES));
         assertArrayEquals(new String[] { "org.apache.aries.jmx.b1;0.0.0" , "org.apache.aries.jmx.b2;2.0.1"}, (String[]) compositeData.get(IMPORTED_PACKAGES));
         assertArrayEquals(new Long[] { new Long(44), new Long(66) }, (Long[]) compositeData.get(REQUIRED_BUNDLES));

Modified: incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/util/FrameworkUtilsTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/util/FrameworkUtilsTest.java?rev=898026&r1=898025&r2=898026&view=diff
==============================================================================
--- incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/util/FrameworkUtilsTest.java (original)
+++ incubator/aries/trunk/jmx/jmx-core/src/test/java/org/apache/aries/jmx/util/FrameworkUtilsTest.java Mon Jan 11 19:35:03 2010
@@ -35,6 +35,9 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import java.util.Dictionary;
+import java.util.Hashtable;
+
 import org.junit.Test;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -141,9 +144,24 @@
         when(admin.getExportedPackages(b2)).thenReturn(new ExportedPackage[] { ep2 });
         when(admin.getExportedPackages(b3)).thenReturn(null);
         
+        //check first with DynamicImport
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        headers.put(Constants.DYNAMICIMPORT_PACKAGE, "*");
+        when(bundle.getHeaders()).thenReturn(headers);
+        assertArrayEquals(new String[] { "org.apache.aries.jmx.b1;0.0.0" , "org.apache.aries.jmx.b2;2.0.1"} 
+                    , getBundleImportedPackages(context, bundle, admin));
+        
+        //check with ImportPackage statement
+        headers.remove(Constants.DYNAMICIMPORT_PACKAGE);
+        String importPackageStatement = "org.apache.aries.jmx.b1;version=0.0.0;resolution:=optional,org.apache.aries.jmx.b2;attribute:=value"; 
+        headers.put(Constants.IMPORT_PACKAGE, importPackageStatement);
+        when(admin.getExportedPackages("org.apache.aries.jmx.b1")).thenReturn(new ExportedPackage[] { ep1 });
+        when(admin.getExportedPackages("org.apache.aries.jmx.b2")).thenReturn(new ExportedPackage[] { ep2 });
+        
         assertArrayEquals(new String[] { "org.apache.aries.jmx.b1;0.0.0" , "org.apache.aries.jmx.b2;2.0.1"} 
                     , getBundleImportedPackages(context, bundle, admin));
         
+        
     }
     
     @Test
@@ -239,6 +257,9 @@
         
         when(context.getBundles()).thenReturn(new Bundle[] { bundle, b1, b2, b3 });
         
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        when(bundle.getHeaders()).thenReturn(headers);
+        
         PackageAdmin admin = mock(PackageAdmin.class);
         assertEquals(0, getBundleDependencies(context, bundle, admin).length);
         
@@ -252,6 +273,8 @@
         when(rb3.getBundle()).thenReturn(b3);
         when(rb3.getRequiringBundles()).thenReturn(new Bundle[] { bundle, b1, b2 });
         
+        headers.put(Constants.REQUIRE_BUNDLE, "b1;bundle-version=\"1.0.0\",b3;bundle-version=\"2.0.0\"");
+        
         when(admin.getRequiredBundles("b1")).thenReturn(new RequiredBundle[] { rb1 });
         when(admin.getRequiredBundles("b2")).thenReturn(new RequiredBundle[] { rb2 });
         when(admin.getRequiredBundles("b3")).thenReturn(new RequiredBundle[] { rb3 });