undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,117 @@
/*
* Copyright (c) 2007, 2024, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4052440 8062588 8165804 8210406 8291660 8174269
* @summary BreakIteratorProvider tests
* @library providersrc/foobarutils
* providersrc/fooprovider
* @modules java.base/sun.util.locale.provider
* java.base/sun.util.resources
* @build com.foobar.Utils
* com.foo.*
* @run main/othervm -Djava.locale.providers=CLDR,SPI BreakIteratorProviderTest
*/
import java.text.BreakIterator;
import java.text.Collator;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Set;
import com.foo.BreakIteratorProviderImpl;
import sun.util.locale.provider.LocaleProviderAdapter;
import sun.util.locale.provider.ResourceBundleBasedAdapter;
public class BreakIteratorProviderTest extends ProviderTest {
BreakIteratorProviderImpl bip = new BreakIteratorProviderImpl();
List<Locale> availloc = Arrays.asList(BreakIterator.getAvailableLocales());
List<Locale> providerloc = Arrays.asList(bip.getAvailableLocales());
List<Locale> fallbackloc = Arrays.asList(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.FALLBACK).getAvailableLocales());
List<Locale> fallbackimplloc = Arrays.asList(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.FALLBACK).getCollatorProvider().getAvailableLocales());
public static void main(String[] s) {
new BreakIteratorProviderTest();
}
BreakIteratorProviderTest() {
availableLocalesTest();
objectValidityTest();
}
void availableLocalesTest() {
Set<Locale> localesFromAPI = new HashSet<>(availloc);
Set<Locale> localesExpected = new HashSet<>(fallbackloc);
localesExpected.addAll(providerloc);
if (localesFromAPI.equals(localesExpected)) {
System.out.println("availableLocalesTest passed.");
} else {
throw new RuntimeException("availableLocalesTest failed");
}
}
void objectValidityTest() {
for (Locale target: availloc) {
// pure FALLBACK implementation
ResourceBundle rb = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.FALLBACK)).getLocaleData().getBreakIteratorInfo(target);
String[] classNames = rb.getStringArray("BreakIteratorClasses");
boolean fbSupportsLocale = fallbackimplloc.contains(target);
// result object
String[] result = new String[4];
result[0] = BreakIterator.getCharacterInstance(target).getClass().getName();
result[1] = BreakIterator.getWordInstance(target).getClass().getName();
result[2] = BreakIterator.getLineInstance(target).getClass().getName();
result[3] = BreakIterator.getSentenceInstance(target).getClass().getName();
// provider's object (if any)
String[] providersResult = new String[4];
if (providerloc.contains(target)) {
providersResult[0] = bip.getCharacterInstance(target).getClass().getName();
providersResult[1] = bip.getWordInstance(target).getClass().getName();
providersResult[2] = bip.getLineInstance(target).getClass().getName();
providersResult[3] = bip.getSentenceInstance(target).getClass().getName();
}
// JRE
String[] jresResult = new String[4];
if (fbSupportsLocale) {
jresResult[0] = "sun.util.locale.provider.BreakIteratorProviderImpl$GraphemeBreakIterator";
for (int i = 1; i < 4; i++) {
jresResult[i] = "sun.text." + classNames[i - 1];
}
}
for (int i = 0; i < 4; i++) {
checkValidity(target, jresResult[i], providersResult[i], result[i], fbSupportsLocale);
}
}
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2012, 2024, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 7058207 8000986 8062588 8210406 8174269
* @summary CalendarDataProvider tests
* @library providersrc/foobarutils
* providersrc/barprovider
* @build com.foobar.Utils
* com.bar.*
* @run main/othervm -Djava.locale.providers=CLDR,SPI CalendarDataProviderTest
*/
import java.util.Calendar;
import java.util.Locale;
import static java.util.Calendar.WEDNESDAY;
/**
* Test case for CalendarDataProvider.
*
* Test strategy:
* com.bar.CalendarDataProviderImpl supports only ja_JP_kids locale. It returns
* unusual week parameter values, WEDNESDAY - first day of week, 7 - minimal
* days in the first week.
*
* A Calendar instance created with ja_JP_kids should use the week parameters
* provided by com.bar.CalendarDataProviderImpl.
*/
public class CalendarDataProviderTest {
public static void main(String[] s) {
new CalendarDataProviderTest().test();
}
void test() {
Locale kids = Locale.of("ja", "JP", "kids"); // test provider's supported locale
Calendar kcal = Calendar.getInstance(kids);
// check the week parameters
checkResult("firstDayOfWeek", kcal.getFirstDayOfWeek(), WEDNESDAY);
checkResult("minimalDaysInFirstWeek", kcal.getMinimalDaysInFirstWeek(), 7);
}
private <T> void checkResult(String msg, T got, T expected) {
if (!expected.equals(got)) {
String s = String.format("%s: got='%s', expected='%s'", msg, got, expected);
throw new RuntimeException(s);
}
}
}

View file

@ -0,0 +1,124 @@
/*
* Copyright (c) 2012, 2024, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8000986 8062588 8210406 8174269
* @summary CalendarNameProvider tests
* @library providersrc/foobarutils
* providersrc/barprovider
* @build com.foobar.Utils
* com.bar.*
* @run main/othervm -Djava.locale.providers=CLDR,SPI CalendarNameProviderTest
*/
import java.util.Calendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import com.bar.CalendarNameProviderImpl;
import static java.util.Calendar.ALL_STYLES;
import static java.util.Calendar.DAY_OF_MONTH;
import static java.util.Calendar.DAY_OF_WEEK;
import static java.util.Calendar.DECEMBER;
import static java.util.Calendar.HOUR_OF_DAY;
import static java.util.Calendar.JANUARY;
import static java.util.Calendar.LONG_STANDALONE;
import static java.util.Calendar.MONTH;
import static java.util.Calendar.SATURDAY;
import static java.util.Calendar.SHORT_STANDALONE;
import static java.util.Calendar.SUNDAY;
/**
* Test case for CalendarNameProvider.
*
* Test strategy:
* com.bar.CalendarNameProviderImpl supports only ja_JP_kids locale. It returns
* month names only in full-width digits, followed by "gatsu" in Hiragana if
* it's a long style. The standalone styles are used because DateFormatSymbols
* has precedence for the format styles.
*
* Calendar.getDisplayName(s) should be called with kids to get the month
* names provided by com.bar.CalendarNameProviderImpl. Other display names
* should be the same as what a Calendar constructed with ja_JP returns.
*/
public class CalendarNameProviderTest {
public static void main(String[] s) {
new CalendarNameProviderTest().test();
}
void test() {
Locale kids = Locale.of("ja", "JP", "kids"); // test provider's supported locale
Calendar kcal = Calendar.getInstance(kids);
Calendar jcal = Calendar.getInstance(Locale.JAPAN);
// check month names and week day names
Map<String, Integer> mapAllStyles = new HashMap<>();
for (int style : new int[] { SHORT_STANDALONE, LONG_STANDALONE }) {
// Check month names provided by com.bar.CalendarNameProviderImpl
Map<String, Integer> map = new HashMap<>();
for (int month = JANUARY; month <= DECEMBER; month++) {
kcal.set(DAY_OF_MONTH, 1);
kcal.set(MONTH, month);
kcal.set(HOUR_OF_DAY, 12); // avoid any standard-daylight transitions...
kcal.getTimeInMillis();
String name = kcal.getDisplayName(MONTH, style, kids);
checkResult("Month name",
name,
CalendarNameProviderImpl.toMonthName(kcal.get(MONTH) + 1, style));
// Builds the map with name to its integer value.
map.put(name, kcal.get(MONTH));
}
checkResult((style == SHORT_STANDALONE ? "Short" : "Long") + " month names map",
kcal.getDisplayNames(MONTH, style, kids), map);
mapAllStyles.putAll(map);
if (style == LONG_STANDALONE) {
checkResult("Short and long month names map",
kcal.getDisplayNames(MONTH, ALL_STYLES, kids), mapAllStyles);
}
// Check week names: kcal and jcal should return the same names and maps.
for (int dow = SUNDAY; dow <= SATURDAY; dow++) {
kcal.set(DAY_OF_WEEK, dow);
jcal.setTimeInMillis(kcal.getTimeInMillis());
String name = kcal.getDisplayName(DAY_OF_WEEK, style, kids);
checkResult("Day of week name", name,
jcal.getDisplayName(DAY_OF_WEEK, style, Locale.JAPAN));
}
checkResult("Short day of week names", kcal.getDisplayNames(DAY_OF_WEEK, style, kids),
jcal.getDisplayNames(DAY_OF_WEEK, style, Locale.JAPAN));
}
}
private <T> void checkResult(String msg, T got, T expected) {
if (!expected.equals(got)) {
String s = String.format("%s: got='%s', expected='%s'", msg, got, expected);
throw new RuntimeException(s);
}
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2007, 2024, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6388652 8062588 8210406 8174269
* @summary Checks whether providers can be loaded from classpath.
* @library providersrc/foobarutils
* providersrc/barprovider
* @build com.foobar.Utils
* com.bar.*
* @run main/othervm -Djava.locale.providers=CLDR,SPI ClasspathTest
*/
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
public class ClasspathTest {
public static void main(String[] s) {
new ClasspathTest();
}
ClasspathTest() {
/*
* Since providers can be loaded from the application's classpath,
* this test will fail if they are NOT loaded from classpath.
*/
Locale OSAKA = Locale.of("ja", "JP", "osaka");
List<Locale> availableLocales = Arrays.asList(Locale.getAvailableLocales());
if (!availableLocales.contains(OSAKA)) {
throw new RuntimeException("LSS providers were NOT loaded from the class path.");
}
}
}

View file

@ -0,0 +1,120 @@
/*
* Copyright (c) 2007, 2024, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4052440 8062588 8210406 8174269
* @summary CollatorProvider tests
* @library providersrc/foobarutils
* providersrc/fooprovider
* @modules java.base/sun.util.locale.provider
* java.base/sun.util.resources
* @build com.foobar.Utils
* com.foo.*
* @run main/othervm -Djava.locale.providers=CLDR,SPI CollatorProviderTest
*/
import java.text.Collator;
import java.text.ParseException;
import java.text.RuleBasedCollator;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;
import com.foo.CollatorProviderImpl;
import sun.util.locale.provider.AvailableLanguageTags;
import sun.util.locale.provider.LocaleProviderAdapter;
import sun.util.locale.provider.ResourceBundleBasedAdapter;
public class CollatorProviderTest extends ProviderTest {
CollatorProviderImpl cp = new CollatorProviderImpl();
List<Locale> availloc = Arrays.asList(Collator.getAvailableLocales());
List<Locale> providerloc = Arrays.asList(cp.getAvailableLocales());
List<Locale> fallbackloc = Arrays.asList(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.FALLBACK).getAvailableLocales());
List<Locale> fallbackimplloc = Arrays.asList(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.FALLBACK).getCollatorProvider().getAvailableLocales());
public static void main(String[] s) {
new CollatorProviderTest();
}
CollatorProviderTest() {
availableLocalesTest();
objectValidityTest();
}
void availableLocalesTest() {
Set<Locale> localesFromAPI = new HashSet<>(availloc);
Set<Locale> localesExpected = new HashSet<>(fallbackloc);
localesExpected.addAll(providerloc);
if (localesFromAPI.equals(localesExpected)) {
System.out.println("availableLocalesTest passed.");
} else {
localesFromAPI.removeAll(localesExpected);
throw new RuntimeException("availableLocalesTest failed"+ localesFromAPI);
}
}
void objectValidityTest() {
Collator def = Collator.getInstance(Locale.of(""));
String defrules = ((RuleBasedCollator)def).getRules();
for (Locale target: availloc) {
// pure JRE implementation
Set<Locale> fbil = new HashSet<>();
for (String tag : ((AvailableLanguageTags)LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.FALLBACK).getCollatorProvider()).getAvailableLanguageTags()) {
fbil.add(Locale.forLanguageTag(tag));
}
ResourceBundle rb = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.FALLBACK)).getLocaleData().getCollationData(target);
boolean fbSupportsLocale = fbil.contains(target);
// result object
Collator result = Collator.getInstance(target);
// provider's object (if any)
Collator providersResult = null;
if (providerloc.contains(target)) {
providersResult = cp.getInstance(target);
}
// Fallback rule
Collator fbResult = null;
if (fbSupportsLocale) {
try {
String rules = rb.getString("Rule");
fbResult = new RuleBasedCollator(defrules+rules);
fbResult.setDecomposition(Collator.NO_DECOMPOSITION);
} catch (MissingResourceException mre) {
} catch (ParseException pe) {
}
}
checkValidity(target, fbResult, providersResult, result, fbSupportsLocale);
}
}
}

