Bug 428684 - [remediation] Plug-ins directly installed can break resulting install

Change-Id: Ibb4a918d708c1d7044a970dedf58ff9b75bb7f6c
Signed-off-by: Pascal Rapicault <pascal@rapicorp.com>
diff --git a/bundles/org.eclipse.equinox.p2.director/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.director/META-INF/MANIFEST.MF
index 578f90d..662f906 100644
--- a/bundles/org.eclipse.equinox.p2.director/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.director/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.equinox.p2.director;singleton:=true
-Bundle-Version: 2.3.0.qualifier
+Bundle-Version: 2.3.100.qualifier
 Bundle-ClassPath: .
 Bundle-Activator: org.eclipse.equinox.internal.p2.director.DirectorActivator
 Bundle-Vendor: %providerName
diff --git a/bundles/org.eclipse.equinox.p2.director/pom.xml b/bundles/org.eclipse.equinox.p2.director/pom.xml
index 07d33f1..0a6e43a 100644
--- a/bundles/org.eclipse.equinox.p2.director/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.director/pom.xml
@@ -9,6 +9,6 @@
   </parent>
   <groupId>org.eclipse.equinox</groupId>
   <artifactId>org.eclipse.equinox.p2.director</artifactId>
-  <version>2.3.0-SNAPSHOT</version>
+  <version>2.3.100-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 </project>
diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/ProfileChangeRequest.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/ProfileChangeRequest.java
index e20b755..00410f5 100644
--- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/ProfileChangeRequest.java
+++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/ProfileChangeRequest.java
@@ -80,7 +80,7 @@
 	public void add(IInstallableUnit toInstall) {
 		if (iusToAdd == null)
 			iusToAdd = new ArrayList<IInstallableUnit>();
-		iusToAdd.add(toInstall);
+		iusToAdd.add(toInstall.unresolved());
 	}
 
 	/* (non-Javadoc)
@@ -102,7 +102,7 @@
 	public void remove(IInstallableUnit toUninstall) {
 		if (iusToRemove == null)
 			iusToRemove = new ArrayList<IInstallableUnit>();
-		iusToRemove.add(toUninstall);
+		iusToRemove.add(toUninstall.unresolved());
 	}
 
 	public void removeInstallableUnits(IInstallableUnit[] toUninstall) {
@@ -142,6 +142,7 @@
 	public void setInstallableUnitProfileProperty(IInstallableUnit iu, String key, String value) {
 		if (iuPropertiesToAdd == null)
 			iuPropertiesToAdd = new HashMap<IInstallableUnit, Map<String, String>>();
+		iu = iu.unresolved();
 		Map<String, String> properties = iuPropertiesToAdd.get(iu);
 		if (properties == null) {
 			properties = new HashMap<String, String>();
@@ -156,6 +157,7 @@
 	public void removeInstallableUnitProfileProperty(IInstallableUnit iu, String key) {
 		if (iuPropertiesToRemove == null)
 			iuPropertiesToRemove = new HashMap<IInstallableUnit, List<String>>();
+		iu = iu.unresolved();
 		List<String> keys = iuPropertiesToRemove.get(iu);
 		if (keys == null) {
 			keys = new ArrayList<String>();
@@ -213,14 +215,14 @@
 	 * @see org.eclipse.equinox.internal.provisional.p2.director.IPCR#setInstallableUnitInclusionRules(org.eclipse.equinox.p2.metadata.IInstallableUnit, java.lang.String)
 	 */
 	public void setInstallableUnitInclusionRules(IInstallableUnit iu, String value) {
-		setInstallableUnitProfileProperty(iu, SimplePlanner.INCLUSION_RULES, value);
+		setInstallableUnitProfileProperty(iu.unresolved(), SimplePlanner.INCLUSION_RULES, value);
 	}
 
 	/* (non-Javadoc)
 	 * @see org.eclipse.equinox.internal.provisional.p2.director.IPCR#removeInstallableUnitInclusionRules(org.eclipse.equinox.p2.metadata.IInstallableUnit)
 	 */
 	public void removeInstallableUnitInclusionRules(IInstallableUnit iu) {
-		removeInstallableUnitProfileProperty(iu, SimplePlanner.INCLUSION_RULES);
+		removeInstallableUnitProfileProperty(iu.unresolved(), SimplePlanner.INCLUSION_RULES);
 	}
 
 	@SuppressWarnings("unchecked")
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 4188b94..e08f33c 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
@@ -136,6 +136,7 @@
 		suite.addTestSuite(PatchTestUsingNegativeRequirement.class);
 		suite.addTestSuite(PermissiveSlicerTest.class);
 		suite.addTestSuite(PP2ShouldFailToInstall.class);
