Bug 558006: Add name of IU requiring the native

Signed-off-by: Jonah Graham <jonah@kichwacoders.com>
Change-Id: I7473d7dd1ba5975fc12ca0b4e205c3fcdee0ca1b
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/Messages.java b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/Messages.java
index dde3435..1dc2c6d 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/Messages.java
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/Messages.java
@@ -70,6 +70,8 @@
 	public static String NativePackageExtractionApplication_MissingParameters;
 	public static String NativePackageExtractionApplication_PersistencePb;
 	public static String NativePackageExtractionApplication_MissingValue;
+	public static String NativeTouchpoint_PromptForNative_RequiredBy;
+	public static String NativeTouchpoint_PromptForNative_YouCanDownloadFrom;
 	public static String PromptForNative_InstallText;
 	public static String PromptForNative_IntroText;
 	public static String PromptForNative_DialogTitle;
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/NativeTouchpoint.java b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/NativeTouchpoint.java
index 64d574c..32bb484 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/NativeTouchpoint.java
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/NativeTouchpoint.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2017 IBM Corporation and others.
+ * Copyright (c) 2007, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -18,12 +18,14 @@
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.*;
+import java.util.stream.Collectors;
 import org.eclipse.core.runtime.*;
 import org.eclipse.equinox.internal.p2.touchpoint.natives.actions.ActionConstants;
 import org.eclipse.equinox.p2.core.*;
 import org.eclipse.equinox.p2.engine.IProfile;
 import org.eclipse.equinox.p2.engine.spi.Touchpoint;
 import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
 import org.eclipse.equinox.p2.repository.artifact.IFileArtifactRepository;
 import org.eclipse.osgi.util.NLS;
 
@@ -38,7 +40,17 @@
 
 	private static Map<IProfile, IBackupStore> backups = new WeakHashMap<>();
 
-	private List<NativePackageEntry> packagesToInstall = new ArrayList<>();
+	private static class NativePackageToInstallInfo {
+		NativePackageEntry entry;
+		IInstallableUnit iu;
+
+		public NativePackageToInstallInfo(NativePackageEntry entry, IInstallableUnit iu) {
+			this.entry = entry;
+			this.iu = iu;
+		}
+	}
+
+	private List<NativePackageToInstallInfo> packagesToInstall = new ArrayList<>();
 	private Properties installCommandsProperties = new Properties();
 
 	private IProvisioningAgent agent;
@@ -98,12 +110,21 @@
 		String text = Messages.PromptForNative_IntroText;
 		String downloadLinks = ""; //$NON-NLS-1$
 		List<NativePackageEntry> entriesWithoutDownloadLink = new ArrayList<>(packagesToInstall.size());