View file

@ -0,0 +1,188 @@
/*
* Copyright (c) 2007, 2025, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4052440 7199750 8000997 8062588 8210406 8174269
* @summary CurrencyNameProvider tests
* @library providersrc/foobarutils
* providersrc/barprovider
* @modules java.base/sun.util.locale.provider
* java.base/sun.util.resources
* @build com.foobar.Utils
* com.bar.*
* @run main/othervm/timeout=480 -Djava.locale.providers=CLDR,SPI CurrencyNameProviderTest
*/
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Currency;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import com.bar.CurrencyNameProviderImpl;
import com.bar.CurrencyNameProviderImpl2;
import sun.util.locale.provider.LocaleProviderAdapter;
import sun.util.locale.provider.ResourceBundleBasedAdapter;
import sun.util.resources.OpenListResourceBundle;
public class CurrencyNameProviderTest extends ProviderTest {
public static void main(String[] s) {
Locale reservedLocale = Locale.getDefault();
try {
new CurrencyNameProviderTest();
} finally {
// restore the reserved locale
Locale.setDefault(reservedLocale);
}
}
CurrencyNameProviderTest() {
test1();
test2();
}
void test1() {
CurrencyNameProviderImpl cnp = new CurrencyNameProviderImpl();
CurrencyNameProviderImpl2 cnp2 = new CurrencyNameProviderImpl2();
Locale[] availloc = Locale.getAvailableLocales();
Locale[] testloc = availloc.clone();
List<Locale> implloc = Arrays.asList(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR).getCurrencyNameProvider().getAvailableLocales());
List<Locale> providerloc = new ArrayList<Locale>();
providerloc.addAll(Arrays.asList(cnp.getAvailableLocales()));
providerloc.addAll(Arrays.asList(cnp2.getAvailableLocales()));
for (Locale target: availloc) {
// pure CLDR implementation
OpenListResourceBundle rb = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR)).getLocaleData().getCurrencyNames(target);
boolean jreSupportsTarget = implloc.contains(target);
for (Locale test: testloc) {
// get a Currency instance
Currency c = null;
try {
c = Currency.getInstance(test);
} catch (IllegalArgumentException iae) {}
if (c == null) {
continue;
}
// the localized symbol for the target locale
String currencyresult = c.getSymbol(target);
// the localized name for the target locale
String nameresult = c.getDisplayName(target);
// provider's name (if any)
String providerscurrency = null;
String providersname = null;
if (providerloc.contains(target)) {
if (cnp.isSupportedLocale(target)) {
providerscurrency = cnp.getSymbol(c.getCurrencyCode(), target);
providersname = cnp.getDisplayName(c.getCurrencyCode(), target);
} else {
providerscurrency = cnp2.getSymbol(c.getCurrencyCode(), target);
providersname = cnp2.getDisplayName(c.getCurrencyCode(), target);
}
}
// JRE's name
String jrescurrency = null;
String jresname = null;
String key = c.getCurrencyCode();
String nameKey = key.toLowerCase(Locale.ROOT);
if (jreSupportsTarget) {
try {
jrescurrency = rb.getString(key);
} catch (MissingResourceException mre) {}
try {
jresname = rb.getString(nameKey);
} catch (MissingResourceException mre) {}
}
checkValidity(target, jrescurrency, providerscurrency, currencyresult,
jreSupportsTarget && jrescurrency != null);
checkValidity(target, jresname, providersname, nameresult,
jreSupportsTarget && jresname != null);
}
}
}
final String pattern = "###,###\u00A4";
final String YEN_IN_OSAKA = "100,000\u5186\u3084\u3002";
final String YEN_IN_KYOTO = "100,000\u5186\u3069\u3059\u3002";
final String YEN_IN_TOKYO= "100,000JPY-tokyo";
final Locale OSAKA = Locale.of("ja", "JP", "osaka");
final Locale KYOTO = Locale.of("ja", "JP", "kyoto");
final Locale TOKYO = Locale.of("ja", "JP", "tokyo");
Integer i = new Integer(100000);
String formatted;
DecimalFormat df;
void test2() {
Locale defloc = Locale.getDefault();
try {
df = new DecimalFormat(pattern, DecimalFormatSymbols.getInstance(OSAKA));
System.out.println(formatted = df.format(i));
if(!formatted.equals(YEN_IN_OSAKA)) {
throw new RuntimeException("formatted currency names mismatch. " +
"Should match with " + YEN_IN_OSAKA);
}
df.parse(YEN_IN_OSAKA);
Locale.setDefault(KYOTO);
df = new DecimalFormat(pattern, DecimalFormatSymbols.getInstance());
System.out.println(formatted = df.format(i));
if(!formatted.equals(YEN_IN_KYOTO)) {
throw new RuntimeException("formatted currency names mismatch. " +
"Should match with " + YEN_IN_KYOTO);
}
df.parse(YEN_IN_KYOTO);
Locale.setDefault(TOKYO);
df = new DecimalFormat(pattern, DecimalFormatSymbols.getInstance());
System.out.println(formatted = df.format(i));
if(!formatted.equals(YEN_IN_TOKYO)) {
throw new RuntimeException("formatted currency names mismatch. " +
"Should match with " + YEN_IN_TOKYO);
}
df.parse(YEN_IN_TOKYO);
} catch (ParseException pe) {
throw new RuntimeException("parse error occured" + pe);
} finally {
Locale.setDefault(defloc);
}
}
}

View file

@ -0,0 +1,205 @@
/*
* Copyright (c) 2007, 2024, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4052440 7003643 8062588 8210406 8174269
* @summary DateFormatProvider tests
* @library providersrc/foobarutils
* providersrc/fooprovider
* @modules java.base/sun.util.locale.provider
* java.base/sun.util.resources
* @build com.foobar.Utils
* com.foo.*
* @run main/othervm/timeout=300 -Djava.locale.providers=CLDR,SPI DateFormatProviderTest
*/
import java.text.DateFormat;
import java.text.Format;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.stream.Stream;
import com.foo.DateFormatProviderImpl;
import sun.util.locale.provider.LocaleProviderAdapter;
import sun.util.locale.provider.ResourceBundleBasedAdapter;
public class DateFormatProviderTest extends ProviderTest {
DateFormatProviderImpl dfp = new DateFormatProviderImpl();
List<Locale> availloc = Arrays.asList(DateFormat.getAvailableLocales());
List<Locale> providerloc = Arrays.asList(dfp.getAvailableLocales());
List<Locale> jreloc = Stream.concat(
Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR).getAvailableLocales()),
Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.FALLBACK).getAvailableLocales())).toList();
List<Locale> jreimplloc = Stream.concat(
Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR).getDateFormatProvider().getAvailableLocales()),
Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.FALLBACK).getDateFormatProvider().getAvailableLocales())).toList();
public static void main(String[] s) {
new DateFormatProviderTest();
}
DateFormatProviderTest() {
availableLocalesTest();
objectValidityTest();
extendedVariantTest();
messageFormatTest();
}
void availableLocalesTest() {
Set<Locale> localesFromAPI = new HashSet<>(availloc);
Set<Locale> localesExpected = new HashSet<>(jreloc);
localesExpected.addAll(providerloc);
if (localesFromAPI.equals(localesExpected)) {
System.out.println("availableLocalesTest passed.");
} else {
throw new RuntimeException("availableLocalesTest failed");
}
}
void objectValidityTest() {
for (Locale target: availloc) {
// Get the key for the date/time patterns which is
// specific to each calendar system.
Calendar cal = Calendar.getInstance(target);
String dkey = "DatePatterns";
String tkey = "TimePatterns";
String dtkey = "DateTimePatterns";
var calType = cal.getCalendarType();
switch (calType) {
case "buddhist":
case "japanese":
dkey = calType + "." + dkey;
tkey = calType + "." + tkey;
break;
}
// pure JRE implementation
ResourceBundle rb = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR)).getLocaleData().getDateFormatData(target);
boolean jreSupportsLocale = jreimplloc.contains(target);
// JRE string arrays
String[] jreDatePatterns = null;
String[] jreTimePatterns = null;
String[] jreDateTimePatterns = null;
if (jreSupportsLocale) {
try {
jreDatePatterns = (String[])rb.getObject(dkey);
jreTimePatterns = (String[])rb.getObject(tkey);
jreDateTimePatterns = (String[])rb.getObject(dtkey);
} catch (MissingResourceException mre) {}
}
for (int style = DateFormat.FULL; style <= DateFormat.SHORT; style ++) {
// result object
DateFormat result = DateFormat.getDateTimeInstance(style, style, target);
// provider's object (if any)
DateFormat providersResult = null;
if (providerloc.contains(target)) {
providersResult = dfp.getDateTimeInstance(style, style, target);
}
// JRE's object (if any)
DateFormat jresResult = null;
if (jreSupportsLocale) {
Object[] dateTimeArgs = {jreTimePatterns[style],
jreDatePatterns[style]};
String pattern = MessageFormat.format(jreDateTimePatterns[style].replaceAll("'", "''"), dateTimeArgs);
jresResult = new SimpleDateFormat(pattern, target);
}
checkValidity(target, jresResult, providersResult, result, jreSupportsLocale);
}
}
}
// Check that fallback correctly occurs with locales with variant including '_'s
// This test assumes that the provider supports the ja_JP_osaka locale, and JRE does not.
void extendedVariantTest() {
Locale[] testlocs = {Locale.of("ja", "JP", "osaka_extended"),
Locale.of("ja", "JP", "osaka_extended_further"),
Locale.of("ja", "JP", "osaka_")};
for (Locale test: testlocs) {
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, test);
DateFormat provider = dfp.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, test);
if (!df.equals(provider)) {
throw new RuntimeException("variant fallback failed. test locale: "+test);
}
}
}
private static final String[] TYPES = {
"date",
"time"
};
private static final String[] MODIFIERS = {
"",
"short",
"medium", // Same as DEFAULT
"long",
"full"
};
void messageFormatTest() {
for (Locale target : providerloc) {
for (String type : TYPES) {
for (String modifier : MODIFIERS) {
String pattern, expected;
if (modifier.equals("")) {
pattern = String.format("%s={0,%s}", type, type);
} else {
pattern = String.format("%s={0,%s,%s}", type, type, modifier);
}
if (modifier.equals("medium")) {
// medium is default.
expected = String.format("%s={0,%s}", type, type);
} else {
expected = pattern;
}
MessageFormat mf = new MessageFormat(pattern, target);
Format[] fmts = mf.getFormats();
if (fmts[0] instanceof SimpleDateFormat) {
continue;
}
String toPattern = mf.toPattern();
if (!toPattern.equals(expected)) {
throw new RuntimeException("messageFormatTest: got '" + toPattern
+ "', expected '" + expected + "'");
}
}
}
}
}
}

View file

