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 });