-		for (NativePackageEntry nativePackageEntry : packagesToInstall) {
-			text += '\t' + nativePackageEntry.name + ' ' + formatVersion(nativePackageEntry) + '\n';
-			if (nativePackageEntry.getDownloadLink() != null) {
-				downloadLinks += "    <a>" + nativePackageEntry.getDownloadLink() + "</a>\n"; //$NON-NLS-1$ //$NON-NLS-2$
+		for (NativePackageToInstallInfo nativePackageEntry : packagesToInstall) {
+			text += '\t' + nativePackageEntry.entry.name + ' ' + formatVersion(nativePackageEntry.entry);
+			if (nativePackageEntry.iu != null) {
+				String name = nativePackageEntry.iu.getProperty(IInstallableUnit.PROP_NAME, null);
+				if (name != null && !name.isEmpty()) {
+					text += ' ';
+					text += NLS.bind(Messages.NativeTouchpoint_PromptForNative_RequiredBy, name);
+				}
+			}
+
+			text += '\n';
+			if (nativePackageEntry.entry.getDownloadLink() != null) {
+				downloadLinks += "    <a>" + nativePackageEntry.entry.getDownloadLink() + "</a>\n"; //$NON-NLS-1$ //$NON-NLS-2$
 			} else {
-				entriesWithoutDownloadLink.add(nativePackageEntry);
+				entriesWithoutDownloadLink.add(nativePackageEntry.entry);
 			}
 		}
 
@@ -114,7 +135,7 @@
 
 		String downloadText = null;
 		if (downloadLinks.length() > 0) {
-			downloadText = "You can download those from the following locations:\n" + downloadLinks;
+			downloadText = Messages.NativeTouchpoint_PromptForNative_YouCanDownloadFrom + downloadLinks;
 		}
 
 		serviceUI.showInformationMessage(Messages.PromptForNative_DialogTitle, text, downloadText);
@@ -158,12 +179,18 @@
 		return text;
 	}
 
-	public void addPackageToInstall(NativePackageEntry entry) {
-		packagesToInstall.add(entry);
+	/**
+	 * Add the given entry as a new native package that needs to be installed.
+	 * 
+	 * @param entry Package information about the native
+	 * @param iu    optional IU that has this requirement
+	 */
+	public void addPackageToInstall(NativePackageEntry entry, IInstallableUnit iu) {
+		packagesToInstall.add(new NativePackageToInstallInfo(entry, iu));
 	}
 
 	public List<NativePackageEntry> getPackagesToInstall() {
-		return Collections.unmodifiableList(packagesToInstall);
+		return Collections.unmodifiableList(packagesToInstall.stream().map(e -> e.entry).collect(Collectors.toList()));
 	}
 
 	public void setDistro(String distro) {
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/CheckAndPromptNativePackage.java b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/CheckAndPromptNativePackage.java
index 38dd03d..66f2cad 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/CheckAndPromptNativePackage.java
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/CheckAndPromptNativePackage.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- *  Copyright (c) 2014, 2017 Rapicorp, Inc. and others.
+ *  Copyright (c) 2014, 2019 Rapicorp, Inc. and others.
  *
  *  This program and the accompanying materials
  *  are made available under the terms of the Eclipse Public License 2.0
@@ -20,6 +20,7 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.equinox.internal.p2.touchpoint.natives.*;
 import org.eclipse.equinox.p2.engine.spi.ProvisioningAction;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
 import org.eclipse.osgi.util.NLS;
 
 public class CheckAndPromptNativePackage extends ProvisioningAction {
@@ -30,22 +31,24 @@
 
 	@Override
 	public IStatus execute(Map<String, Object> parameters) {
-		//Get and check the paremeters
+		// Get and check the paremeters
 		String distro = (String) parameters.get(ActionConstants.PARM_LINUX_DISTRO);
 		String packageName = (String) parameters.get(ActionConstants.PARM_LINUX_PACKAGE_NAME);
 		String packageVersion = (String) parameters.get(ActionConstants.PARM_LINUX_PACKAGE_VERSION);
 		String versionComparator = (String) parameters.get(ActionConstants.PARM_LINUX_VERSION_COMPARATOR);
+		IInstallableUnit iu = (IInstallableUnit) parameters.get(ActionConstants.PARM_IU);
 
 		if (distro == null || packageName == null || (versionComparator != null && packageVersion == null))
 			return new Status(IStatus.ERROR, Activator.ID, Messages.Incorrect_Command);
 
 		distro = distro.toLowerCase();
 
-		//If we are not running the distro we are provisioning, do nothing and return
+		// If we are not running the distro we are provisioning, do nothing and return
 		if (!runningDistro(distro))
 			return Status.OK_STATUS;
 
-		//Check if the desired package is installed and collect information in the touchpoint
+		// Check if the desired package is installed and collect information in the
+		// touchpoint
 		File scriptToExecute = NativeTouchpoint.getFileFromBundle(distro, IS_INSTALLED);
 		if (scriptToExecute == null)
 			return new Status(IStatus.ERROR, Activator.ID, NLS.bind(Messages.Cannot_Find_status, distro));
@@ -64,23 +67,26 @@
 			}
 			int exitValue = new ProcessBuilder(cmd).start().waitFor();
 			switch (exitValue) {
-				case 0 :
-					return Status.OK_STATUS;
-				case 1 :
-				case 2 :
-					((NativeTouchpoint) getTouchpoint()).addPackageToInstall(new NativePackageEntry(packageName, packageVersion, versionComparator));
-					((NativeTouchpoint) getTouchpoint()).setDistro(distro);
-					return Status.OK_STATUS;
+			case 0:
+				return Status.OK_STATUS;
+			case 1:
+			case 2:
+				((NativeTouchpoint) getTouchpoint()).addPackageToInstall(
+						new NativePackageEntry(packageName, packageVersion, versionComparator), iu);
+				((NativeTouchpoint) getTouchpoint()).setDistro(distro);
+				return Status.OK_STATUS;
 			}
 		} catch (IOException e) {
-			return new Status(IStatus.ERROR, Activator.ID, NLS.bind(Messages.Cannot_Check_Package, new String[] {packageName, packageVersion, distro}));
+			return new Status(IStatus.ERROR, Activator.ID,
+					NLS.bind(Messages.Cannot_Check_Package, new String[] { packageName, packageVersion, distro }));
 		} catch (InterruptedException e) {
-			return new Status(IStatus.ERROR, Activator.ID, NLS.bind(Messages.Cannot_Check_Package, new String[] {packageName, packageVersion, distro}));
+			return new Status(IStatus.ERROR, Activator.ID,
+					NLS.bind(Messages.Cannot_Check_Package, new String[] { packageName, packageVersion, distro }));
 		}
 		return Status.OK_STATUS;
 	}
 
-	//Check if the given distro is currently being run
+	// Check if the given distro is currently being run
 	protected boolean runningDistro(String distro) {
 		try {
 			File scriptToExecute = NativeTouchpoint.getFileFromBundle(distro, IS_RUNNING);
@@ -103,7 +109,7 @@
 
 	@Override
 	public IStatus undo(Map<String, Object> parameters) {
-		//Nothing to do since we are not modifying any state.
+		// Nothing to do since we are not modifying any state.
 		return null;
 	}
 
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/CheckAndPromptNativePackageWindowsRegistry.java b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/CheckAndPromptNativePackageWindowsRegistry.java
index b0e4c06..d458412 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/CheckAndPromptNativePackageWindowsRegistry.java
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/CheckAndPromptNativePackageWindowsRegistry.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- *  Copyright (c) 2015, 2017 SAP SE and others.
+ *  Copyright (c) 2015, 2019 SAP SE and others.
  *
  *  This program and the accompanying materials
  *  are made available under the terms of the Eclipse Public License 2.0
@@ -20,6 +20,7 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.equinox.internal.p2.touchpoint.natives.*;
 import org.eclipse.equinox.p2.engine.spi.ProvisioningAction;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
 import org.eclipse.osgi.util.NLS;
 
 public class CheckAndPromptNativePackageWindowsRegistry extends ProvisioningAction {
@@ -31,21 +32,23 @@
 
 	@Override
 	public IStatus execute(Map<String, Object> parameters) {
-		//If we are not running on Windows, do nothing and return
+		// If we are not running on Windows, do nothing and return
 		if (!IS_WINDOWS)
 			return Status.OK_STATUS;
 
-		//Get and check the paremeters
+		// Get and check the paremeters
 		String packageName = (String) parameters.get(ActionConstants.PARM_LINUX_PACKAGE_NAME);
 		String packageVersion = (String) parameters.get(ActionConstants.PARM_LINUX_PACKAGE_VERSION);
 		String key = (String) parameters.get(ActionConstants.PARM_WINDOWS_REGISTRY_KEY);
 		String attName = (String) parameters.get(ActionConstants.PARM_WINDOWS_REGISTRY_ATTRIBUTE_NAME);
 		String attValue = (String) parameters.get(ActionConstants.PARM_WINDOWS_REGISTRY_ATTRIBUTE_VALUE);
+		IInstallableUnit iu = (IInstallableUnit) parameters.get(ActionConstants.PARM_IU);
 
 		if (key == null || (attName != null && attValue == null))
 			return new Status(IStatus.ERROR, Activator.ID, Messages.Incorrect_Command);
 
-		//Check if the desired package is installed and collect information in the touchpoint
+		// Check if the desired package is installed and collect information in the
+		// touchpoint
 		File scriptToExecute = NativeTouchpoint.getFileFromBundle(WINDOWS_DISTRO, IS_INSTALLED);
 		if (scriptToExecute == null)
 			return new Status(IStatus.ERROR, Activator.ID, NLS.bind(Messages.Cannot_Find_status, WINDOWS_DISTRO));
@@ -62,28 +65,30 @@
 			}
 			int exitValue = new ProcessBuilder(cmd).start().waitFor();
 			switch (exitValue) {
-				case 0 :
-					return Status.OK_STATUS;
-				case 1 :
-				case 2 :
-				default :
-					NativePackageEntry packageEntry = new NativePackageEntry(packageName, packageVersion, null);
-					String downloadLink = (String) parameters.get(ActionConstants.PARM_DOWNLOAD_LINK);
-					packageEntry.setDownloadLink(downloadLink);
-					((NativeTouchpoint) getTouchpoint()).addPackageToInstall(packageEntry);
-					((NativeTouchpoint) getTouchpoint()).setDistro(WINDOWS_DISTRO);
-					return Status.OK_STATUS;
+			case 0:
+				return Status.OK_STATUS;
+			case 1:
+			case 2:
+			default:
+				NativePackageEntry packageEntry = new NativePackageEntry(packageName, packageVersion, null);
+				String downloadLink = (String) parameters.get(ActionConstants.PARM_DOWNLOAD_LINK);
+				packageEntry.setDownloadLink(downloadLink);
+				((NativeTouchpoint) getTouchpoint()).addPackageToInstall(packageEntry, iu);
+				((NativeTouchpoint) getTouchpoint()).setDistro(WINDOWS_DISTRO);
+				return Status.OK_STATUS;
 			}
 		} catch (IOException e) {
-			return new Status(IStatus.ERROR, Activator.ID, NLS.bind(Messages.Cannot_Check_Package, new String[] {packageName, packageVersion, WINDOWS_DISTRO}));
+			return new Status(IStatus.ERROR, Activator.ID, NLS.bind(Messages.Cannot_Check_Package,
+					new String[] { packageName, packageVersion, WINDOWS_DISTRO }));
 		} catch (InterruptedException e) {
-			return new Status(IStatus.ERROR, Activator.ID, NLS.bind(Messages.Cannot_Check_Package, new String[] {packageName, packageVersion, WINDOWS_DISTRO}));
+			return new Status(IStatus.ERROR, Activator.ID, NLS.bind(Messages.Cannot_Check_Package,
+					new String[] { packageName, packageVersion, WINDOWS_DISTRO }));
 		}
 	}
 
 	@Override
 	public IStatus undo(Map<String, Object> parameters) {
-		//Nothing to do since we are not modifying any state.
+		// Nothing to do since we are not modifying any state.
 		return null;
 	}
 
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/messages.properties b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/messages.properties
index a58772e..963454d 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/messages.properties
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/messages.properties
@@ -60,6 +60,8 @@
 NativePackageExtractionApplication_MissingParameters=Missing arguments, please specify {0} and {1}.
 NativePackageExtractionApplication_MissingValue=The value is missing for argument {0}.  
 NativePackageExtractionApplication_PersistencePb=error while persisting results in 
+NativeTouchpoint_PromptForNative_RequiredBy=(Required by {0})
+NativeTouchpoint_PromptForNative_YouCanDownloadFrom=You can download those from the following locations:\n
 PromptForNative_InstallText=\n You can install those by executing the following command: \n\t
 PromptForNative_IntroText=The software you installed requires the following OS packages to be installed: \n
 PromptForNative_DialogTitle=Install Native Software Packages