Bug 350377 - [Browser] Default browser detection should use environment variables
diff --git a/bundles/org.eclipse.ui.browser/.classpath b/bundles/org.eclipse.ui.browser/.classpath
index ce73933..304e861 100644
--- a/bundles/org.eclipse.ui.browser/.classpath
+++ b/bundles/org.eclipse.ui.browser/.classpath
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/bundles/org.eclipse.ui.browser/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.ui.browser/.settings/org.eclipse.jdt.core.prefs
index 786358a..5170256 100644
--- a/bundles/org.eclipse.ui.browser/.settings/org.eclipse.jdt.core.prefs
+++ b/bundles/org.eclipse.ui.browser/.settings/org.eclipse.jdt.core.prefs
@@ -1,4 +1,4 @@
-#Tue May 09 14:44:18 EDT 2006
+#Fri Jun 24 22:27:16 CEST 2011
 eclipse.preferences.version=1
 org.eclipse.jdt.core.codeComplete.argumentPrefixes=
 org.eclipse.jdt.core.codeComplete.argumentSuffixes=
@@ -8,11 +8,11 @@
 org.eclipse.jdt.core.codeComplete.localSuffixes=
 org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
 org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
-org.eclipse.jdt.core.compiler.compliance=1.4
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
 org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=error
 org.eclipse.jdt.core.compiler.problem.unnecessaryElse=error
 org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
@@ -21,4 +21,4 @@
 org.eclipse.jdt.core.compiler.problem.unusedImport=error
 org.eclipse.jdt.core.compiler.problem.unusedLocal=error
 org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
-org.eclipse.jdt.core.compiler.source=1.3
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/bundles/org.eclipse.ui.browser/META-INF/MANIFEST.MF b/bundles/org.eclipse.ui.browser/META-INF/MANIFEST.MF
index 3be8763..15bd1f5 100644
--- a/bundles/org.eclipse.ui.browser/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.ui.browser/META-INF/MANIFEST.MF
@@ -14,5 +14,5 @@
  org.eclipse.ui;bundle-version="[3.6.0,4.0.0)"
 Eclipse-LazyStart: true
 Import-Package: com.ibm.icu.text
-Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Bundle-ActivationPolicy: lazy
diff --git a/bundles/org.eclipse.ui.browser/plugin.properties b/bundles/org.eclipse.ui.browser/plugin.properties
index 39ab4fb..f5faa3b 100644
--- a/bundles/org.eclipse.ui.browser/plugin.properties
+++ b/bundles/org.eclipse.ui.browser/plugin.properties
@@ -16,7 +16,7 @@
 viewWebBrowserTitle=Internal Web Browser
 viewWebBrowserSupportTitle= Web Browser
 preferenceWebBrowserTitle=Web Browser
-preferenceKeywords=HTML Firefox Mozilla Netscape Internet Opera Safari
+preferenceKeywords=HTML Firefox Mozilla Internet Opera Safari Chrome
 
 
 command.openBrowser.name=Open Browser
@@ -27,10 +27,6 @@
 commandParameter.openBrowser.tooltip.name=Browser Tooltip
 
 browserInternetExplorer=Internet Explorer
-browserNetscape4=Netscape Communicator v4.x
-browserNetscape7=Netscape v7.x
-browserNetscape=Netscape
-browserMozilla=Mozilla
 browserOpera=Opera
 browserChrome=Chrome
 browserKonqueror=Konqueror
diff --git a/bundles/org.eclipse.ui.browser/plugin.xml b/bundles/org.eclipse.ui.browser/plugin.xml
index a8aa938..ddb5200 100644
--- a/bundles/org.eclipse.ui.browser/plugin.xml
+++ b/bundles/org.eclipse.ui.browser/plugin.xml
@@ -85,26 +85,6 @@
    <extension point="org.eclipse.ui.browser.browsers">
       <!-- Linux -->
       <browser