@ -0,0 +1,164 @@
/*
* Copyright (c) 2007, 2024, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4052440 7200341 8062588 8210406 8174269
* @summary DateFormatSymbolsProvider tests
* @library providersrc/foobarutils
* providersrc/fooprovider
* @modules java.base/sun.util.locale.provider
* java.base/sun.util.resources
* @build com.foobar.Utils
* com.foo.*
* @run main/othervm -Djava.locale.providers=CLDR,SPI DateFormatSymbolsProviderTest
*/
import java.text.DateFormatSymbols;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.stream.Stream;
import com.foo.DateFormatSymbolsProviderImpl;
import sun.util.locale.provider.LocaleProviderAdapter;
import sun.util.locale.provider.ResourceBundleBasedAdapter;
public class DateFormatSymbolsProviderTest extends ProviderTest {
DateFormatSymbolsProviderImpl dfsp = new DateFormatSymbolsProviderImpl();
List<Locale> availloc = Arrays.asList(DateFormatSymbols.getAvailableLocales());
List<Locale> providerloc = Arrays.asList(dfsp.getAvailableLocales());
List<Locale> jreloc = Stream.concat(
Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR).getAvailableLocales()),
Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.FALLBACK).getAvailableLocales())).toList();
List<Locale> jreimplloc = Stream.concat(
Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR).getDateFormatSymbolsProvider().getAvailableLocales()),
Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.FALLBACK).getDateFormatSymbolsProvider().getAvailableLocales())).toList();
public static void main(String[] s) {
new DateFormatSymbolsProviderTest();
}
DateFormatSymbolsProviderTest() {
availableLocalesTest();
objectValidityTest();
hashCodeTest();
}
void availableLocalesTest() {
Set<Locale> localesFromAPI = new HashSet<>(availloc);
Set<Locale> localesExpected = new HashSet<>(jreloc);
localesExpected.addAll(providerloc);
if (localesFromAPI.equals(localesExpected)) {
System.out.println("availableLocalesTest passed.");
} else {
throw new RuntimeException("availableLocalesTest failed");
}
}
void objectValidityTest() {
for (Locale target: availloc) {
// pure JRE implementation
ResourceBundle rb = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR)).getLocaleData().getDateFormatData(target);
boolean jreSupportsLocale = jreimplloc.contains(target);
// JRE string arrays
String[][] jres = new String[6][];
if (jreSupportsLocale) {
try {
jres[0] = (String[])rb.getObject("MonthNames");
jres[1] = (String[])rb.getObject("MonthAbbreviations");
jres[2] = (String[])rb.getObject("DayNames");
jres[3] = (String[])rb.getObject("DayAbbreviations");
jres[4] = (String[])rb.getObject("AmPmMarkers");
jres[5] = (String[])rb.getObject("Eras");
} catch (MissingResourceException mre) {}
}
// result object
DateFormatSymbols dfs = DateFormatSymbols.getInstance(target);
String[][] result = new String[6][];
result[0] = dfs.getMonths();
result[1] = dfs.getShortMonths();
// note that weekdays are 1-based
String[] tmp = dfs.getWeekdays();
result[2] = new String[7];
System.arraycopy(tmp, 1, result[2], 0, result[2].length);
tmp = dfs.getShortWeekdays();
result[3] = new String[7];
System.arraycopy(tmp, 1, result[3], 0, result[3].length);
result[4] = dfs.getAmPmStrings();
result[5] = dfs.getEras();
// provider's object (if any)
DateFormatSymbols providersDfs= null;
String[][] providers = new String[6][];
if (providerloc.contains(target)) {
providersDfs = dfsp.getInstance(target);
providers[0] = providersDfs.getMonths();
providers[1] = providersDfs.getShortMonths();
// note that weekdays are 1-based
tmp = dfs.getWeekdays();
providers[2] = new String[7];
System.arraycopy(tmp, 1, providers[2], 0, providers[2].length);
tmp = dfs.getShortWeekdays();
providers[3] = new String[7];
System.arraycopy(tmp, 1, providers[3], 0, providers[3].length);
providers[4] = providersDfs.getAmPmStrings();
providers[5] = providersDfs.getEras();
}
for (int i = 0; i < result.length; i ++) {
for (int j = 0; j < result[i].length; j++) {
String jresStr =
(jres[i] != null ? jres[i][j] : null);
String providersStr =
(providers[i] != null ? providers[i][j] : null);
String resultStr =
(result[i] != null ? result[i][j] : null);
checkValidity(target, jresStr, providersStr, resultStr, jreSupportsLocale);
}
}
}
}
// Bug 7200341.
void hashCodeTest() {
for (Locale target: availloc) {
// look for provider's object
DateFormatSymbols dfs = DateFormatSymbols.getInstance(target);
if (dfs.getClass().getSimpleName().equals("FooDateFormatSymbols")) {
// call its hashCode(). success if no ArrayIndexOutOfBoundsException is thrown.
dfs.hashCode();
break;
}
}
}
}

View file

@ -0,0 +1,115 @@
/*
* Copyright (c) 2007, 2024, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4052440 8062588 8210406 8174269
* @summary DecimalFormatSymbolsProvider tests
* @library providersrc/foobarutils
* providersrc/fooprovider
* @modules java.base/sun.util.locale.provider
* @build com.foobar.Utils
* com.foo.*
* @run main/othervm -Djava.locale.providers=CLDR,SPI DecimalFormatSymbolsProviderTest
*/
import java.text.DecimalFormatSymbols;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Stream;
import com.foo.DecimalFormatSymbolsProviderImpl;
import sun.util.locale.provider.LocaleProviderAdapter;
public class DecimalFormatSymbolsProviderTest extends ProviderTest {
DecimalFormatSymbolsProviderImpl dfsp = new DecimalFormatSymbolsProviderImpl();
List<Locale> availloc = Arrays.asList(DecimalFormatSymbols.getAvailableLocales());
List<Locale> providerloc = Arrays.asList(dfsp.getAvailableLocales());
List<Locale> jreloc = Stream.concat(
Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR).getAvailableLocales()),
Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.FALLBACK).getAvailableLocales())).toList();
List<Locale> jreimplloc = Stream.concat(
Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR).getDateFormatSymbolsProvider().getAvailableLocales()),
Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.FALLBACK).getDecimalFormatSymbolsProvider().getAvailableLocales())).toList();
public static void main(String[] s) {
new DecimalFormatSymbolsProviderTest();
}
DecimalFormatSymbolsProviderTest() {
availableLocalesTest();
objectValidityTest();
}
void availableLocalesTest() {
Set<Locale> localesFromAPI = new HashSet<>(availloc);
Set<Locale> localesExpected = new HashSet<>(jreloc);
localesExpected.addAll(providerloc);
if (localesFromAPI.equals(localesExpected)) {
System.out.println("availableLocalesTest passed.");
} else {
throw new RuntimeException("availableLocalesTest failed");
}
}
void objectValidityTest() {
for (Locale target: availloc) {
// pure JRE implementation
Object[] data = LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR).getLocaleResources(target).getDecimalFormatSymbolsData();
boolean jreSupportsLocale = jreimplloc.contains(target);
// JRE string arrays
String[] jres = new String[2];
if (jreSupportsLocale) {
String[] tmp = (String[]) data[0];
jres[0] = tmp[9]; // infinity
jres[1] = tmp[10]; // NaN
}
// result object
DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(target);
String[] result = new String[2];
result[0] = dfs.getInfinity();
result[1] = dfs.getNaN();
// provider's object (if any)
DecimalFormatSymbols providersDfs= null;
String[] providers = new String[2];
if (providerloc.contains(target)) {
providersDfs = dfsp.getInstance(target);
providers[0] = providersDfs.getInfinity();
providers[1] = providersDfs.getNaN();
}
for (int i = 0; i < result.length; i ++) {
checkValidity(target, jres[i], providers[i], result[i], jreSupportsLocale);
}
}
}
}

View file

@ -0,0 +1,140 @@
/*
* Copyright (c) 2007, 2024, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4052440 8062588 8210406 8174269
* @summary Generic tests for the pluggable locales feature
* @library providersrc/foobarutils
* providersrc/barprovider
* providersrc/fooprovider
* @modules java.base/sun.util.locale.provider
* @build com.foobar.Utils
* com.bar.*
* com.foo.*
* @run main/othervm -Djava.locale.providers=CLDR,SPI GenericTest
*/
import java.util.Arrays;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import com.bar.CalendarDataProviderImpl;
import com.bar.CalendarNameProviderImpl;
import com.bar.CurrencyNameProviderImpl;
import com.bar.CurrencyNameProviderImpl2;
import com.bar.GenericTimeZoneNameProviderImpl;
import com.bar.LocaleNameProviderImpl;
import com.bar.TimeZoneNameProviderImpl;
import com.foo.BreakIteratorProviderImpl;
import com.foo.CollatorProviderImpl;
import com.foo.DateFormatProviderImpl;
import com.foo.DateFormatSymbolsProviderImpl;
import com.foo.DecimalFormatSymbolsProviderImpl;
import com.foo.NumberFormatProviderImpl;
import sun.util.locale.provider.LocaleProviderAdapter;
public class GenericTest {
// test providers
BreakIteratorProviderImpl breakIP = new BreakIteratorProviderImpl();
CollatorProviderImpl collatorP = new CollatorProviderImpl();
DateFormatProviderImpl dateFP = new DateFormatProviderImpl();
DateFormatSymbolsProviderImpl dateFSP = new DateFormatSymbolsProviderImpl();
DecimalFormatSymbolsProviderImpl decimalFSP = new DecimalFormatSymbolsProviderImpl();
NumberFormatProviderImpl numberFP = new NumberFormatProviderImpl();
CurrencyNameProviderImpl currencyNP = new CurrencyNameProviderImpl();
CurrencyNameProviderImpl2 currencyNP2 = new CurrencyNameProviderImpl2();
LocaleNameProviderImpl localeNP = new LocaleNameProviderImpl();
TimeZoneNameProviderImpl tzNP = new TimeZoneNameProviderImpl();
GenericTimeZoneNameProviderImpl tzGenNP = new GenericTimeZoneNameProviderImpl();
CalendarDataProviderImpl calDataP = new CalendarDataProviderImpl();
CalendarNameProviderImpl calNameP = new CalendarNameProviderImpl();
public static void main(String[] s) {
new GenericTest();
}
GenericTest() {
availableLocalesTest();
localeFallbackTest();
}
/**
* Make sure that all the locales are available from the existing providers
*/
void availableLocalesTest() {
// Check that Locale.getAvailableLocales() returns the union of the CLDR/FALLBACK supported
// locales and providers' locales
HashSet<Locale> result =
new HashSet<>(Arrays.asList(Locale.getAvailableLocales()));
HashSet<Locale> expected =
new HashSet<>(Arrays.asList(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR).getAvailableLocales()));
expected.addAll(Arrays.asList(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.FALLBACK).getAvailableLocales()));
expected.addAll(Arrays.asList(breakIP.getAvailableLocales()));
expected.addAll(Arrays.asList(collatorP.getAvailableLocales()));
expected.addAll(Arrays.asList(dateFP.getAvailableLocales()));
expected.addAll(Arrays.asList(dateFSP.getAvailableLocales()));
expected.addAll(Arrays.asList(decimalFSP.getAvailableLocales()));
expected.addAll(Arrays.asList(numberFP.getAvailableLocales()));
expected.addAll(Arrays.asList(currencyNP.getAvailableLocales()));
expected.addAll(Arrays.asList(currencyNP2.getAvailableLocales()));
expected.addAll(Arrays.asList(localeNP.getAvailableLocales()));
expected.addAll(Arrays.asList(tzNP.getAvailableLocales()));
expected.addAll(Arrays.asList(tzGenNP.getAvailableLocales()));
expected.addAll(Arrays.asList(calDataP.getAvailableLocales()));
expected.addAll(Arrays.asList(calNameP.getAvailableLocales()));
if (!result.equals(expected)) {
throw new RuntimeException("Locale.getAvailableLocales() does not return the union of locales: diff="
+ getDiff(result, expected));
}
}
/**
* test with "xx_YY_ZZ", which is an example locale not contained
* in Locale.getAvailableLocales(). Fallback tests for supported locales
* are done in each xxxProviderTest test cases.
*/
void localeFallbackTest() {
Locale xx = Locale.of("xx");
Locale dispLocale = Locale.of("xx", "YY", "ZZ");
String xxname = xx.getDisplayLanguage(xx);
String expected = localeNP.getDisplayLanguage(xx.getLanguage(), dispLocale);
if (!xxname.equals(expected)) {
throw new RuntimeException("Locale fallback did not perform correctly. got: "+xxname+" expected: "+expected);
}
}
private static String getDiff(Set set1, Set set2) {
Set s1 = (Set)((HashSet)set1).clone();
s1.removeAll(set2);
Set s2 = (Set)((HashSet)set2).clone();
s2.removeAll(set1);
s2.addAll(s1);
return s2.toString();
}
}

