Merge "Use one method to create a Locale from a String." into dalvik-dev
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/BreakIterator.java b/icu/src/main/java/com/ibm/icu4jni/text/BreakIterator.java
index 5ef1161..aa925aa 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/BreakIterator.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/BreakIterator.java
@@ -16,6 +16,7 @@
 
 package com.ibm.icu4jni.text;
 
+import com.ibm.icu4jni.util.Resources;
 import java.text.CharacterIterator;
 import java.text.StringCharacterIterator;
 import java.util.Locale;
@@ -30,36 +31,7 @@
     protected int type = 0;
     
     public static Locale[] getAvailableLocales() {
-        
-        String[] locales = NativeBreakIterator.getAvailableLocalesImpl();
-        
-        Locale[] result = new Locale[locales.length];
-        
-        String locale;
-        
-        int index, index2;
-        
-        for(int i = 0; i < locales.length; i++) {
-            locale = locales[i];
-            
-            index = locale.indexOf('_');
-            index2 = locale.lastIndexOf('_');
-            
-            if(index == -1) {
-                result[i] = new Locale(locales[i]);
-            } else if(index > 0 && index == index2) {
-                result[i] = new Locale(
-                        locale.substring(0,index),
-                        locale.substring(index+1));
-            } else if(index > 0 && index2 > index) {
-                result[i] = new Locale(
-                        locale.substring(0,index),
-                        locale.substring(index+1,index2),
-                        locale.substring(index2+1));
-            }
-        }
-        
-        return result;
+        return Resources.localesFromStrings(NativeBreakIterator.getAvailableLocalesImpl());
     }
     
     public static BreakIterator getCharacterInstance() {
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/Collator.java b/icu/src/main/java/com/ibm/icu4jni/text/Collator.java
index 4a7e1bf..0963b81 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/Collator.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/Collator.java
@@ -10,8 +10,9 @@
 
 package com.ibm.icu4jni.text;
 
-import java.util.Locale;
 import com.ibm.icu4jni.text.RuleBasedCollator;
+import com.ibm.icu4jni.util.Resources;
+import java.util.Locale;
 
 /**
 * Abstract class handling locale specific collation via JNI and ICU.
@@ -394,38 +395,7 @@
   */
   public abstract int hashCode();
   
-  // BEGIN android-added
   public static Locale[] getAvailableLocales() {
-      
-      String[] locales = NativeCollation.getAvailableLocalesImpl();
-      
-      Locale[] result = new Locale[locales.length];
-      
-      String locale;
-      
-      int index, index2;
-      
-      for(int i = 0; i < locales.length; i++) {
-          locale = locales[i];
-
-          index = locale.indexOf('_');
-          index2 = locale.lastIndexOf('_');
-
-          if(index == -1) {
-              result[i] = new Locale(locales[i]);
-          } else if(index == 2 && index == index2) {
-              result[i] = new Locale(
-                      locale.substring(0,2),
-                      locale.substring(3,5));
-          } else if(index == 2 && index2 > index) {
-              result[i] = new Locale(
-                      locale.substring(0,index),
-                      locale.substring(index + 1,index2),
-                      locale.substring(index2 + 1));
-          }
-      }
-      
-      return result;
+      return Resources.localesFromStrings(NativeCollation.getAvailableLocalesImpl());
   }
-  // END android-added
 }
diff --git a/icu/src/main/java/com/ibm/icu4jni/util/Resources.java b/icu/src/main/java/com/ibm/icu4jni/util/Resources.java
index cbad9a5..66bfdfb 100644
--- a/icu/src/main/java/com/ibm/icu4jni/util/Resources.java
+++ b/icu/src/main/java/com/ibm/icu4jni/util/Resources.java
@@ -285,6 +285,35 @@
         return result;
     }
 
+    /**
+     * Returns the appropriate {@code Locale} given a {@code String} of the form returned
+     * by {@code toString}. This is very lenient, and doesn't care what's between the underscores:
+     * this method can parse strings that {@code Locale.toString} won't produce.
+     * Used to remove duplication.
+     */
+    public static Locale localeFromString(String localeName) {
+        int first = localeName.indexOf('_');
+        int second = localeName.indexOf('_', first + 1);
+        if (first == -1) {
+            // Language only ("ja").
+            return new Locale(localeName);
+        } else if (second == -1) {
+            // Language and country ("ja_JP").
+            return new Locale(localeName.substring(0, first), localeName.substring(first + 1));
+        } else {
+            // Language and country and variant ("ja_JP_TRADITIONAL").
+            return new Locale(localeName.substring(0, first), localeName.substring(first + 1, second), localeName.substring(second + 1));
+        }
+    }
+
+    public static Locale[] localesFromStrings(String[] localeNames) {
+        Locale[] result = new Locale[localeNames.length];
+        for (int i = 0; i < result.length; ++i) {
+            result[i] = localeFromString(localeNames[i]);
+        }
+        return result;
+    }
+
     // --- Native methods accessing ICU's database ----------------------------
 
     public static native String getDisplayCountryNative(String countryCode, String locale);