-         id="org.eclipse.ui.browser.mozilla"
-         name="%browserMozilla"
-         os="linux,aix,hpux,solaris"
-         executable="mozilla"
-         factoryclass="org.eclipse.ui.internal.browser.browsers.MozillaFactory">
-         <location>usr/bin/mozilla</location>
-         <location>usr/X11/bin/mozilla</location>
-         <location>usr/sfw/lib/mozilla/mozilla</location>
-      </browser>
-      <browser
-         id="org.eclipse.ui.browser.netscape"
-         name="%browserNetscape"
-         os="linux,aix,hpux,solaris"
-         executable="netscape"
-         factoryclass="org.eclipse.ui.internal.browser.browsers.MozillaFactory">
-         <location>usr/bin/netscape</location>
-         <location>usr/X11R6/bin/netscape</location>
-         <location>usr/dt/bin/netscape</location>
-      </browser>
-      <browser
          id="org.eclipse.ui.browser.firefox"
          name="%browserFirefox"
          os="linux,aix,hpux,solaris"
@@ -131,62 +111,43 @@
       
       <!-- Windows -->
       <browser
-         id="org.eclipse.ui.browser.mozilla"
-         name="%browserMozilla"
-         os="Win32"
-         executable="mozilla.exe"
-         factoryclass="org.eclipse.ui.internal.browser.browsers.MozillaFactory">
-         <location>Program Files\mozilla.org\Mozilla\mozilla.exe</location>
-      </browser>
-      <browser
-         id="org.eclipse.ui.browser.netscape7"
-         name="%browserNetscape7"
-         os="Win32"
-         executable="netsc.exe"
-         factoryclass="org.eclipse.ui.internal.browser.browsers.MozillaFactory">
-         <location>Program Files\Netscape\Netscape\netscp.exe</location>
-      </browser>
-      <browser
-         id="org.eclipse.ui.browser.netscape4"
-         name="%browserNetscape4"
-         os="Win32"
-         executable="netscape.exe"
-         factoryclass="org.eclipse.ui.internal.browser.browsers.MozillaFactory">
-         <location>Program Files\Netscape\Communicator\Program\netscape.exe</location>
-      </browser>
-      <browser
          id="org.eclipse.ui.browser.firefox"
          name="%browserFirefox"
          os="Win32"
          executable="firefox.exe"
          factoryclass="org.eclipse.ui.internal.browser.browsers.MozillaFactory">
-         <location>Program Files\mozilla.org\Firefox\firefox.exe</location>
-         <location>Program Files\Mozilla Firefox\firefox.exe</location>
-         <location>Program Files (x86)\Mozilla Firefox\firefox.exe</location>
+         <location>%%ProgramFiles%\mozilla.org\Firefox\firefox.exe</location>
+         <location>%%ProgramFiles(x86)%\mozilla.org\Firefox\firefox.exe</location>
+         <location>%%ProgramW6432%\mozilla.org\Firefox\firefox.exe</location>
+         
+         <location>%%ProgramFiles%\Mozilla Firefox\firefox.exe</location>
+         <location>%%ProgramFiles(x86)%\Mozilla Firefox\firefox.exe</location>
+         <location>%%ProgramW6432%\Mozilla Firefox\firefox.exe</location>
       </browser>
       <browser
          id="org.eclipse.ui.browser.ie"
          name="%browserInternetExplorer"
          os="Win32"
          executable="iexplore.exe">
-         <location>Program Files\Internet Explorer\iexplore.exe</location>
+         <location>%%ProgramFiles%\Internet Explorer\iexplore.exe</location>
+         <location>%%ProgramFiles(x86)%\Internet Explorer\iexplore.exe</location>
+         <location>%%ProgramW6432%\Internet Explorer\iexplore.exe</location>
       </browser>
       <browser
          id="org.eclipse.ui.browser.chrome"
          name="%browserChrome"
          os="Win32"
          executable="chrome.exe">
