8010666: Implement Currency/LocaleNameProvider in Windows Host LocaleProviderAdapter
authornaoto
Mon, 22 Apr 2013 13:37:07 -0700
changeset 17169 5e5039c3181d
parent 17168 b7d3500f2516
child 17170 9f33b89c7978
child 17185 510e5f180f31
child 18245 7f4796a3f93a
8010666: Implement Currency/LocaleNameProvider in Windows Host LocaleProviderAdapter Reviewed-by: okutsu
jdk/src/macosx/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java
jdk/src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java
jdk/src/windows/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c
jdk/test/java/util/Locale/LocaleProviders.java
jdk/test/java/util/Locale/LocaleProviders.sh
--- a/jdk/src/macosx/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java	Wed Apr 17 11:34:31 2013 +0200
+++ b/jdk/src/macosx/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java	Mon Apr 22 13:37:07 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -520,14 +520,22 @@
     }
 
     private static boolean isSupportedCalendarLocale(Locale locale) {
-        Locale base = locale.stripExtensions();
+        Locale base = locale;
+
+        if (base.hasExtensions() || base.getVariant() != "") {
+            base = new Locale.Builder()
+                            .setLocale(locale)
+                            .clearExtensions()
+                            .build();
+        }
+
         if (!supportedLocaleSet.contains(base)) {
             return false;
         }
 
         String requestedCalType = locale.getUnicodeLocaleType("ca");
         String nativeCalType =
-            getCalendarID(locale.toLanguageTag()).replaceFirst("gregorian", "gregory");
+            getCalendarID(base.toLanguageTag()).replaceFirst("gregorian", "gregory");
 
         if (requestedCalType == null) {
             return Calendar.getAvailableCalendarTypes().contains(nativeCalType);
--- a/jdk/src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java	Wed Apr 17 11:34:31 2013 +0200
+++ b/jdk/src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java	Mon Apr 22 13:37:07 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
 import java.text.spi.NumberFormatProvider;
 import java.util.Calendar;
 import java.util.Collections;
+import java.util.Currency;
 import java.util.HashSet;
 import java.util.Locale;
 import java.util.Map;
@@ -48,6 +49,8 @@
 import java.util.concurrent.atomic.AtomicReferenceArray;
 import java.util.spi.CalendarDataProvider;
 import java.util.spi.CalendarNameProvider;
+import java.util.spi.CurrencyNameProvider;
+import java.util.spi.LocaleNameProvider;
 import sun.util.spi.CalendarProvider;
 
 /**
@@ -72,6 +75,14 @@
     private static final int CD_FIRSTDAYOFWEEK = 0;
     private static final int CD_MINIMALDAYSINFIRSTWEEK = 1;
 
+    // Currency/Locale display name types
+    private static final int DN_CURRENCY_NAME   = 0;
+    private static final int DN_CURRENCY_SYMBOL = 1;
+    private static final int DN_LOCALE_LANGUAGE = 2;
+    private static final int DN_LOCALE_SCRIPT   = 3;
+    private static final int DN_LOCALE_REGION   = 4;
+    private static final int DN_LOCALE_VARIANT  = 5;
+
     // Native Calendar ID to LDML calendar type map
     private static final String[] calIDToLDML = {
         "",
@@ -96,15 +107,25 @@
     private static ConcurrentMap<Locale, SoftReference<DecimalFormatSymbols>> decimalFormatSymbolsCache = new ConcurrentHashMap<>();
 
     private static final Set<Locale> supportedLocaleSet;
+    private static final String nativeDisplayLanguage;
     static {
         Set<Locale> tmpSet = new HashSet<>();
         if (initialize()) {
             // Assuming the default locales do not include any extensions, so
             // no stripping is needed here.
-            Locale l = Locale.forLanguageTag(getDefaultLocale(CAT_FORMAT).replace('_', '-'));
-            tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l));
-            l = Locale.forLanguageTag(getDefaultLocale(CAT_DISPLAY).replace('_', '-'));
-            tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l));
+            Control c = Control.getNoFallbackControl(Control.FORMAT_DEFAULT);
+            String displayLocale = getDefaultLocale(CAT_DISPLAY);
+            Locale l = Locale.forLanguageTag(displayLocale.replace('_', '-'));
+            tmpSet.addAll(c.getCandidateLocales("", l));
+            nativeDisplayLanguage = l.getLanguage();
+
+            String formatLocale = getDefaultLocale(CAT_FORMAT);
+            if (!formatLocale.equals(displayLocale)) {
+                l = Locale.forLanguageTag(formatLocale.replace('_', '-'));
+                tmpSet.addAll(c.getCandidateLocales("", l));
+            }
+        } else {
+            nativeDisplayLanguage = "";
         }
         supportedLocaleSet = Collections.unmodifiableSet(tmpSet);
     }
@@ -392,6 +413,96 @@
         };
     }
 
+    public static CurrencyNameProvider getCurrencyNameProvider() {
+        return new CurrencyNameProvider() {
+            @Override
+            public Locale[] getAvailableLocales() {
+                return supportedLocale;
+            }
+
+            @Override
+            public boolean isSupportedLocale(Locale locale) {
+                // Ignore the extensions for now
+                return supportedLocaleSet.contains(locale.stripExtensions()) &&
+                       locale.getLanguage().equals(nativeDisplayLanguage);
+            }
+
+            @Override
+            public String getSymbol(String currencyCode, Locale locale) {
+                // Retrieves the currency symbol by calling
+                // GetLocaleInfoEx(LOCALE_SCURRENCY).
+                // It only works with the "locale"'s currency in its native
+                // language.
+                try {
+                    if (Currency.getInstance(locale).getCurrencyCode()
+                        .equals(currencyCode)) {
+                        return getDisplayString(locale.toLanguageTag(),
+                                DN_CURRENCY_SYMBOL, currencyCode);
+                    }
+                } catch (IllegalArgumentException iae) {}
+                return null;
+            }
+
+            @Override
+            public String getDisplayName(String currencyCode, Locale locale) {
+                // Retrieves the display name by calling
+                // GetLocaleInfoEx(LOCALE_SNATIVECURRNAME).
+                // It only works with the "locale"'s currency in its native
+                // language.
+                try {
+                    if (Currency.getInstance(locale).getCurrencyCode()
+                        .equals(currencyCode)) {
+                        return getDisplayString(locale.toLanguageTag(),
+                                DN_CURRENCY_NAME, currencyCode);
+                    }
+                } catch (IllegalArgumentException iae) {}
+                return null;
+            }
+        };
+    }
+
+    public static LocaleNameProvider getLocaleNameProvider() {
+        return new LocaleNameProvider() {
+            @Override
+            public Locale[] getAvailableLocales() {
+                return supportedLocale;
+            }
+
+            @Override
+            public boolean isSupportedLocale(Locale locale) {
+                return supportedLocaleSet.contains(locale.stripExtensions()) &&
+                       locale.getLanguage().equals(nativeDisplayLanguage);
+            }
+
+            @Override
+            public String getDisplayLanguage(String languageCode, Locale locale) {
+                // Retrieves the display language name by calling
+                // GetLocaleInfoEx(LOCALE_SLOCALIZEDLANGUAGENAME).
+                return getDisplayString(locale.toLanguageTag(),
+                            DN_LOCALE_LANGUAGE, languageCode);
+            }
+
+            @Override
+            public String getDisplayCountry(String countryCode, Locale locale) {
+                // Retrieves the display country name by calling
+                // GetLocaleInfoEx(LOCALE_SLOCALIZEDCOUNTRYNAME).
+                return getDisplayString(locale.toLanguageTag(),
+                            DN_LOCALE_REGION, nativeDisplayLanguage+"-"+countryCode);
+            }
+
+            @Override
+            public String getDisplayScript(String scriptCode, Locale locale) {
+                return null;
+            }
+
+            @Override
+            public String getDisplayVariant(String variantCode, Locale locale) {
+                return null;
+            }
+        };
+    }
+
+
     private static String convertDateTimePattern(String winPattern) {
         String ret = winPattern.replaceAll("dddd", "EEEE");
         ret = ret.replaceAll("ddd", "EEE");
@@ -413,12 +524,21 @@
     }
 
     private static boolean isSupportedCalendarLocale(Locale locale) {
-        Locale base = locale.stripExtensions();
+        Locale base = locale;
+
+        if (base.hasExtensions() || base.getVariant() != "") {
+            // strip off extensions and variant.
+            base = new Locale.Builder()
+                            .setLocale(locale)
+                            .clearExtensions()
+                            .build();
+        }
+
         if (!supportedLocaleSet.contains(base)) {
             return false;
         }
 
-        int calid = getCalendarID(locale.toLanguageTag());
+        int calid = getCalendarID(base.toLanguageTag());
         if (calid <= 0 || calid >= calIDToLDML.length) {
             return false;
         }
@@ -546,4 +666,7 @@
 
     // For CalendarDataProvider
     private static native int getCalendarDataValue(String langTag, int type);
+
+    // For Locale/CurrencyNameProvider
+    private static native String getDisplayString(String langTag, int key, String value);
 }
--- a/jdk/src/windows/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c	Wed Apr 17 11:34:31 2013 +0200
+++ b/jdk/src/windows/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c	Mon Apr 22 13:37:07 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -196,7 +196,7 @@
             break;
     }
 
-    localeString = getJavaIDFromLangID(langid);
+    localeString = (char *)getJavaIDFromLangID(langid);
     ret = (*env)->NewStringUTF(env, localeString);
     free(localeString);
     return ret;
@@ -366,12 +366,14 @@
  */
 JNIEXPORT jboolean JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_isNativeDigit
   (JNIEnv *env, jclass cls, jstring jlangtag) {
-    WCHAR buf[BUFLEN];
+    DWORD num;
     const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
-    int got = getLocaleInfoWrapper(langtag, LOCALE_IDIGITSUBSTITUTION, buf, BUFLEN);
+    int got = getLocaleInfoWrapper(langtag,
+        LOCALE_IDIGITSUBSTITUTION | LOCALE_RETURN_NUMBER,
+        (LPWSTR)&num, sizeof(num));
     (*env)->ReleaseStringChars(env, jlangtag, langtag);
 
-    return got && buf[0] == L'2'; // 2: native digit substitution
+    return got && num == 2; // 2: native digit substitution
 }
 
 /*
@@ -590,25 +592,72 @@
  */
 JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarDataValue
   (JNIEnv *env, jclass cls, jstring jlangtag, jint type) {
-    WCHAR buf[BUFLEN];
+    DWORD num;
     const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
     int got = 0;
 
     switch (type) {
     case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CD_FIRSTDAYOFWEEK:
-        got = getLocaleInfoWrapper(langtag, LOCALE_IFIRSTDAYOFWEEK, buf, BUFLEN);
+        got = getLocaleInfoWrapper(langtag,
+            LOCALE_IFIRSTDAYOFWEEK | LOCALE_RETURN_NUMBER,
+            (LPWSTR)&num, sizeof(num));
         break;
     }
 
     (*env)->ReleaseStringChars(env, jlangtag, langtag);
 
     if (got) {
-        return _wtoi(buf);
+        return num;
     } else {
         return -1;
     }
 }
 
+/*
+ * Class:     sun_util_locale_provider_HostLocaleProviderAdapterImpl
+ * Method:    getDisplayString
+ * Signature: (Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDisplayString
+  (JNIEnv *env, jclass cls, jstring jlangtag, jint type, jstring jvalue) {
+    LCTYPE lcType;
+    jstring jStr;
+    const jchar * pjChar;
+    WCHAR buf[BUFLEN];
+    int got = 0;
+
+    switch (type) {
+        case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_CURRENCY_NAME:
+            lcType = LOCALE_SNATIVECURRNAME;
+            jStr = jlangtag;
+            break;
+        case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_CURRENCY_SYMBOL:
+            lcType = LOCALE_SCURRENCY;
+            jStr = jlangtag;
+            break;
+        case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_LANGUAGE:
+            lcType = LOCALE_SLOCALIZEDLANGUAGENAME;
+            jStr = jvalue;
+            break;
+        case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_REGION:
+            lcType = LOCALE_SLOCALIZEDCOUNTRYNAME;
+            jStr = jvalue;
+            break;
+        default:
+            return NULL;
+    }
+
+    pjChar = (*env)->GetStringChars(env, jStr, JNI_FALSE);
+    got = getLocaleInfoWrapper(pjChar, lcType, buf, BUFLEN);
+    (*env)->ReleaseStringChars(env, jStr, pjChar);
+
+    if (got) {
+        return (*env)->NewString(env, buf, wcslen(buf));
+    } else {
+        return NULL;
+    }
+}
+
 int getLocaleInfoWrapper(const jchar *langtag, LCTYPE type, LPWSTR data, int buflen) {
     if (pGetLocaleInfoEx) {
         if (wcscmp(L"und", (LPWSTR)langtag) == 0) {
@@ -642,11 +691,13 @@
 }
 
 jint getCalendarID(const jchar *langtag) {
-    WCHAR type[BUFLEN];
-    int got = getLocaleInfoWrapper(langtag, LOCALE_ICALENDARTYPE, type, BUFLEN);
+    DWORD type;
+    int got = getLocaleInfoWrapper(langtag,
+        LOCALE_ICALENDARTYPE | LOCALE_RETURN_NUMBER,
+        (LPWSTR)&type, sizeof(type));
 
     if (got) {
-        return _wtoi(type);
+        return type;
     } else {
         return 0;
     }
@@ -691,28 +742,37 @@
 }
 
 void getNumberPart(const jchar * langtag, const jint numberStyle, WCHAR * number) {
-    WCHAR buf[BUFLEN];
+    DWORD digits = 0;
+    DWORD leadingZero = 0;
     WCHAR grouping[BUFLEN];
+    int groupingLen;
     WCHAR fractionPattern[BUFLEN];
     WCHAR * integerPattern = number;
-    int digits;
-    BOOL leadingZero;
     WCHAR * pDest;
-    int groupingLen;
 
     // Get info from Windows
-    if (numberStyle == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY) {
-        getLocaleInfoWrapper(langtag, LOCALE_ICURRDIGITS, buf, BUFLEN);
-    } else {
-        getLocaleInfoWrapper(langtag, LOCALE_IDIGITS, buf, BUFLEN);
+    switch (numberStyle) {
+        case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY:
+            getLocaleInfoWrapper(langtag,
+                LOCALE_ICURRDIGITS | LOCALE_RETURN_NUMBER,
+                (LPWSTR)&digits, sizeof(digits));
+            break;
+
+        case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_INTEGER:
+            break;
+
+        case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_NUMBER:
+        case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_PERCENT:
+        default:
+            getLocaleInfoWrapper(langtag,
+                LOCALE_IDIGITS | LOCALE_RETURN_NUMBER,
+                (LPWSTR)&digits, sizeof(digits));
+            break;
     }
-    if (numberStyle == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_INTEGER) {
-        digits = 0;
-    } else {
-        digits = _wtoi(buf);
-    }
-    getLocaleInfoWrapper(langtag, LOCALE_ILZERO, buf, BUFLEN);
-    leadingZero = _wtoi(buf) != 0;
+
+    getLocaleInfoWrapper(langtag,
+        LOCALE_ILZERO | LOCALE_RETURN_NUMBER,
+        (LPWSTR)&leadingZero, sizeof(leadingZero));
     groupingLen = getLocaleInfoWrapper(langtag, LOCALE_SGROUPING, grouping, BUFLEN);
 
     // fraction pattern
@@ -749,7 +809,7 @@
         }
     }
 
-    if (leadingZero) {
+    if (leadingZero != 0) {
         *pDest++ = L'0';
     } else {
         *pDest++ = L'#';
@@ -760,29 +820,35 @@
 }
 
 void getFixPart(const jchar * langtag, const jint numberStyle, BOOL positive, BOOL prefix, WCHAR * ret) {
-    WCHAR buf[BUFLEN];
-    int pattern = 0;
+    DWORD pattern = 0;
     int style = numberStyle;
     int got = 0;
 
     if (positive) {
         if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY) {
-            got = getLocaleInfoWrapper(langtag, LOCALE_ICURRENCY, buf, BUFLEN);
+            got = getLocaleInfoWrapper(langtag,
+                LOCALE_ICURRENCY | LOCALE_RETURN_NUMBER,
+                (LPWSTR)&pattern, sizeof(pattern));
         } else if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_PERCENT) {
-            got = getLocaleInfoWrapper(langtag, LOCALE_IPOSITIVEPERCENT, buf, BUFLEN);
+            got = getLocaleInfoWrapper(langtag,
+                LOCALE_IPOSITIVEPERCENT | LOCALE_RETURN_NUMBER,
+                (LPWSTR)&pattern, sizeof(pattern));
         }
     } else {
         if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY) {
-            got = getLocaleInfoWrapper(langtag, LOCALE_INEGCURR, buf, BUFLEN);
+            got = getLocaleInfoWrapper(langtag,
+                LOCALE_INEGCURR | LOCALE_RETURN_NUMBER,
+                (LPWSTR)&pattern, sizeof(pattern));
         } else if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_PERCENT) {
-            got = getLocaleInfoWrapper(langtag, LOCALE_INEGATIVEPERCENT, buf, BUFLEN);
+            got = getLocaleInfoWrapper(langtag,
+                LOCALE_INEGATIVEPERCENT | LOCALE_RETURN_NUMBER,
+                (LPWSTR)&pattern, sizeof(pattern));
         } else {
-            got = getLocaleInfoWrapper(langtag, LOCALE_INEGNUMBER, buf, BUFLEN);
+            got = getLocaleInfoWrapper(langtag,
+                LOCALE_INEGNUMBER | LOCALE_RETURN_NUMBER,
+                (LPWSTR)&pattern, sizeof(pattern));
         }
     }
-    if (got) {
-        pattern = _wtoi(buf);
-    }
 
     if (numberStyle == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_INTEGER) {
         style = sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_NUMBER;
--- a/jdk/test/java/util/Locale/LocaleProviders.java	Wed Apr 17 11:34:31 2013 +0200
+++ b/jdk/test/java/util/Locale/LocaleProviders.java	Mon Apr 22 13:37:07 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
 import java.text.*;
 import java.text.spi.*;
 import java.util.*;
+import java.util.spi.*;
 import sun.util.locale.provider.LocaleProviderAdapter;
 
 public class LocaleProviders {
@@ -55,6 +56,10 @@
                 bug8001440Test();
                 break;
 
+            case "bug8010666Test":
+                bug8010666Test();
+                break;
+
             default:
                 throw new RuntimeException("Test method '"+methodName+"' not found.");
         }
@@ -103,4 +108,38 @@
         NumberFormat nf = NumberFormat.getInstance(locale);
         String nu = nf.format(1234560);
     }
+
+    // This test assumes Windows localized language/country display names.
+    static void bug8010666Test() {
+        if (System.getProperty("os.name").startsWith("Windows")) {
+            NumberFormat nf = NumberFormat.getInstance(Locale.US);
+            try {
+                double ver = nf.parse(System.getProperty("os.version")).doubleValue();
+                System.out.printf("Windows version: %.1f\n", ver);
+                if (ver >= 6.0) {
+                    LocaleProviderAdapter lda = LocaleProviderAdapter.getAdapter(LocaleNameProvider.class, Locale.ENGLISH);
+                    LocaleProviderAdapter.Type type = lda.getAdapterType();
+                    if (type == LocaleProviderAdapter.Type.HOST) {
+                        Locale mkmk = Locale.forLanguageTag("mk-MK");
+                        String result = mkmk.getDisplayLanguage(Locale.ENGLISH);
+                        if (!"Macedonian (FYROM)".equals(result)) {
+                            throw new RuntimeException("Windows locale name provider did not return expected localized language name for \"mk\". Returned name was \"" + result + "\"");
+                        }
+                        result = Locale.US.getDisplayLanguage(Locale.ENGLISH);
+                        if (!"English".equals(result)) {
+                            throw new RuntimeException("Windows locale name provider did not return expected localized language name for \"en\". Returned name was \"" + result + "\"");
+                        }
+                        result = Locale.US.getDisplayCountry(Locale.ENGLISH);
+                        if (ver >= 6.1 && !"United States".equals(result)) {
+                            throw new RuntimeException("Windows locale name provider did not return expected localized country name for \"US\". Returned name was \"" + result + "\"");
+                        }
+                    } else {
+                        throw new RuntimeException("Windows Host LocaleProviderAdapter was not selected for English locale.");
+                    }
+                }
+            } catch (ParseException pe) {
+                throw new RuntimeException("Parsing Windows version failed: "+pe.toString());
+            }
+        }
+    }
 }
--- a/jdk/test/java/util/Locale/LocaleProviders.sh	Wed Apr 17 11:34:31 2013 +0200
+++ b/jdk/test/java/util/Locale/LocaleProviders.sh	Mon Apr 22 13:37:07 2013 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 #!/bin/sh
 #
 # @test
-# @bug 6336885 7196799 7197573 7198834 8000245 8000615 8001440
+# @bug 6336885 7196799 7197573 7198834 8000245 8000615 8001440 8010666
 # @summary tests for "java.locale.providers" system property
 # @compile -XDignore.symbol.file LocaleProviders.java
 # @run shell/timeout=600 LocaleProviders.sh
@@ -258,4 +258,15 @@
 PARAM3=
 runTest
 
+# testing 8010666 fix.
+if [ "${DEFLANG}" = "en" ]
+then
+  METHODNAME=bug8010666Test
+  PREFLIST=HOST
+  PARAM1=
+  PARAM2=
+  PARAM3=
+  runTest
+fi
+
 exit $result