diff --git a/icu/src/test/java/com/ibm/icu4jni/util/ResourcesTest.java b/icu/src/test/java/com/ibm/icu4jni/util/ResourcesTest.java
index 4112d0b..7dcaa9c 100644
--- a/icu/src/test/java/com/ibm/icu4jni/util/ResourcesTest.java
+++ b/icu/src/test/java/com/ibm/icu4jni/util/ResourcesTest.java
@@ -16,6 +16,8 @@
 
 package com.ibm.icu4jni.util;
 
+import java.util.Locale;
+
 public class ResourcesTest extends junit.framework.TestCase {
     public void test_getISOLanguages() throws Exception {
         // Check that corrupting our array doesn't affect other callers.
@@ -55,4 +57,18 @@
         Resources.getDisplayTimeZones(null)[0][0] = null;
         assertNotNull(Resources.getDisplayTimeZones(null)[0][0]);
     }
+
+    public void test_localeFromString() throws Exception {
+        // localeFromString is pretty lenient. Some of these can't be round-tripped
+        // through Locale.toString.
+        assertEquals(Locale.ENGLISH, Resources.localeFromString("en"));
+        assertEquals(Locale.ENGLISH, Resources.localeFromString("en_"));
+        assertEquals(Locale.ENGLISH, Resources.localeFromString("en__"));
+        assertEquals(Locale.US, Resources.localeFromString("en_US"));
+        assertEquals(Locale.US, Resources.localeFromString("en_US_"));
+        assertEquals(new Locale("", "US", ""), Resources.localeFromString("_US"));
+        assertEquals(new Locale("", "US", ""), Resources.localeFromString("_US_"));
+        assertEquals(new Locale("", "", "POSIX"), Resources.localeFromString("__POSIX"));
+        assertEquals(new Locale("aa", "BB", "CC"), Resources.localeFromString("aa_BB_CC"));
+    }
 }
diff --git a/luni/src/main/java/java/util/Locale.java b/luni/src/main/java/java/util/Locale.java
index 5337e48..ec36fcf 100644
--- a/luni/src/main/java/java/util/Locale.java
+++ b/luni/src/main/java/java/util/Locale.java
@@ -327,31 +327,6 @@
         return false;
     }
 
-    // BEGIN android-added
-    static Locale[] find() {
-        String[] locales = Resources.getAvailableLocales();
-        ArrayList<Locale> temp = new ArrayList<Locale>();
-        for (int i = 0; i < locales.length; i++) {
-            String s = locales[i];
-            int first = s.indexOf('_');
-            int second = s.indexOf('_', first + 1);
-
-            if (first == -1) {
-                // Language only
-                temp.add(new Locale(s));
-            } else if (second == -1) {
-                // Language and country
-                temp.add(new Locale(s.substring(0, first), s.substring(first + 1)));
-            } else {
-                // Language and country and variant
-                temp.add(new Locale(s.substring(0, first), s.substring(first + 1, second), s.substring(second + 1)));
-            }
-        }
-        Locale[] result = new Locale[temp.size()];
-        return temp.toArray(result);
-    }
-    // END android-added
-
     /**
      * Gets the list of installed {@code Locale}s. At least a {@code Locale} that is equal to
      * {@code Locale.US} must be contained in this array.
@@ -360,14 +335,8 @@
      */
     public static Locale[] getAvailableLocales() {
         // BEGIN android-changed
-        // ULocale[] ulocales =  ULocale.getAvailableLocales();
-        // Locale[] locales = new Locale[ulocales.length];
-        // for (int i = 0; i < locales.length; i++) {
-        //     locales[i] = ulocales[i].toLocale();
-        // }
-        // return locales;
         if (availableLocales == null) {
-            availableLocales = find();
+            availableLocales = Resources.localesFromStrings(Resources.getAvailableLocales());
         }
         return availableLocales.clone();
         // END android-changed
diff --git a/luni/src/main/java/java/util/ResourceBundle.java b/luni/src/main/java/java/util/ResourceBundle.java
index ec669d6..452ba8a 100644
--- a/luni/src/main/java/java/util/ResourceBundle.java
+++ b/luni/src/main/java/java/util/ResourceBundle.java
@@ -17,6 +17,7 @@
 
 package java.util;
 
+import com.ibm.icu4jni.util.Resources;
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.AccessController;
@@ -444,25 +445,8 @@
     }
 
     private void setLocale(String name) {
-        String language = "", country = "", variant = ""; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
-        if (name.length() > 1) {
-            int nextIndex = name.indexOf('_', 1);
-            if (nextIndex == -1) {
-                nextIndex = name.length();
-            }
-            language = name.substring(1, nextIndex);
-            if (nextIndex + 1 < name.length()) {
-                int index = nextIndex;
-                nextIndex = name.indexOf('_', nextIndex + 1);
-                if (nextIndex == -1) {
-                    nextIndex = name.length();
-                }
-                country = name.substring(index + 1, nextIndex);
-                if (nextIndex + 1 < name.length()) {
-                    variant = name.substring(nextIndex + 1, name.length());
-                }
-            }
-        }
-        locale = new Locale(language, country, variant);
+        // BEGIN android-changed: remove duplication.
+        locale = Resources.localeFromString(name);
+        // END android-changed
     }
 }