Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortoberlies2011-07-01 15:39:18 +0000
committertoberlies2011-07-01 15:39:18 +0000
commit5f0fb71330107d64a71b94c89443627bbc6dd159 (patch)
tree1006fb809a2d291ece522d95327b471a60dd79d8
parent21aef5cd787b0b0408b13fcfb0efa7cff0a46c5d (diff)
downloadrt.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
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/BundlesAction.java62
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/BundlesActionTest.java6
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/testData/BundlesActionTest/test4/META-INF/MANIFEST.MF6
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

Back to the top