View file

@ -0,0 +1,162 @@
/*
* Copyright (c) 2007, 2025, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4052440 8000273 8062588 8210406 8174269 8356040
* @summary LocaleNameProvider tests
* @library providersrc/foobarutils
* providersrc/barprovider
* @modules java.base/sun.util.locale.provider
* java.base/sun.util.resources
* @build com.foobar.Utils
* com.bar.*
* @run junit/othervm/timeout=960 -Djava.locale.providers=CLDR,SPI LocaleNameProviderTest
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import com.bar.LocaleNameProviderImpl;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import sun.util.locale.provider.LocaleProviderAdapter;
import sun.util.locale.provider.ResourceBundleBasedAdapter;
import sun.util.resources.OpenListResourceBundle;
public class LocaleNameProviderTest extends ProviderTest {
private static final LocaleNameProviderImpl LNP = new LocaleNameProviderImpl();
/*
* This is not an exhaustive test. Such a test would require iterating (1000x1000)+
* inputs. Instead, we check against Japanese lang locales which guarantees
* we will run into cases where the CLDR is not the preferred provider as the
* SPI has defined variants of the Japanese locale (E.g. osaka).
* See LocaleNameProviderImpl and LocaleNames ResourceBundle.
*/
@ParameterizedTest
@MethodSource
void checkAvailLocValidityTest(Locale target, Locale test, ResourceBundle rb,
boolean jreSupports, boolean spiSupports) {
// codes
String lang = test.getLanguage();
String ctry = test.getCountry();
String vrnt = test.getVariant();
// the localized name
String langresult = test.getDisplayLanguage(target);
String ctryresult = test.getDisplayCountry(target);
String vrntresult = test.getDisplayVariant(target);
// provider's name (if any)
String providerslang = null;
String providersctry = null;
String providersvrnt = null;
if (spiSupports) {
providerslang = LNP.getDisplayLanguage(lang, target);
providersctry = LNP.getDisplayCountry(ctry, target);
providersvrnt = LNP.getDisplayVariant(vrnt, target);
}
// JRE's name
String jreslang = null;
String jresctry = null;
String jresvrnt = null;
if (!lang.isEmpty()) {
try {
jreslang = rb.getString(lang);
} catch (MissingResourceException mre) {}
}
if (!ctry.isEmpty()) {
try {
jresctry = rb.getString(ctry);
} catch (MissingResourceException mre) {}
}
if (!vrnt.isEmpty()) {
try {
jresvrnt = rb.getString("%%"+vrnt);
} catch (MissingResourceException mre) {}
}
checkValidity(target, jreslang, providerslang, langresult,
jreSupports && jreslang != null);
checkValidity(target, jresctry, providersctry, ctryresult,
jreSupports && jresctry != null);
checkValidity(target, jresvrnt, providersvrnt, vrntresult,
jreSupports && jresvrnt != null);
}
public static List<Arguments> checkAvailLocValidityTest() {
var args = new ArrayList<Arguments>();
Locale[] availloc = Locale.availableLocales()
.filter(l -> l.getLanguage().equals("ja"))
.toArray(Locale[]::new);
List<Locale> jreimplloc = Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR)
.getLocaleNameProvider().getAvailableLocales())
.filter(l -> l.getLanguage().equals("ja"))
.toList();
List<Locale> providerloc = Arrays.asList(LNP.getAvailableLocales());
for (Locale target : availloc) {
// pure JRE implementation
OpenListResourceBundle rb = ((ResourceBundleBasedAdapter) LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR)).getLocaleData().getLocaleNames(target);
boolean jreSupportsTarget = jreimplloc.contains(target);
boolean providerSupportsTarget = providerloc.contains(target);
for (Locale test : availloc) {
args.add(Arguments.of(target, test, rb, jreSupportsTarget, providerSupportsTarget));
}
}
return args;
}
@Test
void variantFallbackTest() {
Locale YY = Locale.of("yy", "YY", "YYYY");
Locale YY_suffix = Locale.of("yy", "YY", "YYYY_suffix");
String retVrnt = null;
String message = "variantFallbackTest() succeeded.";
try {
YY.getDisplayVariant(YY_suffix);
message = "variantFallbackTest() failed. Either provider wasn't invoked, or invoked without suffix.";
} catch (RuntimeException re) {
retVrnt = re.getMessage();
if (YY_suffix.getVariant().equals(retVrnt)) {
System.out.println(message);
return;
}
message = "variantFallbackTest() failed. Returned variant: "+retVrnt;
}
throw new RuntimeException(message);
}
}

View file

@ -0,0 +1,227 @@
/*
* Copyright (c) 2007, 2024, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4052440 7003643 8062588 8210406 8174269
* @summary NumberFormatProvider tests
* @library providersrc/foobarutils
* providersrc/fooprovider
* @modules java.base/sun.util.locale.provider
* @build com.foobar.Utils
* com.foo.*
* @run main/othervm -Djava.locale.providers=CLDR,SPI NumberFormatProviderTest
*/
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Currency;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Stream;
import com.foo.FooNumberFormat;
import com.foo.NumberFormatProviderImpl;
import sun.util.locale.provider.LocaleProviderAdapter;
public class NumberFormatProviderTest extends ProviderTest {
NumberFormatProviderImpl nfp = new NumberFormatProviderImpl();
List<Locale> availloc = Arrays.asList(NumberFormat.getAvailableLocales());
List<Locale> providerloc = Arrays.asList(nfp.getAvailableLocales());
List<Locale> jreloc = Stream.concat(
Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR).getAvailableLocales()),
Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.FALLBACK).getAvailableLocales())).toList();
List<Locale> jreimplloc = Stream.concat(
Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR).getNumberFormatProvider().getAvailableLocales()),
Arrays.stream(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.FALLBACK).getNumberFormatProvider().getAvailableLocales())).toList();
public static void main(String[] s) {
new NumberFormatProviderTest();
}
NumberFormatProviderTest() {
availableLocalesTest();
objectValidityTest();
messageFormatTest();
}
void availableLocalesTest() {
Set<Locale> localesFromAPI = new HashSet<>(availloc);
Set<Locale> localesExpected = new HashSet<>(jreloc);
localesExpected.addAll(providerloc);
if (localesFromAPI.equals(localesExpected)) {
System.out.println("availableLocalesTest passed.");
} else {
throw new RuntimeException("availableLocalesTest failed");
}
}
void objectValidityTest() {
for (Locale target: availloc) {
boolean jreSupportsLocale = jreimplloc.contains(target);
// JRE string arrays
String[] jreNumberPatterns = null;
if (jreSupportsLocale) {
jreNumberPatterns = LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR).getLocaleResources(target).getNumberPatterns();
}
// result object
String resultCur = getPattern(NumberFormat.getCurrencyInstance(target));
String resultInt = getPattern(NumberFormat.getIntegerInstance(target));
String resultNum = getPattern(NumberFormat.getNumberInstance(target));
String resultPer = getPattern(NumberFormat.getPercentInstance(target));
// provider's object (if any)
String providersCur = null;
String providersInt = null;
String providersNum = null;
String providersPer = null;
if (providerloc.contains(target)) {
NumberFormat dfCur = nfp.getCurrencyInstance(target);
if (dfCur != null) {
providersCur = getPattern(dfCur);
}
NumberFormat dfInt = nfp.getIntegerInstance(target);
if (dfInt != null) {
providersInt = getPattern(dfInt);
}
NumberFormat dfNum = nfp.getNumberInstance(target);
if (dfNum != null) {
providersNum = getPattern(dfNum);
}
NumberFormat dfPer = nfp.getPercentInstance(target);
if (dfPer != null) {
providersPer = getPattern(dfPer);
}
}
// JRE's object (if any)
// note that this totally depends on the current implementation
String jresCur = null;
String jresInt = null;
String jresNum = null;
String jresPer = null;
if (jreSupportsLocale) {
DecimalFormat dfCur = new DecimalFormat(jreNumberPatterns[1],
DecimalFormatSymbols.getInstance(target));
if (dfCur != null) {
adjustForCurrencyDefaultFractionDigits(dfCur);
jresCur = dfCur.toPattern();
}
DecimalFormat dfInt = new DecimalFormat(jreNumberPatterns[0],
DecimalFormatSymbols.getInstance(target));
if (dfInt != null) {
dfInt.setMaximumFractionDigits(0);
dfInt.setDecimalSeparatorAlwaysShown(false);
dfInt.setParseIntegerOnly(true);
jresInt = dfInt.toPattern();
}
DecimalFormat dfNum = new DecimalFormat(jreNumberPatterns[0],
DecimalFormatSymbols.getInstance(target));
if (dfNum != null) {
jresNum = dfNum.toPattern();
}
DecimalFormat dfPer = new DecimalFormat(jreNumberPatterns[2],
DecimalFormatSymbols.getInstance(target));
if (dfPer != null) {
jresPer = dfPer.toPattern();
}
}
checkValidity(target, jresCur, providersCur, resultCur, jreSupportsLocale);
checkValidity(target, jresInt, providersInt, resultInt, jreSupportsLocale);
checkValidity(target, jresNum, providersNum, resultNum, jreSupportsLocale);
checkValidity(target, jresPer, providersPer, resultPer, jreSupportsLocale);
}
}
/**
* Adjusts the minimum and maximum fraction digits to values that
* are reasonable for the currency's default fraction digits.
*/
void adjustForCurrencyDefaultFractionDigits(DecimalFormat df) {
DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();
Currency currency = dfs.getCurrency();
if (currency == null) {
try {
currency = Currency.getInstance(dfs.getInternationalCurrencySymbol());
} catch (IllegalArgumentException e) {
}
}
if (currency != null) {
int digits = currency.getDefaultFractionDigits();
if (digits != -1) {
int oldMinDigits = df.getMinimumFractionDigits();
// Common patterns are "#.##", "#.00", "#".
// Try to adjust all of them in a reasonable way.
if (oldMinDigits == df.getMaximumFractionDigits()) {
df.setMinimumFractionDigits(digits);
df.setMaximumFractionDigits(digits);
} else {
df.setMinimumFractionDigits(Math.min(digits, oldMinDigits));
df.setMaximumFractionDigits(digits);
}
}
}
}
private static String getPattern(NumberFormat nf) {
if (nf instanceof DecimalFormat) {
return ((DecimalFormat)nf).toPattern();
}
if (nf instanceof FooNumberFormat) {
return ((FooNumberFormat)nf).toPattern();
}
return null;
}
private static final String[] NUMBER_PATTERNS = {
"num={0,number}",
"num={0,number,currency}",
"num={0,number,percent}",
"num={0,number,integer}"
};
void messageFormatTest() {
for (Locale target : providerloc) {
for (String pattern : NUMBER_PATTERNS) {
MessageFormat mf = new MessageFormat(pattern, target);
String toPattern = mf.toPattern();
if (!pattern.equals(toPattern)) {
throw new RuntimeException("MessageFormat.toPattern: got '"
+ toPattern
+ "', expected '" + pattern + "'");
}
}
}
}
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2007, 2012, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
*/
import java.text.*;
import java.util.*;
import sun.util.locale.provider.*;
public class ProviderTest {
void checkValidity(Locale target, Object jres, Object providers, Object result, boolean jresPreferred) {
if (jresPreferred) {
if ((result==null && jres!=null) || !result.equals(jres)) {
throw new RuntimeException(
"result do not match with jre's result. target: "+target+" result: "+result+" jre's: "+jres);
}
} else {
if (providers!=null && !result.equals(providers)) {
throw new RuntimeException(
"result do not match with provider's result. target: "+target+" result: "+result+" providers: "+providers);
}
}
System.out.println("checkValidity succeeded. target: "+target+" result: "+result+" jre's: "+jres+" providers: "+providers+" jre-preferred: "+jresPreferred);
}
}

View file