-         <location homeRelative="true">AppData\Local\Google\Chrome\Application\chrome.exe</location>
+         <location>%%LOCALAPPDATA%\Google\Chrome\Application\chrome.exe</location>
       </browser>
       <browser
          id="org.eclipse.ui.browser.opera"
          name="%browserOpera"
          os="Win32"
          executable="opera.exe">
-         <location>Program Files\Opera7\opera.exe</location>
-         <location>
-            Program Files\Opera\opera.exe
-         </location>
+         <location>%%ProgramFiles%\Opera\opera.exe</location>
+         <location>%%ProgramFiles(x86)%\Opera\opera.exe</location>
+         <location>%%ProgramW6432%\Opera\opera.exe</location>
       </browser>
       
       <!-- Mac -->
@@ -214,14 +175,6 @@
          <location>Applications/Safari.app/Contents/MacOS/Safari</location>
       </browser> -->
       <browser
-         id="org.eclipse.ui.browser.mozilla"
-         name="%browserMozilla"
-         os="MacOSX"
-         executable="mozilla-bin"
-         factoryclass="org.eclipse.ui.internal.browser.browsers.MozillaFactory">
-         <location>Applications/Mozilla.app/Contents/MacOS/mozilla-bin</location>
-      </browser>
-      <browser
          id="org.eclipse.ui.browser.ie"
          name="%browserInternetExplorer"
          os="MacOSX"
diff --git a/bundles/org.eclipse.ui.browser/schema/browsers.exsd b/bundles/org.eclipse.ui.browser/schema/browsers.exsd
index 594fe9e..3bee277 100644
--- a/bundles/org.eclipse.ui.browser/schema/browsers.exsd
+++ b/bundles/org.eclipse.ui.browser/schema/browsers.exsd
@@ -101,21 +101,14 @@
       </complexType>
    </element>
 
-   <element name="location">
+   <element name="location" type="string">
       <annotation>
          <documentation>
-            Default install locations. these locations should not contain the initial path, as it will be substituted with all known drives. (e.g. on Windows, a location of &quot;test.exe&quot; would look for &quot;c:\test.exe&quot;, &quot;d:\test.exe&quot;, etc. for all known drives.
+            Default install locations. These locations should not contain the initial path, as it will be substituted with all known drives. E.g. on Windows, a location of &quot;test.exe&quot; would look for &quot;c:\test.exe&quot;, &quot;d:\test.exe&quot;, etc. for all known drives.
+&lt;p&gt;
+On Windows, the path can also start with an environment variable, e.g. &quot;%%ProgramFiles%\folder\test.exe&quot;. Note the double % at the beginning to prevent localization.&lt;/p&gt;
          </documentation>
       </annotation>
-      <complexType>
-         <attribute name="homeRelative" type="boolean" use="default" value="false">
-            <annotation>
-               <documentation>
-                  If true the browser location is relative to the users home directory
-               </documentation>
-            </annotation>
-         </attribute>
-      </complexType>
    </element>
 
    <annotation>
@@ -139,13 +132,13 @@
  &lt;extension point=&quot;org.eclipse.ui.browser.browsers&quot;&gt;
   &lt;browser
      id=&quot;org.eclipse.ui.browser.firefox&quot;
-     name=Firefox
+     name=&quot;Firefox&quot;
      os=&quot;Win32&quot;
      executable=&quot;firefox.exe&quot;
      factoryclass=&quot;org.eclipse.ui.internal.browser.browsers.MozillaFactory&quot;&gt;
-     &lt;location&gt;Program Files\mozilla.org\Firefox\firefox.exe&lt;/location&gt;
-     &lt;location&gt;Program Files\Mozilla Firefox\firefox.exe&lt;/location&gt;
-   &lt;/browser&gt;
+       &lt;location&gt;%%ProgramFiles%\Mozilla Firefox\firefox.exe&lt;/location&gt;
+       &lt;location&gt;%%ProgramFiles(x86)%\Mozilla Firefox\firefox.exe&lt;/location&gt;
+  &lt;/browser&gt;
  &lt;/extension&gt;
 &lt;/pre&gt;
 &lt;/p&gt;
diff --git a/bundles/org.eclipse.ui.browser/src/org/eclipse/ui/internal/browser/BrowserExt.java b/bundles/org.eclipse.ui.browser/src/org/eclipse/ui/internal/browser/BrowserExt.java
index 1f523e4..973a0c4 100644
--- a/bundles/org.eclipse.ui.browser/src/org/eclipse/ui/internal/browser/BrowserExt.java
+++ b/bundles/org.eclipse.ui.browser/src/org/eclipse/ui/internal/browser/BrowserExt.java
@@ -79,15 +79,6 @@
 		list.toArray(s);
 		return s;
 	}
