diff options
author | toberlies | 2011-07-01 15:39:18 +0000 |
---|---|---|
committer | toberlies | 2011-07-01 15:39:18 +0000 |
commit | 5f0fb71330107d64a71b94c89443627bbc6dd159 (patch) | |
tree | 1006fb809a2d291ece522d95327b471a60dd79d8 | |
parent | 21aef5cd787b0b0408b13fcfb0efa7cff0a46c5d (diff) | |
download | rt.equinox.p2-5f0fb71330107d64a71b94c89443627bbc6dd159.tar.gz rt.equinox.p2-5f0fb71330107d64a71b94c89443627bbc6dd159.tar.xz rt.equinox.p2-5f0fb71330107d64a71b94c89443627bbc6dd159.zip |
247099 Ability to disable greedy behavior of optional dependencies
3 files changed, 65 insertions, 9 deletions
diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/BundlesAction.java b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/BundlesAction.java index aa7d3895b..f3eb893a5 100644 --- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/BundlesAction.java +++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/BundlesAction.java @@ -94,7 +94,23 @@ public class BundlesAction extends AbstractPublisherAction { private static final String FEATURE_FILENAME_DESCRIPTOR = "feature.xml"; //$NON-NLS-1$ private static final String PLUGIN_FILENAME_DESCRIPTOR = "plugin.xml"; //$NON-NLS-1$ private static final String FRAGMENT_FILENAME_DESCRIPTOR = "fragment.xml"; //$NON-NLS-1$ - public static String BUNDLE_SHAPE = "Eclipse-BundleShape"; //$NON-NLS-1$ + public static final String BUNDLE_SHAPE = "Eclipse-BundleShape"; //$NON-NLS-1$ + + /** + * Manifest header directive for specifying how optional runtime + * requirements shall be handled during installation. + * + * @see #INSTALLATION_GREEDY + */ + public static final String INSTALLATION_DIRECTIVE = "x-installation"; //$NON-NLS-1$ + + /** + * Value for {@link #INSTALLATION_DIRECTIVE} indicating that an optional + * requirement shall be installed unless this is prevented by other + * mandatory requirements. Optional requirements without this directive + * value are ignored during installation. + */ + public static final String INSTALLATION_GREEDY = "greedy"; //$NON-NLS-1$ private File[] locations; private BundleDescription[] bundles; @@ -151,20 +167,27 @@ public class BundlesAction extends AbstractPublisherAction { boolean isFragment = bd.getHost() != null; // boolean requiresAFragment = isFragment ? false : requireAFragment(bd, manifest); - //Process the required bundles + // Process the required bundles BundleSpecification requiredBundles[] = bd.getRequiredBundles(); ArrayList<IRequirement> reqsDeps = new ArrayList<IRequirement>(); // if (requiresAFragment) // reqsDeps.add(MetadataFactory.createRequiredCapability(CAPABILITY_TYPE_OSGI_FRAGMENTS, bd.getSymbolicName(), VersionRange.emptyRange, null, false, false)); if (isFragment) reqsDeps.add(MetadataFactory.createRequirement(CAPABILITY_NS_OSGI_BUNDLE, bd.getHost().getName(), PublisherHelper.fromOSGiVersionRange(bd.getHost().getVersionRange()), null, false, false)); + + ManifestElement[] rawRequireBundleHeader = parseManifestHeader(Constants.REQUIRE_BUNDLE, manifest, bd.getLocation()); for (BundleSpecification requiredBundle : requiredBundles) { - boolean optional = requiredBundle.isOptional(); - boolean greedy = !optional; + final boolean optional = requiredBundle.isOptional(); + final boolean greedy; + if (optional) + greedy = INSTALLATION_GREEDY.equals(getInstallationDirective(requiredBundle.getName(), rawRequireBundleHeader)); + else + greedy = true; reqsDeps.add(MetadataFactory.createRequirement(CAPABILITY_NS_OSGI_BUNDLE, requiredBundle.getName(), PublisherHelper.fromOSGiVersionRange(requiredBundle.getVersionRange()), null, optional ? 0 : 1, 1, greedy)); } // Process the import packages + ManifestElement[] rawImportPackageHeader = parseManifestHeader(Constants.IMPORT_PACKAGE, manifest, bd.getLocation()); ImportPackageSpecification osgiImports[] = bd.getImportPackages(); for (int i = 0; i < osgiImports.length; i++) { // TODO we need to sort out how we want to handle wild-carded dynamic imports - for now we ignore them @@ -172,8 +195,12 @@ public class BundlesAction extends AbstractPublisherAction { if (isDynamicImport(importSpec)) continue; VersionRange versionRange = PublisherHelper.fromOSGiVersionRange(importSpec.getVersionRange()); - boolean optional = isOptional(importSpec); - boolean greedy = !optional; + final boolean optional = isOptional(importSpec); + final boolean greedy; + if (optional) + greedy = INSTALLATION_GREEDY.equals(getInstallationDirective(importSpec.getName(), rawImportPackageHeader)); + else + greedy = true; //TODO this needs to be refined to take into account all the attribute handled by imports reqsDeps.add(MetadataFactory.createRequirement(PublisherHelper.CAPABILITY_NS_JAVA_PACKAGE, importSpec.getName(), versionRange, null, optional ? 0 : 1, 1, greedy)); } @@ -586,6 +613,29 @@ public class BundlesAction extends AbstractPublisherAction { } + private static ManifestElement[] parseManifestHeader(String header, Map<String, String> manifest, String bundleLocation) { + try { + return ManifestElement.parseHeader(header, manifest.get(header)); + } catch (BundleException e) { + String message = NLS.bind(Messages.exception_errorReadingManifest, bundleLocation, e.getMessage()); + LogHelper.log(new Status(IStatus.ERROR, Activator.ID, message, e)); + return null; + } + } + + private static String getInstallationDirective(String requirementId, ManifestElement[] correspondingBundleHeader) { + for (ManifestElement manifestElement : correspondingBundleHeader) { + String[] packages = manifestElement.getValueComponents(); + for (String pckg : packages) { + if (requirementId.equals(pckg)) { + return manifestElement.getDirective(INSTALLATION_DIRECTIVE); + } + } + } + // TODO this case indicates an internal error -> return assertion error status + return null; + } + public BundlesAction(File[] locations) { this.locations = locations; } diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/BundlesActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/BundlesActionTest.java index 4879f0116..a8f4ab6be 100644 --- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/BundlesActionTest.java +++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/BundlesActionTest.java @@ -51,7 +51,9 @@ public class BundlesActionTest extends ActionTest { private static final String TEST3_PROVBUNDLE_NAME = "test3";//$NON-NLS-1$ private static final String TEST4_PROVBUNDLE_NAME = "test4";//$NON-NLS-1$ private static final String TEST4_REQ_PACKAGE_OPTIONAL_NAME = "iue";//$NON-NLS-1$ + private static final String TEST4_REQ_PACKAGE_OPTGREEDY_NAME = "iuf";//$NON-NLS-1$ private static final String TEST4_REQ_BUNDLE_OPTIONAL_NAME = "iug";//$NON-NLS-1$ + private static final String TEST4_REQ_BUNDLE_OPTGREEDY_NAME = "iuh";//$NON-NLS-1$ private static final File TEST_BASE = new File(TestActivator.getTestDataFolder(), "BundlesActionTest");//$NON-NLS-1$ private static final File TEST_FILE1 = new File(TEST_BASE, TEST1_PROVBUNDLE_NAME); @@ -303,8 +305,10 @@ public class BundlesActionTest extends ActionTest { // check required capabilities Collection<IRequirement> requiredCapability = bundle4IU.getRequirements(); verifyRequiredCapability(requiredCapability, JAVA_PACKAGE, TEST4_REQ_PACKAGE_OPTIONAL_NAME, DEFAULT_VERSION_RANGE, 0, 1, false); + verifyRequiredCapability(requiredCapability, JAVA_PACKAGE, TEST4_REQ_PACKAGE_OPTGREEDY_NAME, DEFAULT_VERSION_RANGE, 0, 1, true); verifyRequiredCapability(requiredCapability, OSGI, TEST4_REQ_BUNDLE_OPTIONAL_NAME, DEFAULT_VERSION_RANGE, 0, 1, false); - assertEquals("2.0", 2, requiredCapability.size()); + verifyRequiredCapability(requiredCapability, OSGI, TEST4_REQ_BUNDLE_OPTGREEDY_NAME, DEFAULT_VERSION_RANGE, 0, 1, true); + assertEquals("2.0", 4, requiredCapability.size()); } public void cleanup() { diff --git a/bundles/org.eclipse.equinox.p2.tests/testData/BundlesActionTest/test4/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.tests/testData/BundlesActionTest/test4/META-INF/MANIFEST.MF index 13d7ce505..e9cce7f66 100644 --- a/bundles/org.eclipse.equinox.p2.tests/testData/BundlesActionTest/test4/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.p2.tests/testData/BundlesActionTest/test4/META-INF/MANIFEST.MF @@ -3,5 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: test4 Bundle-SymbolicName: test4;singleton:=true Bundle-Version: 2.0.1 -Import-Package: iue;resolution:=optional -Require-Bundle: iug;resolution:=optional
\ No newline at end of file +Import-Package: iue;resolution:=optional, + iuf;resolution:=optional;x-installation:=greedy +Require-Bundle: iug;resolution:=optional, + iuh;resolution:=optional;x-installation:=greedy |