Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal Rapicault2011-04-11 08:42:27 -0400
committerPascal Rapicault2011-04-11 08:42:27 -0400
commit0d994b471404206e9bb84c89c04ff0491f70ea08 (patch)
treed63d786c6229c2c365ed1e98d874813941d9ae07
parent32d32d7038ee02b115135571e2c81e32b57b3b84 (diff)
downloadrt.equinox.p2-0d994b471404206e9bb84c89c04ff0491f70ea08.tar.gz
rt.equinox.p2-0d994b471404206e9bb84c89c04ff0491f70ea08.tar.xz
rt.equinox.p2-0d994b471404206e9bb84c89c04ff0491f70ea08.zip
Bug 341537 - more flexible feature dependency versions
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/FeatureManifestParser.java44
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/FeatureEntry.java38
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/FeaturesAction.java37
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/FeaturesActionTest.java61
4 files changed, 140 insertions, 40 deletions
diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/FeatureManifestParser.java b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/FeatureManifestParser.java
index 2c773db6f..3802959b2 100644
--- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/FeatureManifestParser.java
+++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/FeatureManifestParser.java
@@ -17,21 +17,14 @@ import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.MultiStatus;
-import org.eclipse.core.runtime.Status;
+import javax.xml.parsers.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.p2.metadata.VersionRange;
import org.eclipse.equinox.p2.publisher.eclipse.Feature;
import org.eclipse.equinox.p2.publisher.eclipse.FeatureEntry;
import org.eclipse.osgi.util.NLS;
-import org.eclipse.pde.internal.publishing.Activator;
-import org.eclipse.pde.internal.publishing.Constants;
-import org.eclipse.pde.internal.publishing.Messages;
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
+import org.eclipse.pde.internal.publishing.*;
+import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
/**
@@ -45,7 +38,7 @@ public class FeatureManifestParser extends DefaultHandler {
private URL url;
private StringBuffer characters = null;
private MultiStatus status = null;
- private boolean hasImports = false;
+ private final boolean hasImports = false;
private final List<String> messageKeys = new ArrayList<String>();
@@ -185,19 +178,24 @@ public class FeatureManifestParser extends DefaultHandler {
private void processImport(Attributes attributes) {
String id = attributes.getValue("feature"); //$NON-NLS-1$
+ boolean isPlugin = false;
+ if (id == null) {
+ id = attributes.getValue("plugin"); //$NON-NLS-1$
+ if (id == null)
+ throw new IllegalStateException();
+ isPlugin = true;
+ }
+ String versionStr = attributes.getValue("version"); //$NON-NLS-1$
FeatureEntry entry = null;
- if (id != null) {
- if ("true".equalsIgnoreCase(attributes.getValue("patch"))) { //$NON-NLS-1$ //$NON-NLS-2$
- entry = FeatureEntry.createRequires(id, attributes.getValue("version"), "perfect", attributes.getValue("filter"), false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- entry.setPatch(true);
- } else {
- entry = FeatureEntry.createRequires(id, attributes.getValue("version"), attributes.getValue("match"), attributes.getValue("filter"), false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
+ if ("versionRange".equals(attributes.getValue("match"))) { //$NON-NLS-1$//$NON-NLS-2$
+ VersionRange versionRange = new VersionRange(versionStr);
+ entry = FeatureEntry.createRequires(id, versionRange, attributes.getValue("match"), attributes.getValue("filter"), isPlugin); //$NON-NLS-1$ //$NON-NLS-2$
} else {
- id = attributes.getValue("plugin"); //$NON-NLS-1$
- entry = FeatureEntry.createRequires(id, attributes.getValue("version"), attributes.getValue("match"), attributes.getValue("filter"), true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ entry = FeatureEntry.createRequires(id, versionStr, attributes.getValue("match"), attributes.getValue("filter"), isPlugin); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (!isPlugin && "true".equalsIgnoreCase(attributes.getValue("patch"))) { //$NON-NLS-1$ //$NON-NLS-2$
+ entry.setPatch(true);
}
- hasImports = true;
result.addEntry(entry);
}
diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/FeatureEntry.java b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/FeatureEntry.java
index 6c8c862b6..2c4736443 100644
--- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/FeatureEntry.java
+++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/FeatureEntry.java
@@ -12,12 +12,13 @@
package org.eclipse.equinox.p2.publisher.eclipse;
import org.eclipse.equinox.p2.metadata.Version;
+import org.eclipse.equinox.p2.metadata.VersionRange;
/**
*/
public class FeatureEntry implements IPlatformEntry {
private final String id;
- private String version;
+ private String versionOrRange;
private String url;
private String os;
private String ws;
@@ -39,6 +40,19 @@ public class FeatureEntry implements IPlatformEntry {
FeatureEntry result = new FeatureEntry(id, version, isPlugin);
result.match = match;
result.isRequires = true;
+ // for requires we don't care what the form is so leave it as false (JAR'd)
+ result.unpack = false;
+ if (filter != null)
+ result.setFilter(filter);
+ return result;
+ }
+
+ public static FeatureEntry createRequires(String id, VersionRange versionRange, String match, String filter, boolean isPlugin) {
+ FeatureEntry result = new FeatureEntry(id, versionRange, isPlugin);
+ result.match = match;
+ result.isRequires = true;
+ // for requires we don't care what the form is so leave it as false (JAR'd)
+ result.unpack = false;
if (filter != null)
result.setFilter(filter);
return result;
@@ -46,7 +60,13 @@ public class FeatureEntry implements IPlatformEntry {
public FeatureEntry(String id, String version, boolean isPlugin) {
this.id = id;
- this.version = Version.parseVersion(version).toString();
+ this.versionOrRange = Version.parseVersion(version).toString();
+ this.isPlugin = isPlugin;
+ }
+
+ public FeatureEntry(String id, VersionRange versionRange, boolean isPlugin) {
+ this.id = id;
+ this.versionOrRange = versionRange.toString();
this.isPlugin = isPlugin;
}
@@ -64,10 +84,10 @@ public class FeatureEntry implements IPlatformEntry {
return false;
} else if (!id.equals(other.id))
return false;
- if (version == null) {
- if (other.version != null)
+ if (versionOrRange == null) {
+ if (other.versionOrRange != null)
return false;
- } else if (!version.equals(other.version))
+ } else if (!versionOrRange.equals(other.versionOrRange))
return false;
if (isPlugin() != other.isPlugin())
@@ -109,7 +129,7 @@ public class FeatureEntry implements IPlatformEntry {
}
public String getVersion() {
- return version;
+ return versionOrRange;
}
public String getWS() {
@@ -121,7 +141,7 @@ public class FeatureEntry implements IPlatformEntry {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
- result = prime * result + ((version == null) ? 0 : version.hashCode());
+ result = prime * result + ((versionOrRange == null) ? 0 : versionOrRange.hashCode());
return result;
}
@@ -177,7 +197,7 @@ public class FeatureEntry implements IPlatformEntry {
}
public void setVersion(String value) {
- version = Version.parseVersion(value).toString();
+ versionOrRange = Version.parseVersion(value).toString();
}
@Override
@@ -186,7 +206,7 @@ public class FeatureEntry implements IPlatformEntry {
result.append(isRequires ? "Requires: " : ""); //$NON-NLS-1$ //$NON-NLS-2$
result.append(isPlugin ? "Plugin: " : "Feature: "); //$NON-NLS-1$ //$NON-NLS-2$
result.append(id != null ? id.toString() : ""); //$NON-NLS-1$
- result.append(version != null ? " " + version.toString() : ""); //$NON-NLS-1$ //$NON-NLS-2$
+ result.append(versionOrRange != null ? " " + versionOrRange.toString() : ""); //$NON-NLS-1$ //$NON-NLS-2$
return result.toString();
}
diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/FeaturesAction.java b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/FeaturesAction.java
index b69b6611f..0201801a4 100644
--- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/FeaturesAction.java
+++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/FeaturesAction.java
@@ -13,21 +13,44 @@ package org.eclipse.equinox.p2.publisher.eclipse;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
import java.util.Map.Entry;
-import org.eclipse.core.runtime.*;
-import org.eclipse.equinox.internal.p2.core.helpers.*;
+import java.util.StringTokenizer;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.URIUtil;
+import org.eclipse.equinox.internal.p2.core.helpers.FileUtils;
import org.eclipse.equinox.internal.p2.core.helpers.FileUtils.IPathComputer;
+import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
import org.eclipse.equinox.internal.p2.metadata.ArtifactKey;
import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
import org.eclipse.equinox.internal.p2.publisher.FileSetDescriptor;
import org.eclipse.equinox.internal.p2.publisher.Messages;
import org.eclipse.equinox.internal.p2.publisher.eclipse.FeatureParser;
-import org.eclipse.equinox.p2.metadata.*;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.metadata.ILicense;
+import org.eclipse.equinox.p2.metadata.IProvidedCapability;
+import org.eclipse.equinox.p2.metadata.IRequirement;
+import org.eclipse.equinox.p2.metadata.IRequirementChange;
+import org.eclipse.equinox.p2.metadata.ITouchpointType;
+import org.eclipse.equinox.p2.metadata.IUpdateDescriptor;
+import org.eclipse.equinox.p2.metadata.MetadataFactory;
import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription;
import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitPatchDescription;
+import org.eclipse.equinox.p2.metadata.Version;
+import org.eclipse.equinox.p2.metadata.VersionRange;
import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
-import org.eclipse.equinox.p2.publisher.*;
+import org.eclipse.equinox.p2.publisher.AbstractPublisherAction;
+import org.eclipse.equinox.p2.publisher.IPublisherInfo;
+import org.eclipse.equinox.p2.publisher.IPublisherResult;
import org.eclipse.equinox.p2.publisher.actions.IFeatureRootAdvice;
import org.eclipse.equinox.p2.repository.IRepository;
import org.eclipse.equinox.p2.repository.IRepositoryReference;
@@ -558,12 +581,14 @@ public class FeaturesAction extends AbstractPublisherAction {
String versionSpec = entry.getVersion();
if (versionSpec == null)
return VersionRange.emptyRange;
+ String match = entry.getMatch();
+ if ("versionRange".equals(match)) //$NON-NLS-1$
+ return new VersionRange(versionSpec);
Version version = Version.parseVersion(versionSpec);
if (version.equals(Version.emptyVersion))
return VersionRange.emptyRange;
if (!entry.isRequires())
return new VersionRange(version, true, version, true);
- String match = entry.getMatch();
if (match == null)
// TODO should really be returning VersionRange.emptyRange here...
return null;
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/FeaturesActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/FeaturesActionTest.java
index b2614eb9c..4b067a0e8 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/FeaturesActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/FeaturesActionTest.java
@@ -25,6 +25,7 @@ import org.eclipse.equinox.internal.p2.metadata.IRequiredCapability;
import org.eclipse.equinox.p2.metadata.*;
import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription;
import org.eclipse.equinox.p2.metadata.expression.ExpressionUtil;
+import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
import org.eclipse.equinox.p2.publisher.*;
import org.eclipse.equinox.p2.publisher.actions.*;
import org.eclipse.equinox.p2.publisher.eclipse.FeaturesAction;
@@ -64,8 +65,64 @@ public class FeaturesActionTest extends ActionTest {
debug("Completed FeaturesAction."); //$NON-NLS-1$
}
- public void testFeaturePatch() {
- //TODO add a test for generating a feature patch
+ public void testFeaturePatch() throws Exception {
+ File testFolder = getTestFolder("FeaturesAction.testFilters");
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("<feature id=\"test.feature\" version=\"1.0.0\" > \n");
+ buffer.append(" <requires> \n");
+ buffer.append(" <import feature=\"org.foo\" version=\"[1.0.0,2.0.0)\" match=\"versionRange\" patch=\"true\"/> \n");
+ buffer.append(" </requires> \n");
+ buffer.append("</feature> \n");
+ File featureXML = new File(testFolder, "feature.xml");
+ writeBuffer(featureXML, buffer);
+
+ publisherInfo = new PublisherInfo();
+ FeaturesAction action = new FeaturesAction(new File[] {testFolder});
+ action.perform(publisherInfo, publisherResult, new NullProgressMonitor());
+
+ IInstallableUnitPatch iu = (IInstallableUnitPatch) publisherResult.getIU("test.feature.feature.group", Version.parseVersion("1.0.0"), null);
+ IRequirement[][] applicabilityScope = iu.getApplicabilityScope();
+ assertEquals(1, applicabilityScope.length);
+ IRequiredCapability require = (IRequiredCapability) applicabilityScope[0][0];
+ assertEquals("org.foo.feature.group", require.getName());
+ IMatchExpression<IInstallableUnit> matches = require.getMatches();
+ assertEquals("providedCapabilities.exists(x | x.name == $0 && x.namespace == $1 && x.version >= $2 && x.version < $3)", matches.toString());
+ assertEquals(Version.parseVersion("1.0.0"), matches.getParameters()[2]);
+ assertEquals(Version.parseVersion("2.0.0"), matches.getParameters()[3]);
+ }
+
+ public void testMatchRange() throws Exception {
+ File testFolder = getTestFolder("FeaturesAction.testFilters");
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("<feature id=\"test.feature\" version=\"1.0.0\" > \n");
+ buffer.append(" <requires> \n");
+ buffer.append(" <import plugin=\"org.plug\" version=\"[1.0.0,2.0.0)\" match=\"versionRange\" /> \n");
+ buffer.append(" <import feature=\"org.foo\" version=\"[1.0.0,2.0.0)\" match=\"versionRange\" /> \n");
+ buffer.append(" </requires> \n");
+ buffer.append("</feature> \n");
+ File featureXML = new File(testFolder, "feature.xml");
+ writeBuffer(featureXML, buffer);
+
+ publisherInfo = new PublisherInfo();
+ FeaturesAction action = new FeaturesAction(new File[] {testFolder});
+ action.perform(publisherInfo, publisherResult, new NullProgressMonitor());
+
+ IInstallableUnit iu = publisherResult.getIU("test.feature.feature.group", Version.parseVersion("1.0.0"), null);
+ Collection<IRequirement> requires = iu.getRequirements();
+ assertEquals(3, requires.size());
+ for (IRequirement require : requires) {
+ if (((IRequiredCapability) require).getName().equals("org.foo.feature.group")) {
+ IMatchExpression<IInstallableUnit> matches = require.getMatches();
+ assertEquals("providedCapabilities.exists(x | x.name == $0 && x.namespace == $1 && x.version >= $2 && x.version < $3)", matches.toString());
+ assertEquals(Version.parseVersion("1.0.0"), matches.getParameters()[2]);
+ assertEquals(Version.parseVersion("2.0.0"), matches.getParameters()[3]);
+ } else if (((IRequiredCapability) require).getName().equals("org.plug")) {
+ IMatchExpression<IInstallableUnit> matches = require.getMatches();
+ assertEquals("providedCapabilities.exists(x | x.name == $0 && x.namespace == $1 && x.version >= $2 && x.version < $3)", matches.toString());
+ assertEquals(Version.parseVersion("1.0.0"), matches.getParameters()[2]);
+ assertEquals(Version.parseVersion("2.0.0"), matches.getParameters()[3]);
+ }
+ }
}
public void testFilters() throws Exception {

Back to the top