@ -0,0 +1,76 @@
/*
* Copyright (c) 2012, 2022, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 7168528
* @summary Test the default implementation of LocaleServiceProvider.isSupportedLocale.
*/
import java.util.*;
import java.util.spi.LocaleServiceProvider;
public class SupportedLocalesTest {
private static final Locale[] GOOD_ONES = {
Locale.forLanguageTag("ja-JP-x-lvariant-JP"),
Locale.forLanguageTag("th-TH-x-lvariant-TH"),
Locale.US,
};
private static final Locale[] BAD_ONES = {
Locale.GERMAN,
Locale.GERMANY,
Locale.CANADA,
Locale.TAIWAN,
};
public static void main(String[] args) {
LocaleServiceProvider provider = new TestLocaleServiceProvider();
List<Locale> locs = new ArrayList<>();
locs.addAll(Arrays.asList(GOOD_ONES));
locs.addAll(Arrays.asList(provider.getAvailableLocales()));
for (Locale locale : locs) {
if (!provider.isSupportedLocale(locale)) {
throw new RuntimeException(locale + " is NOT supported.");
}
}
for (Locale locale : BAD_ONES) {
if (provider.isSupportedLocale(locale)) {
throw new RuntimeException(locale + " should NOT be supported.");
}
}
}
private static class TestLocaleServiceProvider extends LocaleServiceProvider {
private static final Locale[] locales = {
Locale.of("ja", "JP", "JP"),
Locale.of("th", "TH", "TH"),
Locale.forLanguageTag("en-US-u-ca-buddhist"),
};
@Override
public Locale[] getAvailableLocales() {
return locales.clone();
}
}
}

View file

@ -0,0 +1,252 @@
/*
* Copyright (c) 2007, 2025, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4052440 8003267 8062588 8210406 8174269 8327434 8347841 8347955
* @summary TimeZoneNameProvider tests
* @library providersrc/foobarutils
* providersrc/barprovider
* @modules java.base/sun.util.locale.provider
* java.base/sun.util.resources
* @build com.foobar.Utils
* com.bar.*
* @run main/othervm -Djava.locale.providers=CLDR,SPI TimeZoneNameProviderTest
*/
import java.text.DateFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.time.format.TextStyle;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.TimeZone;
import java.util.function.Predicate;
import java.util.stream.Stream;
import com.bar.TimeZoneNameProviderImpl;
import sun.util.locale.provider.LocaleProviderAdapter;
import sun.util.locale.provider.ResourceBundleBasedAdapter;
import sun.util.resources.OpenListResourceBundle;
public class TimeZoneNameProviderTest extends ProviderTest {
TimeZoneNameProviderImpl tznp = new TimeZoneNameProviderImpl();
public static void main(String[] s) {
new TimeZoneNameProviderTest();
}
TimeZoneNameProviderTest() {
test1();
test2();
test3();
aliasTest();
genericFallbackTest();
}
void test1() {
List<Locale> jreimplloc = Arrays.asList(LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR).getTimeZoneNameProvider().getAvailableLocales());
List<Locale> providerLocales = Arrays.asList(tznp.getAvailableLocales());
String[] ids = TimeZone.availableIDs()
.filter(Predicate.not(ZoneId.SHORT_IDS::containsKey))
.toArray(String[]::new);
// Sampling relevant locales
Stream.concat(Stream.of(Locale.ROOT, Locale.US, Locale.JAPAN), providerLocales.stream()).forEach(target -> {
// pure JRE implementation
OpenListResourceBundle rb = ((ResourceBundleBasedAdapter)LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR)).getLocaleData().getTimeZoneNames(target);
boolean jreSupportsTarget = jreimplloc.contains(target);
for (String id: ids) {
// the time zone
TimeZone tz = TimeZone.getTimeZone(id);
// JRE string array for the id
String[] jrearray = null;
if (jreSupportsTarget) {
try {
jrearray = rb.getStringArray(id);
} catch (MissingResourceException mre) {}
}
for (int i = 1; i <=(tz.useDaylightTime()?4:2); i++) {
// the localized name
String name = tz.getDisplayName(i>=3, i%2, target);
// provider's name (if any)
String providersname = null;
if (providerLocales.contains(target)) {
providersname = tznp.getDisplayName(id, i>=3, i%2, target);
}
// JRE's name
String jresname = null;
if (jrearray != null && !jrearray[i].isEmpty() && !jrearray[i].equals("\u2205\u2205\u2205")) {
jresname = jrearray[i];
}
checkValidity(target, jresname, providersname, name,
jreSupportsTarget && jresname != null);
}
}
});
}
final String pattern = "z";
final Locale OSAKA = Locale.of("ja", "JP", "osaka");
final Locale KYOTO = Locale.of("ja", "JP", "kyoto");
final Locale GENERIC = Locale.of("ja", "JP", "generic");
final String[] TIMEZONES = {
"GMT", "America/Los_Angeles", "SystemV/PST8",
"SystemV/PST8PDT", "PST8PDT",
};
final String[] DISPLAY_NAMES_OSAKA = {
tznp.getDisplayName(TIMEZONES[0], false, TimeZone.SHORT, OSAKA),
tznp.getDisplayName(TIMEZONES[1], false, TimeZone.SHORT, OSAKA),
tznp.getDisplayName(TIMEZONES[2], false, TimeZone.SHORT, OSAKA),
tznp.getDisplayName(TIMEZONES[3], false, TimeZone.SHORT, OSAKA),
tznp.getDisplayName(TIMEZONES[4], false, TimeZone.SHORT, OSAKA)
};
final String[] DISPLAY_NAMES_KYOTO = {
tznp.getDisplayName(TIMEZONES[0], false, TimeZone.SHORT, KYOTO),
tznp.getDisplayName(TIMEZONES[1], false, TimeZone.SHORT, KYOTO),
tznp.getDisplayName(TIMEZONES[2], false, TimeZone.SHORT, KYOTO),
tznp.getDisplayName(TIMEZONES[3], false, TimeZone.SHORT, KYOTO),
tznp.getDisplayName(TIMEZONES[4], false, TimeZone.SHORT, KYOTO)
};
void test2() {
Locale defaultLocale = Locale.getDefault();
TimeZone reservedTimeZone = TimeZone.getDefault();
Date d = new Date(2005-1900, Calendar.DECEMBER, 22);
String formatted;
TimeZone tz;
SimpleDateFormat df;
try {
for (int i = 0; i < TIMEZONES.length; i++) {
tz = TimeZone.getTimeZone(TIMEZONES[i]);
TimeZone.setDefault(tz);
df = new SimpleDateFormat(pattern, DateFormatSymbols.getInstance(OSAKA));
Locale.setDefault(defaultLocale);
System.out.println(formatted = df.format(d));
if(!formatted.equals(DISPLAY_NAMES_OSAKA[i])) {
throw new RuntimeException("TimeZone " + TIMEZONES[i] +
": formatted zone names mismatch. " +
formatted + " should match with " +
DISPLAY_NAMES_OSAKA[i]);
}
df.parse(DISPLAY_NAMES_OSAKA[i]);
Locale.setDefault(KYOTO);
df = new SimpleDateFormat(pattern, DateFormatSymbols.getInstance());
System.out.println(formatted = df.format(d));
if(!formatted.equals(DISPLAY_NAMES_KYOTO[i])) {
throw new RuntimeException("Timezone " + TIMEZONES[i] +
": formatted zone names mismatch. " +
formatted + " should match with " +
DISPLAY_NAMES_KYOTO[i]);
}
df.parse(DISPLAY_NAMES_KYOTO[i]);
}
} catch (ParseException pe) {
throw new RuntimeException("parse error occurred" + pe);
} finally {
// restore the reserved locale and time zone
Locale.setDefault(defaultLocale);
TimeZone.setDefault(reservedTimeZone);
}
}
void test3() {
final String[] TZNAMES = {
LATIME, PST8PDT, US_PACIFIC,
TOKYOTIME, JAPAN,
};
for (String tzname : TZNAMES) {
TimeZone tz = TimeZone.getTimeZone(tzname);
for (int style : new int[] { TimeZone.LONG, TimeZone.SHORT }) {
String osakaStd = tz.getDisplayName(false, style, OSAKA);
if (osakaStd != null) {
String generic = tz.toZoneId().getDisplayName(
style == TimeZone.LONG ? TextStyle.FULL : TextStyle.SHORT,
GENERIC);
String expected = "Generic " + osakaStd;
if (!expected.equals(generic)) {
throw new RuntimeException("Wrong generic name: got=\"" + generic
+ "\", expected=\"" + expected + "\"");
}
}
}
}
}
final String LATIME = "America/Los_Angeles";
final String PST8PDT = "PST8PDT";
final String US_PACIFIC = "US/Pacific";
final String LATIME_IN_OSAKA =
tznp.getDisplayName(LATIME, false, TimeZone.LONG, OSAKA);
final String TOKYOTIME = "Asia/Tokyo";
final String JAPAN = "Japan";
void aliasTest() {
// Check that provider's name for a standard id (America/Los_Angeles) is
// propagated to its aliases
String latime = TimeZone.getTimeZone(LATIME).getDisplayName(OSAKA);
if (!LATIME_IN_OSAKA.equals(latime)) {
throw new RuntimeException("Could not get provider's localized name. result: "+latime+" expected: "+LATIME_IN_OSAKA);
}
String us_pacific = TimeZone.getTimeZone(US_PACIFIC).getDisplayName(OSAKA);
if (!LATIME_IN_OSAKA.equals(us_pacific)) {
throw new RuntimeException("Provider's localized name is not available for an alias ID: "+US_PACIFIC+". result: "+us_pacific+" expected: "+LATIME_IN_OSAKA);
}
}
/*
* Tests whether generic names can be retrieved through fallback.
* The test assumes the provider impl for OSAKA locale does NOT
* provide generic names.
*/
final String PT = "PT"; // SHORT generic name for "America/Los_Angeles"
void genericFallbackTest() {
String generic =
TimeZone.getTimeZone(LATIME)
.toZoneId()
.getDisplayName(TextStyle.SHORT, OSAKA);
if (!PT.equals(generic)) {
throw new RuntimeException("Generic name fallback failed. got: "+generic);
}
}
}

View file

@ -0,0 +1,7 @@
#
#
#
# fully-qualified name of the java.util.spi.CalendarDataProvider
# implementation class
#
com.bar.CalendarDataProviderImpl

View file

@ -0,0 +1,7 @@
#
#
#
# fully-qualified name of the java.util.spi.CalendarNameProvider
# implementation class
#
com.bar.CalendarNameProviderImpl

View file

@ -0,0 +1,8 @@
#
#
#
# fully-qualified name of the java.util.spi.LocaleNameProvider
# implementation class
#
com.bar.CurrencyNameProviderImpl
com.bar.CurrencyNameProviderImpl2

View file

@ -0,0 +1,7 @@
#
#
#
# fully-qualified name of the java.util.spi.LocaleNameProvider
# implementation class
#
com.bar.LocaleNameProviderImpl

View file

@ -0,0 +1,8 @@
#
#
#
# fully-qualified name of the java.util.spi.TimeZoneNameProvider
# implementation class
#
com.bar.TimeZoneNameProviderImpl
com.bar.GenericTimeZoneNameProviderImpl

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2012, 2022, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.bar;
import com.foobar.Utils;
import java.util.Arrays;
import static java.util.Calendar.*;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.spi.CalendarDataProvider;
public class CalendarDataProviderImpl extends CalendarDataProvider {
static final char FULLWIDTH_ZERO = '\uff10';
static final Locale[] avail = {
Locale.of("ja", "JP", "kids"),
};
@Override
public int getFirstDayOfWeek(Locale locale) {
return WEDNESDAY;
}
@Override
public int getMinimalDaysInFirstWeek(Locale locale) {
return 7;
}
@Override
public Locale[] getAvailableLocales() {
return avail.clone();
}
}

View file