+		suite.addTestSuite(ResolvedIUInPCR.class);
 		//		suite.addTestSuite(ProvisioningPlanQueryTest.class); disabled, see bug 313812 
 		suite.addTestSuite(SDKPatchingTest1.class);
 		suite.addTestSuite(SDKPatchingTest2.class);
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/ResolvedIUInPCR.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/ResolvedIUInPCR.java
new file mode 100644
index 0000000..9c3a9d1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/ResolvedIUInPCR.java
@@ -0,0 +1,133 @@
+package org.eclipse.equinox.p2.tests.planner;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import org.eclipse.equinox.internal.p2.director.ProfileChangeRequest;
+import org.eclipse.equinox.internal.p2.metadata.ResolvedInstallableUnit;
+import org.eclipse.equinox.p2.engine.IProfile;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.tests.*;
+
+public class ResolvedIUInPCR extends AbstractProvisioningTest {
+
+	@IUDescription(content = "package: iu1 \n" + "singleton: true\n" + "version: 1 \n")
+	public IInstallableUnit iu1;
+
+	@IUDescription(content = "package: iu2 \n" + "singleton: true\n" + "version: 1 \n")
+	public IInstallableUnit iu2;
+
+	private IProfile profile;
+
+	protected void setUp() throws Exception {
+		IULoader.loadIUs(this);
+		profile = createProfile("ResolvedIUInPCR." + getName());
+	}
+
+	public void testNoResolvedIUInAddition() {
+		ResolvedInstallableUnit riu1 = new ResolvedInstallableUnit(iu1);
+		ProfileChangeRequest pcr = new ProfileChangeRequest(profile);
+		pcr.add(riu1);
+
+		assertFalse(identityContains(pcr.getAdditions(), riu1));
+		assertTrue(identityContains(pcr.getAdditions(), iu1));
+	}
+
+	public void testNoResolvedIUInBulkAddition() {
+		Collection<IInstallableUnit> riusToAdd = new ArrayList<IInstallableUnit>();
+		ResolvedInstallableUnit riu1 = new ResolvedInstallableUnit(iu1);
+		riusToAdd.add(riu1);
+
+		ProfileChangeRequest pcr = new ProfileChangeRequest(profile);
+		pcr.addAll(riusToAdd);
+
+		assertFalse(identityContains(pcr.getAdditions(), riu1));
+		assertTrue(identityContains(pcr.getAdditions(), iu1));
+	}
+
+	public void testNoResolvedIUInBulkAddition2() {
+		ResolvedInstallableUnit riu1 = new ResolvedInstallableUnit(iu1);
+		ResolvedInstallableUnit riu2 = new ResolvedInstallableUnit(iu2);
+
+		ProfileChangeRequest pcr = new ProfileChangeRequest(profile);
+		pcr.addInstallableUnits(riu1, riu2);
+
+		assertFalse(identityContains(pcr.getAdditions(), riu1));
+		assertFalse(identityContains(pcr.getAdditions(), riu2));
+
+		assertTrue(identityContains(pcr.getAdditions(), iu1));
+		assertTrue(identityContains(pcr.getAdditions(), iu2));
+	}
+
+	public void testNoResolvedIUInRemoval() {
+		ResolvedInstallableUnit riu1 = new ResolvedInstallableUnit(iu1);
+		ProfileChangeRequest pcr = new ProfileChangeRequest(profile);
+		pcr.remove(riu1);
+
+		assertFalse(identityContains(pcr.getRemovals(), riu1));
+		assertTrue(identityContains(pcr.getRemovals(), iu1));
+	}
+
+	public void testNoResolvedIUInBulkRemoval() {
+		Collection<IInstallableUnit> riusToAdd = new ArrayList<IInstallableUnit>();
+		ResolvedInstallableUnit riu1 = new ResolvedInstallableUnit(iu1);
+		riusToAdd.add(riu1);
+
+		ProfileChangeRequest pcr = new ProfileChangeRequest(profile);
+		pcr.removeAll(riusToAdd);
+
+		assertFalse(identityContains(pcr.getRemovals(), riu1));
+		assertTrue(identityContains(pcr.getRemovals(), iu1));
+	}
+
+	public void testNoResolvedIUInBulkRemoval2() {
+		ResolvedInstallableUnit riu1 = new ResolvedInstallableUnit(iu1);
+		ResolvedInstallableUnit riu2 = new ResolvedInstallableUnit(iu2);
+
+		ProfileChangeRequest pcr = new ProfileChangeRequest(profile);
+		pcr.removeInstallableUnits(new IInstallableUnit[] {riu1, riu2});
+
+		assertFalse(identityContains(pcr.getRemovals(), riu1));
+		assertFalse(identityContains(pcr.getRemovals(), riu2));
+
+		assertTrue(identityContains(pcr.getRemovals(), iu1));
+		assertTrue(identityContains(pcr.getRemovals(), iu2));
+	}
+
+	public void testNoResolvedIUInstallableUnitInclusionRules() {
+		ResolvedInstallableUnit riu1 = new ResolvedInstallableUnit(iu1);
+		ResolvedInstallableUnit riu2 = new ResolvedInstallableUnit(iu2);
+
+		ProfileChangeRequest pcr = new ProfileChangeRequest(profile);
+		pcr.setInstallableUnitInclusionRules(riu1, "inclusion");
+		pcr.setInstallableUnitProfileProperty(riu2, "a", "b");
+
+		assertFalse(identityContains(pcr.getInstallableUnitProfilePropertiesToAdd().keySet(), riu1));
+		assertFalse(identityContains(pcr.getInstallableUnitProfilePropertiesToAdd().keySet(), riu2));
+
+		assertTrue(identityContains(pcr.getInstallableUnitProfilePropertiesToAdd().keySet(), iu1));
+		assertTrue(identityContains(pcr.getInstallableUnitProfilePropertiesToAdd().keySet(), iu2));
+	}
+
+	public void testNoResolvedIUInstallableUnitInclusionRules2() {
+		ResolvedInstallableUnit riu1 = new ResolvedInstallableUnit(iu1);
+		ResolvedInstallableUnit riu2 = new ResolvedInstallableUnit(iu2);
+
+		ProfileChangeRequest pcr = new ProfileChangeRequest(profile);
+		pcr.removeInstallableUnitInclusionRules(riu1);
+		pcr.removeInstallableUnitProfileProperty(riu2, "a");
+
+		assertFalse(identityContains(pcr.getInstallableUnitProfilePropertiesToRemove().keySet(), riu1));
+		assertFalse(identityContains(pcr.getInstallableUnitProfilePropertiesToRemove().keySet(), riu2));
+
+		assertTrue(identityContains(pcr.getInstallableUnitProfilePropertiesToRemove().keySet(), iu1));
+		assertTrue(identityContains(pcr.getInstallableUnitProfilePropertiesToRemove().keySet(), iu2));
+	}
+
+	private boolean identityContains(Collection<IInstallableUnit> ius, IInstallableUnit match) {
+		for (IInstallableUnit iu : ius) {
+			if (iu == match)
+				return true;
+		}
+		return false;
+	}
+}