Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Oberlies2015-02-11 12:32:16 -0500
committerTobias Oberlies2015-02-16 03:29:36 -0500
commitac896028a4cc69551aa137135fce3c06642016d5 (patch)
treec771dc79b6fcbb89323e55b09a2a3fd8a65b4cf8
parent82f2b6357622391f971295b0ebc8a8d0c2dd1ab6 (diff)
downloadrt.equinox.p2-ac896028a4cc69551aa137135fce3c06642016d5.tar.gz
rt.equinox.p2-ac896028a4cc69551aa137135fce3c06642016d5.tar.xz
rt.equinox.p2-ac896028a4cc69551aa137135fce3c06642016d5.zip
428889 Don't include installMode="root" features in the product IU
- Ignore features marked with installMode="root" when publishing products. This attribute is currently only supported by Tycho (cf. bug 427563 for adding p2 support for this) and entails that the feature must *not* be referenced from the product IU. This is achieved with the changed implementation of getFeatures(). - This change allows to get rid of separate product file pre-processing steps in Tycho. Bug: 428889 Change-Id: Ib7aa666c6746fbf417fa7437a7fa7b6a95ebd51f
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/FeatureInstallMode.java35
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/IProductDescriptor.java20
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/Messages.java1
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/ProductFile.java26
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/messages.properties1
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AdditionalCoreMatchers.java36
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductFileTest.java29
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/testData/ProductActionTest/rootFeatures.product23
8 files changed, 165 insertions, 6 deletions
diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/FeatureInstallMode.java b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/FeatureInstallMode.java
new file mode 100644
index 000000000..e21b67456
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/FeatureInstallMode.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2015 SAP SE and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * SAP SE - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.publisher.eclipse;
+
+import org.eclipse.osgi.util.NLS;
+
+enum FeatureInstallMode {
+ INCLUDE("include"), ROOT("root"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ private final String attributeValue;
+
+ private FeatureInstallMode(String attributeValue) {
+ this.attributeValue = attributeValue;
+ }
+
+ public static FeatureInstallMode parse(String value) {
+ if (value == null) {
+ return INCLUDE;
+ }
+ for (FeatureInstallMode mode : FeatureInstallMode.values()) {
+ if (mode.attributeValue.equals(value))
+ return mode;
+ }
+ throw new IllegalArgumentException(NLS.bind(Messages.exception_invalidFeatureInstallMode, value));
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/IProductDescriptor.java b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/IProductDescriptor.java
index 8bdc4be46..87f7fd0a9 100644
--- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/IProductDescriptor.java
+++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/IProductDescriptor.java
@@ -29,6 +29,15 @@ import org.eclipse.equinox.p2.repository.IRepositoryReference;
public interface IProductDescriptor {
/**
+ * Flag for {@link #getFeatures(int)} to obtain the features included in the product.
+ */
+ int INCLUDED_FEATURES = 0x1;
+ /**
+ * Flag for {@link #getFeatures(int)} to obtain the features to be installed as separately updatable roots.
+ */
+ int ROOT_FEATURES = 0x2;
+
+ /**
* Gets the name of the launcher.
*/
public String getLauncherName();
@@ -48,12 +57,21 @@ public interface IProductDescriptor {
public List<IVersionedId> getFragments();
/**
- * Returns the features listed in the product. Note: These features are only part of
+ * Returns the features listed in the product. Same as <code>getFeatures(INCLUDED_FEATURES)</code>. Note: These features are only part of
* the product if {@link #useFeatures()} returns <code>true</code>.
*/
public List<IVersionedId> getFeatures();
/**
+ * Returns the features listed in the product. Note: These features are only part of
+ * the product if {@link #useFeatures()} returns <code>true</code>.
+ * @param options bitmask to indicate what kind of features to return.
+ * @see #INCLUDED_FEATURES
+ * @see #ROOT_FEATURES
+ */
+ public List<IVersionedId> getFeatures(int options);
+
+ /**
* Returns the path to the config.ini file as specified in the .product file.
*/
public String getConfigIniPath(String os);
diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/Messages.java b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/Messages.java
index c914949a0..8c176ba2d 100644
--- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/Messages.java
+++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/Messages.java
@@ -22,6 +22,7 @@ public class Messages extends NLS {
public static String exception_featureParse;
public static String exception_productParse;
public static String exception_invalidProductContentType;
+ public static String exception_invalidFeatureInstallMode;
// feature parsing
public static String feature_parse_invalidIdOrVersion;
diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/ProductFile.java b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/ProductFile.java
index 73fd078dc..109837b64 100644
--- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/ProductFile.java
+++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/ProductFile.java
@@ -61,6 +61,7 @@ public class ProductFile extends DefaultHandler implements IProductDescriptor {
private static final String ATTRIBUTE_OS = "os"; //$NON-NLS-1$
private static final String ATTRIBUTE_ARCH = "arch"; //$NON-NLS-1$
private static final String ATTRIBUTE_ENABLED = "enabled"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_FEATURE_INSTALL_MODE = "installMode"; //$NON-NLS-1$
private static final String PROPERTY_ECLIPSE_APPLICATION = "eclipse.application"; //$NON-NLS-1$
private static final String PROPERTY_ECLIPSE_PRODUCT = "eclipse.product"; //$NON-NLS-1$
@@ -183,6 +184,7 @@ public class ProductFile extends DefaultHandler implements IProductDescriptor {
protected List<FeatureEntry> plugins = new ArrayList<FeatureEntry>();
protected List<FeatureEntry> fragments = new ArrayList<FeatureEntry>();
private final List<FeatureEntry> features = new ArrayList<FeatureEntry>();
+ private final List<FeatureEntry> rootFeatures = new ArrayList<FeatureEntry>();
private String splashLocation = null;
private String productName = null;
private String application = null;
@@ -393,10 +395,21 @@ public class ProductFile extends DefaultHandler implements IProductDescriptor {
* Returns a List<VersionedName> of features that constitute this product.
*/
public List<IVersionedId> getFeatures() {
+ return getFeatures(INCLUDED_FEATURES);
+ }
+
+ public List<IVersionedId> getFeatures(int options) {
List<IVersionedId> result = new LinkedList<IVersionedId>();
- for (FeatureEntry feature : features) {
- result.add(new VersionedId(feature.getId(), feature.getVersion()));
+ if ((options & INCLUDED_FEATURES) != 0) {
+ for (FeatureEntry feature : features) {
+ result.add(new VersionedId(feature.getId(), feature.getVersion()));
+ }
+ }
+ if ((options & ROOT_FEATURES) != 0) {
+ for (FeatureEntry feature : rootFeatures) {
+ result.add(new VersionedId(feature.getId(), feature.getVersion()));
+ }
}
return result;
@@ -1099,9 +1112,16 @@ public class ProductFile extends DefaultHandler implements IProductDescriptor {
private void processFeature(Attributes attributes) {
String featureId = attributes.getValue(ATTRIBUTE_ID);
String featureVersion = attributes.getValue(ATTRIBUTE_VERSION);
+ FeatureInstallMode installMode = FeatureInstallMode.parse(attributes.getValue(ATTRIBUTE_FEATURE_INSTALL_MODE));
FeatureEntry featureEntry = new FeatureEntry(featureId, featureVersion != null ? featureVersion : GENERIC_VERSION_NUMBER, false);
- features.add(featureEntry);
+ switch (installMode) {
+ case ROOT :
+ rootFeatures.add(featureEntry);
+ break;
+ default :
+ features.add(featureEntry);
+ }
}
private void processProduct(Attributes attributes) {
diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/messages.properties b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/messages.properties
index 4c63bca8c..99db74ae0 100644
--- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/messages.properties
+++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/messages.properties
@@ -16,6 +16,7 @@ exception_missingElement = Unable to find element: {0}.
exception_featureParse = Problems parsing the feature {0}.
exception_productParse = Problems parsing the product file {0}.
exception_invalidProductContentType=Provided value \"{0}\" for product content type is not valid. Allowed values are {1}
+exception_invalidFeatureInstallMode=Invalid value for attribute 'installMode': {0}
### feature parsing
feature_parse_invalidIdOrVersion= Invalid ID \"{0}\" or version \"{1}\" encountered.
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AdditionalCoreMatchers.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AdditionalCoreMatchers.java
new file mode 100644
index 000000000..1bd3c120e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AdditionalCoreMatchers.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2015 SAP SE and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * SAP SE - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.tests;
+
+import java.util.Collection;
+import org.hamcrest.*;
+
+public class AdditionalCoreMatchers {
+
+ /**
+ * Creates a matcher matching any collection with the given size.
+ *
+ * @see CoreMatchers#hasItem(Matcher)
+ */
+ public static <T> Matcher<Collection<? extends T>> hasSize(final int size) {
+ return new TypeSafeMatcher<Collection<? extends T>>() {
+
+ public void describeTo(Description description) {
+ description.appendText("a collection with size " + size);
+ }
+
+ protected boolean matchesSafely(Collection<? extends T> item) {
+ return item.size() == size;
+ }
+ };
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductFileTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductFileTest.java
index e62ca72bb..8ec7a5fb5 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductFileTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductFileTest.java
@@ -9,13 +9,18 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.publisher.actions;
+import static org.eclipse.equinox.p2.tests.AdditionalCoreMatchers.hasSize;
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
import java.util.List;
import java.util.Map;
import junit.framework.TestCase;
import org.eclipse.equinox.frameworkadmin.BundleInfo;
+import org.eclipse.equinox.internal.p2.publisher.eclipse.IProductDescriptor;
import org.eclipse.equinox.internal.p2.publisher.eclipse.ProductFile;
-import org.eclipse.equinox.p2.metadata.IVersionedId;
-import org.eclipse.equinox.p2.metadata.Version;
+import org.eclipse.equinox.p2.metadata.*;
import org.eclipse.equinox.p2.tests.TestData;
/**
@@ -28,6 +33,7 @@ public class ProductFileTest extends TestCase {
ProductFile noLauncherFlag = null;
ProductFile falseLauncherFlag = null;
ProductFile trueLauncherFlag = null;
+ ProductFile rootFeaturesProduct;
String configFile = "/org.eclipse.equinox.p2.tests/testData/ProductActionTest/productWithConfig/config.ini";
private String uidProductFileLocation;
@@ -41,6 +47,7 @@ public class ProductFileTest extends TestCase {
productFile = new ProductFile(productFileLocation);
uidProductFileLocation = TestData.getFile("ProductActionTest/productWithConfig", "uidproduct.product").toString();
uidProductFile = new ProductFile(uidProductFileLocation);
+ rootFeaturesProduct = new ProductFile(TestData.getFile("ProductActionTest", "rootFeatures.product").toString());
}
/**
@@ -112,6 +119,24 @@ public class ProductFileTest extends TestCase {
assertEquals("1.2", Version.create("3.5.0.v20081110-9C9tEvNEla71LZ2jFz-RFB-t"), ((IVersionedId) features.get(0)).getVersion());
}
+ public void testGetRootFeatures() {
+ List<IVersionedId> features = rootFeaturesProduct.getFeatures(IProductDescriptor.ROOT_FEATURES);
+ assertThat(features, hasItem(new VersionedId("org.eclipse.help", "2.0.102.v20140128")));
+ assertThat(features, hasItem(new VersionedId("org.eclipse.egit", "0.0.0")));
+ assertThat(features, hasSize(2));
+ }
+
+ public void testGetIncludedFeatures() {
+ List<IVersionedId> features = rootFeaturesProduct.getFeatures(IProductDescriptor.INCLUDED_FEATURES);
+ assertThat(features, hasItem(new VersionedId("org.eclipse.rcp", "4.4.0.v20140128")));
+ assertThat(features, hasItem(new VersionedId("org.eclipse.e4.rcp", "0.0.0")));
+ assertThat(features, hasSize(2));
+ }
+
+ public void testGetFeaturesOnlyReturnsIncludedFeatures() {
+ assertThat(rootFeaturesProduct.getFeatures(), is(rootFeaturesProduct.getFeatures(IProductDescriptor.INCLUDED_FEATURES)));
+ }
+
/**
* Test method for {@link org.eclipse.equinox.internal.p2.publisher.eclipse.ProductFile#getIcons(java.lang.String)}.
*/
diff --git a/bundles/org.eclipse.equinox.p2.tests/testData/ProductActionTest/rootFeatures.product b/bundles/org.eclipse.equinox.p2.tests/testData/ProductActionTest/rootFeatures.product
new file mode 100644
index 000000000..9bb6a22ae
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/testData/ProductActionTest/rootFeatures.product
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?pde version="3.5"?>
+
+<product uid="product.with.root.features" useFeatures="true" includeLaunchers="true">
+
+ <configIni use="default">
+ </configIni>
+
+ <launcherArgs>
+ <vmArgsMac>-XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts</vmArgsMac>
+ </launcherArgs>
+
+ <plugins>
+ </plugins>
+
+ <features>
+ <feature id="org.eclipse.rcp" version="4.4.0.v20140128" installMode="include"/>
+ <feature id="org.eclipse.e4.rcp"/> <!-- "include" is the default -->
+ <feature id="org.eclipse.help" version="2.0.102.v20140128" installMode="root"/>
+ <feature id="org.eclipse.egit" installMode="root"/>
+ </features>
+
+</product>

Back to the top