@ -0,0 +1,102 @@
/*
* Copyright (c) 2012, 2022, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.bar;
import com.foobar.Utils;
import java.util.Arrays;
import static java.util.Calendar.*;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.spi.CalendarNameProvider;
public class CalendarNameProviderImpl extends CalendarNameProvider {
static final char FULLWIDTH_ZERO = '\uff10';
static final Locale[] avail = {
Locale.of("ja", "JP", "kids"),
};
@Override
public String getDisplayName(String calendarType, int field, int value, int style, Locale locale) {
if (calendarType == null || locale == null) {
throw new NullPointerException();
}
if (!Utils.supportsLocale(Arrays.asList(avail), locale)) {
throw new IllegalArgumentException("locale is not one of available locales: "+ locale);
}
if (field != MONTH) {
return null;
}
return toMonthName(value + 1, style);
}
@Override
public Map<String, Integer> getDisplayNames(String calendarType, int field, int style, Locale locale) {
if (calendarType == null || locale == null) {
throw new NullPointerException();
}
if (!Utils.supportsLocale(Arrays.asList(avail), locale)) {
throw new IllegalArgumentException("locale is not one of available locales: " + locale);
}
if (field != MONTH) {
return null;
}
Map<String, Integer> map = new HashMap<>();
if (style == LONG_STANDALONE) {
style = LONG;
} else if (style == SHORT_STANDALONE) {
style = SHORT;
}
for (int month = JANUARY; month <= DECEMBER; month++) {
if (style == ALL_STYLES || style == LONG) {
map.put(toMonthName(month + 1, LONG), month);
}
if (style == ALL_STYLES || style == SHORT) {
map.put(toMonthName(month + 1, SHORT), month);
}
}
return map;
}
@Override
public Locale[] getAvailableLocales() {
return avail.clone();
}
// month is 1-based.
public static String toMonthName(int month, int style) {
StringBuilder sb = new StringBuilder();
if (month >= 10) {
sb.append((char)(FULLWIDTH_ZERO + 1));
sb.appendCodePoint((char)(FULLWIDTH_ZERO + (month % 10)));
} else {
sb.appendCodePoint((char)(FULLWIDTH_ZERO + month));
}
if (style == SHORT || style == SHORT_STANDALONE) {
return sb.toString(); // full-width digit(s)
}
sb.append("\u304c\u3064"); // + "gatsu" in Hiragana
return sb.toString();
}
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2007, 2022, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
*/
package com.bar;
import java.util.*;
import java.util.spi.*;
import com.foobar.Utils;
public class CurrencyNameProviderImpl extends CurrencyNameProvider {
static Locale[] avail = {Locale.of("ja", "JP", "osaka"),
Locale.of("ja", "JP", "kyoto"),
Locale.JAPAN,
Locale.of("xx")};
public Locale[] getAvailableLocales() {
return avail;
}
public String getSymbol(String c, Locale locale) {
if (!Utils.supportsLocale(Arrays.asList(avail), locale)) {
throw new IllegalArgumentException("locale is not supported: "+locale);
}
if (c.equals("JPY")) {
if (Utils.supportsLocale(avail[0], locale)) {
return "\u5186\u3084\u3002";
} else if (Utils.supportsLocale(avail[1], locale)) {
return "\u5186\u3069\u3059\u3002";
} else if (Utils.supportsLocale(avail[2], locale)) {
return "\u5186\u3067\u3059\u3002";
} else if (Utils.supportsLocale(avail[3], locale)) {
return "\u5186\u3070\u3064\u3070\u3064\u3002";
}
}
return null;
}
@Override
public String getDisplayName(String c, Locale locale) {
if (!Utils.supportsLocale(Arrays.asList(avail), locale)) {
throw new IllegalArgumentException("locale is not supported: "+locale);
}
if (c.equals("JPY")) {
if (Utils.supportsLocale(avail[0], locale)) {
return "\u65e5\u672c\u5186\u3084\u3002";
} else if (Utils.supportsLocale(avail[1], locale)) {
return "\u65e5\u672c\u5186\u3069\u3059\u3002";
} else if (Utils.supportsLocale(avail[2], locale)) {
return "\u65e5\u672c\u5186\u3067\u3059\u3002";
} else if (Utils.supportsLocale(avail[3], locale)) {
return "\u65e5\u672c\u5186\u3070\u3064\u3070\u3064\u3002";
}
}
return null;
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2012, 2022, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
*/
package com.bar;
import java.util.*;
import java.util.spi.*;
import com.foobar.Utils;
public class CurrencyNameProviderImpl2 extends CurrencyNameProvider {
static Locale[] avail = {Locale.of("ja", "JP", "tokyo"),
Locale.of("ja", "JP", "osaka"), };
public Locale[] getAvailableLocales() {
return avail;
}
@Override
public String getSymbol(String c, Locale locale) {
if (!Utils.supportsLocale(Arrays.asList(avail), locale)) {
throw new IllegalArgumentException("locale is not supported: "+locale);
}
if (c.equals("JPY")) {
if (Utils.supportsLocale(avail[0], locale)) {
return "JPY-tokyo";
} else if (Utils.supportsLocale(avail[1], locale)) {
return "JPY-osaka";
}
}
return null;
}
@Override
public String getDisplayName(String c, Locale locale) {
if (!Utils.supportsLocale(Arrays.asList(avail), locale)) {
throw new IllegalArgumentException("locale is not supported: "+locale);
}
if (c.equals("JPY")) {
if (Utils.supportsLocale(avail[0], locale)) {
return "JPY-tokyo";
} else if (Utils.supportsLocale(avail[1], locale)) {
return "JPY-osaka";
}
}
return null;
}
}

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2012, 2022, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
*/
package com.bar;
import java.util.*;
import java.util.spi.*;
import com.foobar.Utils;
/**
* Implementation class for getGenericTimeZoneName which returns "Generic "+<standard name in OSAKA>.
*/
public class GenericTimeZoneNameProviderImpl extends TimeZoneNameProviderImpl {
static final Locale jaJPGeneric = Locale.of("ja", "JP", "generic");
static final Locale OSAKA = Locale.of("ja", "JP", "osaka");
static Locale[] avail = {
jaJPGeneric
};
@Override
public Locale[] getAvailableLocales() {
return avail;
}
@Override
public String getGenericDisplayName(String id, int style, Locale locale) {
if (!jaJPGeneric.equals(locale)) {
return null;
}
String std = super.getDisplayName(id, false, style, OSAKA);
return (std != null) ? "Generic " + std : null;
}
}

View file

@ -0,0 +1,100 @@
/*
* Copyright (c) 2007, 2022, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
*/
package com.bar;
import java.text.*;
import java.util.*;
import java.util.spi.*;
import com.foobar.Utils;
public class LocaleNameProviderImpl extends LocaleNameProvider {
static Locale[] avail = {Locale.JAPANESE,
Locale.JAPAN,
Locale.of("ja", "JP", "osaka"),
Locale.of("ja", "JP", "kyoto"),
Locale.of("xx"),
Locale.of("yy", "YY", "YYYY")};
static List<Locale> availList = Arrays.asList(avail);
public Locale[] getAvailableLocales() {
return avail;
}
@Override
public String getDisplayLanguage(String lang, Locale target) {
return getDisplayString(lang, target);
}
@Override
public String getDisplayCountry(String ctry, Locale target) {
return getDisplayString(ctry, target);
}
@Override
public String getDisplayVariant(String vrnt, Locale target) {
return getDisplayString(vrnt, target);
}
private String getDisplayString(String key, Locale target) {
if (!Utils.supportsLocale(availList, target)) {
throw new IllegalArgumentException("locale is not supported: "+target);
}
String ret = null;
if (target.getLanguage().equals("yy") &&
target.getCountry().equals("YY")) {
String vrnt = target.getVariant();
if (vrnt.startsWith("YYYY")) {
switch (key) {
case "yy":
case "YY":
ret = "waiwai";
break;
case "YYYY":
if (vrnt.equals("YYYY_suffix")) {
// for LocaleNameProviderTest.variantFallbackTest()
throw new RuntimeException(vrnt);
} else {
ret = "waiwai";
}
break;
}
}
} else {
// resource bundle based (allows fallback)
try {
ResourceBundle rb = ResourceBundle.getBundle("com.bar.LocaleNames", target);
ret = rb.getString(key);
} catch (MissingResourceException mre) {
}
}
return ret;
}
}

View file

@ -0,0 +1,25 @@
#
# Copyright (c) 2007, 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
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
osaka=Osaka
kyoto=Kyoto
xx=batsubatsu

View file

@ -0,0 +1,30 @@
#
# Copyright (c) 2007, 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
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
ja=日本語です。
JP=日本です。
#
# added ones
#
osaka=大阪です。
kyoto=京都です。
xx=ばつばつです。

View file

@ -0,0 +1,28 @@
#
# Copyright (c) 2007, 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
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
ja=日本語どす。
JP=日本どす。
#
osaka=大阪どす。
kyoto=京都どす。
xx=ぺけぺけどす。

View file

@ -0,0 +1,28 @@
#
# Copyright (c) 2007, 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
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
ja=祖国語や。
JP=やまとや。
#
osaka=大阪や。
kyoto=京都や。
xx=ぺけぺけや。

View file

@ -0,0 +1,23 @@
#
# Copyright (c) 2007, 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
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
xx=batsubatsu

View file

@ -0,0 +1,150 @@
/*
* Copyright (c) 2007, 2022, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
*/
package com.bar;
import java.util.*;
import java.util.spi.*;
import com.foobar.Utils;
public class TimeZoneNameProviderImpl extends TimeZoneNameProvider {
static Locale[] avail = {Locale.of("ja", "JP", "osaka"),
Locale.of("ja", "JP", "kyoto"),
Locale.of("xx"),
Locale.JAPAN};
static String[][] zoneOsaka = {
{"GMT",
"\u30b0_\u30ea_\u30cb_\u30c3_\u30b8_\u6a19_\u6e96_\u6642_\u3084_\u3002",
"G_M_T_\u3084_\u3002",
"\u30b0_\u30ea_\u30cb_\u30c3_\u30b8_\u6a19_\u6e96_\u6642_\u3084_\u3002",
"G_M_T_\u3084_\u3002"},
{"JST",
"\u3084_\u307e_\u3068_\u6a19_\u6e96_\u6642_\u3084_\u3002",
"J_S_T_\u3084_\u3002",
"\u3084_\u307e_\u3068_\u6a19_\u6e96_\u6642_\u3084_\u3002",
"J_S_T_\u3084_\u3002"},
{"America/Los_Angeles",
"\u592a_\u5e73_\u6d0b_\u6a19_\u6e96_\u6642_\u3084_\u3002",
"P_S_T_\u3084_\u3002",
"\u592a_\u5e73_\u6d0b_\u590f_\u6642_\u9593_\u3084_\u3002",
"P_D_T_\u3084_\u3002"},
{"SystemV/PST8",
"\u592a_\u5e73_\u6d0b_\u6a19_\u6e96_\u6642_\u3084_\u3002",
"P_S_T_\u3084_\u3002",
"\u592a_\u5e73_\u6d0b_\u590f_\u6642_\u9593_\u3084_\u3002",
"P_D_T_\u3084_\u3002"},
{"SystemV/PST8PDT",
"\u592a_\u5e73_\u6d0b_\u6a19_\u6e96_\u6642_\u3084_\u3002",
"P_S_T_\u3084_\u3002",
"\u592a_\u5e73_\u6d0b_\u590f_\u6642_\u9593_\u3084_\u3002",
"P_D_T_\u3084_\u3002"},
{"PST8PDT",
"\u592a_\u5e73_\u6d0b_\u6a19_\u6e96_\u6642_\u3084_\u3002",
"P_S_T_\u3084_\u3002",
"\u592a_\u5e73_\u6d0b_\u590f_\u6642_\u9593_\u3084_\u3002",
"P_D_T_\u3084_\u3002"},
};
static String[][] zoneKyoto = {
{"GMT",
"\u30b0_\u30ea_\u30cb_\u30c3_\u30b8_\u6a19_\u6e96_\u6642_\u3069_\u3059_\u3002",
"G_M_T_\u3069_\u3059_\u3002",
"\u30b0_\u30ea_\u30cb_\u30c3_\u30b8_\u6a19_\u6e96_\u6642_\u3069_\u3059_\u3002",
"G_M_T_\u3069_\u3059_\u3002"},
{"America/Los_Angeles",
"\u592a_\u5e73_\u6d0b_\u6a19_\u6e96_\u6642_\u3069_\u3059_\u3002",
"P_S_T_\u3069_\u3059_\u3002",
"\u592a_\u5e73_\u6d0b_\u590f_\u6642_\u9593_\u3069_\u3059_\u3002",
"P_D_T_\u3069_\u3059_\u3002"},
{"SystemV/PST8",
"\u592a_\u5e73_\u6d0b_\u6a19_\u6e96_\u6642_\u3069_\u3059_\u3002",
"P_S_T_\u3069_\u3059_\u3002",
"\u592a_\u5e73_\u6d0b_\u590f_\u6642_\u9593_\u3069_\u3059_\u3002",
"P_D_T_\u3069_\u3059_\u3002"},
{"SystemV/PST8PDT",
"\u592a_\u5e73_\u6d0b_\u6a19_\u6e96_\u6642_\u3069_\u3059_\u3002",
"P_S_T_\u3069_\u3059_\u3002",
"\u592a_\u5e73_\u6d0b_\u590f_\u6642_\u9593_\u3069_\u3059_\u3002",
"P_D_T_\u3069_\u3059_\u3002"},
{"PST8PDT",
"\u592a_\u5e73_\u6d0b_\u6a19_\u6e96_\u6642_\u3069_\u3059_\u3002",
"P_S_T_\u3069_\u3059_\u3002",
"\u592a_\u5e73_\u6d0b_\u590f_\u6642_\u9593_\u3069_\u3059_\u3002",
"P_D_T_\u3069_\u3059_\u3002"},
};
static String[][] zoneXX = {
{"GMT",
"\u30b0_\u30ea_\u30cb_\u30c3_\u30b8_\u6a19_\u6e96_\u6642\u3070\u3064\u3070\u3064\u3002",
"G_M_T_\u3070\u3064\u3070\u3064\u3002",
"\u30b0_\u30ea_\u30cb_\u30c3_\u30b8_\u6a19_\u6e96_\u6642\u3070\u3064\u3070\u3064\u3002",
"G_M_T_\u3070\u3064\u3070\u3064\u3002"},
{"America/Los_Angeles",
"\u592a_\u5e73_\u6d0b_\u6a19_\u6e96_\u6642_\u3070\u3064\u3070\u3064\u3002",
"P_S_T_\u3070\u3064\u3070\u3064\u3002",
"\u592a_\u5e73_\u6d0b_\u590f_\u6642_\u9593_\u3070\u3064\u3070\u3064\u3002",
"P_D_T_\u3070\u3064\u3070\u3064\u3002"}};
static String[][] zoneJaJP = {
{"GMT",
"\u30b0_\u30ea_\u30cb_\u30c3_\u30b8_\u6a19_\u6e96_\u6642_\u3067_\u3059_\u3002",
"G_M_T_\u3067_\u3059_\u3002",
"\u30b0_\u30ea_\u30cb_\u30c3_\u30b8_\u6a19_\u6e96_\u6642_\u3067_\u3059_\u3002",
"G_M_T_\u3067_\u3059_\u3002"},
{"America/Los_Angeles",
"\u30b0_\u30ea_\u30cb_\u30c3_\u30b8_\u6a19_\u6e96_\u6642_\u3067_\u3059_\u3002",
"P_S_T_\u3067_\u3059_\u3002",
"\u592a_\u5e73_\u6d0b_\u590f_\u6642_\u9593_\u3067_\u3059_\u3002",
"P_D_T_\u3067_\u3059_\u3002"}};
static String[][][] names = {zoneOsaka, zoneKyoto, zoneXX, zoneJaJP};
public Locale[] getAvailableLocales() {
return avail;
}
public String getDisplayName(String id, boolean dst, int style, Locale language) {
if (!Utils.supportsLocale(Arrays.asList(avail), language)) {
throw new IllegalArgumentException("locale is not one of available locales: "+language);
}
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], language)) {
String[][] namesForALocale = names[i];
for (int j = 0; j < namesForALocale.length; j++) {
String[] array = namesForALocale[j];
if (id.equals(array[0])) {
String ret = array[(style==TimeZone.LONG?0:1)+(dst?2:0)+1];
return ret;
}
}
}
}
return null;
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2007, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
*/
package com.foobar;
import java.util.*;
public class Utils {
public static boolean supportsLocale(Locale supported, Locale requested) {
if (supported.getLanguage() == "") {
return true;
} else if (supported.getLanguage() != requested.getLanguage()) {
return false;
}
if (supported.getCountry() == "") {
return true;
} else if (supported.getCountry() != requested.getCountry()) {
return false;
}
String supVar = supported.getVariant();
String reqVar = requested.getVariant();
if (supVar == "") {
return true;
} else {
int underIndex;
while ((underIndex = reqVar.lastIndexOf('_')) != (-1)) {
reqVar = reqVar.substring(0, underIndex);
if (supVar.equals(reqVar)) {
return true;
}
}
return supVar.equals(reqVar);
}
}
public static boolean supportsLocale(List<Locale> supported, Locale requested) {
for (Locale l : supported) {
if (supportsLocale(l, requested)) {
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,7 @@
#
#
#
# fully-qualified name of the java.text.spi.BreakIteratorProvider
# implementation class
#
com.foo.BreakIteratorProviderImpl

View file

@ -0,0 +1,7 @@
#
#
#
# fully-qualified name of the java.text.spi.CollatorProvider
# implementation class
#
com.foo.CollatorProviderImpl

View file

@ -0,0 +1,7 @@
#
#
#
# fully-qualified name of the java.text.spi.DateFormatProvider
# implementation class
#
com.foo.DateFormatProviderImpl

View file

@ -0,0 +1,7 @@
#
#
#
# fully-qualified name of the java.text.spi.DateFormatProvider
# implementation class
#
com.foo.DateFormatSymbolsProviderImpl

View file

@ -0,0 +1,7 @@
#
#
#
# fully-qualified name of the java.text.spi.DecimalFormatProvider
# implementation class
#
com.foo.DecimalFormatSymbolsProviderImpl

View file

@ -0,0 +1,7 @@
#
#
#
# fully-qualified name of the java.text.spi.NumberFormatProvider
# implementation class
#
com.foo.NumberFormatProviderImpl

View file

@ -0,0 +1,140 @@
/*
* Copyright (c) 2007, 2022, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
*/
package com.foo;
import java.text.*;
import java.text.spi.*;
import java.util.*;
import com.foobar.Utils;
public class BreakIteratorProviderImpl extends BreakIteratorProvider {
static Locale[] avail = {
Locale.JAPAN,
Locale.of("ja", "JP", "osaka"),
Locale.of("ja", "JP", "kyoto"),
Locale.of("xx", "YY")};
static String[] dialect = {
"\u3067\u3059\u3002",
"\u3084\u3002",
"\u3069\u3059\u3002",
"-xx-YY"
};
static enum Type {CHARACTER, LINE, SENTENCE, WORD};
public Locale[] getAvailableLocales() {
return avail;
}
public BreakIterator getCharacterInstance(Locale locale) {
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) {
return new FooBreakIterator(Type.CHARACTER, i);
}
}
throw new IllegalArgumentException("locale is not supported: "+locale);
}
public BreakIterator getLineInstance(Locale locale) {
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) {
return new FooBreakIterator(Type.LINE, i);
}
}
throw new IllegalArgumentException("locale is not supported: "+locale);
}
public BreakIterator getSentenceInstance(Locale locale) {
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) {
return new FooBreakIterator(Type.SENTENCE, i);
}
}
throw new IllegalArgumentException("locale is not supported: "+locale);
}
public BreakIterator getWordInstance(Locale locale) {
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) {
return new FooBreakIterator(Type.WORD, i);
}
}
throw new IllegalArgumentException("locale is not supported: "+locale);
}
// dummy implementation
class FooBreakIterator extends BreakIterator {
public FooBreakIterator(Type t, int index) {
super();
}
public int current() {
return 0;
}
public int first() {
return 0;
}
public int following(int offset) {
return 0;
}
public CharacterIterator getText() {
return null;
}
public boolean isBoundary(int offset) {
return true;
}
public int last() {
return 0;
}
public int next() {
return 0;
}
public int next(int n) {
return 0;
}
public int preceding(int offset) {
return 0;
}
public int previous() {
return 0;
}
public void setText(CharacterIterator ci) {
}
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2007, 2022, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
*/
package com.foo;
import java.text.*;
import java.text.spi.*;
import java.util.*;
import com.foobar.Utils;
public class CollatorProviderImpl extends CollatorProvider {
static Locale[] avail = {
Locale.JAPAN,
Locale.of("ja", "JP", "osaka"),
Locale.of("ja", "JP", "kyoto"),
Locale.of("xx", "YY", "ZZZZ")};
static String[] dialect = {
"\u3067\u3059\u3002",
"\u3084\u3002",
"\u3069\u3059\u3002",
"-xx-YY-ZZZZ"
};
public Locale[] getAvailableLocales() {
return avail;
}
public Collator getInstance(Locale locale) {
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) {
RuleBasedCollator ja = (RuleBasedCollator)Collator.getInstance(Locale.JAPANESE);
try {
return new RuleBasedCollator(ja.getRules()+"& Z < "+dialect[i]);
} catch (ParseException pe) {
System.err.println(pe+ja.getRules()+"& Z < "+dialect[i]);
return ja;
}
}
}
throw new IllegalArgumentException("locale is not supported: "+locale);
}
}

