Fix Issue 4045: cannot start in Turkish locale
Ensure all calls to String.to{Lower,Upper}Case in the dev packages
specify the English locale, so that Turkish users don't experience 'I'
mapping to dotless small 'i'.  We also avoid calls to
Character.to{Lower,Upper}Case since they do not specify the locale.

There's a separate issue around the JS implementation of these methods,
but this patch addresses only the non-emulated 'gwt-dev' case.

Review by: jat



git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@6889 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/BootStrapPlatform.java b/dev/core/src/com/google/gwt/dev/BootStrapPlatform.java
index 04af8bc..a74b16d 100644
--- a/dev/core/src/com/google/gwt/dev/BootStrapPlatform.java
+++ b/dev/core/src/com/google/gwt/dev/BootStrapPlatform.java
@@ -17,6 +17,7 @@
 
 import java.awt.GraphicsEnvironment;
 import java.awt.Toolkit;
+import java.util.Locale;
 
 /**
  * Initializes platform stuff.
@@ -62,7 +63,7 @@
    * Return true if we are running on a Mac.
    */
   private static boolean isMac() {
-    String lcOSName = System.getProperty("os.name").toLowerCase();
+    String lcOSName = System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
     return lcOSName.startsWith("mac ");
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/GWTShell.java b/dev/core/src/com/google/gwt/dev/GWTShell.java
index 2879f4b..9df74f6 100644
--- a/dev/core/src/com/google/gwt/dev/GWTShell.java
+++ b/dev/core/src/com/google/gwt/dev/GWTShell.java
@@ -28,6 +28,7 @@
 import com.google.gwt.util.tools.ArgHandlerExtra;
 
 import java.io.File;
+import java.util.Locale;
 import java.util.Set;
 
 /**
@@ -127,7 +128,7 @@
 
   public static String checkHost(String hostUnderConsideration,
       Set<String> hosts) {
-    hostUnderConsideration = hostUnderConsideration.toLowerCase();
+    hostUnderConsideration = hostUnderConsideration.toLowerCase(Locale.ENGLISH);
     for (String rule : hosts) {
       // match on lowercased regex
       if (hostUnderConsideration.matches(".*" + rule + ".*")) {
diff --git a/dev/core/src/com/google/gwt/dev/ServletValidator.java b/dev/core/src/com/google/gwt/dev/ServletValidator.java
index 24f021ef..1fc93da 100644
--- a/dev/core/src/com/google/gwt/dev/ServletValidator.java
+++ b/dev/core/src/com/google/gwt/dev/ServletValidator.java
@@ -31,6 +31,7 @@
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 
@@ -117,7 +118,8 @@
   static String suggestServletName(String servletClass) {
     int pos = servletClass.lastIndexOf('.');
     String suggest = (pos < 0) ? servletClass : servletClass.substring(pos + 1);
-    suggest = Character.toLowerCase(suggest.charAt(0)) + suggest.substring(1);
+    String firstChar = suggest.substring(0, 1).toLowerCase(Locale.ENGLISH);
+    suggest = firstChar + suggest.substring(1);
     return suggest;
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/javac/JsniChecker.java b/dev/core/src/com/google/gwt/dev/javac/JsniChecker.java
index 3921877..a8a0238 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JsniChecker.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JsniChecker.java
@@ -51,6 +51,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
 import org.eclipse.jdt.internal.compiler.lookup.UnresolvedReferenceBinding;
 
+import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 
@@ -320,13 +321,13 @@
               Expression valueExpr = pair.value;
               if (valueExpr instanceof StringLiteral) {
                 // @SuppressWarnings("Foo")
-                return Sets.create(((StringLiteral) valueExpr).constant.stringValue().toLowerCase());
+                return Sets.create(((StringLiteral) valueExpr).constant.stringValue().toLowerCase(Locale.ENGLISH));
               } else if (valueExpr instanceof ArrayInitializer) {
                 // @SuppressWarnings({ "Foo", "Bar"})
                 ArrayInitializer ai = (ArrayInitializer) valueExpr;
                 String[] values = new String[ai.expressions.length];
                 for (int i = 0, j = values.length; i < j; i++) {
-                  values[i] = ((StringLiteral) ai.expressions[i]).constant.stringValue().toLowerCase();
+                  values[i] = ((StringLiteral) ai.expressions[i]).constant.stringValue().toLowerCase(Locale.ENGLISH);
                 }
                 return Sets.create(values);
               } else {
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java b/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java
index 5454b7b..4e353e9 100644
--- a/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java
+++ b/dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java
@@ -36,6 +36,7 @@
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.Map.Entry;
@@ -167,7 +168,7 @@
       throws URISyntaxException, IOException {
     if (url.getProtocol().equals("file")) {
       File f = new File(url.toURI());
-      String lowerCaseFileName = f.getName().toLowerCase();
+      String lowerCaseFileName = f.getName().toLowerCase(Locale.ENGLISH);
       if (f.isDirectory()) {
         return new DirectoryClassPathEntry(f);
       } else if (f.isFile() && lowerCaseFileName.endsWith(".jar")) {
diff --git a/dev/core/src/com/google/gwt/dev/shell/BrowserWidgetHostChecker.java b/dev/core/src/com/google/gwt/dev/shell/BrowserWidgetHostChecker.java
index fe9bc59..af266b2 100644
--- a/dev/core/src/com/google/gwt/dev/shell/BrowserWidgetHostChecker.java
+++ b/dev/core/src/com/google/gwt/dev/shell/BrowserWidgetHostChecker.java
@@ -21,6 +21,7 @@
 import java.net.UnknownHostException;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Locale;
 import java.util.Set;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
@@ -124,9 +125,9 @@
   public static String checkHost(String hostUnderConsideration,
       Set<String> hosts) {
     // TODO(jat): build a single regex instead of looping
-    hostUnderConsideration = hostUnderConsideration.toLowerCase();
+    hostUnderConsideration = hostUnderConsideration.toLowerCase(Locale.ENGLISH);
     for (String rule : hosts) {
-      rule = rule.toLowerCase();
+      rule = rule.toLowerCase(Locale.ENGLISH);
       // match on lowercased regex
       if (hostUnderConsideration.matches(".*" + rule + ".*")) {
         return rule;
diff --git a/dev/core/src/com/google/gwt/dev/shell/CheckForUpdates.java b/dev/core/src/com/google/gwt/dev/shell/CheckForUpdates.java
index 51fe903..dd33501 100644
--- a/dev/core/src/com/google/gwt/dev/shell/CheckForUpdates.java
+++ b/dev/core/src/com/google/gwt/dev/shell/CheckForUpdates.java
@@ -40,6 +40,7 @@
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.Date;
+import java.util.Locale;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.FutureTask;
@@ -157,7 +158,7 @@
   public static CheckForUpdates createUpdateChecker(TreeLogger logger,
       String entryPoint) {
     // Windows has a custom implementation to handle proxies.
-    if (System.getProperty("os.name").toLowerCase().contains("win")) {
+    if (System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("win")) {
       return new CheckForUpdatesIE6(logger, entryPoint);
     } else {
       return new CheckForUpdates(logger, entryPoint);
diff --git a/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteJsniMethods.java b/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteJsniMethods.java
index aed8145..da8a029 100644
--- a/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteJsniMethods.java
+++ b/dev/core/src/com/google/gwt/dev/shell/rewrite/RewriteJsniMethods.java
@@ -26,6 +26,7 @@
 import com.google.gwt.dev.util.Name.InternalName;
 
 import java.lang.reflect.Modifier;
+import java.util.Locale;
 import java.util.Map;
 
 /**
@@ -119,8 +120,8 @@
       for (Class<?> c : primitives) {
         Type type = Type.getType(c);
         String typeName = type.getClassName();
-        typeName = Character.toUpperCase(typeName.charAt(0))
-            + typeName.substring(1);
+        String firstChar = typeName.substring(0, 1).toUpperCase(Locale.ENGLISH);
+        typeName = firstChar + typeName.substring(1);
         SORT_MAP[type.getSort()] = new JavaScriptHostInfo(type, "invokeNative"
             + typeName);
       }
diff --git a/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java b/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java
index 5d72cf1..cfb0a87 100644
--- a/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java
+++ b/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java
@@ -45,6 +45,7 @@
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Collections;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 
@@ -361,12 +362,14 @@
     String prefix = "";
     String urlString = url.toString();
     if (urlString.startsWith("jar:")) {
-      assert urlString.toLowerCase().contains(".jar!/" + tomcatEtcDir);
+      assert urlString.toLowerCase(Locale.ENGLISH).contains(".jar!/"
+          + tomcatEtcDir);
       urlString = urlString.substring(4, urlString.indexOf('!'));
       url = new URL(urlString);
       prefix = tomcatEtcDir;
     } else if (urlString.startsWith("zip:")) {
-      assert urlString.toLowerCase().contains(".zip!/" + tomcatEtcDir);
+      assert urlString.toLowerCase(Locale.ENGLISH).contains(".zip!/"
+          + tomcatEtcDir);
       urlString = urlString.substring(4, urlString.indexOf('!'));
       url = new URL(urlString);
       prefix = tomcatEtcDir;
diff --git a/dev/core/src/com/google/gwt/dev/util/BrowserInfo.java b/dev/core/src/com/google/gwt/dev/util/BrowserInfo.java
index 2e4cc9d..57f3c3c 100644
--- a/dev/core/src/com/google/gwt/dev/util/BrowserInfo.java
+++ b/dev/core/src/com/google/gwt/dev/util/BrowserInfo.java
@@ -15,6 +15,8 @@
  */
 package com.google.gwt.dev.util;
 
+import java.util.Locale;
+
 /**
  * Holds information about the browser used in the UI.
  */
@@ -35,7 +37,7 @@
    * @return short name of user agent
    */
   public static String getShortName(String userAgent) {
-    String lcAgent = userAgent.toLowerCase();
+    String lcAgent = userAgent.toLowerCase(Locale.ENGLISH);
     if (lcAgent.contains("msie")) {
       return IE;
     } else if (lcAgent.contains("chrome")) {
diff --git a/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerScriptStyle.java b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerScriptStyle.java
index f98f0c8..e45ce49 100644
--- a/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerScriptStyle.java
+++ b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerScriptStyle.java
@@ -18,6 +18,8 @@
 import com.google.gwt.dev.jjs.JsOutputOption;
 import com.google.gwt.util.tools.ArgHandler;
 
+import java.util.Locale;
+
 /**
  * Argument handler for processing the script style flag.
  */
@@ -47,7 +49,7 @@
 
   public int handle(String[] args, int startIndex) {
     if (startIndex + 1 < args.length) {
-      String style = args[startIndex + 1].toLowerCase();
+      String style = args[startIndex + 1].toLowerCase(Locale.ENGLISH);
       if (style.startsWith("obf")) {
         option.setOutput(JsOutputOption.OBFUSCATED);
         return 1;
diff --git a/dev/core/test/com/google/gwt/dev/resource/impl/PathPrefixSetTest.java b/dev/core/test/com/google/gwt/dev/resource/impl/PathPrefixSetTest.java
index 8c73c99..b0dd848 100644
--- a/dev/core/test/com/google/gwt/dev/resource/impl/PathPrefixSetTest.java
+++ b/dev/core/test/com/google/gwt/dev/resource/impl/PathPrefixSetTest.java
@@ -17,6 +17,8 @@
 
 import junit.framework.TestCase;
 
+import java.util.Locale;
+
 /**
  * Tests the trie and filtering behavior of path prefix set.
  */
@@ -72,7 +74,7 @@
     PathPrefixSet pps = new PathPrefixSet();
     ResourceFilter allowsGifs = new ResourceFilter() {
       public boolean allows(String path) {
-        return path.toLowerCase().endsWith(".gif");
+        return path.toLowerCase(Locale.ENGLISH).endsWith(".gif");
       }
     };