Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal Rapicault2008-04-23 12:05:39 -0400
committerPascal Rapicault2008-04-23 12:05:39 -0400
commit18e4d1a93ed0062c5e45147b9d1763e17feed988 (patch)
treedbd00c8f384a3a3fc5ccb826cf45976e394b489a /bundles
parent87cb1f672019a8aa4d4ca99646ada3fcfbd3b59e (diff)
downloadrt.equinox.p2-18e4d1a93ed0062c5e45147b9d1763e17feed988.tar.gz
rt.equinox.p2-18e4d1a93ed0062c5e45147b9d1763e17feed988.tar.xz
rt.equinox.p2-18e4d1a93ed0062c5e45147b9d1763e17feed988.zip
Bug 215924 - [prov] Metadata for fix pack aka patchesPost_patches_merge
Diffstat (limited to 'bundles')
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/ApplicablePatchQuery.java47
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java208
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Slicer.java21
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/resolution/ResolutionHelper.java6
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.generator/Metadata Generator Plugins and Features.launch23
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/p2/metadata/generator/features/FeatureParser.java5
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/FeatureEntry.java9
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/MetadataGeneratorHelper.java78
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/io/MetadataParser.java178
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/io/MetadataWriter.java47
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/io/XMLConstants.java8
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/IInstallableUnit.java8
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/IInstallableUnitPatch.java17
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/InstallableUnitPatch.java52
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/MetadataFactory.java37
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/RequirementChange.java126
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AbstractProvisioningTest.java47
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/generator/PatchIUGeneration.java48
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/IUPatchPersistenceTest.java370
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/IUPersistenceTest.java54
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/AllTests.java13
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest1.java49
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest10.java76
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest11.java76
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest12.java76
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest1b.java55
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest1c.java57
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest2.java99
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest3.java114
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest4.java123
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest5.java60
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest6.java97
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest7.java101
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest7b.java88
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest8.java90
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest9.java70
36 files changed, 2577 insertions, 56 deletions
diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/ApplicablePatchQuery.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/ApplicablePatchQuery.java
new file mode 100644
index 000000000..314d258f1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/ApplicablePatchQuery.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.internal.p2.director;
+
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.internal.provisional.p2.query.Query;
+
+public class ApplicablePatchQuery extends Query {
+ IInstallableUnit iu;
+
+ public ApplicablePatchQuery(IInstallableUnit iu) {
+ this.iu = iu;
+ }
+
+ public boolean isMatch(Object candidate) {
+ if (!(candidate instanceof IInstallableUnitPatch))
+ return false;
+ IInstallableUnitPatch patchIU = (IInstallableUnitPatch) candidate;
+ RequiredCapability[][] scopeDescription = patchIU.getApplicabilityScope();
+ if (scopeDescription == null)
+ return false;
+ if (scopeDescription.length == 0)
+ return true;
+
+ ProvidedCapability[] cap = iu.getProvidedCapabilities();
+ for (int i = 0; i < scopeDescription.length; i++) {
+ int matchedScopeEntry = scopeDescription[i].length;
+ for (int j = 0; j < scopeDescription[i].length; j++) {
+ for (int k = 0; k < cap.length; k++) {
+ if (cap[k].isSatisfiedBy(scopeDescription[i][j])) {
+ matchedScopeEntry--;
+ break;
+ }
+ }
+ }
+ if (matchedScopeEntry == 0)
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java
index 215e5f4a8..19eecbc46 100644
--- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java
+++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java
@@ -13,8 +13,7 @@ import java.io.*;
import java.util.*;
import java.util.Map.Entry;
import org.eclipse.core.runtime.*;
-import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.internal.provisional.p2.metadata.RequiredCapability;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
import org.eclipse.equinox.internal.provisional.p2.metadata.query.CapabilityQuery;
import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery;
import org.eclipse.equinox.internal.provisional.p2.query.Collector;
@@ -33,12 +32,13 @@ import org.sat4j.specs.*;
* back into information understandable by the planner.
*/
public class Projector {
- private static boolean DEBUG = false;
+ private static boolean DEBUG = true;
private IQueryable picker;
private Map variables; //key IU, value corresponding variable in the problem
private Map noopVariables; //key IU, value corresponding no optionality variable in the problem,
private List abstractVariables;
+ private List abstractVarsForPatches;
private TwoTierMap slice; //The IUs that have been considered to be part of the problem
@@ -56,7 +56,7 @@ public class Projector {
private File problemFile;
private MultiStatus result;
- // private int commentsCount = 0;
+ private int commentsCount = 0;
public Projector(IQueryable q, Dictionary context) {
picker = q;
@@ -68,6 +68,7 @@ public class Projector {
dependencies = new ArrayList();
selectionContext = context;
abstractVariables = new ArrayList();
+ abstractVarsForPatches = new ArrayList();
result = new MultiStatus(DirectorActivator.PI_DIRECTOR, IStatus.OK, Messages.Planner_Problems_resolving_plan, null);
}
@@ -111,6 +112,10 @@ public class Projector {
return "-1 " + a + " -1 " + b + ">= -1 ;"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
+ private String implies(String a, String b) {
+ return "-1 " + a + " +1 " + b + ">= -1 ;"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+ }
+
//Create an optimization function favoring the highest version of each IU
private void createOptimizationFunction() {
final String MIN_STR = "min:"; //$NON-NLS-1$
@@ -163,7 +168,11 @@ public class Projector {
}
private void createNegation(IInstallableUnit iu) {
- tautologies.add(" +1" + getVariable(iu) + " = 0;"); //$NON-NLS-1$//$NON-NLS-2$
+ createNegation(getVariable(iu));
+ }
+
+ private void createNegation(String var) {
+ tautologies.add(" +1" + var + " = 0;"); //$NON-NLS-1$//$NON-NLS-2$
}
// Check whether the requirement is applicable
@@ -183,7 +192,7 @@ public class Projector {
try {
problemFile = File.createTempFile("p2Encoding", ".opb"); //$NON-NLS-1$//$NON-NLS-2$
BufferedWriter w = new BufferedWriter(new FileWriter(problemFile));
- int clauseCount = tautologies.size() + dependencies.size() + constraints.size();// - commentsCount;
+ int clauseCount = tautologies.size() + dependencies.size() + constraints.size() - commentsCount;
w.write("* #variable= " + varCount + " #constraint= " + clauseCount + " "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
w.newLine();
@@ -288,16 +297,132 @@ public class Projector {
return;
}
- RequiredCapability[] reqs = iu.getRequiredCapabilities();
- if (reqs.length == 0) {
- return;
+ Collector patches = getApplicablePatches(iu);
+ //No patches apply, normal code path
+ if (patches.size() == 0) {
+ RequiredCapability[] reqs = iu.getRequiredCapabilities();
+ if (reqs.length == 0) {
+ return;
+ }
+ for (int i = 0; i < reqs.length; i++) {
+ if (!isApplicable(reqs[i]))
+ continue;
+
+ expandRequirement(null, iu, reqs[i]);
+ }
+ addOptionalityExpression();
+ } else {
+ //Patches are applicable to the IU
+
+ //Unmodified dependencies
+ Map allRequirements = new HashMap(iu.getRequiredCapabilities().length);
+
+ for (Iterator iterator = patches.iterator(); iterator.hasNext();) {
+ IInstallableUnitPatch patch = (IInstallableUnitPatch) iterator.next();
+ RequiredCapability[][] reqs = mergeRequirements(iu, patch);
+ if (reqs.length == 0)
+ return;
+
+ List variablesResultingFromPatchApplication = new ArrayList();
+ int count = -1;
+ for (int i = 0; i < reqs.length; i++) {
+ if (reqs[i][0] == reqs[i][1]) //The requirement has not changed
+ continue;
+ if (!isApplicable(reqs[i][1])) //TODO We may have to do something here
+ continue;
+
+ //create IU & Patch -> reqVar
+ String appliedPatchVar = getVariableForAppliedPatches(iu, patch, reqs[i][0]);
+ commentsCount++;
+ dependencies.add("* " + iu + " & " + patch + "->" + appliedPatchVar); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ dependencies.add("-1 " + getVariable(iu) + " -1" + getVariable(patch) + " +1 " + appliedPatchVar + " = -1;"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+
+ variablesResultingFromPatchApplication.add(appliedPatchVar);
+ //Collect variable used to patch the requirement
+ List appliedPatchesVarForRequirement = (List) allRequirements.get(reqs[i][0]);
+ if (appliedPatchesVarForRequirement == null) {
+ appliedPatchesVarForRequirement = new ArrayList();
+ allRequirements.put(reqs[i][0], appliedPatchesVarForRequirement);
+ }
+ appliedPatchesVarForRequirement.add(appliedPatchVar);
+
+ expandRequirement(appliedPatchVar, iu, reqs[i][1]);
+ count++;
+ }
+ for (Iterator iterator2 = variablesResultingFromPatchApplication.iterator(); iterator2.hasNext();) {
+ String var = (String) iterator2.next();
+ commentsCount++;
+ dependencies.add("* " + patch + " -> " + var);
+ dependencies.add(implies(getVariable(patch), var));
+ }
+ }
+
+ //Generate expressions for requirements that have not been patched
+ RequiredCapability[] reqs = iu.getRequiredCapabilities();
+ if (reqs.length == 0) {
+ return;
+ }
+ for (int i = 0; i < reqs.length; i++) {
+ if (!isApplicable(reqs[i]))
+ continue;
+ String varForAllPatchedRequirement = null;
+ if (allRequirements.get(reqs[i]) != null) {
+ //generate the no patch expression summing all the req applications and generate a new variable
+ //A & !allRequissss -> AbsctVar
+ String expression = "-1 " + getVariable(iu); //$NON-NLS-1$
+ for (Iterator iterator = ((ArrayList) allRequirements.get(reqs[i])).iterator(); iterator.hasNext();) {
+ expression += " +1 " + (String) iterator.next(); //$NON-NLS-1$
+ }
+ varForAllPatchedRequirement = getVariableForAppliedPatches(null, null, null);
+ commentsCount++;
+ dependencies.add("* " + iu + " & !reqsvars ->" + varForAllPatchedRequirement);
+ expression += " +1 " + varForAllPatchedRequirement + " >= -1 ;"; //$NON-NLS-1$
+ dependencies.add(expression);
+ }
+
+ expandRequirement(varForAllPatchedRequirement, iu, reqs[i]);
+ }
+ addOptionalityExpression();
}
- for (int i = 0; i < reqs.length; i++) {
- if (isApplicable(reqs[i])) {
- expandRequirement(iu, reqs[i]);
+ }
+
+ private String getVariableForAppliedPatches(IInstallableUnit iu1, IInstallableUnit iu2, RequiredCapability req) {
+ String newVar = new String("x" + varCount++); //$NON-NLS-1$
+ abstractVarsForPatches.add(newVar);
+ return newVar;
+ }
+
+ //Return a new array of requirements representing the application of the patch
+ private RequiredCapability[][] mergeRequirements(IInstallableUnit iu, IInstallableUnitPatch patch) {
+ if (patch == null)
+ return null;
+ RequirementChange[] changes = patch.getRequirementsChange();
+ RequiredCapability[] originalRequirements = new RequiredCapability[iu.getRequiredCapabilities().length];
+ System.arraycopy(iu.getRequiredCapabilities(), 0, originalRequirements, 0, originalRequirements.length);
+ List rrr = new ArrayList();
+ boolean found = false;
+ for (int i = 0; i < changes.length; i++) {
+ for (int j = 0; j < originalRequirements.length; j++) {
+ if (originalRequirements[j] != null && changes[i].matches(originalRequirements[j])) {
+ found = true;
+ if (changes[i].newValue() != null)
+ rrr.add(new RequiredCapability[] {originalRequirements[j], changes[i].newValue()});
+ else
+ // case where a requirement is removed
+ rrr.add(new RequiredCapability[] {originalRequirements[j], null});
+ originalRequirements[j] = null;
+ }
+ // break;
}
+ if (!found && changes[i].applyOn() == null && changes[i].newValue() != null) //Case where a new requirement is added
+ rrr.add(new RequiredCapability[] {null, changes[i].newValue()});
+ }
+ //Add all the unmodified requirements to the result
+ for (int i = 0; i < originalRequirements.length; i++) {
+ if (originalRequirements[i] != null)
+ rrr.add(new RequiredCapability[] {originalRequirements[i], originalRequirements[i]});
}
- addOptionalityExpression();
+ return (RequiredCapability[][]) rrr.toArray(new RequiredCapability[rrr.size()][]);
}
private void addOptionalityExpression() {
@@ -310,30 +435,32 @@ public class Projector {
private String optionalityExpression = null;
private int countOptionalIUs = 0;
- private void expandOptionalRequirement(IInstallableUnit iu, RequiredCapability req) {
+ private void expandOptionalRequirement(String iuVar, IInstallableUnit iu, RequiredCapability req) {
+ if (iuVar == null)
+ iuVar = getVariable(iu);
String abstractVar = getAbstractVariable();
String expression = " -1 " + abstractVar; //$NON-NLS-1$
Collector matches = picker.query(new CapabilityQuery(req), new Collector(), null);
if (optionalityExpression == null)
- optionalityExpression = " -1 " + getVariable(iu) + " 1 " + getNoOperationVariable(iu); //$NON-NLS-1$ //$NON-NLS-2$
- // StringBuffer comment = new StringBuffer();
- // comment.append("* ");
- // comment.append(iu.toString());
- // comment.append(" requires optionaly either ");
+ optionalityExpression = " -1 " + iuVar + " 1 " + getNoOperationVariable(iu); //$NON-NLS-1$ //$NON-NLS-2$
+ StringBuffer comment = new StringBuffer();
+ comment.append("* ");
+ comment.append(iu.toString());
+ comment.append(" requires optionaly either ");
int countMatches = 0;
for (Iterator iterator = matches.iterator(); iterator.hasNext();) {
IInstallableUnit match = (IInstallableUnit) iterator.next();
if (isApplicable(match)) {
countMatches++;
expression += " 1 " + getVariable(match); //$NON-NLS-1$
- // comment.append(match.toString());
- // comment.append(' ');
+ comment.append(match.toString());
+ comment.append(' ');
}
}
countOptionalIUs += countMatches;
if (countMatches > 0) {
- // dependencies.add(comment.toString());
- // commentsCount++;
+ dependencies.add(comment.toString());
+ commentsCount++;
dependencies.add(impliesNo(getNoOperationVariable(iu), abstractVar));
dependencies.add(expression + " >= 0;"); //$NON-NLS-1$
optionalityExpression += " 1 " + abstractVar; //$NON-NLS-1$
@@ -343,40 +470,47 @@ public class Projector {
System.out.println("No IU found to satisfy optional dependency of " + iu + " req " + req); //$NON-NLS-1$//$NON-NLS-2$
}
- private void expandNormalRequirement(IInstallableUnit iu, RequiredCapability req) {
+ private void expandNormalRequirement(String varIu, IInstallableUnit iu, RequiredCapability req) {
//Generate the regular requirement
- String expression = "-1 " + getVariable(iu); //$NON-NLS-1$
+ if (varIu == null)
+ varIu = getVariable(iu);
+ String expression = "-1 " + varIu; //$NON-NLS-1$
Collector matches = picker.query(new CapabilityQuery(req), new Collector(), null);
- // StringBuffer comment = new StringBuffer();
- // comment.append("* ");
- // comment.append(iu.toString());
- // comment.append(" requires either ");
+ StringBuffer comment = new StringBuffer();
+ comment.append("* ");
+ comment.append(iu.toString());
+ comment.append(" requires either ");
int countMatches = 0;
for (Iterator iterator = matches.iterator(); iterator.hasNext();) {
IInstallableUnit match = (IInstallableUnit) iterator.next();
if (isApplicable(match)) {
countMatches++;
expression += " +1 " + getVariable(match); //$NON-NLS-1$
- // comment.append(match.toString());
- // comment.append(' ');
+ comment.append(match.toString());
+ comment.append(' ');
}
}
if (countMatches > 0) {
- // dependencies.add(comment.toString());
- // commentsCount++;
+ dependencies.add(comment.toString());
+ commentsCount++;
dependencies.add(expression + " >= 0;"); //$NON-NLS-1$
} else {
result.add(new Status(IStatus.WARNING, DirectorActivator.PI_DIRECTOR, NLS.bind(Messages.Planner_Unsatisfied_dependency, iu, req)));
- createNegation(iu);
+ createNegation(varIu);
}
}
- private void expandRequirement(IInstallableUnit iu, RequiredCapability req) {
+ //Return IUPatches that are applicable for the given iu
+ private Collector getApplicablePatches(IInstallableUnit iu) {
+ return picker.query(new ApplicablePatchQuery(iu), new Collector(), null);
+ }
+
+ private void expandRequirement(String var, IInstallableUnit iu, RequiredCapability req) {
if (req.isOptional())
- expandOptionalRequirement(iu, req);
+ expandOptionalRequirement(var, iu, req);
else
- expandNormalRequirement(iu, req);
+ expandNormalRequirement(var, iu, req);
}
//Create constraints to deal with singleton
diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Slicer.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Slicer.java
index eddf39681..cdee19242 100644
--- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Slicer.java
+++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Slicer.java
@@ -11,8 +11,7 @@ package org.eclipse.equinox.internal.p2.director;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
-import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.internal.provisional.p2.metadata.RequiredCapability;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
import org.eclipse.equinox.internal.provisional.p2.metadata.query.CapabilityQuery;
import org.eclipse.equinox.internal.provisional.p2.query.Collector;
import org.eclipse.equinox.internal.provisional.p2.query.IQueryable;
@@ -110,7 +109,7 @@ public class Slicer {
return;
}
- RequiredCapability[] reqs = iu.getRequiredCapabilities();
+ RequiredCapability[] reqs = getRequiredCapabilities(iu);
if (reqs.length == 0) {
return;
}
@@ -126,6 +125,22 @@ public class Slicer {
}
}
+ private RequiredCapability[] getRequiredCapabilities(IInstallableUnit iu) {
+ if (!(iu instanceof IInstallableUnitPatch)) {
+ return iu.getRequiredCapabilities();
+ }
+ RequiredCapability[] aggregatedCapabilities;
+ IInstallableUnitPatch patchIU = (IInstallableUnitPatch) iu;
+ RequirementChange[] changes = patchIU.getRequirementsChange();
+ int initialRequirementCount = iu.getRequiredCapabilities().length;
+ aggregatedCapabilities = new RequiredCapability[initialRequirementCount + changes.length];
+ System.arraycopy(iu.getRequiredCapabilities(), 0, aggregatedCapabilities, 0, initialRequirementCount);
+ for (int i = 0; i < changes.length; i++) {
+ aggregatedCapabilities[initialRequirementCount++] = changes[i].newValue();
+ }
+ return aggregatedCapabilities;
+ }
+
private void expandRequirement(IInstallableUnit iu, RequiredCapability req) {
Collector matches = possibilites.query(new CapabilityQuery(req), new Collector(), null);
int validMatches = 0;
diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/resolution/ResolutionHelper.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/resolution/ResolutionHelper.java
index 12c2221f1..fb7a8e618 100644
--- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/resolution/ResolutionHelper.java
+++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/resolution/ResolutionHelper.java
@@ -105,7 +105,9 @@ public class ResolutionHelper {
public Collection attachCUs(Collection toAttach) {
initialize();
for (Iterator iterator = toAttach.iterator(); iterator.hasNext();) {
- addInResolution((IInstallableUnit) iterator.next());
+ IInstallableUnit iu = (IInstallableUnit) iterator.next();
+ if (iu != null)
+ addInResolution(iu);
}
state.resolve();
BundleDescription[] bds = state.getBundles();
@@ -169,6 +171,8 @@ public class ResolutionHelper {
Collection result = new HashSet(toAttach.size());
for (Iterator iterator = toAttach.iterator(); iterator.hasNext();) {
IInstallableUnit iu = (IInstallableUnit) iterator.next();
+ if (iu == null)
+ continue;
//just return fragments as they are
if (iu.isFragment()) {
result.add(iu);
diff --git a/bundles/org.eclipse.equinox.p2.metadata.generator/Metadata Generator Plugins and Features.launch b/bundles/org.eclipse.equinox.p2.metadata.generator/Metadata Generator Plugins and Features.launch
new file mode 100644
index 000000000..68c4fe175
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata.generator/Metadata Generator Plugins and Features.launch
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.pde.ui.EquinoxLauncher">
+<booleanAttribute key="append.args" value="true"/>
+<booleanAttribute key="automaticAdd" value="false"/>
+<booleanAttribute key="automaticValidate" value="false"/>
+<stringAttribute key="bootstrap" value=""/>
+<stringAttribute key="checked" value="[NONE]"/>
+<booleanAttribute key="clearConfig" value="false"/>
+<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/Metadata Generator Plugins and Features"/>
+<booleanAttribute key="default_auto_start" value="false"/>
+<intAttribute key="default_start_level" value="4"/>
+<booleanAttribute key="includeOptional" value="false"/>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-console &#13;&#10;-consolelog&#13;&#10;-application org.eclipse.equinox.p2.metadata.generator.EclipseGenerator&#13;&#10;-metadataRepository file:C:/equinox.p2/servers/&#13;&#10;-artifactRepository file:C:/equinox.p2/servers/&#13;&#10;-source d:/tmp/orbit/eclipse&#13;&#10;-publishArtifacts&#13;&#10;-append&#13;&#10;-noDefaultIUs"/>
+<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
+<stringAttribute key="pde.version" value="3.3"/>
+<booleanAttribute key="show_selected_only" value="false"/>
+<stringAttribute key="target_bundles" value="org.eclipse.equinox.security.win32.x86*1.0.0.v20080324@default:false,org.eclipse.core.runtime.compatibility.registry*3.2.200.v20070717@default:false,org.eclipse.osgi.services*3.1.200.v20071203@default:default,org.eclipse.ant.core*3.2.0.v20080319@default:default,org.eclipse.core.runtime*3.4.0.v20080324-1725@default:default,org.eclipse.equinox.preferences*3.2.200.v20080201@default:default,org.eclipse.core.contenttype*3.3.0.v20080414@default:default,org.eclipse.equinox.common*3.4.0.v20080407@default:default,org.eclipse.equinox.app*1.0.100.v20080331@default:true,org.eclipse.osgi*3.4.0.v20080414@:,org.eclipse.core.runtime.compatibility.auth*3.2.100.v20070502@default:default,org.eclipse.update.configurator*3.2.200.v20080404@default:default,org.eclipse.equinox.registry*3.4.0.v20080316@default:default,org.eclipse.equinox.security*1.0.0.v20080414@default:default,org.eclipse.core.jobs*3.4.0.v20080310@default:default,org.eclipse.core.variables*3.2.100.v20080324-1600@default:default"/>
+<booleanAttribute key="tracing" value="false"/>
+<booleanAttribute key="useDefaultConfigArea" value="true"/>
+<booleanAttribute key="useNamedJRE" value="true"/>
+<stringAttribute key="workspace_bundles" value="org.eclipse.ecf.provider.filetransfer.ssl*1.0.0.qualifier@default:false,org.eclipse.ecf.filetransfer*2.0.0.qualifier@default:default,org.eclipse.equinox.p2.core*0.1.0.qualifier@default:true,org.eclipse.equinox.frameworkadmin.equinox*0.1.0.qualifier@default:true,org.eclipse.equinox.p2.artifact.repository*0.1.0.qualifier@default:default,org.eclipse.equinox.p2.metadata*0.1.0.qualifier@default:default,org.eclipse.equinox.p2.engine*0.1.0.qualifier@default:default,org.eclipse.ecf.ssl*1.0.0.qualifier@default:false,org.eclipse.ecf*2.0.0.qualifier@default:default,org.eclipse.equinox.p2.metadata.repository*0.1.0.qualifier@default:default,org.eclipse.ecf.identity*2.0.0.qualifier@default:default,org.eclipse.equinox.p2.metadata.generator*0.1.0.qualifier@default:default,org.eclipse.equinox.frameworkadmin*0.1.0.qualifier@default:default,org.eclipse.ecf.provider.filetransfer*2.0.0.qualifier@default:default"/>
+</launchConfiguration>
diff --git a/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/p2/metadata/generator/features/FeatureParser.java b/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/p2/metadata/generator/features/FeatureParser.java
index fc9768d22..9b7f3a8ec 100644
--- a/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/p2/metadata/generator/features/FeatureParser.java
+++ b/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/p2/metadata/generator/features/FeatureParser.java
@@ -255,7 +255,10 @@ public class FeatureParser extends DefaultHandler {
String id = attributes.getValue("feature"); //$NON-NLS-1$
FeatureEntry entry = null;
if (id != null) {
- entry = FeatureEntry.createRequires(id, attributes.getValue("version"), attributes.getValue("match"), attributes.getValue("filter"), false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ if (attributes.getValue("patch").equalsIgnoreCase("true")) { //$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 {
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$
diff --git a/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/FeatureEntry.java b/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/FeatureEntry.java
index 1f63ce370..6ab0a226e 100644
--- a/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/FeatureEntry.java
+++ b/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/FeatureEntry.java
@@ -26,6 +26,7 @@ public class FeatureEntry {
private boolean isRequires = false;
private boolean unpack = true;
private boolean optional = false;
+ private boolean isPatch = false;
/**
* Temporary field to add provisioning filters to features
@@ -174,4 +175,12 @@ public class FeatureEntry {
result.append(version != null ? " " + version.toString() : ""); //$NON-NLS-1$ //$NON-NLS-2$
return result.toString();
}
+
+ public boolean isPatch() {
+ return isPatch;
+ }
+
+ public void setPatch(boolean patch) {
+ this.isPatch = patch;
+ }
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/MetadataGeneratorHelper.java b/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/MetadataGeneratorHelper.java
index 2b7d352f8..e9d6b2286 100644
--- a/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/MetadataGeneratorHelper.java
+++ b/bundles/org.eclipse.equinox.p2.metadata.generator/src/org/eclipse/equinox/internal/provisional/p2/metadata/generator/MetadataGeneratorHelper.java
@@ -28,8 +28,7 @@ import org.eclipse.equinox.internal.provisional.p2.artifact.repository.ArtifactD
import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactDescriptor;
import org.eclipse.equinox.internal.provisional.p2.artifact.repository.processing.ProcessingStepDescriptor;
import org.eclipse.equinox.internal.provisional.p2.metadata.*;
-import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory.InstallableUnitDescription;
-import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory.InstallableUnitFragmentDescription;
+import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory.*;
import org.eclipse.osgi.service.environment.EnvironmentInfo;
import org.eclipse.osgi.service.resolver.*;
import org.eclipse.osgi.util.ManifestElement;
@@ -581,6 +580,8 @@ public class MetadataGeneratorHelper {
}
public static IInstallableUnit createGroupIU(Feature feature, IInstallableUnit featureIU, Properties extraProperties) {
+ if (isPatch(feature))
+ return createPatchIU(feature, featureIU, extraProperties);
InstallableUnitDescription iu = new MetadataFactory.InstallableUnitDescription();
String id = getTransformedId(feature.getId(), /*isPlugin*/false, /*isGroup*/true);
iu.setId(id);
@@ -619,6 +620,79 @@ public class MetadataGeneratorHelper {
return MetadataFactory.createInstallableUnit(iu);
}
+ public static IInstallableUnit createPatchIU(Feature feature, IInstallableUnit featureIU, Properties extraProperties) {
+ InstallableUnitPatchDescription iu = new MetadataFactory.InstallableUnitPatchDescription();
+ String id = getTransformedId(feature.getId(), /*isPlugin*/false, /*isGroup*/true);
+ iu.setId(id);
+ Version version = new Version(feature.getVersion());
+ iu.setVersion(version);
+ iu.setProperty(IInstallableUnit.PROP_NAME, feature.getLabel());
+ if (feature.getLicense() != null)
+ iu.setLicense(new License(feature.getLicenseURL(), feature.getLicense()));
+ if (feature.getCopyright() != null)
+ iu.setCopyright(new Copyright(feature.getCopyrightURL(), feature.getCopyright()));
+ iu.setUpdateDescriptor(MetadataFactory.createUpdateDescriptor(id, new VersionRange(new Version(0, 0, 0), true, new Version(feature.getVersion()), false), IUpdateDescriptor.NORMAL, null));
+
+ FeatureEntry entries[] = feature.getEntries();
+ ArrayList applicabilityScope = new ArrayList();
+ ArrayList patchRequirements = new ArrayList();
+ ArrayList requirementChanges = new ArrayList();
+ for (int i = 0; i < entries.length; i++) {
+ VersionRange range = getVersionRange(entries[i]);
+ RequiredCapability req = MetadataFactory.createRequiredCapability(IU_NAMESPACE, getTransformedId(entries[i].getId(), entries[i].isPlugin(), /*isGroup*/true), range, getFilter(entries[i]), entries[i].isOptional(), false);
+ if (entries[i].isRequires()) {
+ applicabilityScope.add(req);
+ continue;
+ }
+ if (entries[i].isPlugin()) {
+ RequiredCapability from = MetadataFactory.createRequiredCapability(IU_NAMESPACE, getTransformedId(entries[i].getId(), entries[i].isPlugin(), /*isGroup*/true), VersionRange.emptyRange, getFilter(entries[i]), entries[i].isOptional(), false);
+ requirementChanges.add(new RequirementChange(from, req));
+ continue;
+ }
+ patchRequirements.add(req);
+ }
+ //Always add a requirement on the IU containing the feature jar
+ patchRequirements.add(MetadataFactory.createRequiredCapability(IU_NAMESPACE, featureIU.getId(), new VersionRange(featureIU.getVersion(), true, featureIU.getVersion(), true), INSTALL_FEATURES_FILTER, false, false));
+ iu.setRequiredCapabilities((RequiredCapability[]) patchRequirements.toArray(new RequiredCapability[requirementChanges.size()]));
+ iu.setApplicabilityScope(new RequiredCapability[][] {(RequiredCapability[]) applicabilityScope.toArray(new RequiredCapability[applicabilityScope.size()])});
+ iu.setRequirementChanges((RequirementChange[]) requirementChanges.toArray(new RequirementChange[requirementChanges.size()]));
+
+ //Generate lifecycle
+ RequiredCapability lifeCycle = null;
+ if (applicabilityScope.size() > 0) {
+ RequiredCapability req = (RequiredCapability) applicabilityScope.get(0);
+ lifeCycle = MetadataFactory.createRequiredCapability(req.getNamespace(), req.getName(), req.getRange(), null, false, false, false);
+ iu.setLifeCycle(lifeCycle);
+ }
+
+ iu.setTouchpointType(TouchpointType.NONE);
+ iu.setProperty(IInstallableUnit.PROP_TYPE_GROUP, Boolean.TRUE.toString());
+ iu.setProperty(IInstallableUnit.PROP_TYPE_PATCH, Boolean.TRUE.toString());
+ // TODO: shouldn't the filter for the group be constructed from os, ws, arch, nl
+ // of the feature?
+ // iu.setFilter(filter);
+ iu.setCapabilities(new ProvidedCapability[] {createSelfCapability(id, version)});
+
+ if (extraProperties != null) {
+ Enumeration e = extraProperties.propertyNames();
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ iu.setProperty(name, extraProperties.getProperty(name));
+ }
+ }
+
+ return MetadataFactory.createInstallableUnitPatch(iu);
+ }
+
+ private static boolean isPatch(Feature feature) {
+ FeatureEntry[] entries = feature.getEntries();
+ for (int i = 0; i < entries.length; i++) {
+ if (entries[i].isPatch())
+ return true;
+ }
+ return false;
+ }
+
/**
* Creates IUs and artifact descriptors for the JRE. The resulting IUs are added
* to the given set, and the resulting artifact descriptor, if any, is returned.
diff --git a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/io/MetadataParser.java b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/io/MetadataParser.java
index bc2023ffd..5b09362ad 100644
--- a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/io/MetadataParser.java
+++ b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/io/MetadataParser.java
@@ -18,8 +18,7 @@ import org.eclipse.equinox.internal.p2.core.helpers.OrderedProperties;
import org.eclipse.equinox.internal.p2.metadata.ArtifactKey;
import org.eclipse.equinox.internal.p2.persistence.XMLParser;
import org.eclipse.equinox.internal.provisional.p2.metadata.*;
-import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory.InstallableUnitDescription;
-import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory.InstallableUnitFragmentDescription;
+import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory.*;
import org.eclipse.equinox.internal.provisional.spi.p2.metadata.repository.RepositoryReference;
import org.eclipse.osgi.service.resolver.VersionRange;
import org.osgi.framework.BundleContext;
@@ -77,7 +76,6 @@ public abstract class MetadataParser extends XMLParser implements XMLConstants {
}
protected class InstallableUnitsHandler extends AbstractHandler {
-
private ArrayList units;
public InstallableUnitsHandler(AbstractHandler parentHandler, Attributes attributes) {
@@ -107,7 +105,6 @@ public abstract class MetadataParser extends XMLParser implements XMLConstants {
}
protected class InstallableUnitHandler extends AbstractHandler {
-
private final String[] required = new String[] {ID_ATTRIBUTE, VERSION_ATTRIBUTE};
private final String[] optional = new String[] {SINGLETON_ATTRIBUTE};
@@ -124,6 +121,9 @@ public abstract class MetadataParser extends XMLParser implements XMLConstants {
private UpdateDescriptorHandler updateDescriptorHandler = null;
private LicensesHandler licensesHandler = null;
private CopyrightHandler copyrightHandler = null;
+ private RequirementsChangeHandler requirementChangesHandler = null;
+ private ApplicabilityScopesHandler applicabilityScopeHandler = null;
+ private LifeCycleHandler lifeCycleHandler;
private String id;
private Version version;
@@ -201,12 +201,33 @@ public abstract class MetadataParser extends XMLParser implements XMLConstants {
} else if (UPDATE_DESCRIPTOR_ELEMENT.equals(name)) {
if (updateDescriptorHandler == null)
updateDescriptorHandler = new UpdateDescriptorHandler(this, attributes);
+ else {
+ duplicateElement(this, name, attributes);
+ }
} else if (LICENSES_ELEMENT.equals(name)) {
if (licensesHandler == null) {
licensesHandler = new LicensesHandler(this, attributes);
} else {
duplicateElement(this, name, attributes);
}
+ } else if (REQUIREMENT_CHANGES.equals(name)) {
+ if (requirementChangesHandler == null) {
+ requirementChangesHandler = new RequirementsChangeHandler(this, attributes);
+ } else {
+ duplicateElement(this, name, attributes);
+ }
+ } else if (APPLICABILITY_SCOPE.equals(name)) {
+ if (applicabilityScopeHandler == null) {
+ applicabilityScopeHandler = new ApplicabilityScopesHandler(this, attributes);
+ } else {
+ duplicateElement(this, name, attributes);
+ }
+ } else if (LIFECYCLE.equals(name)) {
+ if (lifeCycleHandler == null) {
+ lifeCycleHandler = new LifeCycleHandler(this, attributes);
+ } else {
+ duplicateElement(this, name, attributes);
+ }
} else if (COPYRIGHT_ELEMENT.equals(name)) {
if (copyrightHandler == null) {
copyrightHandler = new CopyrightHandler(this, attributes);
@@ -220,7 +241,14 @@ public abstract class MetadataParser extends XMLParser implements XMLConstants {
protected void finished() {
if (isValidXML()) {
- if (hostRequiredCapabilitiesHandler == null || hostRequiredCapabilitiesHandler.getHostRequiredCapabilities().length == 0) {
+ if (requirementChangesHandler != null) {
+ currentUnit = new MetadataFactory.InstallableUnitPatchDescription();
+ ((InstallableUnitPatchDescription) currentUnit).setRequirementChanges((RequirementChange[]) requirementChangesHandler.getRequirementChanges().toArray(new RequirementChange[requirementChangesHandler.getRequirementChanges().size()]));
+ if (applicabilityScopeHandler != null)
+ ((InstallableUnitPatchDescription) currentUnit).setApplicabilityScope(applicabilityScopeHandler.getScope());
+ if (lifeCycleHandler != null)
+ ((InstallableUnitPatchDescription) currentUnit).setLifeCycle(lifeCycleHandler.getLifeCycleRequirement());
+ } else if (hostRequiredCapabilitiesHandler == null || hostRequiredCapabilitiesHandler.getHostRequiredCapabilities().length == 0) {
currentUnit = new InstallableUnitDescription();
} else {
currentUnit = new MetadataFactory.InstallableUnitFragmentDescription();
@@ -286,8 +314,144 @@ public abstract class MetadataParser extends XMLParser implements XMLConstants {
}
}
- protected class ProvidedCapabilitiesHandler extends AbstractHandler {
+ protected class ApplicabilityScopesHandler extends AbstractHandler {
+ private List scopes;
+
+ public ApplicabilityScopesHandler(AbstractHandler parentHandler, Attributes attributes) {
+ super(parentHandler, APPLICABILITY_SCOPE);
+ String size = parseOptionalAttribute(attributes, COLLECTION_SIZE_ATTRIBUTE);
+ scopes = (size != null ? new ArrayList(new Integer(size).intValue()) : new ArrayList(4));
+ }
+
+ public void startElement(String name, Attributes attributes) {
+ if (APPLY_ON.equals(name)) {
+ new ApplicabilityScopeHandler(this, attributes, scopes);
+ } else {
+ duplicateElement(this, name, attributes);
+ }
+ }
+
+ public RequiredCapability[][] getScope() {
+ return (RequiredCapability[][]) scopes.toArray(new RequiredCapability[scopes.size()][]);
+ }
+ }
+
+ protected class ApplicabilityScopeHandler extends AbstractHandler {
+ private RequiredCapabilitiesHandler children;
+ private List scopes;
+
+ public ApplicabilityScopeHandler(AbstractHandler parentHandler, Attributes attributes, List scopes) {
+ super(parentHandler, APPLY_ON);
+ this.scopes = scopes;
+ }
+
+ public void startElement(String name, Attributes attributes) {
+ if (REQUIRED_CAPABILITIES_ELEMENT.equals(name)) {
+ children = new RequiredCapabilitiesHandler(this, attributes);
+ } else {
+ duplicateElement(this, name, attributes);
+ }
+ }
+
+ protected void finished() {
+ scopes.add(children.getRequiredCapabilities());
+ }
+ }
+
+ protected class RequirementsChangeHandler extends AbstractHandler {
+ private List requirementChanges;
+
+ public RequirementsChangeHandler(InstallableUnitHandler parentHandler, Attributes attributes) {
+ super(parentHandler, REQUIREMENT_CHANGES);
+ String size = parseOptionalAttribute(attributes, COLLECTION_SIZE_ATTRIBUTE);
+ requirementChanges = (size != null ? new ArrayList(new Integer(size).intValue()) : new ArrayList(4));
+ }
+
+ public void startElement(String name, Attributes attributes) {
+ if (name.equals(REQUIREMENT_CHANGE)) {
+ new RequirementChangeHandler(this, attributes, requirementChanges);
+ } else {
+ invalidElement(name, attributes);
+ }
+ }
+
+ public List getRequirementChanges() {
+ return requirementChanges;
+ }
+ }
+
+ protected class RequirementChangeHandler extends AbstractHandler {
+ private List from;
+ private List to;
+ private List requirementChanges;
+
+ public RequirementChangeHandler(AbstractHandler parentHandler, Attributes attributes, List requirementChanges) {
+ super(parentHandler, REQUIREMENT_CHANGE);
+ from = new ArrayList(1);
+ to = new ArrayList(1);
+ this.requirementChanges = requirementChanges;
+ }
+
+ public void startElement(String name, Attributes attributes) {
+ if (name.equals(REQUIREMENT_FROM)) {
+ new RequirementChangeEltHandler(this, REQUIREMENT_FROM, attributes, from);
+ return;
+ }
+
+ if (name.equals(REQUIREMENT_TO)) {
+ new RequirementChangeEltHandler(this, REQUIREMENT_TO, attributes, to);
+ return;
+ }
+ invalidElement(name, attributes);
+ }
+
+ protected void finished() {
+ requirementChanges.add(new RequirementChange(from.size() == 0 ? null : (RequiredCapability) from.get(0), to.size() == 0 ? null : (RequiredCapability) to.get(0)));
+ }
+ }
+
+ protected class RequirementChangeEltHandler extends AbstractHandler {
+ private List requirement;
+
+ public RequirementChangeEltHandler(AbstractHandler parentHandler, String parentId, Attributes attributes, List from) {
+ super(parentHandler, parentId);
+ requirement = from;
+ }
+ public void startElement(String name, Attributes attributes) {
+ if (REQUIRED_CAPABILITY_ELEMENT.equals(name))
+ new RequiredCapabilityHandler(this, attributes, requirement);
+ else {
+ invalidElement(name, attributes);
+ }
+ }
+
+ }
+
+ protected class LifeCycleHandler extends AbstractHandler {
+ private List lifeCycleRequirement;
+
+ public LifeCycleHandler(AbstractHandler parentHandler, Attributes attributes) {
+ super(parentHandler, LIFECYCLE);
+ lifeCycleRequirement = new ArrayList(1);
+ }
+
+ public RequiredCapability getLifeCycleRequirement() {
+ if (lifeCycleRequirement.size() == 0)
+ return null;
+ return (RequiredCapability) lifeCycleRequirement.get(0);
+ }
+
+ public void startElement(String name, Attributes attributes) {
+ if (REQUIRED_CAPABILITY_ELEMENT.equals(name)) {
+ new RequiredCapabilityHandler(this, attributes, lifeCycleRequirement);
+ } else {
+ invalidElement(name, attributes);
+ }
+ }
+ }
+
+ protected class ProvidedCapabilitiesHandler extends AbstractHandler {
private List providedCapabilities;
public ProvidedCapabilitiesHandler(AbstractHandler parentHandler, Attributes attributes) {
@@ -310,7 +474,6 @@ public abstract class MetadataParser extends XMLParser implements XMLConstants {
}
protected class ProvidedCapabilityHandler extends AbstractHandler {
-
private final String[] required = new String[] {NAMESPACE_ATTRIBUTE, NAME_ATTRIBUTE, VERSION_ATTRIBUTE};
public ProvidedCapabilityHandler(AbstractHandler parentHandler, Attributes attributes, List capabilities) {
@@ -370,7 +533,6 @@ public abstract class MetadataParser extends XMLParser implements XMLConstants {
}
protected class RequiredCapabilityHandler extends AbstractHandler {
-
private final String[] required = new String[] {NAMESPACE_ATTRIBUTE, NAME_ATTRIBUTE, VERSION_RANGE_ATTRIBUTE};
private final String[] optional = new String[] {CAPABILITY_OPTIONAL_ATTRIBUTE, CAPABILITY_MULTIPLE_ATTRIBUTE, CAPABILITY_GREED_ATTRIBUTE};
diff --git a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/io/MetadataWriter.java b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/io/MetadataWriter.java
index 685932c66..7aea45226 100644
--- a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/io/MetadataWriter.java
+++ b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/io/MetadataWriter.java
@@ -57,6 +57,13 @@ public abstract class MetadataWriter extends XMLWriter implements XMLConstants {
writeHostRequiredCapabilities(fragment.getHost());
}
+ if (iu instanceof IInstallableUnitPatch) {
+ IInstallableUnitPatch patch = (IInstallableUnitPatch) iu;
+ writeApplicabilityScope(patch.getApplicabilityScope());
+ writeRequirementsChange(patch.getRequirementsChange());
+ writeLifeCycle(patch.getLifeCycle());
+ }
+
writeUpdateDescriptor(resolvedIU, resolvedIU.getUpdateDescriptor());
writeProperties(iu.getProperties());
writeProvidedCapabilities(iu.getProvidedCapabilities());
@@ -72,6 +79,14 @@ public abstract class MetadataWriter extends XMLWriter implements XMLConstants {
end(INSTALLABLE_UNIT_ELEMENT);
}
+ protected void writeLifeCycle(RequiredCapability capability) {
+ if (capability == null)
+ return;
+ start(LIFECYCLE);
+ writeRequiredCapability(capability);
+ end(LIFECYCLE);
+ }
+
protected void writeHostRequiredCapabilities(RequiredCapability[] capabilities) {
if (capabilities != null && capabilities.length > 0) {
start(HOST_REQUIRED_CAPABILITIES_ELEMENT);
@@ -119,7 +134,39 @@ public abstract class MetadataWriter extends XMLWriter implements XMLConstants {
attribute(UPDATE_DESCRIPTOR_SEVERITY, descriptor.getSeverity());
attribute(DESCRIPTION_ATTRIBUTE, descriptor.getDescription());
end(UPDATE_DESCRIPTOR_ELEMENT);
+ }
+
+ protected void writeApplicabilityScope(RequiredCapability[][] capabilities) {
+ start(APPLICABILITY_SCOPE);
+ for (int i = 0; i < capabilities.length; i++) {
+ start(APPLY_ON);
+ writeRequiredCapabilities(capabilities[i]);
+ end(APPLY_ON);
+ }
+ end(APPLICABILITY_SCOPE);
+ }
+ protected void writeRequirementsChange(RequirementChange[] changes) {
+ start(REQUIREMENT_CHANGES);
+ for (int i = 0; i < changes.length; i++) {
+ writeRequirementChange(changes[i]);
+ }
+ end(REQUIREMENT_CHANGES);
+ }
+
+ protected void writeRequirementChange(RequirementChange change) {
+ start(REQUIREMENT_CHANGE);
+ if (change.applyOn() != null) {
+ start(REQUIREMENT_FROM);
+ writeRequiredCapability(change.applyOn());
+ end(REQUIREMENT_FROM);
+ }
+ if (change.newValue() != null) {
+ start(REQUIREMENT_TO);
+ writeRequiredCapability(change.newValue());
+ end(REQUIREMENT_TO);
+ }
+ end(REQUIREMENT_CHANGE);
}
protected void writeRequiredCapability(RequiredCapability capability) {
diff --git a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/io/XMLConstants.java b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/io/XMLConstants.java
index df7a61fdb..e7031c4ea 100644
--- a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/io/XMLConstants.java
+++ b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/io/XMLConstants.java
@@ -46,6 +46,14 @@ public interface XMLConstants extends org.eclipse.equinox.internal.p2.persistenc
public static final String IU_FILTER_ELEMENT = "filter"; //$NON-NLS-1$
public static final String UPDATE_DESCRIPTOR_ELEMENT = "update"; //$NON-NLS-1$
+ public static final String APPLICABILITY_SCOPE = "patchScope"; //$NON-NLS-1$
+ public static final String APPLY_ON = "scope"; //$NON-NLS-1$
+ public static final String REQUIREMENT_CHANGES = "changes"; //$NON-NLS-1$
+ public static final String REQUIREMENT_CHANGE = "change"; //$NON-NLS-1$
+ public static final String REQUIREMENT_FROM = "from"; //$NON-NLS-1$
+ public static final String REQUIREMENT_TO = "to"; //$NON-NLS-1$
+ public static final String LIFECYCLE = "lifeCycle"; //$NON-NLS-1$
+
// Constants for attributes of an installable unit element
public static final String SINGLETON_ATTRIBUTE = "singleton"; //$NON-NLS-1$
public static final String FRAGMENT_ATTRIBUTE = "fragment"; //$NON-NLS-1$
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/IInstallableUnit.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/IInstallableUnit.java
index 6007e44bf..69e53c4d6 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/IInstallableUnit.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/IInstallableUnit.java
@@ -72,6 +72,14 @@ public interface IInstallableUnit extends Comparable {
public static final String PROP_TYPE_GROUP = "org.eclipse.equinox.p2.type.group"; //$NON-NLS-1$
/**
+ * A property key (value <code>"org.eclipse.equinox.p2.type.patch"</code>) for a
+ * boolean property indicating that an installable unit is a group.
+ *
+ * @see #getProperty(String)
+ */
+ public static final String PROP_TYPE_PATCH = "org.eclipse.equinox.p2.type.patch"; //$NON-NLS-1$
+
+ /**
* A property key (value <code>"org.eclipse.equinox.p2.type.lock"</code>) for an
* integer property indicating how an installable unit is locked in its profile.
* The integer is a bit-mask indicating the different locks defined on the installable
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/IInstallableUnitPatch.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/IInstallableUnitPatch.java
new file mode 100644
index 000000000..507b7e0a7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/IInstallableUnitPatch.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.internal.provisional.p2.metadata;
+
+public interface IInstallableUnitPatch extends IInstallableUnit {
+ RequiredCapability[][] getApplicabilityScope();
+
+ RequirementChange[] getRequirementsChange();
+
+ RequiredCapability getLifeCycle();
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/InstallableUnitPatch.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/InstallableUnitPatch.java
new file mode 100644
index 000000000..d6ca8a34a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/InstallableUnitPatch.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.internal.provisional.p2.metadata;
+
+import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
+
+public class InstallableUnitPatch extends InstallableUnit implements IInstallableUnitPatch {
+ private RequirementChange[] changes;
+ private RequiredCapability[][] scope;
+ private RequiredCapability lifeCycle;
+
+ public void setRequirementsChange(RequirementChange[] changes) {
+ this.changes = changes;
+ }
+
+ public RequirementChange[] getRequirementsChange() {
+ return changes;
+ }
+
+ public RequiredCapability getLifeCycle() {
+ return lifeCycle;
+ }
+
+ public void setLifeCycle(RequiredCapability lifeCycle) {
+ if (lifeCycle == null)
+ return;
+ this.lifeCycle = lifeCycle;
+ addRequiredCapability(new RequiredCapability[] {lifeCycle});
+ }
+
+ public RequiredCapability[][] getApplicabilityScope() {
+ return scope;
+ }
+
+ public void setApplicabilityScope(RequiredCapability[][] applyTo) {
+ scope = applyTo;
+ }
+
+ private void addRequiredCapability(RequiredCapability[] toAdd) {
+ RequiredCapability[] current = super.getRequiredCapabilities();
+ RequiredCapability[] result = new RequiredCapability[current.length + toAdd.length];
+ System.arraycopy(current, 0, result, 0, current.length);
+ System.arraycopy(toAdd, 0, result, current.length, toAdd.length);
+ setRequiredCapabilities(result);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/MetadataFactory.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/MetadataFactory.java
index b0836d7b5..ccb8f0eac 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/MetadataFactory.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/MetadataFactory.java
@@ -110,6 +110,26 @@ public class MetadataFactory {
}
}
+ public static class InstallableUnitPatchDescription extends InstallableUnitDescription {
+ public void setRequirementChanges(RequirementChange[] changes) {
+ ((InstallableUnitPatch) unit()).setRequirementsChange(changes);
+ }
+
+ InstallableUnit unit() {
+ if (unit == null)
+ unit = new InstallableUnitPatch();
+ return unit;
+ }
+
+ public void setApplicabilityScope(RequiredCapability[][] applyTo) {
+ ((InstallableUnitPatch) unit()).setApplicabilityScope(applyTo);
+ }
+
+ public void setLifeCycle(RequiredCapability lifeCycle) {
+ ((InstallableUnitPatch) unit()).setLifeCycle(lifeCycle);
+ }
+ }
+
/**
* Singleton touchpoint data for a touchpoint with no instructions.
*/
@@ -125,7 +145,7 @@ public class MetadataFactory {
* discarded from the description object.
*
* @param description The description of the unit to create
- * @return The created installable unit or fragment
+ * @return The created installable unit
*/
public static IInstallableUnit createInstallableUnit(InstallableUnitDescription description) {
Assert.isNotNull(description);
@@ -138,7 +158,7 @@ public class MetadataFactory {
* discarded from the description object.
*
* @param description The description of the unit to create
- * @return The created installable unit or fragment
+ * @return The created installable unit fragment
*/
public static IInstallableUnitFragment createInstallableUnitFragment(InstallableUnitFragmentDescription description) {
Assert.isNotNull(description);
@@ -146,6 +166,19 @@ public class MetadataFactory {
}
/**
+ * Returns an {@link IInstallableUnitPatch} based on the given
+ * description. Once the patch installable unit has been created, the information is
+ * discarded from the description object.
+ *
+ * @param description The description of the unit to create
+ * @return The created installable unit patch
+ */
+ public static IInstallableUnitPatch createInstallableUnitPatch(InstallableUnitPatchDescription description) {
+ Assert.isNotNull(description);
+ return (IInstallableUnitPatch) description.unitCreate();
+ }
+
+ /**
* Returns a {@link ProvidedCapability} with the given values.
*
* @param namespace The capability namespace
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/RequirementChange.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/RequirementChange.java
new file mode 100644
index 000000000..92a78eca7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/provisional/p2/metadata/RequirementChange.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.internal.provisional.p2.metadata;
+
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class RequirementChange {
+ private RequiredCapability applyOn;
+ private RequiredCapability newValue;
+
+ public RequirementChange(RequiredCapability applyOn2, RequiredCapability newValue2) {
+ if (applyOn2 == null && newValue2 == null)
+ throw new IllegalArgumentException();
+ this.applyOn = applyOn2;
+ this.newValue = newValue2;
+ }
+
+ public RequiredCapability applyOn() {
+ return applyOn;
+ }
+
+ public RequiredCapability newValue() {
+ return newValue;
+ }
+
+ public boolean matches(RequiredCapability toMatch) {
+ if (!toMatch.getNamespace().equals(applyOn.getNamespace()))
+ return false;
+ if (!toMatch.getName().equals(applyOn.getName()))
+ return false;
+ if (toMatch.getRange().equals(applyOn.getRange()))
+ return true;
+
+ return intersect(toMatch.getRange(), applyOn.getRange()) == null ? false : true;
+ }
+
+ boolean matches(RequirementChange toMatch) {
+ return matches(toMatch.applyOn());
+ }
+
+ protected RequirementChange merge(RequirementChange r2) {
+ VersionRange result = intersect(newValue().getRange(), r2.newValue().getRange());
+ if (result == null)
+ return null;
+ return new RequirementChange(applyOn, MetadataFactory.createRequiredCapability(applyOn.getNamespace(), applyOn.getName(), result, null, false, false));
+ }
+
+ private VersionRange intersect(VersionRange r1, VersionRange r2) {
+ Version resultMin = null;
+ boolean resultMinIncluded = false;
+ Version resultMax = null;
+ boolean resultMaxIncluded = false;
+
+ int minCompare = r1.getMinimum().compareTo(r2.getMinimum());
+ if (minCompare < 0) {
+ resultMin = r2.getMinimum();
+ resultMinIncluded = r2.getIncludeMinimum();
+ } else if (minCompare > 0) {
+ resultMin = r1.getMinimum();
+ resultMinIncluded = r1.getIncludeMinimum();
+ } else if (minCompare == 0) {
+ resultMin = r1.getMinimum();
+ resultMinIncluded = r1.getIncludeMinimum() && r2.getIncludeMinimum();
+ }
+
+ int maxCompare = r1.getMaximum().compareTo(r2.getMaximum());
+ if (maxCompare > 0) {
+ resultMax = r2.getMaximum();
+ resultMaxIncluded = r2.getIncludeMaximum();
+ } else if (maxCompare < 0) {
+ resultMax = r1.getMaximum();
+ resultMaxIncluded = r1.getIncludeMaximum();
+ } else if (maxCompare == 0) {
+ resultMax = r1.getMaximum();
+ resultMaxIncluded = r1.getIncludeMaximum() && r2.getIncludeMaximum();
+ }
+
+ int resultRangeComparison = resultMin.compareTo(resultMax);
+ if (resultRangeComparison < 0)
+ return new VersionRange(resultMin, resultMinIncluded, resultMax, resultMaxIncluded);
+ else if (resultRangeComparison == 0 && resultMinIncluded == resultMaxIncluded)
+ return new VersionRange(resultMin, resultMinIncluded, resultMax, resultMaxIncluded);
+ else
+ return null;
+ }
+
+ public boolean isCompatible(RequirementChange other) {
+ return intersect(newValue.getRange(), other.newValue.getRange()) != null;
+ }
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((applyOn == null) ? 0 : applyOn.hashCode());
+ result = prime * result + ((newValue == null) ? 0 : newValue.hashCode());
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final RequirementChange other = (RequirementChange) obj;
+ if (applyOn == null) {
+ if (other.applyOn != null)
+ return false;
+ } else if (!applyOn.equals(other.applyOn))
+ return false;
+ if (newValue == null) {
+ if (other.newValue != null)
+ return false;
+ } else if (!newValue.equals(other.newValue))
+ return false;
+ return true;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AbstractProvisioningTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AbstractProvisioningTest.java
index 29dc1405e..5bcbffc99 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AbstractProvisioningTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AbstractProvisioningTest.java
@@ -18,8 +18,7 @@ import org.eclipse.equinox.internal.p2.metadata.repository.MetadataRepositoryMan
import org.eclipse.equinox.internal.provisional.p2.director.*;
import org.eclipse.equinox.internal.provisional.p2.engine.*;
import org.eclipse.equinox.internal.provisional.p2.metadata.*;
-import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory.InstallableUnitDescription;
-import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory.InstallableUnitFragmentDescription;
+import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory.*;
import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery;
import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepository;
import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepositoryManager;
@@ -333,6 +332,38 @@ public abstract class AbstractProvisioningTest extends TestCase {
return createIU(name, version, filter, required, additionalProvides, properties, tpType, tpData, singleton, null);
}
+ public static IInstallableUnitPatch createIUPatch(String name, Version version, boolean singleton, RequirementChange[] changes, RequiredCapability[][] scope, RequiredCapability lifeCycle) {
+ return createIUPatch(name, version, null, NO_REQUIRES, NO_PROVIDES, NO_PROPERTIES, TouchpointType.NONE, NO_TP_DATA, singleton, null, changes, scope, lifeCycle);
+ }
+
+ public static IInstallableUnitPatch createIUPatch(String name, Version version, String filter, RequiredCapability[] required, ProvidedCapability[] additionalProvides, Map properties, TouchpointType tpType, TouchpointData tpData, boolean singleton, IUpdateDescriptor update, RequirementChange[] reqChanges, RequiredCapability[][] scope, RequiredCapability lifeCycle) {
+ InstallableUnitPatchDescription iu = new MetadataFactory.InstallableUnitPatchDescription();
+ iu.setId(name);
+ iu.setVersion(version);
+ iu.setFilter(filter);
+ ProvidedCapability[] provides = new ProvidedCapability[additionalProvides.length + 1];
+ provides[0] = getSelfCapability(name, version);
+ for (int i = 0; i < additionalProvides.length; i++) {
+ provides[i + 1] = additionalProvides[i];
+ }
+ for (Iterator iter = properties.keySet().iterator(); iter.hasNext();) {
+ String nextKey = (String) iter.next();
+ String nextValue = (String) properties.get(nextKey);
+ iu.setProperty(nextKey, nextValue);
+ }
+ iu.setCapabilities(provides);
+ iu.setRequiredCapabilities(required);
+ iu.setTouchpointType(tpType);
+ if (tpData != null)
+ iu.addTouchpointData(tpData);
+ iu.setSingleton(singleton);
+ iu.setUpdateDescriptor(update);
+ iu.setRequirementChanges(reqChanges);
+ iu.setApplicabilityScope(scope);
+ iu.setLifeCycle(lifeCycle);
+ return MetadataFactory.createInstallableUnitPatch(iu);
+ }
+
public static IInstallableUnit createIU(String name, Version version, String filter, RequiredCapability[] required, ProvidedCapability[] additionalProvides, Map properties, TouchpointType tpType, TouchpointData tpData, boolean singleton, IUpdateDescriptor update) {
InstallableUnitDescription iu = new MetadataFactory.InstallableUnitDescription();
iu.setId(name);
@@ -671,6 +702,18 @@ public abstract class AbstractProvisioningTest extends TestCase {
fail("Can't find " + iu + " in the plan");
}
+ protected void assertUninstallOperand(ProvisioningPlan plan, IInstallableUnit iu) {
+ Operand[] ops = plan.getOperands();
+ for (int i = 0; i < ops.length; i++) {
+ if (ops[i] instanceof InstallableUnitOperand) {
+ InstallableUnitOperand iuOp = (InstallableUnitOperand) ops[i];
+ if (iu.equals(iuOp.first()))
+ return;
+ }
+ }
+ fail("Can't find " + iu + " in the plan");
+ }
+
protected void assertNoOperand(ProvisioningPlan plan, IInstallableUnit iu) {
Operand[] ops = plan.getOperands();
for (int i = 0; i < ops.length; i++) {
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/generator/PatchIUGeneration.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/generator/PatchIUGeneration.java
new file mode 100644
index 000000000..c4066ce6b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/generator/PatchIUGeneration.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.generator;
+
+import org.eclipse.equinox.internal.p2.metadata.generator.features.FeatureParser;
+import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnitPatch;
+import org.eclipse.equinox.internal.provisional.p2.metadata.generator.Feature;
+import org.eclipse.equinox.internal.provisional.p2.metadata.generator.MetadataGeneratorHelper;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+public class PatchIUGeneration extends AbstractProvisioningTest {
+
+ public void testGeneratedIU() {
+ FeatureParser parser = new FeatureParser();
+ Feature feature = parser.parse(getTestData("org.eclipse.jdt.core.feature.patch", "testData/org.eclipse.jdt.3.2.1.patch_1.0.0.jar"));
+ if (feature == null)
+ fail();
+ IInstallableUnit featureIU = MetadataGeneratorHelper.createFeatureJarIU(feature, true, null);
+ IInstallableUnitPatch patchIU = (IInstallableUnitPatch) MetadataGeneratorHelper.createGroupIU(feature, featureIU, null);
+
+ //Check id
+ assertEquals(patchIU.getId(), "org.eclipse.jdt.3.2.1.patch.feature.group");
+
+ //Check applicability scope
+ assertEquals(IInstallableUnit.NAMESPACE_IU_ID, patchIU.getApplicabilityScope()[0][0].getNamespace());
+ assertEquals("org.eclipse.jdt.feature.group", patchIU.getApplicabilityScope()[0][0].getName());
+ assertEquals(new VersionRange("[3.2.1.r321_v20060905-R4CM1Znkvre9wC-,3.2.1.r321_v20060905-R4CM1Znkvre9wC-]"), patchIU.getApplicabilityScope()[0][0].getRange());
+
+ assertEquals("org.eclipse.jdt.core", patchIU.getRequirementsChange()[0].applyOn().getName());
+ assertEquals(VersionRange.emptyRange, patchIU.getRequirementsChange()[0].applyOn().getRange());
+ assertEquals("org.eclipse.jdt.core", patchIU.getRequirementsChange()[0].newValue().getName());
+ assertEquals(new VersionRange("[3.2.2,3.2.2]"), patchIU.getRequirementsChange()[0].newValue().getRange());
+ assertEquals(Boolean.TRUE.toString(), patchIU.getProperty(IInstallableUnit.PROP_TYPE_PATCH));
+ assertEquals(1, patchIU.getRequiredCapabilities().length);
+ assertEquals(featureIU.getId(), patchIU.getRequiredCapabilities()[0].getName());
+ assertEquals("org.eclipse.jdt.feature.group", patchIU.getLifeCycle().getName());
+ assertFalse(patchIU.getLifeCycle().isGreedy());
+ assertFalse(patchIU.getLifeCycle().isOptional());
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/IUPatchPersistenceTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/IUPatchPersistenceTest.java
new file mode 100644
index 000000000..62cc3742c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/IUPatchPersistenceTest.java
@@ -0,0 +1,370 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.tests.metadata;
+
+import java.io.*;
+import java.util.*;
+import javax.xml.parsers.ParserConfigurationException;
+import org.eclipse.equinox.internal.p2.core.helpers.OrderedProperties;
+import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
+import org.eclipse.equinox.internal.p2.metadata.repository.io.MetadataParser;
+import org.eclipse.equinox.internal.p2.metadata.repository.io.MetadataWriter;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.equinox.p2.tests.TestActivator;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Version;
+import org.xml.sax.*;
+
+public class IUPatchPersistenceTest extends AbstractProvisioningTest {
+
+ // Randomly chose org.eclipse.osgi.services as the IU for testing persistence
+ // but 'enhanced' it for better coverage.
+ private static String PackagesNS = "osgi.packages";
+
+ private static String id = "org.eclipse.osgi.services";
+ private static Version version = new Version("3.1.200.v20070605");
+ private static String filter = "(& (osgi.ws=win32) (osgi.os=win32) (osgi.arch=x86))"; // not really
+
+ private static String[][] properties = new String[][] {new String[] {"equinox.p2.name", "OSGi Release 4.0.1 Services"}, //
+ new String[] {"equinox.p2.description", "OSGi Service Platform Release 4.0.1 Service Interfaces and Classes"}, //
+ new String[] {"equinox.p2.provider", "Eclipse.org"}, //
+ new String[] {"equinox.p2.contact", "www.eclipse.org"}, //
+ new String[] {"equinox.p2.copyright", "Copyright (c) 2003, 2004 IBM Corporation and others. A long-winded copyright notice."}};
+
+ private static String[][] provides = new String[][] {new String[] {PackagesNS, "org.osgi.service.cm", "1.2.0"}, //
+ new String[] {PackagesNS, "org.osgi.service.component", "1.0.0"}, //
+ new String[] {PackagesNS, "org.osgi.service.device", "1.1.0"}, //
+ new String[] {PackagesNS, "org.osgi.service.event", "1.1.0"}, //
+ new String[] {PackagesNS, "org.osgi.service.http", "1.2.0"}, //
+ new String[] {PackagesNS, "org.osgi.service.io", "1.0.0"}, //
+ new String[] {PackagesNS, "org.osgi.service.log", "1.3.0"}, //
+ new String[] {PackagesNS, "org.osgi.service.metatype", "1.1.0"}, //
+ new String[] {PackagesNS, "org.osgi.service.provisioning", "1.1.0"}, //
+ new String[] {PackagesNS, "org.osgi.service.upnp", "1.1.0"}, //
+ new String[] {PackagesNS, "org.osgi.service.useradmin", "1.1.0"}, //
+ new String[] {PackagesNS, "org.osgi.service.wireadmin", "1.0.0"}}; //
+
+ private static String[][] requires = new String[][] {new String[] {PackagesNS, "javax.servlet", "0.0.0", "true"}, //
+ new String[] {PackagesNS, "javax.servlet.http", "0.0.0", "true"}, //
+ new String[] {PackagesNS, "org.osgi.framework", "1.2.0", "false"}}; //
+
+ private static String[][] instructions = new String[][] {new String[] {"manifest", "Manifest-Version: 1.0\\Bundle-Vendor: Eclipse.org\\Bundle-ContactAddress: www.eclipse.org\\...a whole bunch of other manifest content..."}, new String[] {"zipped", "true"}, //
+ new String[] {"configure", "addProgramArg(programArg:-startup);addProgramArg(programArg:@artifact);"}}; //
+
+ public static IInstallableUnit createPersistenceTestIU() {
+ Map propertyMap = createProperties(properties);
+ ProvidedCapability[] additionalProvides = createProvided(provides);
+ RequiredCapability[] requirements = createRequired(requires);
+ TouchpointData tpData = createTouchpointData(instructions);
+ IUpdateDescriptor update = createUpdateDescriptor();
+ boolean singleton = false;
+ IInstallableUnit iu = createIU(id, version, filter, requirements, additionalProvides, propertyMap, TOUCHPOINT_OSGI, tpData, singleton, update);
+ return iu;
+ }
+
+ private static IUpdateDescriptor createUpdateDescriptor() {
+ return MetadataFactory.createUpdateDescriptor(id, new VersionRange(IU_TEST_VERSION, true, IU_TEST_VERSION, true), IUpdateDescriptor.HIGH, "desc");
+ }
+
+ private static Map createProperties(String[][] keyValuePairs) {
+ OrderedProperties props = new OrderedProperties(keyValuePairs.length);
+ for (int i = 0; i < keyValuePairs.length; i++) {
+ String[] nextPair = keyValuePairs[i];
+ props.put(nextPair[0], nextPair[1]);
+ }
+ return props;
+ }
+
+ private static ProvidedCapability[] createProvided(String[][] provideTuples) {
+ ProvidedCapability[] provided = new ProvidedCapability[provideTuples.length];
+ for (int i = 0; i < provideTuples.length; i++) {
+ String[] nextTuple = provideTuples[i];
+ provided[i] = MetadataFactory.createProvidedCapability(nextTuple[0], nextTuple[1], new Version(nextTuple[2]));
+ }
+ // provided[provideTuples.length] = BUNDLE_CAPABILITY;
+ return provided;
+ }
+
+ private static RequiredCapability[] createRequired(String[][] requireTuples) {
+ RequiredCapability[] required = new RequiredCapability[requireTuples.length];
+ for (int i = 0; i < requireTuples.length; i++) {
+ String[] nextTuple = requireTuples[i];
+ required[i] = MetadataFactory.createRequiredCapability(nextTuple[0], nextTuple[1], new VersionRange(nextTuple[2]), null, Boolean.valueOf(nextTuple[3]).booleanValue(), false);
+ }
+ return required;
+ }
+
+ private static TouchpointData createTouchpointData(String[][] instructionData) {
+ Map map = new LinkedHashMap(instructionData.length);
+ for (int i = 0; i < instructionData.length; i++) {
+ String[] nextInstruction = instructionData[i];
+ map.put(nextInstruction[0], nextInstruction[1]);
+ }
+ return MetadataFactory.createTouchpointData(map);
+ }
+
+ private static String IU_TEST_TARGET = "installableUnitTest";
+ private static Version IU_TEST_VERSION = new Version("0.0.1");
+
+ private static String IU_TEST_ELEMENT = "test";
+
+ class IUStringWriter extends MetadataWriter {
+
+ public IUStringWriter(ByteArrayOutputStream stream) throws IOException {
+ super(stream, new ProcessingInstruction[] {ProcessingInstruction.makeClassVersionInstruction(IU_TEST_TARGET, InstallableUnit.class, IU_TEST_VERSION)});
+ }
+
+ public void writeTest(IInstallableUnit iu) {
+ start(IU_TEST_ELEMENT);
+ writeInstallableUnit(iu);
+ end(IU_TEST_ELEMENT);
+ flush();
+ }
+ }
+
+ class IUStringParser extends MetadataParser {
+
+ public IUStringParser(BundleContext context, String bundleId) {
+ super(context, bundleId);
+ }
+
+ public void parse(String profileString) throws IOException {
+ this.status = null;
+ try {
+ getParser();
+ TestHandler testHandler = new TestHandler();
+ xmlReader.setContentHandler(new IUDocHandler(IU_TEST_ELEMENT, testHandler));
+ xmlReader.parse(new InputSource(new StringReader(profileString)));
+ if (isValidXML()) {
+ theIU = testHandler.getIU();
+ }
+ } catch (SAXException e) {
+ throw new IOException(e.getMessage());
+ } catch (ParserConfigurationException e) {
+ fail();
+ }
+ }
+
+ private IInstallableUnit theIU = null;
+
+ private final class IUDocHandler extends DocHandler {
+
+ public IUDocHandler(String rootName, RootHandler rootHandler) {
+ super(rootName, rootHandler);
+ }
+
+ public void processingInstruction(String target, String data) throws SAXException {
+ if (IU_TEST_TARGET.equals(target)) {
+ String clazz = extractPIClass(data);
+ try {
+ if (!Class.forName(clazz).equals(InstallableUnit.class)) {
+ throw new SAXException("Wrong class '" + clazz + "' in processing instruction"); //$NON-NLS-1$//$NON-NLS-2$
+ }
+ } catch (ClassNotFoundException e) {
+ throw new SAXException("InstallableUnit class '" + clazz + "' not found"); //$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ Version iuTestVersion = extractPIVersion(target, data);
+ if (!IU_TEST_VERSION.equals(iuTestVersion)) {
+ throw new SAXException("Bad iu test version.");
+ }
+ }
+ }
+ }
+
+ private final class TestHandler extends RootHandler {
+
+ private InstallableUnitHandler iuHandler = null;
+
+ private InstallableUnit iu = null;
+ private List singleton = new ArrayList(1);
+
+ public TestHandler() {
+ super();
+ }
+
+ public InstallableUnit getIU() {
+ return iu;
+ }
+
+ protected void handleRootAttributes(Attributes attributes) {
+ parseAttributes(attributes, noAttributes, noAttributes);
+ }
+
+ public void startElement(String name, Attributes attributes) {
+ if (INSTALLABLE_UNIT_ELEMENT.equals(name)) {
+ if (iuHandler == null) {
+ iuHandler = new InstallableUnitHandler(this, attributes, singleton);
+ } else {
+ duplicateElement(this, name, attributes);
+ }
+ } else {
+ invalidElement(name, attributes);
+ }
+ }
+
+ protected void finished() {
+ if (isValidXML()) {
+ if (iuHandler != null && singleton.size() == 1) {
+ iu = (InstallableUnit) iuHandler.getInstallableUnit();
+ }
+ }
+ }
+ }
+
+ protected String getErrorMessage() {
+ return "Error parsing installable unit string";
+ }
+
+ protected Object getRootObject() {
+ return theIU;
+ }
+
+ }
+
+ public void testIUPersistence() throws IOException {
+ IInstallableUnit iu0 = createPersistenceTestIU();
+ validateIU(iu0);
+ ByteArrayOutputStream output0 = new ByteArrayOutputStream(3072);
+ IUStringWriter writer0 = new IUStringWriter(output0);
+ writer0.writeTest(iu0);
+ String iuText0 = output0.toString();
+ output0.close();
+
+ IUStringParser parser = new IUStringParser(TestActivator.context, TestActivator.PI_PROV_TESTS);
+ parser.parse(iuText0);
+ assertTrue("Error parsing test iu: " + parser.getStatus().getMessage(), parser.getStatus().isOK());
+ InstallableUnit iu1 = (InstallableUnit) parser.getRootObject();
+ validateIU(iu1);
+ ByteArrayOutputStream output1 = new ByteArrayOutputStream(1492);
+ IUStringWriter writer = new IUStringWriter(output1);
+ writer.writeTest(iu1);
+ String iuText1 = output1.toString();
+ output1.close();
+ assertTrue("Installable unit write after read after write produced different XML", iuText1.equals(iuText0));
+ }
+
+ public void testIUPatchPersistence() throws IOException {
+ IInstallableUnit iu0 = createPatchIU();
+ validateIU(iu0);
+ ByteArrayOutputStream output0 = new ByteArrayOutputStream(3072);
+ IUStringWriter writer0 = new IUStringWriter(output0);
+ writer0.writeTest(iu0);
+ String iuText0 = output0.toString();
+ output0.close();
+
+ IUStringParser parser = new IUStringParser(TestActivator.context, TestActivator.PI_PROV_TESTS);
+ parser.parse(iuText0);
+ assertTrue("Error parsing test iu: " + parser.getStatus().getMessage(), parser.getStatus().isOK());
+ InstallableUnitPatch iu1 = (InstallableUnitPatch) parser.getRootObject();
+ validateIU(iu1);
+ validateIUPatch(iu1);
+ ByteArrayOutputStream output1 = new ByteArrayOutputStream(1492);
+ IUStringWriter writer = new IUStringWriter(output1);
+ writer.writeTest(iu1);
+ String iuText1 = output1.toString();
+ output1.close();
+ assertTrue("Installable unit write after read after write produced different XML", iuText1.equals(iuText0));
+
+ }
+
+ private IInstallableUnitPatch createPatchIU() {
+ Map propertyMap = createProperties(properties);
+ ProvidedCapability[] additionalProvides = createProvided(provides);
+ RequiredCapability[] requirements = createRequired(requires);
+ TouchpointData tpData = createTouchpointData(instructions);
+ IUpdateDescriptor update = createUpdateDescriptor();
+ boolean singleton = false;
+ RequirementChange change1 = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.1.0, 1.3.0)"), null, false, false, true));
+ RequirementChange change2 = new RequirementChange(null, MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.1.0, 1.3.0)"), null, false, false, true));
+ RequirementChange change3 = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), null);
+ RequiredCapability[][] scope = new RequiredCapability[][] { {MetadataFactory.createRequiredCapability("foo", "bar", null, null, true, true), MetadataFactory.createRequiredCapability("foo", "bar", null, null, true, true)}, {MetadataFactory.createRequiredCapability("zoo", "far", null, null, true, true)}};
+ RequiredCapability lifeCycle = MetadataFactory.createRequiredCapability("zoo", "x", null, null, false, false, false);
+ IInstallableUnitPatch iu = createIUPatch(id, version, filter, requirements, additionalProvides, propertyMap, TOUCHPOINT_OSGI, tpData, singleton, update, new RequirementChange[] {change1, change2, change3}, scope, lifeCycle);
+ return iu;
+ }
+
+ private static void validateIUPatch(IInstallableUnitPatch iu) {
+ validateIU(iu);
+ assertTrue(iu.getApplicabilityScope() != null);
+ assertTrue(iu.getRequiredCapabilities() != null);
+ assertEquals(3, iu.getRequirementsChange().length);
+ assertEquals(null, iu.getRequirementsChange()[1].applyOn());
+ assertNotNull(iu.getRequirementsChange()[1].newValue());
+ assertEquals(null, iu.getRequirementsChange()[2].newValue());
+ assertNotNull(iu.getRequirementsChange()[2].applyOn());
+ assertEquals(2, iu.getApplicabilityScope().length);
+ assertEquals(2, iu.getApplicabilityScope()[0].length);
+ assertEquals(1, iu.getApplicabilityScope()[1].length);
+ assertNotNull(iu.getLifeCycle());
+ }
+
+ private static void validateIU(IInstallableUnit iu) {
+ assertTrue("Installable unit id is not correct", id.equals(iu.getId()));
+ assertTrue("Installable unit version is not correct", version.equals(iu.getVersion()));
+ assertTrue("Installable unit filter is not correct", filter.equals(iu.getFilter()));
+ // assertTrue("Installable unit properties are not correct", Arrays.equals(properties, extractProperties(iu)));
+ assertTrue("Installable unit properties are not correct", equal(properties, extractProperties(iu)));
+ assertTrue("Installable unit provided capabilities are not correct", equal(addSelfCapability(iu, provides), extractProvides(iu)));
+ // assertTrue("Installable unit required capabilities are not correct", equal(requires, extractRequires(iu))); The lifecycle is added as a requirement for now to make things easier
+ assertTrue("Installable unit update descriptor are not correct", id.equals(iu.getUpdateDescriptor().getId()));
+ assertTrue("Installable unit update descriptor are not correct", IUpdateDescriptor.HIGH == iu.getUpdateDescriptor().getSeverity());
+ assertTrue("Installable unit update descriptor are not correct", "desc".equals(iu.getUpdateDescriptor().getDescription()));
+ assertTrue("Installable unit update descriptor are not correct", new VersionRange(IU_TEST_VERSION, true, IU_TEST_VERSION, true).equals(iu.getUpdateDescriptor().getRange()));
+ }
+
+ private static String[][] extractProperties(IInstallableUnit iu) {
+ Map props = iu.getProperties();
+ Set keys = props.keySet();
+ String[][] pairs = new String[keys.size()][2];
+ int index = 0;
+ for (Iterator iter = keys.iterator(); iter.hasNext();) {
+ String nextKey = (String) iter.next();
+ String nextValue = (String) props.get(nextKey);
+ pairs[index] = new String[] {nextKey, nextValue};
+ index++;
+ }
+ return pairs;
+ }
+
+ private static String[][] addSelfCapability(IInstallableUnit iu, String[][] provideTuples) {
+ String[][] augmentedProvides = new String[provideTuples.length + 1][3];
+ ProvidedCapability self = getSelfCapability(iu);
+ augmentedProvides[0] = new String[] {self.getNamespace(), self.getName(), self.getVersion().toString()};
+ for (int i = 0; i < provideTuples.length; i++) {
+ augmentedProvides[i + 1] = provideTuples[i];
+ }
+ return augmentedProvides;
+ }
+
+ private static String[][] extractProvides(IInstallableUnit iu) {
+ ProvidedCapability[] provydes = iu.getProvidedCapabilities();
+ String[][] tuples = new String[provydes.length][3];
+ for (int i = 0; i < provydes.length; i++) {
+ ProvidedCapability next = provydes[i];
+ tuples[i] = new String[] {next.getNamespace(), next.getName(), next.getVersion().toString()};
+ }
+ return tuples;
+ }
+
+ // private static String[][] extractRequires(IInstallableUnit iu) {
+ // RequiredCapability[] requyres = iu.getRequiredCapabilities();
+ // String[][] tuples = new String[requyres.length][4];
+ // for (int i = 0; i < requyres.length; i++) {
+ // RequiredCapability next = requyres[i];
+ // tuples[i] = new String[] {next.getNamespace(), next.getName(), next.getRange().toString(), Boolean.valueOf(next.isOptional()).toString()};
+ // }
+ // return tuples;
+ // }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/IUPersistenceTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/IUPersistenceTest.java
index d94ce9ca0..fe852e566 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/IUPersistenceTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/IUPersistenceTest.java
@@ -254,6 +254,60 @@ public class IUPersistenceTest extends AbstractProvisioningTest {
assertTrue("Installable unit write after read after write produced different XML", iuText1.equals(iuText0));
}
+ public void testIUPatchPersistence() throws IOException {
+ IInstallableUnit iu0 = createPatchIU();
+ validateIU(iu0);
+ ByteArrayOutputStream output0 = new ByteArrayOutputStream(3072);
+ IUStringWriter writer0 = new IUStringWriter(output0);
+ writer0.writeTest(iu0);
+ String iuText0 = output0.toString();
+ output0.close();
+
+ IUStringParser parser = new IUStringParser(TestActivator.context, TestActivator.PI_PROV_TESTS);
+ parser.parse(iuText0);
+ assertTrue("Error parsing test iu: " + parser.getStatus().getMessage(), parser.getStatus().isOK());
+ InstallableUnitPatch iu1 = (InstallableUnitPatch) parser.getRootObject();
+ validateIU(iu1);
+ validateIUPatch(iu1);
+ ByteArrayOutputStream output1 = new ByteArrayOutputStream(1492);
+ IUStringWriter writer = new IUStringWriter(output1);
+ writer.writeTest(iu1);
+ String iuText1 = output1.toString();
+ output1.close();
+ assertTrue("Installable unit write after read after write produced different XML", iuText1.equals(iuText0));
+
+ }
+
+ private IInstallableUnitPatch createPatchIU() {
+ Map propertyMap = createProperties(properties);
+ ProvidedCapability[] additionalProvides = createProvided(provides);
+ RequiredCapability[] requirements = createRequired(requires);
+ TouchpointData tpData = createTouchpointData(instructions);
+ IUpdateDescriptor update = createUpdateDescriptor();
+ boolean singleton = false;
+ RequirementChange change1 = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.1.0, 1.3.0)"), null, false, false, true));
+ RequirementChange change2 = new RequirementChange(null, MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.1.0, 1.3.0)"), null, false, false, true));
+ RequirementChange change3 = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), null);
+ RequiredCapability[][] scope = new RequiredCapability[][] { {MetadataFactory.createRequiredCapability("foo", "bar", null, null, true, true), MetadataFactory.createRequiredCapability("foo", "bar", null, null, true, true)}, {MetadataFactory.createRequiredCapability("zoo", "far", null, null, true, true)}};
+ IInstallableUnitPatch iu = createIUPatch(id, version, filter, requirements, additionalProvides, propertyMap, TOUCHPOINT_OSGI, tpData, singleton, update, new RequirementChange[] {change1, change2, change3}, scope, null);
+ return iu;
+ }
+
+ private static void validateIUPatch(IInstallableUnitPatch iu) {
+ validateIU(iu);
+ assertTrue(iu.getApplicabilityScope() != null);
+ assertTrue(iu.getRequiredCapabilities() != null);
+ assertEquals(3, iu.getRequirementsChange().length);
+ assertEquals(null, iu.getRequirementsChange()[1].applyOn());
+ assertNotNull(iu.getRequirementsChange()[1].newValue());
+ assertEquals(null, iu.getRequirementsChange()[2].newValue());
+ assertNotNull(iu.getRequirementsChange()[2].applyOn());
+ assertEquals(2, iu.getApplicabilityScope().length);
+ assertEquals(2, iu.getApplicabilityScope()[0].length);
+ assertEquals(1, iu.getApplicabilityScope()[1].length);
+ assertNull(iu.getLifeCycle());
+ }
+
private static void validateIU(IInstallableUnit iu) {
assertTrue("Installable unit id is not correct", id.equals(iu.getId()));
assertTrue("Installable unit version is not correct", version.equals(iu.getVersion()));
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/AllTests.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/AllTests.java
index 86c242e0d..491ec7152 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/AllTests.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/AllTests.java
@@ -45,6 +45,19 @@ public class AllTests extends TestCase {
suite.addTestSuite(MultipleProvider.class);
suite.addTestSuite(MultipleSingleton.class);
suite.addTestSuite(NoRequirements.class);
+ suite.addTestSuite(PatchTest1.class);
+ suite.addTestSuite(PatchTest10.class);
+ suite.addTestSuite(PatchTest1b.class);
+ suite.addTestSuite(PatchTest1c.class);
+ suite.addTestSuite(PatchTest2.class);
+ suite.addTestSuite(PatchTest3.class);
+ suite.addTestSuite(PatchTest4.class);
+ suite.addTestSuite(PatchTest5.class);
+ suite.addTestSuite(PatchTest6.class);
+ suite.addTestSuite(PatchTest7.class);
+ suite.addTestSuite(PatchTest7b.class);
+ suite.addTestSuite(PatchTest8.class);
+ suite.addTestSuite(PatchTest9.class);
suite.addTestSuite(SimpleOptionalTest.class);
suite.addTestSuite(SimpleOptionalTest2.class);
suite.addTestSuite(SimpleOptionalTest3.class);
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest1.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest1.java
new file mode 100644
index 000000000..697e05030
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest1.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.planner;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.provisional.p2.director.*;
+import org.eclipse.equinox.internal.provisional.p2.engine.IEngine;
+import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class PatchTest1 extends AbstractProvisioningTest {
+ IInstallableUnit a1;
+ IInstallableUnit b1;
+ IInstallableUnitPatch p1;
+
+ IProfile profile1;
+ IPlanner planner;
+ IEngine engine;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ a1 = createIU("A", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.0.0, 1.1.0)"), null, false, true)});
+ b1 = createIU("B", new Version(1, 2, 0), true);
+ RequirementChange change = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.1.0, 1.3.0)"), null, false, false, true));
+ p1 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {change}, new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", VersionRange.emptyRange, null, false, false)}}, null);
+
+ createTestMetdataRepository(new IInstallableUnit[] {a1, b1, p1});
+
+ profile1 = createProfile("TestProfile." + getName());
+ planner = createPlanner();
+ engine = createEngine();
+ }
+
+ public void testInstall() {
+ ProfileChangeRequest req1 = new ProfileChangeRequest(profile1);
+ req1.addInstallableUnits(new IInstallableUnit[] {a1, p1});
+ ProvisioningPlan plan1 = planner.getProvisioningPlan(req1, null, null);
+ assertEquals(IStatus.WARNING, plan1.getStatus().getSeverity());
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest10.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest10.java
new file mode 100644
index 000000000..484e1f0b6
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest10.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.planner;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.provisional.p2.director.*;
+import org.eclipse.equinox.internal.provisional.p2.engine.IEngine;
+import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class PatchTest10 extends AbstractProvisioningTest {
+ IInstallableUnit a1;
+ IInstallableUnit b1;
+ IInstallableUnit b2;
+ IInstallableUnit b3;
+ IInstallableUnitPatch p1;
+ IInstallableUnitPatch pp1;
+
+ IProfile profile1;
+ IPlanner planner;
+ IEngine engine;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ a1 = createIU("A", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.0.0, 1.1.0)"), null, false, true)});
+ b1 = createIU("B", new Version(1, 0, 0), true);
+ b2 = createIU("B", new Version(1, 2, 0), true);
+ b3 = createIU("B", new Version(1, 3, 0), true);
+ RequirementChange change = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.2.0, 1.2.0]"), null, false, false, true));
+ p1 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {change}, new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", VersionRange.emptyRange, null, false, false)}}, null);
+
+ RequirementChange anotherChangeB = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.3.0, 1.3.0]"), null, false, false, true));
+ pp1 = createIUPatch("PP", new Version("1.0.0"), true, new RequirementChange[] {anotherChangeB}, new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", VersionRange.emptyRange, null, false, false)}}, null);
+
+ createTestMetdataRepository(new IInstallableUnit[] {a1, b1, b2, b3, p1, pp1});
+
+ profile1 = createProfile("TestProfile." + getName());
+ planner = createPlanner();
+ engine = createEngine();
+ }
+
+ public void testConflictingPatches() {
+ //a1 and p1 can be installed together
+ ProfileChangeRequest req1 = new ProfileChangeRequest(profile1);
+ req1.addInstallableUnits(new IInstallableUnit[] {a1, p1});
+ ProvisioningPlan plan1 = planner.getProvisioningPlan(req1, null, null);
+ assertEquals(IStatus.OK, plan1.getStatus().getSeverity());
+ assertInstallOperand(plan1, a1);
+ assertInstallOperand(plan1, p1);
+ assertInstallOperand(plan1, b2);
+
+ //a1 and pp1 can be installed together
+ ProfileChangeRequest req2 = new ProfileChangeRequest(profile1);
+ req2.addInstallableUnits(new IInstallableUnit[] {a1, pp1});
+ ProvisioningPlan plan2 = planner.getProvisioningPlan(req2, null, null);
+ assertEquals(IStatus.OK, plan2.getStatus().getSeverity());
+ assertInstallOperand(plan2, a1);
+ assertInstallOperand(plan2, pp1);
+ assertInstallOperand(plan2, b3);
+
+ //a1, p1, and pp1 can not be installed together
+ ProfileChangeRequest req3 = new ProfileChangeRequest(profile1);
+ req3.addInstallableUnits(new IInstallableUnit[] {a1, p1, pp1});
+ ProvisioningPlan plan3 = planner.getProvisioningPlan(req3, null, null);
+ assertEquals(IStatus.ERROR, plan3.getStatus().getSeverity());
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest11.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest11.java
new file mode 100644
index 000000000..fdc101ed0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest11.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.planner;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.provisional.p2.director.*;
+import org.eclipse.equinox.internal.provisional.p2.engine.IEngine;
+import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class PatchTest11 extends AbstractProvisioningTest {
+ IInstallableUnit a1;
+ IInstallableUnit b1;
+ IInstallableUnit b2;
+ IInstallableUnitPatch p1;
+
+ IProfile profile1;
+ IPlanner planner;
+ IEngine engine;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ a1 = createIU("A", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.0.0, 1.1.0)"), null, false, true, true)});
+ b1 = createIU("B", new Version(1, 0, 0), true);
+ b2 = createIU("B", new Version(1, 2, 0), true);
+ RequirementChange change = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.1.0, 1.3.0)"), "foo=bar", false, false, true));
+ p1 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {change}, new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", VersionRange.emptyRange, null, false, false)}}, null);
+
+ createTestMetdataRepository(new IInstallableUnit[] {a1, b1, b2, p1});
+
+ profile1 = createProfile("TestProfile." + getName());
+ planner = createPlanner();
+ engine = createEngine();
+ }
+
+ public void testInstallBogusInstallFilterInPatch() {
+ //Verify that a1 installs properly
+ // ProfileChangeRequest req1 = new ProfileChangeRequest(profile1);
+ // req1.addInstallableUnits(new IInstallableUnit[] {a1});
+ // ProvisioningPlan plan1 = planner.getProvisioningPlan(req1, null, null);
+ // assertTrue(IStatus.ERROR != plan1.getStatus().getSeverity());
+ // assertNoOperand(plan1, p1);
+ // assertNoOperand(plan1, b2);
+ // assertNoOperand(plan1, p1);
+ // assertInstallOperand(plan1, a1);
+ // assertInstallOperand(plan1, b1);
+
+ //Try to install a1 and p1 optionally
+ ProfileChangeRequest req2 = new ProfileChangeRequest(profile1);
+ req2.addInstallableUnits(new IInstallableUnit[] {a1, p1});
+ req2.setInstallableUnitInclusionRules(p1, PlannerHelper.createOptionalInclusionRule(p1));
+ ProvisioningPlan plan2 = planner.getProvisioningPlan(req2, null, null);
+ assertTrue(IStatus.ERROR != plan2.getStatus().getSeverity());
+ assertNoOperand(plan2, p1);
+ assertNoOperand(plan2, b2);
+ assertNoOperand(plan2, p1);
+ assertInstallOperand(plan2, a1);
+ assertInstallOperand(plan2, b1);
+
+ //Try to install a1 and p1. This should fail because the patch adds an invalid filter
+ ProfileChangeRequest req3 = new ProfileChangeRequest(profile1);
+ req3.addInstallableUnits(new IInstallableUnit[] {a1, p1});
+ ProvisioningPlan plan3 = planner.getProvisioningPlan(req3, null, null);
+ assertTrue(IStatus.ERROR == plan3.getStatus().getSeverity());
+
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest12.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest12.java
new file mode 100644
index 000000000..4c370706d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest12.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.planner;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.provisional.p2.director.*;
+import org.eclipse.equinox.internal.provisional.p2.engine.IEngine;
+import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class PatchTest12 extends AbstractProvisioningTest {
+ IInstallableUnit a1;
+ IInstallableUnit b1;
+ IInstallableUnit b2;
+ IInstallableUnitPatch p1;
+
+ IProfile profile1;
+ IPlanner planner;
+ IEngine engine;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ a1 = createIU("A", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.0.0, 1.1.0)"), null, false, true, true)});
+ b1 = createIU("B", new Version(1, 0, 0), true);
+ b2 = createIU("B", new Version(1, 2, 0), true);
+ RequirementChange change = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.4.0, 1.5.0)"), null, false, false, true));
+ p1 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {change}, new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", VersionRange.emptyRange, null, false, false)}}, null);
+
+ createTestMetdataRepository(new IInstallableUnit[] {a1, b1, b2, p1});
+
+ profile1 = createProfile("TestProfile." + getName());
+ planner = createPlanner();
+ engine = createEngine();
+ }
+
+ public void testInstallBogusInstallFilterInPatch() {
+ //Verify that a1 installs properly
+ // ProfileChangeRequest req1 = new ProfileChangeRequest(profile1);
+ // req1.addInstallableUnits(new IInstallableUnit[] {a1});
+ // ProvisioningPlan plan1 = planner.getProvisioningPlan(req1, null, null);
+ // assertTrue(IStatus.ERROR != plan1.getStatus().getSeverity());
+ // assertNoOperand(plan1, p1);
+ // assertNoOperand(plan1, b2);
+ // assertNoOperand(plan1, p1);
+ // assertInstallOperand(plan1, a1);
+ // assertInstallOperand(plan1, b1);
+
+ //Try to install a1 and p1 optionally
+ ProfileChangeRequest req2 = new ProfileChangeRequest(profile1);
+ req2.addInstallableUnits(new IInstallableUnit[] {a1, p1});
+ req2.setInstallableUnitInclusionRules(p1, PlannerHelper.createOptionalInclusionRule(p1));
+ ProvisioningPlan plan2 = planner.getProvisioningPlan(req2, null, null);
+ assertTrue(IStatus.ERROR != plan2.getStatus().getSeverity());
+ assertNoOperand(plan2, p1);
+ assertNoOperand(plan2, b2);
+ assertNoOperand(plan2, p1);
+ assertInstallOperand(plan2, a1);
+ assertInstallOperand(plan2, b1);
+
+ //Try to install a1 and p1. This should fail because the patch adds an invalid filter
+ ProfileChangeRequest req3 = new ProfileChangeRequest(profile1);
+ req3.addInstallableUnits(new IInstallableUnit[] {a1, p1});
+ ProvisioningPlan plan3 = planner.getProvisioningPlan(req3, null, null);
+ assertTrue(IStatus.ERROR == plan3.getStatus().getSeverity());
+
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest1b.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest1b.java
new file mode 100644
index 000000000..befbf575a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest1b.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.planner;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.provisional.p2.director.*;
+import org.eclipse.equinox.internal.provisional.p2.engine.IEngine;
+import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class PatchTest1b extends AbstractProvisioningTest {
+ IInstallableUnit a1;
+ IInstallableUnit b1;
+ IInstallableUnit b2;
+ IInstallableUnitPatch p1;
+
+ IProfile profile1;
+ IPlanner planner;
+ IEngine engine;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ a1 = createIU("A", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.0.0, 1.1.0)"), null, false, true)});
+ b1 = createIU("B", new Version(1, 0, 0), true);
+ b2 = createIU("B", new Version(1, 2, 0), true);
+ RequirementChange change = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.1.0, 1.3.0)"), null, false, false, true));
+ p1 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {change}, new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", VersionRange.emptyRange, null, false, false)}}, null);
+
+ createTestMetdataRepository(new IInstallableUnit[] {a1, b1, b2, p1});
+
+ profile1 = createProfile("TestProfile." + getName());
+ planner = createPlanner();
+ engine = createEngine();
+ }
+
+ public void testInstall() {
+ ProfileChangeRequest req1 = new ProfileChangeRequest(profile1);
+ req1.addInstallableUnits(new IInstallableUnit[] {a1, p1});
+ ProvisioningPlan plan1 = planner.getProvisioningPlan(req1, null, null);
+ assertTrue(IStatus.ERROR != plan1.getStatus().getSeverity());
+ assertInstallOperand(plan1, a1);
+ assertInstallOperand(plan1, p1);
+ assertInstallOperand(plan1, b2);
+ assertNoOperand(plan1, b1);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest1c.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest1c.java
new file mode 100644
index 000000000..fbbb95280
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest1c.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.planner;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.provisional.p2.director.*;
+import org.eclipse.equinox.internal.provisional.p2.engine.IEngine;
+import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class PatchTest1c extends AbstractProvisioningTest {
+ IInstallableUnit a1;
+ IInstallableUnit b1;
+ IInstallableUnit b2;
+ IInstallableUnit b3;
+ IInstallableUnitPatch p1;
+
+ IProfile profile1;
+ IPlanner planner;
+ IEngine engine;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ a1 = createIU("A", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.0.0, 1.1.0)"), null, false, true)});
+ b1 = createIU("B", new Version(1, 0, 0), true);
+ b2 = createIU("B", new Version(1, 2, 0), true);
+ b3 = createIU("B", new Version(1, 3, 0), true);
+ RequirementChange change = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.2.0, 1.2.0]"), null, false, false, true));
+ p1 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {change}, new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", VersionRange.emptyRange, null, false, false)}}, null);
+
+ createTestMetdataRepository(new IInstallableUnit[] {a1, b1, b2, p1});
+
+ profile1 = createProfile("TestProfile." + getName());
+ planner = createPlanner();
+ engine = createEngine();
+ }
+
+ public void testInstall() {
+ ProfileChangeRequest req1 = new ProfileChangeRequest(profile1);
+ req1.addInstallableUnits(new IInstallableUnit[] {a1, p1});
+ ProvisioningPlan plan1 = planner.getProvisioningPlan(req1, null, null);
+ assertTrue(IStatus.ERROR != plan1.getStatus().getSeverity());
+ assertInstallOperand(plan1, a1);
+ assertInstallOperand(plan1, p1);
+ assertInstallOperand(plan1, b2);
+ assertNoOperand(plan1, b1);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest2.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest2.java
new file mode 100644
index 000000000..9d79659c0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest2.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.planner;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.provisional.p2.director.*;
+import org.eclipse.equinox.internal.provisional.p2.engine.IEngine;
+import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class PatchTest2 extends AbstractProvisioningTest {
+ IInstallableUnit a1;
+ IInstallableUnit b1;
+ IInstallableUnitPatch p1;
+ IInstallableUnitPatch p2;
+ IInstallableUnitPatch p3;
+ IInstallableUnitPatch p4;
+ IInstallableUnitPatch p5;
+ IInstallableUnitPatch p6;
+ IInstallableUnitPatch p7;
+
+ IProfile profile1;
+ IPlanner planner;
+ IEngine engine;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ ProvidedCapability[] cap = new ProvidedCapability[] {MetadataFactory.createProvidedCapability("foo", "bar", new Version(1, 0, 0))};
+ a1 = createIU("A", new Version("1.0.0"), null, new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.0.0, 1.1.0)"), null, false, false)}, cap, NO_PROPERTIES, TouchpointType.NONE, NO_TP_DATA, false, null);
+ b1 = createIU("B", new Version(1, 2, 0), true);
+ RequirementChange change = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.1.0, 1.3.0)"), null, false, false, true));
+ p1 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {change}, new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[1.0.0, 1.1.0]"), null, false, false, false)}}, null);
+ p2 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {change}, new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[1.3.0, 1.5.0]"), null, false, false, false)}}, null);
+ p3 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {change}, new RequiredCapability[][] { {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[1.0.0, 1.1.0]"), null, false, false, false)}, {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[1.3.0, 1.5.0]"), null, false, false, false)}}, null);
+ p4 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {change}, new RequiredCapability[][] { {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[1.6.0, 1.7.0]"), null, false, false, false)}, {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[1.3.0, 1.5.0]"), null, false, false, false)}}, null);
+ p5 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {change}, new RequiredCapability[][] {{MetadataFactory.createRequiredCapability("foo", "bar", new VersionRange("[1.0.0, 2.0.0)"), null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[1.0.0, 1.5.0]"), null, false, false, false)}}, null);
+ p6 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {change}, new RequiredCapability[][] {}, null);
+ p7 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {change}, null, null);
+ createTestMetdataRepository(new IInstallableUnit[] {a1, b1, p1, p2, p3, p4, p5, p6});
+
+ profile1 = createProfile("TestProfile." + getName());
+ planner = createPlanner();
+ engine = createEngine();
+ }
+
+ public void testPatchScope() {
+ //p6 applies to all IUs therefore A's installation succeed
+ ProfileChangeRequest req8 = new ProfileChangeRequest(profile1);
+ req8.addInstallableUnits(new IInstallableUnit[] {a1, p6});
+ ProvisioningPlan plan8 = planner.getProvisioningPlan(req8, null, null);
+ assertEquals(IStatus.WARNING, plan8.getStatus().getSeverity());
+
+ //p7 does not apply therefore A should not be installable
+ ProfileChangeRequest req7 = new ProfileChangeRequest(profile1);
+ req7.addInstallableUnits(new IInstallableUnit[] {a1, p7});
+ ProvisioningPlan plan7 = planner.getProvisioningPlan(req7, null, null);
+ assertEquals(IStatus.ERROR, plan7.getStatus().getSeverity());
+
+ //p5 does not causes a1 to resolve therefore the application fails
+ ProfileChangeRequest req6 = new ProfileChangeRequest(profile1);
+ req6.addInstallableUnits(new IInstallableUnit[] {a1, p5});
+ ProvisioningPlan plan6 = planner.getProvisioningPlan(req6, null, null);
+ assertEquals(IStatus.WARNING, plan6.getStatus().getSeverity());
+
+ //Ensure that p1 causes a1 to resolve
+ ProfileChangeRequest req2 = new ProfileChangeRequest(profile1);
+ req2.addInstallableUnits(new IInstallableUnit[] {a1, p1});
+ ProvisioningPlan plan2 = planner.getProvisioningPlan(req2, null, null);
+ assertEquals(IStatus.WARNING, plan2.getStatus().getSeverity());
+
+ //p2 does not causes a1 to resolve therefore the application fails
+ ProfileChangeRequest req3 = new ProfileChangeRequest(profile1);
+ req3.addInstallableUnits(new IInstallableUnit[] {a1, p2});
+ ProvisioningPlan plan3 = planner.getProvisioningPlan(req3, null, null);
+ assertEquals(IStatus.ERROR, plan3.getStatus().getSeverity());
+
+ //Ensure that p3 causes a1 to resolve since it has two scopes where one is applicable
+ ProfileChangeRequest req4 = new ProfileChangeRequest(profile1);
+ req4.addInstallableUnits(new IInstallableUnit[] {a1, p3});
+ ProvisioningPlan plan4 = planner.getProvisioningPlan(req4, null, null);
+ assertEquals(IStatus.WARNING, plan4.getStatus().getSeverity());
+
+ //p4 does not causes a1 to resolve therefore the application fails
+ ProfileChangeRequest req5 = new ProfileChangeRequest(profile1);
+ req5.addInstallableUnits(new IInstallableUnit[] {a1, p4});
+ ProvisioningPlan plan5 = planner.getProvisioningPlan(req5, null, null);
+ assertEquals(IStatus.ERROR, plan5.getStatus().getSeverity());
+
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest3.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest3.java
new file mode 100644
index 000000000..be383f5e2
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest3.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.planner;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.provisional.p2.director.*;
+import org.eclipse.equinox.internal.provisional.p2.engine.*;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class PatchTest3 extends AbstractProvisioningTest {
+ IInstallableUnit f1;
+ IInstallableUnit f2;
+ IInstallableUnit a1;
+ IInstallableUnit a3;
+ IInstallableUnit b1, b2;
+ IInstallableUnitPatch p1;
+
+ IProfile profile1;
+ IPlanner planner;
+ IEngine engine;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ f1 = createIU("F", new Version(1, 0, 0), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[1.0.0, 1.1.0]"), null, false, false, true)});
+ f2 = createIU("F", new Version(2, 0, 0), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[3.0.0, 4.0.0)"), null, false, false, true)});
+ ProvidedCapability[] cap = new ProvidedCapability[] {MetadataFactory.createProvidedCapability("foo", "bar", new Version(1, 0, 0))};
+ a1 = createIU("A", new Version("1.0.0"), null, new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.0.0, 1.1.0)"), null, false, false)}, cap, NO_PROPERTIES, TouchpointType.NONE, NO_TP_DATA, false, null);
+ a3 = createIU("A", new Version(3, 0, 0), true);
+ b1 = createIU("B", new Version(1, 0, 0), true);
+ b2 = createIU("B", new Version(2, 0, 0), true);
+ RequirementChange change = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[2.0.0, 2.1.0)"), null, false, false, true));
+ RequiredCapability lifeCycle = MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "F", new VersionRange("[1.0.0, 1.1.0)"), null, false, false, false);
+ p1 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {change}, new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[1.0.0, 1.1.0]"), null, false, false, false)}}, lifeCycle);
+ createTestMetdataRepository(new IInstallableUnit[] {a1, b1, b2, p1, a3, f1, f2});
+
+ profile1 = createProfile("TestProfile." + getName());
+ planner = createPlanner();
+ engine = createEngine();
+ }
+
+ public void testCompleteScenario() {
+ // Install a1
+ ProfileChangeRequest req1 = new ProfileChangeRequest(profile1);
+ req1.addInstallableUnits(new IInstallableUnit[] {f1});
+ ProvisioningPlan plan1 = planner.getProvisioningPlan(req1, null, null);
+ assertEquals(IStatus.OK, plan1.getStatus().getSeverity());
+ assertInstallOperand(plan1, b1);
+ assertInstallOperand(plan1, a1);
+ assertInstallOperand(plan1, f1);
+ engine.perform(profile1, new DefaultPhaseSet(), plan1.getOperands(), null, null);
+ assertProfileContainsAll("A1 is missing", profile1, new IInstallableUnit[] {a1});
+ assertProfileContainsAll("B1 is missing", profile1, new IInstallableUnit[] {b1});
+ assertProfileContainsAll("B1 is missing", profile1, new IInstallableUnit[] {f1});
+
+ //Install p1, this should cause b1 to be uninstalled and b2 to be used instead
+ ProfileChangeRequest req2 = new ProfileChangeRequest(profile1);
+ req2.addInstallableUnits(new IInstallableUnit[] {p1});
+ req2.setInstallableUnitInclusionRules(p1, PlannerHelper.createOptionalInclusionRule(p1));
+ ProvisioningPlan plan2 = planner.getProvisioningPlan(req2, null, null);
+ assertTrue(IStatus.ERROR != plan2.getStatus().getSeverity());
+ assertInstallOperand(plan2, p1);
+ assertInstallOperand(plan2, b2);
+ engine.perform(profile1, new DefaultPhaseSet(), plan2.getOperands(), null, null);
+ assertProfileContainsAll("A1 is missing", profile1, new IInstallableUnit[] {a1});
+ assertProfileContainsAll("B2 is missing", profile1, new IInstallableUnit[] {b2});
+ assertProfileContainsAll("P1 is missing", profile1, new IInstallableUnit[] {p1});
+ assertProfileContainsAll("P1 is missing", profile1, new IInstallableUnit[] {f1});
+
+ //Try to uninstall p1, this causes b1 to come back and b2 to go away
+ ProfileChangeRequest req3 = new ProfileChangeRequest(profile1);
+ req3.removeInstallableUnits(new IInstallableUnit[] {p1});
+ ProvisioningPlan plan3 = planner.getProvisioningPlan(req3, null, null);
+ assertTrue(IStatus.ERROR != plan3.getStatus().getSeverity());
+ assertInstallOperand(plan3, b1);
+ assertUninstallOperand(plan3, b2);
+ assertUninstallOperand(plan3, p1);
+
+ //Try to uninstall f should not be blocked by p1 since it is installed optionally
+ ProfileChangeRequest req4 = new ProfileChangeRequest(profile1);
+ req4.removeInstallableUnits(new IInstallableUnit[] {f1});
+ ProvisioningPlan plan4 = planner.getProvisioningPlan(req4, null, null);
+ assertTrue(IStatus.ERROR != plan4.getStatus().getSeverity());
+ assertUninstallOperand(plan4, b2);
+ assertUninstallOperand(plan4, a1);
+ assertUninstallOperand(plan4, f1);
+ assertUninstallOperand(plan4, p1);
+
+ //update from f1 to f2. This should cause p1 to go away
+ ProfileChangeRequest req5 = new ProfileChangeRequest(profile1);
+ req5.removeInstallableUnits(new IInstallableUnit[] {f1});
+ req5.addInstallableUnits(new IInstallableUnit[] {f2});
+ ProvisioningPlan plan5 = planner.getProvisioningPlan(req5, null, null);
+ assertTrue(IStatus.ERROR != plan5.getStatus().getSeverity());
+ assertUninstallOperand(plan5, b2);
+ assertUninstallOperand(plan5, a1);
+ assertUninstallOperand(plan5, f1);
+ assertUninstallOperand(plan5, p1);
+ assertInstallOperand(plan5, f2);
+ assertInstallOperand(plan5, a3);
+ engine.perform(profile1, new DefaultPhaseSet(), plan5.getOperands(), null, null);
+ assertProfileContainsAll("", profile1, new IInstallableUnit[] {f2, a3});
+
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest4.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest4.java
new file mode 100644
index 000000000..62b45e838
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest4.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.planner;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.provisional.p2.director.*;
+import org.eclipse.equinox.internal.provisional.p2.engine.*;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class PatchTest4 extends AbstractProvisioningTest {
+ IInstallableUnit f1;
+ IInstallableUnit a1;
+ IInstallableUnit b1;
+ IInstallableUnit b2;
+ IInstallableUnit c1;
+ IInstallableUnit d1;
+ IInstallableUnit d2;
+
+ IInstallableUnitPatch p1;
+ IInstallableUnitPatch p2;
+
+ IProfile profile1;
+ IPlanner planner;
+ IEngine engine;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ f1 = createIU("F", new Version(1, 0, 0), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", VersionRange.emptyRange, null, false, false, true), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "C", VersionRange.emptyRange, null, false, false, true)});
+ a1 = createIU("A", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.0.0, 1.1.0)"), null, false, false, true)});
+ b1 = createIU("B", new Version(1, 0, 0), true);
+ c1 = createIU("C", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "D", new VersionRange("[1.0.0, 1.1.0)"), null, false, false, true)});
+ d1 = createIU("D", new Version(1, 0, 0), true);
+ b2 = createIU("B", new Version(2, 0, 0), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "D", new VersionRange("[2.0.0, 3.1.0)"), null, false, false, true)});
+ d2 = createIU("D", new Version(2, 0, 0), true);
+
+ RequirementChange changeA = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[2.0.0, 2.1.0)"), null, false, false, true));
+ RequirementChange changeC = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "D", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "D", new VersionRange("[2.0.0, 2.1.0)"), null, false, false, true));
+
+ RequiredCapability lifeCycle = MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "F", VersionRange.emptyRange, null, false, false, false);
+ RequiredCapability[][] scope = new RequiredCapability[][] { {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[1.0.0, 1.1.0]"), null, false, false, false)}, {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "C", new VersionRange("[1.0.0, 1.1.0]"), null, false, false, false)}};
+ p1 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {changeA, changeC}, scope, lifeCycle);
+ p2 = createIUPatch("P", new Version("2.0.0"), true, new RequirementChange[] {changeA, changeC}, new RequiredCapability[0][0], lifeCycle);
+ createTestMetdataRepository(new IInstallableUnit[] {f1, a1, b1, b2, c1, d1, d2, p1});
+
+ profile1 = createProfile("TestProfile." + getName());
+ planner = createPlanner();
+ engine = createEngine();
+ }
+
+ public void testCompleteScenario() {
+ // Install f1
+ ProfileChangeRequest req1 = new ProfileChangeRequest(profile1);
+ req1.addInstallableUnits(new IInstallableUnit[] {f1});
+ ProvisioningPlan plan1 = planner.getProvisioningPlan(req1, null, null);
+ assertEquals(IStatus.OK, plan1.getStatus().getSeverity());
+ assertInstallOperand(plan1, b1);
+ assertInstallOperand(plan1, a1);
+ assertInstallOperand(plan1, f1);
+ engine.perform(profile1, new DefaultPhaseSet(), plan1.getOperands(), null, null);
+ assertProfileContainsAll("A1 is missing", profile1, new IInstallableUnit[] {a1});
+ assertProfileContainsAll("B1 is missing", profile1, new IInstallableUnit[] {b1});
+ assertProfileContainsAll("C1 is missing", profile1, new IInstallableUnit[] {c1});
+ assertProfileContainsAll("D1 is missing", profile1, new IInstallableUnit[] {d1});
+
+ //Install p1, this will cause C2 and D2 to be installed
+ ProfileChangeRequest req2 = new ProfileChangeRequest(profile1);
+ req2.addInstallableUnits(new IInstallableUnit[] {p1});
+ req2.setInstallableUnitInclusionRules(p1, PlannerHelper.createOptionalInclusionRule(p1));
+ ProvisioningPlan plan2 = planner.getProvisioningPlan(req2, null, null);
+ assertTrue(IStatus.ERROR != plan2.getStatus().getSeverity());
+ assertInstallOperand(plan2, b2);
+ assertInstallOperand(plan2, d2);
+ engine.perform(profile1, new DefaultPhaseSet(), plan2.getOperands(), null, null);
+ assertProfileContainsAll("A1 is missing", profile1, new IInstallableUnit[] {a1});
+ assertProfileContainsAll("B2 is missing", profile1, new IInstallableUnit[] {b2});
+ assertProfileContainsAll("P1 is missing", profile1, new IInstallableUnit[] {p1});
+ assertProfileContainsAll("C1 is missing", profile1, new IInstallableUnit[] {c1});
+ assertProfileContainsAll("D2 is missing", profile1, new IInstallableUnit[] {d2});
+ assertProfileContainsAll("F1 is missing", profile1, new IInstallableUnit[] {f1});
+ }
+
+ public void OfftestCompleteScenario2() {
+ //This test when no scopes are specified
+ // Install f1
+ ProfileChangeRequest req1 = new ProfileChangeRequest(profile1);
+ req1.addInstallableUnits(new IInstallableUnit[] {f1});
+ ProvisioningPlan plan1 = planner.getProvisioningPlan(req1, null, null);
+ assertEquals(IStatus.OK, plan1.getStatus().getSeverity());
+ assertInstallOperand(plan1, b1);
+ assertInstallOperand(plan1, a1);
+ assertInstallOperand(plan1, f1);
+ engine.perform(profile1, new DefaultPhaseSet(), plan1.getOperands(), null, null);
+ assertProfileContainsAll("A1 is missing", profile1, new IInstallableUnit[] {a1});
+ assertProfileContainsAll("B1 is missing", profile1, new IInstallableUnit[] {b1});
+ assertProfileContainsAll("C1 is missing", profile1, new IInstallableUnit[] {c1});
+ assertProfileContainsAll("D1 is missing", profile1, new IInstallableUnit[] {d1});
+
+ //Install p2, this should cause b1 to be uninstalled and b2 to be used instead
+ ProfileChangeRequest req2 = new ProfileChangeRequest(profile1);
+ req2.addInstallableUnits(new IInstallableUnit[] {p2});
+ req2.setInstallableUnitInclusionRules(p1, PlannerHelper.createOptionalInclusionRule(p1));
+ ProvisioningPlan plan2 = planner.getProvisioningPlan(req2, null, null);
+ assertTrue(IStatus.ERROR != plan2.getStatus().getSeverity());
+ assertInstallOperand(plan2, b2);
+ assertInstallOperand(plan2, d2);
+ engine.perform(profile1, new DefaultPhaseSet(), plan2.getOperands(), null, null);
+ assertProfileContainsAll("A1 is missing", profile1, new IInstallableUnit[] {a1});
+ assertProfileContainsAll("B2 is missing", profile1, new IInstallableUnit[] {b2});
+ assertProfileContainsAll("P1 is missing", profile1, new IInstallableUnit[] {p1});
+ assertProfileContainsAll("C1 is missing", profile1, new IInstallableUnit[] {c1});
+ assertProfileContainsAll("D2 is missing", profile1, new IInstallableUnit[] {d2});
+ assertProfileContainsAll("F1 is missing", profile1, new IInstallableUnit[] {f1});
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest5.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest5.java
new file mode 100644
index 000000000..a3bea8227
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest5.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.planner;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.provisional.p2.director.*;
+import org.eclipse.equinox.internal.provisional.p2.engine.IEngine;
+import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class PatchTest5 extends AbstractProvisioningTest {
+ IInstallableUnit a1;
+ IInstallableUnit f1;
+ IInstallableUnit top;
+ IInstallableUnit b1;
+ IInstallableUnitPatch p1;
+
+ IProfile profile1;
+ IPlanner planner;
+ IEngine engine;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ top = createIU("TOP", new Version(1, 0, 0), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "F", new VersionRange("[1.0.0, 1.0.0]"), null, false, false, true)});
+ f1 = createIU("F", new Version(1, 0, 0), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[1.0.0, 1.0.0]"), null, false, false, true)});
+ a1 = createIU("A", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.0.0, 1.1.0)"), null, false, true)});
+ b1 = createIU("B", new Version(1, 2, 0), true);
+ RequirementChange change = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.1.0, 1.3.0)"), null, false, false, true));
+ RequiredCapability lifeCycle = MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "F", new VersionRange("[1.0.0, 1.0.0]"), null, false, false, true);
+ RequiredCapability[][] scope = new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[1.0.0,1.0.0]"), null, false, false)}};
+ p1 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {change}, scope, lifeCycle);
+
+ createTestMetdataRepository(new IInstallableUnit[] {a1, b1, f1, top, p1});
+
+ profile1 = createProfile("TestProfile." + getName());
+ planner = createPlanner();
+ engine = createEngine();
+ }
+
+ public void testInstall() {
+ ProfileChangeRequest req1 = new ProfileChangeRequest(profile1);
+ req1.addInstallableUnits(new IInstallableUnit[] {top});
+ ProvisioningPlan plan1 = planner.getProvisioningPlan(req1, null, null);
+ assertEquals(IStatus.ERROR, plan1.getStatus().getSeverity());
+
+ ProfileChangeRequest req2 = new ProfileChangeRequest(profile1);
+ req2.addInstallableUnits(new IInstallableUnit[] {top, p1});
+ ProvisioningPlan plan2 = planner.getProvisioningPlan(req2, null, null);
+ assertEquals(IStatus.WARNING, plan2.getStatus().getSeverity());
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest6.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest6.java
new file mode 100644
index 000000000..304d136dd
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest6.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.planner;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.provisional.p2.director.*;
+import org.eclipse.equinox.internal.provisional.p2.engine.IEngine;
+import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class PatchTest6 extends AbstractProvisioningTest {
+ IInstallableUnit a1;
+ IInstallableUnit b1;
+ IInstallableUnit c1;
+ IInstallableUnit d1;
+
+ IInstallableUnitPatch p1;
+ IInstallableUnitPatch pp1;
+
+ IProfile profile1;
+ IPlanner planner;
+ IEngine engine;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ a1 = createIU("A", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.0.0, 1.1.0)"), null, false, true)});
+ b1 = createIU("B", new Version(1, 2, 0), true);
+
+ c1 = createIU("C", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "D", new VersionRange("[1.0.0, 1.1.0)"), null, false, true)});
+ d1 = createIU("D", new Version(1, 2, 0), true);
+
+ RequirementChange changeA = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.1.0, 1.3.0)"), null, false, false, true));
+ RequiredCapability[][] scopeP1 = new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", VersionRange.emptyRange, null, false, false, false)}};
+ RequiredCapability[] reqOnPP = new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "PP", new VersionRange("[1.0.0, 2.0.0)"), null, false, false, true)};
+ p1 = createIUPatch("P", new Version("1.0.0"), null, reqOnPP, NO_PROVIDES, NO_PROPERTIES, TouchpointType.NONE, NO_TP_DATA, false, null, new RequirementChange[] {changeA}, scopeP1, null);
+
+ RequirementChange changeC = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "D", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "D", new VersionRange("[1.1.0, 1.3.0)"), null, false, false, true));
+ RequiredCapability[][] scopePP1 = new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "C", VersionRange.emptyRange, null, false, false, false)}};
+ pp1 = createIUPatch("PP", new Version("1.0.0"), true, new RequirementChange[] {changeC}, scopePP1, null);
+ createTestMetdataRepository(new IInstallableUnit[] {a1, b1, c1, d1, p1, pp1});
+
+ profile1 = createProfile("TestProfile." + getName());
+ planner = createPlanner();
+ engine = createEngine();
+ }
+
+ public void testInstall() {
+ //Confirm that a1 and c1 can't be installed
+ ProfileChangeRequest req1 = new ProfileChangeRequest(profile1);
+ req1.addInstallableUnits(new IInstallableUnit[] {a1, c1});
+ ProvisioningPlan plan1 = planner.getProvisioningPlan(req1, null, null);
+ assertEquals(IStatus.ERROR, plan1.getStatus().getSeverity());
+
+ //Verify that the installation of c1 and pp1 succeed
+ ProfileChangeRequest req2 = new ProfileChangeRequest(profile1);
+ req2.addInstallableUnits(new IInstallableUnit[] {c1, pp1});
+ ProvisioningPlan plan2 = planner.getProvisioningPlan(req2, null, null);
+ assertEquals(IStatus.WARNING, plan2.getStatus().getSeverity());
+
+ //Verify that p1 can be installed alone (kind of meaningless)
+ ProfileChangeRequest req3 = new ProfileChangeRequest(profile1);
+ req3.addInstallableUnits(new IInstallableUnit[] {p1});
+ ProvisioningPlan plan3 = planner.getProvisioningPlan(req3, null, null);
+ assertEquals(IStatus.OK, plan3.getStatus().getSeverity());
+
+ //Install a1 and p1.
+ ProfileChangeRequest req4 = new ProfileChangeRequest(profile1);
+ req4.addInstallableUnits(new IInstallableUnit[] {a1, p1});
+ ProvisioningPlan plan4 = planner.getProvisioningPlan(req4, null, null);
+ assertEquals(IStatus.WARNING, plan4.getStatus().getSeverity());
+ assertInstallOperand(plan4, a1);
+ assertInstallOperand(plan4, p1);
+ assertInstallOperand(plan4, pp1);
+ assertInstallOperand(plan4, b1);
+
+ //Install a1, c1 and p1.
+ ProfileChangeRequest req5 = new ProfileChangeRequest(profile1);
+ req5.addInstallableUnits(new IInstallableUnit[] {a1, c1, p1});
+ ProvisioningPlan plan5 = planner.getProvisioningPlan(req5, null, null);
+ assertEquals(IStatus.WARNING, plan5.getStatus().getSeverity());
+ assertInstallOperand(plan4, a1);
+ assertInstallOperand(plan4, p1);
+ assertInstallOperand(plan4, b1);
+ assertInstallOperand(plan4, pp1);
+ assertInstallOperand(plan5, d1);
+ assertInstallOperand(plan5, c1);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest7.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest7.java
new file mode 100644
index 000000000..6e166ba05
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest7.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.planner;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.provisional.p2.director.*;
+import org.eclipse.equinox.internal.provisional.p2.engine.IEngine;
+import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class PatchTest7 extends AbstractProvisioningTest {
+ // IInstallableUnit a1;
+ // IInstallableUnit b1;
+ IInstallableUnit c1;
+ // IInstallableUnit x1;
+ IInstallableUnit y1;
+ IInstallableUnit y2;
+ IInstallableUnit f1;
+
+ // IInstallableUnitPatch p1;
+ IInstallableUnitPatch pp1;
+
+ IProfile profile1;
+ IPlanner planner;
+ IEngine engine;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ // x1 = createIU("X", new Version(1, 2, 0), true);
+ y1 = createIU("Y", new Version(1, 0, 0), true);
+ y2 = createIU("Y", new Version(1, 2, 0), true);
+ // a1 = createIU("A", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "X", new VersionRange("[1.0.0, 1.1.0)"), null, false, true)});
+ // b1 = createIU("B", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "X", new VersionRange("[1.0.0, 1.1.0)"), null, false, true)});
+ c1 = createIU("C", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "Y", new VersionRange("[1.0.0, 1.1.0)"), null, false, true)});
+
+ RequiredCapability[] req = new RequiredCapability[1];
+ // req[0] = MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[1.0.0, 1.1.0)"), null, false, true);
+ // req[1] = MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.0.0, 1.1.0)"), null, false, true);
+ req[0] = MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "C", new VersionRange("[1.0.0, 1.1.0)"), null, false, true);
+ f1 = createIU("F", new Version(1, 0, 0), req);
+
+ // RequirementChange changeX = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "X", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "X", new VersionRange("[1.1.0, 1.3.0)"), null, false, false, true));
+ // RequiredCapability[][] scope = new RequiredCapability[0][0]; //new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", VersionRange.emptyRange, null, false, false, false)}};
+ // p1 = createIUPatch("P", new Version("1.0.0"), null, NO_REQUIRES, NO_PROVIDES, NO_PROPERTIES, TouchpointType.NONE, NO_TP_DATA, false, null, new RequirementChange[] {changeX}, scope, null);
+
+ RequirementChange changeY = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "Y", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "Y", new VersionRange("[1.1.0, 1.3.0)"), null, false, false, true));
+ RequiredCapability[][] scopePP = new RequiredCapability[0][0]; //new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "C", VersionRange.emptyRange, null, false, false, false)}};
+ pp1 = createIUPatch("PP", new Version("1.0.0"), null, NO_REQUIRES, NO_PROVIDES, NO_PROPERTIES, TouchpointType.NONE, NO_TP_DATA, false, null, new RequirementChange[] {changeY}, scopePP, null);
+
+ // createTestMetdataRepository(new IInstallableUnit[] {a1, b1, c1, x1, y1, y2, f1, p1, pp1});
+ createTestMetdataRepository(new IInstallableUnit[] {c1, y1, y2, f1, pp1});
+
+ profile1 = createProfile("TestProfile." + getName());
+ planner = createPlanner();
+ engine = createEngine();
+ }
+
+ public void testGeneralScope() {
+ // //Confirm that f1 can't be installed
+ // ProfileChangeRequest req1 = new ProfileChangeRequest(profile1);
+ // req1.addInstallableUnits(new IInstallableUnit[] {f1});
+ // ProvisioningPlan plan1 = planner.getProvisioningPlan(req1, null, null);
+ // assertEquals(IStatus.ERROR, plan1.getStatus().getSeverity());
+ //
+ // //Verify that the installation of f1 and p1 succeed
+ // ProfileChangeRequest req2 = new ProfileChangeRequest(profile1);
+ // req2.addInstallableUnits(new IInstallableUnit[] {f1, p1});
+ // ProvisioningPlan plan2 = planner.getProvisioningPlan(req2, null, null);
+ // assertEquals(IStatus.WARNING, plan2.getStatus().getSeverity());
+ // assertInstallOperand(plan2, f1);
+ // assertInstallOperand(plan2, a1);
+ // assertInstallOperand(plan2, b1);
+ // assertInstallOperand(plan2, c1);
+ // assertInstallOperand(plan2, x1);
+ // assertInstallOperand(plan2, y1);
+ // assertInstallOperand(plan2, p1);
+
+ //Verify that the installation of f1 and p1 succeed
+ ProfileChangeRequest req3 = new ProfileChangeRequest(profile1);
+ req3.addInstallableUnits(new IInstallableUnit[] {f1, pp1});
+ ProvisioningPlan plan3 = planner.getProvisioningPlan(req3, null, null);
+ assertEquals(IStatus.OK, plan3.getStatus().getSeverity());
+ assertInstallOperand(plan3, f1);
+ // assertInstallOperand(plan3, a1);
+ // assertInstallOperand(plan3, b1);
+ assertInstallOperand(plan3, c1);
+ // assertInstallOperand(plan3, x1);
+ assertInstallOperand(plan3, y2);
+ // assertInstallOperand(plan3, p1);
+ assertInstallOperand(plan3, pp1);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest7b.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest7b.java
new file mode 100644
index 000000000..be4d43b0f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest7b.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.planner;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.provisional.p2.director.*;
+import org.eclipse.equinox.internal.provisional.p2.engine.IEngine;
+import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class PatchTest7b extends AbstractProvisioningTest {
+ IInstallableUnit a1;
+ IInstallableUnit b1;
+ IInstallableUnit c1;
+ IInstallableUnit x1;
+ IInstallableUnit y1;
+ IInstallableUnit y2;
+ IInstallableUnit f1;
+
+ IInstallableUnitPatch p1;
+ IInstallableUnitPatch pp1;
+
+ IProfile profile1;
+ IPlanner planner;
+ IEngine engine;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ x1 = createIU("X", new Version(1, 2, 0), true);
+ y1 = createIU("Y", new Version(1, 0, 0), true);
+ y2 = createIU("Y", new Version(1, 2, 0), true);
+ a1 = createIU("A", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "X", new VersionRange("[1.0.0, 1.1.0)"), null, false, true)});
+ b1 = createIU("B", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "X", new VersionRange("[1.0.0, 1.1.0)"), null, false, true)});
+ c1 = createIU("C", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "Y", new VersionRange("[1.0.0, 1.1.0)"), null, false, true)});
+
+ RequiredCapability[] req = new RequiredCapability[3];
+ req[2] = MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[1.0.0, 1.1.0)"), null, false, true);
+ req[1] = MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.0.0, 1.1.0)"), null, false, true);
+ req[0] = MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "C", new VersionRange("[1.0.0, 1.1.0)"), null, false, true);
+ f1 = createIU("F", new Version(1, 0, 0), req);
+
+ RequirementChange changeX = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "X", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "X", new VersionRange("[1.1.0, 1.3.0)"), null, false, false, true));
+ RequiredCapability[][] scope = new RequiredCapability[0][0]; //new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", VersionRange.emptyRange, null, false, false, false)}};
+ p1 = createIUPatch("P", new Version("1.0.0"), null, NO_REQUIRES, NO_PROVIDES, NO_PROPERTIES, TouchpointType.NONE, NO_TP_DATA, false, null, new RequirementChange[] {changeX}, scope, null);
+
+ RequirementChange changeY = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "Y", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "Y", new VersionRange("[1.1.0, 1.3.0)"), null, false, false, true));
+ RequiredCapability[][] scopePP = new RequiredCapability[0][0]; //new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "C", VersionRange.emptyRange, null, false, false, false)}};
+ pp1 = createIUPatch("PP", new Version("1.0.0"), null, NO_REQUIRES, NO_PROVIDES, NO_PROPERTIES, TouchpointType.NONE, NO_TP_DATA, false, null, new RequirementChange[] {changeY}, scopePP, null);
+
+ createTestMetdataRepository(new IInstallableUnit[] {a1, b1, c1, x1, y1, y2, f1, p1, pp1});
+ // createTestMetdataRepository(new IInstallableUnit[] {c1, y1, y2, f1, pp1});
+
+ profile1 = createProfile("TestProfile." + getName());
+ planner = createPlanner();
+ engine = createEngine();
+ }
+
+ public void testGeneralScope() {
+ //Confirm that f1 can't be installed
+ // ProfileChangeRequest req1 = new ProfileChangeRequest(profile1);
+ // req1.addInstallableUnits(new IInstallableUnit[] {f1});
+ // ProvisioningPlan plan1 = planner.getProvisioningPlan(req1, null, null);
+ // assertEquals(IStatus.ERROR, plan1.getStatus().getSeverity());
+
+ //Verify that the installation of f1 and p1 succeed
+ ProfileChangeRequest req2 = new ProfileChangeRequest(profile1);
+ req2.addInstallableUnits(new IInstallableUnit[] {f1, p1});
+ ProvisioningPlan plan2 = planner.getProvisioningPlan(req2, null, null);
+ assertEquals(IStatus.WARNING, plan2.getStatus().getSeverity());
+ assertInstallOperand(plan2, f1);
+ assertInstallOperand(plan2, a1);
+ assertInstallOperand(plan2, b1);
+ assertInstallOperand(plan2, c1);
+ assertInstallOperand(plan2, x1);
+ assertInstallOperand(plan2, y1);
+ assertInstallOperand(plan2, p1);
+
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest8.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest8.java
new file mode 100644
index 000000000..37f557122
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest8.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.planner;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.provisional.p2.director.*;
+import org.eclipse.equinox.internal.provisional.p2.engine.IEngine;
+import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class PatchTest8 extends AbstractProvisioningTest {
+ IInstallableUnit a1;
+ IInstallableUnit a2;
+ IInstallableUnit b1;
+ IInstallableUnit b2;
+ IInstallableUnit c2;
+ IInstallableUnit f1;
+
+ IInstallableUnitPatch p1;
+ IInstallableUnitPatch r1;
+
+ IProfile profile1;
+ IPlanner planner;
+ IEngine engine;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ a1 = createIU("A", new Version(1, 0, 0), true);
+ a2 = createIU("A", new Version("2.0.0"), true);
+ b1 = createIU("B", new Version("1.0.0"), true);
+ b2 = createIU("B", new Version("2.0.0"), true);
+ c2 = createIU("C", new Version("2.0.0"), true);
+
+ RequiredCapability[] req = new RequiredCapability[3];
+ req[0] = MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[1.0.0, 1.1.0)"), null, false, true);
+ req[1] = MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.0.0, 1.1.0)"), null, false, true);
+ req[2] = MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "C", new VersionRange("[2.0.0, 3.1.0)"), null, false, true);
+ f1 = createIU("F", new Version(1, 0, 0), req);
+
+ RequirementChange changeA = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", new VersionRange("[2.0.0, 3.0.0)"), null, false, false, true));
+ RequiredCapability[][] scope = new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "F", VersionRange.emptyRange, null, false, false, false)}};
+ p1 = createIUPatch("P", new Version("1.0.0"), null, NO_REQUIRES, NO_PROVIDES, NO_PROPERTIES, TouchpointType.NONE, NO_TP_DATA, false, null, new RequirementChange[] {changeA}, scope, null);
+
+ RequirementChange changeB = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[2.0.0, 3.0.0)"), null, false, false, true));
+ RequiredCapability[][] scopePP = new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "F", VersionRange.emptyRange, null, false, false, false)}};
+ r1 = createIUPatch("R", new Version("1.0.0"), null, NO_REQUIRES, NO_PROVIDES, NO_PROPERTIES, TouchpointType.NONE, NO_TP_DATA, false, null, new RequirementChange[] {changeB}, scopePP, null);
+
+ createTestMetdataRepository(new IInstallableUnit[] {a1, a2, b1, b2, c2, f1, p1, r1});
+
+ profile1 = createProfile("TestProfile." + getName());
+ planner = createPlanner();
+ engine = createEngine();
+ }
+
+ public void testOneIUWithMultiplePatchesApplyingOnIt() {
+ // //Confirm that f1 can't be installed
+ // ProfileChangeRequest req1 = new ProfileChangeRequest(profile1);
+ // req1.addInstallableUnits(new IInstallableUnit[] {f1});
+ // ProvisioningPlan plan1 = planner.getProvisioningPlan(req1, null, null);
+ // assertEquals(IStatus.ERROR, plan1.getStatus().getSeverity());
+ //
+ // //Verify that the installation of f1 and p1 succeed
+ // ProfileChangeRequest req2 = new ProfileChangeRequest(profile1);
+ // req2.addInstallableUnits(new IInstallableUnit[] {f1, p1});
+ // ProvisioningPlan plan2 = planner.getProvisioningPlan(req2, null, null);
+ // assertEquals(IStatus.WARNING, plan2.getStatus().getSeverity());
+ // assertInstallOperand(plan2, f1);
+ // assertInstallOperand(plan2, a1);
+ // assertInstallOperand(plan2, b1);
+ // assertInstallOperand(plan2, c1);
+ // assertInstallOperand(plan2, x1);
+ // assertInstallOperand(plan2, y1);
+ // assertInstallOperand(plan2, p1);
+
+ //Verify that the installation of f1 and p1 succeed
+ ProfileChangeRequest req3 = new ProfileChangeRequest(profile1);
+ req3.addInstallableUnits(new IInstallableUnit[] {f1, p1, r1});
+ ProvisioningPlan plan3 = planner.getProvisioningPlan(req3, null, null);
+ assertEquals(IStatus.OK, plan3.getStatus().getSeverity());
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest9.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest9.java
new file mode 100644
index 000000000..8910c1998
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/PatchTest9.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation 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: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.p2.tests.planner;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.provisional.p2.director.*;
+import org.eclipse.equinox.internal.provisional.p2.engine.IEngine;
+import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
+import org.eclipse.equinox.internal.provisional.p2.metadata.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class PatchTest9 extends AbstractProvisioningTest {
+ IInstallableUnit a1;
+ IInstallableUnit b1;
+ IInstallableUnit b2;
+ IInstallableUnit c1;
+ IInstallableUnitPatch p1;
+ IInstallableUnitPatch pp1;
+
+ IProfile profile1;
+ IPlanner planner;
+ IEngine engine;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ a1 = createIU("A", new Version("1.0.0"), new RequiredCapability[] {MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.0.0, 1.1.0)"), null, false, true), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "C", new VersionRange("[1.0.0, 1.1.0)"), null, false, true)});
+ b1 = createIU("B", new Version(1, 0, 0), true);
+ b2 = createIU("B", new Version(1, 2, 0), true);
+ c1 = createIU("C", new Version(1, 0, 0), true);
+ RequirementChange changeB = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "B", new VersionRange("[1.1.0, 1.3.0)"), null, false, false, true));
+ RequirementChange changeC = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "C", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "C", new VersionRange("[1.1.0, 1.3.0)"), null, false, false, true));
+ p1 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {changeB, changeC}, new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", VersionRange.emptyRange, null, false, false)}}, null);
+
+ RequirementChange anotherChangeC = new RequirementChange(MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "C", VersionRange.emptyRange, null, false, false, false), MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "C", new VersionRange("[1.1.0, 1.3.0)"), null, true, false, true));
+ pp1 = createIUPatch("P", new Version("1.0.0"), true, new RequirementChange[] {changeB, anotherChangeC}, new RequiredCapability[][] {{MetadataFactory.createRequiredCapability(IInstallableUnit.NAMESPACE_IU_ID, "A", VersionRange.emptyRange, null, false, false)}}, null);
+
+ createTestMetdataRepository(new IInstallableUnit[] {a1, b1, b2, c1, p1, pp1});
+
+ profile1 = createProfile("TestProfile." + getName());
+ planner = createPlanner();
+ engine = createEngine();
+ }
+
+ public void testPatchDoesNotApply() {
+ //The application of the patch does not succeed because there is no C matching the requirement imposed by the patch
+ ProfileChangeRequest req1 = new ProfileChangeRequest(profile1);
+ req1.addInstallableUnits(new IInstallableUnit[] {a1, p1});
+ ProvisioningPlan plan1 = planner.getProvisioningPlan(req1, null, null);
+ assertEquals(IStatus.ERROR, plan1.getStatus().getSeverity());
+ }
+
+ public void testPatchApply() {
+ //The application of the patch succeed because the dependency that PP puts on C is optional
+ ProfileChangeRequest req2 = new ProfileChangeRequest(profile1);
+ req2.addInstallableUnits(new IInstallableUnit[] {a1, pp1});
+ ProvisioningPlan plan2 = planner.getProvisioningPlan(req2, null, null);
+ assertEquals(IStatus.OK, plan2.getStatus().getSeverity());
+ assertInstallOperand(plan2, a1);
+ assertInstallOperand(plan2, pp1);
+ assertInstallOperand(plan2, b2);
+ }
+}

Back to the top