diff options
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 { |