-	
-	public boolean isSearchHome(int i) {
-		IConfigurationElement[] children = element.getChildren("location"); //$NON-NLS-1$
-		if (children != null) {
-            String searchInHome = children[i].getAttribute("homeRelative"); //$NON-NLS-1$
-			return "true".equalsIgnoreCase(searchInHome); //$NON-NLS-1$
-		}
-		return false;
-	}
 
 	protected BrowserFactory getDelegate() {
 		if (delegate == null) {
diff --git a/bundles/org.eclipse.ui.browser/src/org/eclipse/ui/internal/browser/IBrowserExt.java b/bundles/org.eclipse.ui.browser/src/org/eclipse/ui/internal/browser/IBrowserExt.java
index 215ab9b..6cc12d6 100644
--- a/bundles/org.eclipse.ui.browser/src/org/eclipse/ui/internal/browser/IBrowserExt.java
+++ b/bundles/org.eclipse.ui.browser/src/org/eclipse/ui/internal/browser/IBrowserExt.java
@@ -67,13 +67,6 @@
 	 */
 	public String[] getDefaultLocations();
 	
-    /**
-     * Determines whether a location is relative to the users home directory
-     * @param i
-     * @return true if getDefaultLocations()[i] is a location relative to the users home directory
-     */
-	public boolean isSearchHome(int i);
-	
 	/**
 	 * Checks whether the factory can work on the user system.
 	 * 
diff --git a/bundles/org.eclipse.ui.browser/src/org/eclipse/ui/internal/browser/WebBrowserUtil.java b/bundles/org.eclipse.ui.browser/src/org/eclipse/ui/internal/browser/WebBrowserUtil.java
index 11a181a..36d712b 100644
--- a/bundles/org.eclipse.ui.browser/src/org/eclipse/ui/internal/browser/WebBrowserUtil.java
+++ b/bundles/org.eclipse.ui.browser/src/org/eclipse/ui/internal/browser/WebBrowserUtil.java
@@ -20,6 +20,7 @@
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.util.Util;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.browser.Browser;
 import org.eclipse.swt.program.Program;
@@ -174,12 +175,12 @@
 		return Program.findProgram("html") != null; //$NON-NLS-1$
 	}
 
-	public static List getExternalBrowserPaths() {
-		List paths = new ArrayList();
-		Iterator iterator = BrowserManager.getInstance().getWebBrowsers()
-				.iterator();
+	public static List<String> getExternalBrowserPaths() {
+		List<String> paths = new ArrayList<String>();
+		Iterator<IBrowserDescriptor> iterator = BrowserManager.getInstance()
+				.getWebBrowsers().iterator();
 		while (iterator.hasNext()) {
-			IBrowserDescriptor wb = (IBrowserDescriptor) iterator.next();
+			IBrowserDescriptor wb = iterator.next();
 			if (wb != null && wb.getLocation() != null)
 				paths.add(wb.getLocation().toLowerCase());
 		}
@@ -190,30 +191,24 @@
 	 * Add any supported EXTERNAL web browsers found after an arbitrary check in
 	 * specific paths
 	 */
-	public static void addFoundBrowsers(List list) {
-		List paths = getExternalBrowserPaths();
+	public static void addFoundBrowsers(List<BrowserDescriptor> list) {
+		List<String> paths = getExternalBrowserPaths();
 
 		String os = Platform.getOS();
 		File[] roots = getUsableDrives(File.listRoots());
-		File[] home = getHomeDirectory();
 
 		IBrowserExt[] browsers = WebBrowserUIPlugin.getBrowsers();
 		int size = browsers.length;
 		for (int i = 0; i < size; i++) {
 			IBrowserExt browserExt = browsers[i];
-			if (browserExt.getDefaultLocations() != null
+			String[] locations = browserExt.getDefaultLocations();
+			if (locations != null
 					&& browserExt.getOS().toLowerCase().indexOf(os) >= 0) {
-				int size2 = browserExt.getDefaultLocations().length;
+				int size2 = locations.length;
 				for (int j = 0; j < size2; j++) {
-					String location = browserExt.getDefaultLocations()[j];
+					String location = locations[j];
 
-					
-					String foundBrowserPath = null;
-					
-					boolean searchHome = browserExt.isSearchHome(j);
-					File[] searchRoots = searchHome ? home : roots;
-					foundBrowserPath = locateBrowser(paths, location,
-							searchRoots);
+					String foundBrowserPath = locateBrowser(paths, location, roots);
 
 					if (foundBrowserPath != null) {
 						BrowserDescriptor descriptor = new BrowserDescriptor();
@@ -231,11 +226,34 @@
 	}
 
 	/*
-	 * Look for the file on each of the search roots
+	 * Look for the file on each of the search roots.
+	 * If the location starts with a Windows environment variable, expand it.
 	 */
-	private static String locateBrowser(List alreadyFoundPaths,
+	private static String locateBrowser(List<String> alreadyFoundPaths,
 			String location, File[] searchRoots) {
 		int rootSize = searchRoots.length;
+
+		if (Util.isWindows() && location.startsWith("%")) { //$NON-NLS-1$
+			int envVarEnd = location.indexOf('%', 1);
+			if (envVarEnd != -1) {
+				try {
+					String expanded = System.getenv(location.substring(1, envVarEnd));
+					if (expanded != null) {
+						File f = new File(expanded + location.substring(envVarEnd + 1));
+						String absolutePath = f.getAbsolutePath();
+						if (!alreadyFoundPaths.contains(absolutePath.toLowerCase())) {
+							if (f.exists()) {
+								return absolutePath;
+							}
+						}
+						return null;
+					}
+				} catch (Exception e) {
+					// ignore
+				}
+			}
+		}
+
 		for (int k = 0; k < rootSize; k++) {
 			try {
 				File f = new File(searchRoots[k], location);
@@ -252,21 +270,11 @@
 		}
 		return null;
 	}
-	
-	private static File[] getHomeDirectory() {
-		try {
-			String userHome=System.getProperty("user.home"); //$NON-NLS-1$
-			File home = new File(userHome);
-			return new File[] { home };
-		}  catch (Exception e) {
-			return new File[0];
-		}		
-	}
 
 	private static File[] getUsableDrives(File[] roots) {
 		if (!Platform.getOS().equals(Platform.OS_WIN32))
 			return roots;
-		ArrayList list = new ArrayList();
+		ArrayList<File> list = new ArrayList<File>();
 		for (int i = 0; i < roots.length; i++) {
 			String path = roots[i].getAbsolutePath();
 			if (path != null
@@ -274,7 +282,7 @@
 				continue;
 			list.add(roots[i]);
 		}
-		return (File[]) list.toArray(new File[list.size()]);
+		return list.toArray(new File[list.size()]);
 	}
 
 	/**