View file

@ -0,0 +1,95 @@
/*
* Copyright (c) 2007, 2022, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
*/
package com.foo;
import java.text.*;
import java.text.spi.*;
import java.util.*;
import com.foobar.Utils;
public class DateFormatProviderImpl extends DateFormatProvider {
static Locale[] avail = {
Locale.JAPAN,
Locale.of("ja", "JP", "osaka"),
Locale.of("ja", "JP", "kyoto"),
Locale.of("yy")};
static String[] datePattern = {
"yyyy'\u5e74'M'\u6708'd'\u65e5'", // full date pattern
"yyyy/MMM/dd", // long date pattern
"yyyy/MM/dd", // medium date pattern
"yy/MM/dd" // short date pattern
};
static String[] timePattern = {
"H'\u6642'mm'\u5206'ss'\u79d2' z", // full time pattern
"H:mm:ss z", // long time pattern
"H:mm:ss", // medium time pattern
"H:mm" // short time pattern
};
static String[] dialect = {
"\u3067\u3059\u3002",
"\u3084\u3002",
"\u3069\u3059\u3002",
"\u308f\u3044\u308f\u3044"
};
public Locale[] getAvailableLocales() {
return avail;
}
public DateFormat getDateInstance(int style, Locale locale) {
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) {
return new FooDateFormat(datePattern[style]+dialect[i], locale);
}
}
throw new IllegalArgumentException("locale is not supported: "+locale);
}
public DateFormat getTimeInstance(int style, Locale locale) {
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) {
return new FooDateFormat(timePattern[style]+dialect[i], locale);
}
}
throw new IllegalArgumentException("locale is not supported: "+locale);
}
public DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale locale) {
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) {
return new FooDateFormat(
datePattern[dateStyle]+" "+timePattern[timeStyle]+dialect[i], locale);
}
}
throw new IllegalArgumentException("locale is not supported: "+locale);
}
}

View file

@ -0,0 +1,230 @@
/*
* Copyright (c) 2007, 2022, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
*/
package com.foo;
import java.text.*;
import java.text.spi.*;
import java.util.*;
import com.foobar.Utils;
public class DateFormatSymbolsProviderImpl extends DateFormatSymbolsProvider {
static Locale[] avail = {
Locale.of("ja", "JP", "osaka"),
Locale.of("ja", "JP", "kyoto"),
Locale.JAPAN,
Locale.of("yy", "ZZ")
};
static List<Locale> availList = Arrays.asList(avail);
static String[] dialect = {
"\u3084\u3002",
"\u3069\u3059\u3002",
"\u3067\u3059\u3002",
"-yy-ZZ"
};
static Map<Locale, FooDateFormatSymbols> symbols = new HashMap<Locale, FooDateFormatSymbols>(4);
public Locale[] getAvailableLocales() {
return avail;
}
public DateFormatSymbols getInstance(Locale locale) {
if (!Utils.supportsLocale(availList, locale)) {
throw new IllegalArgumentException("locale is not supported: "+locale);
}
FooDateFormatSymbols fdfs = symbols.get(locale);
if (fdfs == null) {
for (int index = 0; index < avail.length; index ++) {
if (Utils.supportsLocale(avail[index], locale)) {
fdfs = new FooDateFormatSymbols(index);
symbols.put(locale, fdfs);
break;
}
}
}
return fdfs;
}
class FooDateFormatSymbols extends DateFormatSymbols {
String dialect = "";
String[] eras = null;
String[] months = null;
String[] shortMonths = null;
String[] weekdays = null;
String[] shortWeekdays = null;
String[] ampms = null;
public FooDateFormatSymbols(int index) {
super(DateFormatSymbolsProviderImpl.this.avail[index]);
dialect = DateFormatSymbolsProviderImpl.this.dialect[index];
}
public String[] getEras() {
if (eras == null) {
eras = super.getEras();
for (int i = 0; i < eras.length; i++) {
eras[i] = eras[i]+dialect;
}
}
return eras;
}
/**
* Sets era strings. For example: "AD" and "BC".
* @param newEras the new era strings.
*/
public void setEras(String[] newEras) {
eras = newEras;
}
/**
* Gets month strings. For example: "January", "February", etc.
* @return the month strings.
*/
public String[] getMonths() {
if (months == null) {
months = super.getMonths();
for (int i = 0; i < months.length; i++) {
months[i] = months[i]+dialect;
}
}
return months;
}
/**
* Sets month strings. For example: "January", "February", etc.
* @param newMonths the new month strings.
*/
public void setMonths(String[] newMonths) {
months = newMonths;
}
/**
* Gets short month strings. For example: "Jan", "Feb", etc.
* @return the short month strings.
*/
public String[] getShortMonths() {
if (shortMonths == null) {
shortMonths = super.getShortMonths();
for (int i = 0; i < shortMonths.length; i++) {
shortMonths[i] = shortMonths[i]+dialect;
}
}
return shortMonths;
}
/**
* Sets short month strings. For example: "Jan", "Feb", etc.
* @param newShortMonths the new short month strings.
*/
public void setShortMonths(String[] newShortMonths) {
shortMonths = newShortMonths;
}
/**
* Gets weekday strings. For example: "Sunday", "Monday", etc.
* @return the weekday strings. Use <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc. to index the result array.
*/
public String[] getWeekdays() {
if (weekdays == null) {
weekdays = super.getWeekdays();
for (int i = 0; i < weekdays.length; i++) {
weekdays[i] = weekdays[i]+dialect;
}
}
return weekdays;
}
/**
* Sets weekday strings. For example: "Sunday", "Monday", etc.
* @param newWeekdays the new weekday strings. The array should
* be indexed by <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc.
*/
public void setWeekdays(String[] newWeekdays) {
weekdays = newWeekdays;
}
/**
* Gets short weekday strings. For example: "Sun", "Mon", etc.
* @return the short weekday strings. Use <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc. to index the result array.
*/
public String[] getShortWeekdays() {
if (shortWeekdays == null) {
shortWeekdays = super.getShortWeekdays();
for (int i = 0; i < shortWeekdays.length; i++) {
shortWeekdays[i] = shortWeekdays[i]+dialect;
}
}
return shortWeekdays;
}
/**
* Sets short weekday strings. For example: "Sun", "Mon", etc.
* @param newShortWeekdays the new short weekday strings. The array should
* be indexed by <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc.
*/
public void setShortWeekdays(String[] newShortWeekdays) {
shortWeekdays = newShortWeekdays;
}
/**
* Gets ampm strings. For example: "AM" and "PM".
* @return the ampm strings.
*/
public String[] getAmPmStrings() {
if (ampms == null) {
ampms = super.getAmPmStrings();
for (int i = 0; i < ampms.length; i++) {
ampms[i] = ampms[i]+dialect;
}
}
return ampms;
}
/**
* Sets ampm strings. For example: "AM" and "PM".
* @param newAmpms the new ampm strings.
*/
public void setAmPmStrings(String[] newAmpms) {
ampms = newAmpms;
}
@Override
public String[][] getZoneStrings() {
return new String[0][0];
}
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2007, 2022, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
*/
package com.foo;
import java.text.*;
import java.text.spi.*;
import java.util.*;
import com.foobar.Utils;
public class DecimalFormatSymbolsProviderImpl extends DecimalFormatSymbolsProvider {
static Locale[] avail = {
Locale.of("ja", "JP", "osaka"),
Locale.of("ja", "JP", "kyoto"),
Locale.JAPAN,
Locale.of("yy", "ZZ", "UUU")
};
static List<Locale> availList = Arrays.asList(avail);
static String[] dialect = {
"\u3084\u3002",
"\u3069\u3059\u3002",
"\u3067\u3059\u3002",
"-yy-ZZ-UUU"
};
static HashMap<Locale, FooDecimalFormatSymbols> symbols = new HashMap<Locale, FooDecimalFormatSymbols>(4);
public Locale[] getAvailableLocales() {
return avail;
}
public DecimalFormatSymbols getInstance(Locale locale) {
if (!Utils.supportsLocale(availList, locale)) {
throw new IllegalArgumentException("locale is not supported: "+locale);
}
FooDecimalFormatSymbols fdfs = symbols.get(locale);
if (fdfs == null) {
for (int index = 0; index < avail.length; index ++) {
if (Utils.supportsLocale(avail[index], locale)) {
fdfs = new FooDecimalFormatSymbols(index);
symbols.put(locale, fdfs);
break;
}
}
}
return fdfs;
}
class FooDecimalFormatSymbols extends DecimalFormatSymbols {
String dialect = "";
String infinity = null;
String nan = null;
public FooDecimalFormatSymbols(int index) {
super(DecimalFormatSymbolsProviderImpl.this.avail[index]);
dialect = DecimalFormatSymbolsProviderImpl.this.dialect[index];
}
// overrides methods only returns Strings
public String getInfinity() {
if (infinity == null) {
infinity = super.getInfinity() + dialect;
}
return infinity;
}
public void setInfinity(String infinity) {
this.infinity = infinity;
}
public String getNaN() {
if (nan == null) {
nan = super.getNaN() + dialect;
}
return nan;
}
public void setNaN(String nan) {
this.nan = nan;
}
}
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2010, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.foo;
import java.text.*;
import java.util.*;
/**
* FooDateFormat provides SimpleDateFormat methods required for the SPI testing.
*/
public class FooDateFormat extends DateFormat {
private SimpleDateFormat sdf;
public FooDateFormat(String pattern, Locale loc) {
sdf = new SimpleDateFormat(pattern, loc);
}
@Override
public StringBuffer format(Date date,
StringBuffer toAppendTo,
FieldPosition fieldPosition) {
return sdf.format(date, toAppendTo, fieldPosition);
}
@Override
public Date parse(String source, ParsePosition pos) {
return sdf.parse(source, pos);
}
@Override
public boolean equals(Object other) {
return other instanceof FooDateFormat
&& sdf.equals(((FooDateFormat)other).sdf);
}
@Override
public int hashCode() {
return sdf.hashCode();
}
}

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2010, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.foo;
import java.text.*;
/**
* FooNumberFormat provides DecimalFormat methods required for the SPI testing.
*/
public class FooNumberFormat extends NumberFormat {
private DecimalFormat df;
public FooNumberFormat(String pattern, DecimalFormatSymbols dfs) {
df = new DecimalFormat(pattern, dfs);
}
@Override
public StringBuffer format(double number,
StringBuffer toAppendTo,
FieldPosition pos) {
return df.format(number, toAppendTo, pos);
}
@Override
public StringBuffer format(long number,
StringBuffer toAppendTo,
FieldPosition pos) {
return df.format(number, toAppendTo, pos);
}
@Override
public Number parse(String source, ParsePosition parsePosition) {
return df.parse(source, parsePosition);
}
@Override
public boolean equals(Object other) {
return other instanceof FooNumberFormat
&& df.equals(((FooNumberFormat)other).df);
}
@Override
public int hashCode() {
return df.hashCode();
}
// DecimalFormat specific methods required for testing
public String toPattern() {
return df.toPattern();
}
public DecimalFormatSymbols getDecimalFormatSymbols() {
return df.getDecimalFormatSymbols();
}
public void setDecimalSeparatorAlwaysShown(boolean newValue) {
df.setDecimalSeparatorAlwaysShown(newValue);
}
}

View file

@ -0,0 +1,156 @@
/*
* Copyright (c) 2007, 2022, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
*/
package com.foo;
import java.text.*;
import java.text.spi.*;
import java.util.*;
import com.foobar.Utils;
public class NumberFormatProviderImpl extends NumberFormatProvider {
static Locale[] avail = {
Locale.JAPAN,
Locale.of("ja", "JP", "osaka"),
Locale.of("ja", "JP", "kyoto"),
Locale.of("zz")};
static String[] dialect = {
"\u3067\u3059\u3002",
"\u3084\u3002",
"\u3069\u3059\u3002",
"-zz"
};
static String[] patterns = {
"#,##0.###{0};-#,##0.###{1}", // decimal pattern
"#{0};(#){1}", // integer pattern
"\u00A4#,##0{0};-\u00A4#,##0{1}", // currency pattern
"#,##0%{0}" // percent pattern
};
// Constants used by factory methods to specify a style of format.
static final int NUMBERSTYLE = 0;
static final int INTEGERSTYLE = 1;
static final int CURRENCYSTYLE = 2;
static final int PERCENTSTYLE = 3;
public Locale[] getAvailableLocales() {
return avail;
}
public NumberFormat getCurrencyInstance(Locale locale) {
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) {
String pattern =
MessageFormat.format(patterns[CURRENCYSTYLE],
dialect[i],
dialect[i]);
FooNumberFormat nf = new FooNumberFormat(pattern,
DecimalFormatSymbols.getInstance(locale));
adjustForCurrencyDefaultFractionDigits(nf);
return nf;
}
}
throw new IllegalArgumentException("locale is not supported: "+locale);
}
public NumberFormat getIntegerInstance(Locale locale) {
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) {
String pattern =
MessageFormat.format(patterns[INTEGERSTYLE],
dialect[i],
dialect[i]);
FooNumberFormat nf = new FooNumberFormat(pattern,
DecimalFormatSymbols.getInstance(locale));
nf.setMaximumFractionDigits(0);
nf.setDecimalSeparatorAlwaysShown(false);
nf.setParseIntegerOnly(true);
return nf;
}
}
throw new IllegalArgumentException("locale is not supported: "+locale);
}
public NumberFormat getNumberInstance(Locale locale) {
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) {
String pattern =
MessageFormat.format(patterns[NUMBERSTYLE],
dialect[i],
dialect[i]);
return new FooNumberFormat(pattern,
DecimalFormatSymbols.getInstance(locale));
}
}
throw new IllegalArgumentException("locale is not supported: "+locale);
}
public NumberFormat getPercentInstance(Locale locale) {
for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) {
String pattern =
MessageFormat.format(patterns[PERCENTSTYLE],
dialect[i]);
return new FooNumberFormat(pattern,
DecimalFormatSymbols.getInstance(locale));
}
}
throw new IllegalArgumentException("locale is not supported: "+locale);
}
/**
* Adjusts the minimum and maximum fraction digits to values that
* are reasonable for the currency's default fraction digits.
*/
void adjustForCurrencyDefaultFractionDigits(FooNumberFormat nf) {
DecimalFormatSymbols dfs = nf.getDecimalFormatSymbols();
Currency currency = dfs.getCurrency();
if (currency == null) {
try {
currency = Currency.getInstance(dfs.getInternationalCurrencySymbol());
} catch (IllegalArgumentException e) {
}
}
if (currency != null) {
int digits = currency.getDefaultFractionDigits();
if (digits != -1) {
int oldMinDigits = nf.getMinimumFractionDigits();
// Common patterns are "#.##", "#.00", "#".
// Try to adjust all of them in a reasonable way.
if (oldMinDigits == nf.getMaximumFractionDigits()) {
nf.setMinimumFractionDigits(digits);
nf.setMaximumFractionDigits(digits);
} else {
nf.setMinimumFractionDigits(Math.min(digits, oldMinDigits));
nf.setMaximumFractionDigits(digits);
}
}
}
}
}