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,98 @@
/*
* Copyright (c) 2018, 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 8179071 8202537 8231273 8251317
* @summary Test that language aliases of CLDR supplemental metadata are handled correctly.
* @modules jdk.localedata
* @run junit AliasesShouldBeRecognizedInCLDR
*/
/*
* This fix is dependent on a particular version of CLDR data.
*/
import java.time.Month;
import java.time.format.TextStyle;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Stream;
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 static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class AliasesShouldBeRecognizedInCLDR {
/*
* Deprecated and Legacy tags.
* As of CLDR 38, language aliases for some legacy tags have been removed.
*/
private static final Set<String> LegacyAliases = Set.of(
"zh-guoyu", "zh-min-nan", "i-klingon", "i-tsu",
"sgn-CH-DE", "mo", "i-tay", "scc",
"i-hak", "sgn-BE-FR", "i-lux", "tl", "zh-hakka", "i-ami", "aa-SAAHO",
"zh-xiang", "i-pwn", "sgn-BE-NL", "jw", "sh", "i-bnn");
// Ensure the display name for the given tag's January is correct
@ParameterizedTest
@MethodSource("shortJanuaryNames")
public void janDisplayNameTest(String tag, String expected) {
Locale target = Locale.forLanguageTag(tag);
Month day = Month.JANUARY;
TextStyle style = TextStyle.SHORT;
String actual = day.getDisplayName(style, target);
assertEquals(expected, actual);
}
// Expected month format data for locales after language aliases replacement.
private static Stream<Arguments> shortJanuaryNames() {
return Stream.of(
Arguments.of("pa-PK", "\u0a1c\u0a28"),
Arguments.of("uz-AF", "yan"),
Arguments.of("sr-ME", "\u0458\u0430\u043d"),
Arguments.of("scc", "\u0458\u0430\u043d"),
Arguments.of("sh", "jan"),
Arguments.of("ha-Latn-NE", "Jan"),
Arguments.of("i-lux", "Jan.")
);
}
// getAvailableLocales() should not contain any deprecated or Legacy language tags
@Test
public void invalidTagsTest() {
Set<String> invalidTags = new HashSet<>();
Arrays.stream(Locale.getAvailableLocales())
.map(Locale::toLanguageTag)
.forEach(tag -> {if(LegacyAliases.contains(tag)) {invalidTags.add(tag);}});
assertTrue(invalidTags.isEmpty(),
"Deprecated and Legacy tags found " + invalidTags + " in AvailableLocales ");
}
}

View file

@ -0,0 +1,123 @@
/*
* Copyright (c) 2007, 2023, 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 4122700 8282319
* @summary Verify implementation of getAvailableLocales() and availableLocales()
* @run junit AvailableLocalesTest
*/
import java.util.Arrays;
import java.util.Locale;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.Arguments;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
public class AvailableLocalesTest {
/**
* Test that Locale.getAvailableLocales() is non-empty and prints out
* the returned locales - 4122700.
*/
@Test
public void nonEmptyLocalesTest() {
Locale[] systemLocales = Locale.getAvailableLocales();
assertNotEquals(systemLocales.length, 0, "Available locale list is empty!");
System.out.println("Found " + systemLocales.length + " locales:");
printLocales(systemLocales);
}
/**
* Test to validate that the methods: Locale.getAvailableLocales()
* and Locale.availableLocales() contain the same underlying elements
*/
@Test
public void streamEqualsArrayTest() {
Locale[] arrayLocales = Locale.getAvailableLocales();
Stream<Locale> streamedLocales = Locale.availableLocales();
Locale[] convertedLocales = streamedLocales.toArray(Locale[]::new);
if (Arrays.equals(arrayLocales, convertedLocales)) {
System.out.println("$$$ Passed: The underlying elements" +
" of getAvailableLocales() and availableLocales() are the same!");
} else {
throw new RuntimeException("$$$ Error: The underlying elements" +
" of getAvailableLocales() and availableLocales()" +
" are not the same.");
}
}
/**
* Test to validate that the stream has the required
* Locale.ROOT and Locale.US.
*/
@ParameterizedTest
@MethodSource("requiredLocaleProvider")
public void requiredLocalesTest(Locale requiredLocale, String localeName) {
if (Locale.availableLocales().anyMatch(loc -> (loc.equals(requiredLocale)))) {
System.out.printf("$$$ Passed: Stream has %s!%n", localeName);
} else {
throw new RuntimeException(String.format("$$$ Error:" +
" Stream is missing %s!", localeName));
}
}
// Helper method to print out all the system locales
private void printLocales(Locale[] systemLocales) {
Locale[] locales = new Locale[systemLocales.length];
for (int i = 0; i < locales.length; i++) {
Locale lowest = null;
for (Locale systemLocale : systemLocales) {
if (i > 0 && locales[i - 1].toString().compareTo(systemLocale.toString()) >= 0)
continue;
if (lowest == null || systemLocale.toString().compareTo(lowest.toString()) < 0)
lowest = systemLocale;
}
locales[i] = lowest;
}
for (Locale locale : locales) {
if (locale.getCountry().length() == 0)
System.out.println(" " + locale.getDisplayLanguage() + ":");
else {
if (locale.getVariant().length() == 0)
System.out.println(" " + locale.getDisplayCountry());
else
System.out.println(" " + locale.getDisplayCountry() + ", "
+ locale.getDisplayVariant());
}
}
}
// Data provider for testStreamRequirements
private static Stream<Arguments> requiredLocaleProvider() {
return Stream.of(
Arguments.of(Locale.ROOT, "Root locale"),
Arguments.of(Locale.US, "US locale")
);
}
}

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2007, 2023, 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 4210525
* @summary Locale variant should not be case folded
* @run junit CaseCheckVariant
*/
import java.util.Locale;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CaseCheckVariant {
static final String LANG = "en";
static final String COUNTRY = "US";
/**
* When a locale is created with a given variant, ensure
* that the variant is not case normalized.
*/
@ParameterizedTest
@MethodSource("variants")
public void variantCaseTest(String variant) {
Locale aLocale = Locale.of(LANG, COUNTRY, variant);
String localeVariant = aLocale.getVariant();
assertEquals(localeVariant, variant);
}
private static Stream<String> variants() {
return Stream.of(
"socal",
"Norcal"
);
}
}

View file

@ -0,0 +1,204 @@
/*
* Copyright (c) 2023, 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 8159337 8368981
* @summary Test Locale.caseFoldLanguageTag(String languageTag)
* @run junit CaseFoldLanguageTagTest
*/
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.IllformedLocaleException;
import java.util.Locale;
import java.util.stream.Stream;
/**
* Test the implementation of Locale.caseFoldLanguageTag(String languageTag).
* A variety of well-formed tags are tested, composed of the following subtags:
* language, extlang, script, region, variant, extension, singleton, privateuse,
* grandfathered, and irregular. For more info, see the following,
* <a href="https://www.rfc-editor.org/rfc/rfc5646.html#section-2.1">Tag Syntax</a>).
* In addition, the method is tested to ensure that IllformedLocaleException and
* NullPointerException are thrown given the right circumstances.
*/
public class CaseFoldLanguageTagTest {
@ParameterizedTest
@MethodSource("wellFormedTags")
void wellFormedTagsTest(String tag, String foldedTag) {
assertEquals(foldedTag, Locale.caseFoldLanguageTag(tag), String.format("Folded %s", tag));
}
@ParameterizedTest
@MethodSource("legacyTags")
void legacyTagsTest(String tag) {
var lowerTag = tag.toLowerCase(Locale.ROOT);
var upperTag = tag.toUpperCase(Locale.ROOT);
assertEquals(tag, Locale.caseFoldLanguageTag(lowerTag),
String.format("Folded %s", lowerTag));
assertEquals(tag, Locale.caseFoldLanguageTag(upperTag),
String.format("Folded %s", upperTag));
}
@ParameterizedTest
@MethodSource("illFormedTags")
void illFormedTagsTest(String tag) {
assertThrows(IllformedLocaleException.class, () ->
Locale.caseFoldLanguageTag(tag));
}
@Test
void throwNPETest() {
assertThrows(NullPointerException.class, () ->
Locale.caseFoldLanguageTag(null));
}
// Well-formed legacy tags in expected case
static Stream<String> legacyTags() {
return Stream.of(
"art-lojban",
"cel-gaulish",
"en-GB-oed",
"i-ami",
"i-bnn",
"i-default",
"i-enochian",
"i-hak",
"i-klingon",
"i-lux",
"i-mingo",
"i-navajo",
"i-pwn",
"i-tao",
"i-tay",
"i-tsu",
"no-bok",
"no-nyn",
"sgn-BE-FR",
"sgn-BE-NL",
"sgn-CH-DE",
"zh-guoyu",
"zh-hakka",
"zh-min",
"zh-min-nan",
"zh-xiang"
);
}
static Stream<Arguments> wellFormedTags() {
return Stream.of(
// langtag tests
// language
Arguments.of("AB", "ab"),
// language - ext
Arguments.of("AB-ABC", "ab-abc"),
// language - ext - script
Arguments.of("AB-ABC-ABCD", "ab-abc-Abcd"),
// language - ext - script - region
Arguments.of("AB-ABC-ABCD-ab", "ab-abc-Abcd-AB"),
// language - region
Arguments.of("AB-ab", "ab-AB"),
// language - script
Arguments.of("AB-aBCD", "ab-Abcd"),
// language - private use
Arguments.of("AB-X-AB-ABCD", "ab-x-ab-abcd"),
// language - ext - script - region - variant
Arguments.of("AB-ABC-ABCD-ab-ABCDE", "ab-abc-Abcd-AB-ABCDE"),
// language - ext - script - region - variant x 2
Arguments.of("AB-ABC-ABCD-ab-ABCDE-fghij",
"ab-abc-Abcd-AB-ABCDE-fghij"),
// language - ext - script - region - variant - extension
Arguments.of("AB-ABC-ABCD-ab-ABCDE-A-ABCD",
"ab-abc-Abcd-AB-ABCDE-a-abcd"),
// language - ext - script - region - variant - private
Arguments.of("AB-ABC-ABCD-ab-ABCDE-X-ABCD",
"ab-abc-Abcd-AB-ABCDE-x-abcd"),
// language - ext - script - region - variant - extension x2
Arguments.of("AB-ABC-ABCD-ab-ABCDE-A-ABCD-B-EFGHI",
"ab-abc-Abcd-AB-ABCDE-a-abcd-b-efghi"),
// language - ext - script - region - variant - extension - private
Arguments.of("AB-ABC-ABCD-ab-ABCDE-A-ABCD-X-ABCD",
"ab-abc-Abcd-AB-ABCDE-a-abcd-x-abcd"),
// language - ext - script - region - variant x2 - extension x2 - private (x2 ext)
Arguments.of("AB-ABC-ABCD-ab-ABCDE-A-ABCD-X-ABCD-EFGHI",
"ab-abc-Abcd-AB-ABCDE-a-abcd-x-abcd-efghi"),
// language - variant x2 - extension x3 - private
Arguments.of("AB-aBcDeF-GhIjKl-a-ABC-DEFGH-B-ABC-C-ABC-X-A-ABC-DEF",
"ab-aBcDeF-GhIjKl-a-abc-defgh-b-abc-c-abc-x-a-abc-def"),
// language - ext- script - region - variant - extension x2 - private (x2 ext)
Arguments.of("AB-ABC-ABCD-ab-abCDe12-A-AB-B-ABCD-X-AB-ABCD",
"ab-abc-Abcd-AB-abCDe12-a-ab-b-abcd-x-ab-abcd"),
// Multiple singleton extensions
Arguments.of("AB-ABC-ABCD-ab-ABCDE-A-ABCD-GGG-ZZZ-B-EFGHI",
"ab-abc-Abcd-AB-ABCDE-a-abcd-ggg-zzz-b-efghi"),
// private use tests
Arguments.of("X-Abc", "x-abc"), // regular private
Arguments.of("X-A-ABC", "x-a-abc"), // private w/ extended (incl. 1)
Arguments.of("X-A-AB-Abcd", "x-a-ab-abcd"), // private w/ extended (incl. 1, 2, 4)
// Special JDK Cases (Variant and x-lvariant)
Arguments.of("de-POSIX-x-URP-lvariant-Abc-Def", "de-POSIX-x-urp-lvariant-Abc-Def"),
Arguments.of("JA-JPAN-JP-U-CA-JAPANESE-x-RANDOM-lvariant-JP",
"ja-Jpan-JP-u-ca-japanese-x-random-lvariant-JP"),
Arguments.of("ja-JP-u-ca-japanese-x-lvariant-JP", "ja-JP-u-ca-japanese-x-lvariant-JP"),
Arguments.of("XX-ABCD-yy-VARIANT-x-TEST-lvariant-JDK",
"xx-Abcd-YY-VARIANT-x-test-lvariant-JDK"),
Arguments.of("ja-kana-jp-x-lvariant-Oracle-JDK-Standard-Edition",
"ja-Kana-JP-x-lvariant-Oracle-JDK-Standard-Edition"),
Arguments.of("ja-kana-jp-x-Oracle-JDK-Standard-Edition",
"ja-Kana-JP-x-oracle-jdk-standard-edition"),
Arguments.of("ja-kana-jp-a-ABC-EFG-ZZZ-b-aaa-x-Oracle-JDK-Standard-Edition",
"ja-Kana-JP-a-abc-efg-zzz-b-aaa-x-oracle-jdk-standard-edition")
);
}
static Stream<Arguments> illFormedTags() {
return Stream.of(
// Starts with non-language
Arguments.of("xabadadoo-me"),
// Starts with singleton
Arguments.of("a-abc"),
Arguments.of("a-singleton-en-us"),
// Hanging dash
Arguments.of("en-"),
// Double dash
Arguments.of("en--US"),
// Script before ext lang
Arguments.of("ab-Script-ext"),
// Region before ext lang
Arguments.of("ab-AB-ext"),
// Variants at start
Arguments.of("variant-first-ab")
);
}
}

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2023, 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 8304982 8174269
* @summary Check if a warning is logged with COMPAT locale provider
* @run main/othervm -Djava.locale.providers=COMPAT CompatWarning
* @run main/othervm -Djava.locale.providers=SPI,COMPAT CompatWarning
* @run main/othervm -Djava.locale.providers=COMPAT,SPI CompatWarning
* @run main/othervm -Djava.locale.providers=JRE CompatWarning
* @run main/othervm -Djava.locale.providers=SPI,JRE CompatWarning
* @run main/othervm -Djava.locale.providers=JRE,SPI CompatWarning
*/
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
public class CompatWarning {
private static final String WARNING =
"COMPAT locale provider has been removed";
private static boolean logged;
public static void main(String[] args) throws Throwable {
File conf = new File(System.getProperty("test.src", "./src"), "compatlog.properties");
if (!conf.canRead()) {
throw new IOException("Can't read config file: " + conf.getAbsolutePath());
}
System.setProperty("java.util.logging.config.file", conf.getAbsolutePath());
DateFormat.getInstance();
if (!logged) {
throw new RuntimeException("COMPAT warning message was not emitted");
}
}
public static class CheckWarning extends Handler {
@Override
public void publish(LogRecord record) {
var level = record.getLevel();
var msg = record.getMessage();
System.out.printf("""
LogRecord emitted:
Level: %s
Message: %s
""", level, msg);
if (level == Level.WARNING && WARNING.equals(msg)) {
logged = true;
}
}
@Override
public void flush() {}
@Override
public void close() throws SecurityException {}
}
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2014, 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 8008577 8138613 8174269
* @summary Check whether CLDR locale provider adapter is enabled by default
* @compile -XDignore.symbol.file ExpectedAdapterTypes.java
* @modules java.base/sun.util.locale.provider
* @run junit ExpectedAdapterTypes
*/
import java.util.Arrays;
import java.util.List;
import sun.util.locale.provider.LocaleProviderAdapter;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ExpectedAdapterTypes {
static final LocaleProviderAdapter.Type[] expected = {
LocaleProviderAdapter.Type.CLDR,
LocaleProviderAdapter.Type.FALLBACK,
};
/**
* This test ensures LocaleProviderAdapter.getAdapterPreference() returns
* the correct preferred adapter types. This test should fail whenever a change is made
* to the implementation and the expected list is not updated accordingly.
*/
@Test
public void correctAdapterListTest() {
List<LocaleProviderAdapter.Type> actualTypes = LocaleProviderAdapter.getAdapterPreference();
List<LocaleProviderAdapter.Type> expectedTypes = Arrays.asList(expected);
assertEquals(actualTypes, expectedTypes, String.format("getAdapterPreference() " +
"returns: %s, but the expected adapter list returns: %s", actualTypes, expectedTypes));
}
}

View file

@ -0,0 +1,64 @@
/*
* 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 Locale.hasExtensions() and Locale.stripExtensions().
*/
import java.util.*;
public class ExtensionsTest {
public static void main(String[] args) {
Locale jaJPJP = Locale.of("ja", "JP", "JP");
if (!jaJPJP.hasExtensions()) {
error(jaJPJP + " should have an extension.");
}
Locale stripped = jaJPJP.stripExtensions();
if (stripped.hasExtensions()) {
error(stripped + " should NOT have an extension.");
}
if (jaJPJP.equals(stripped)) {
throw new RuntimeException("jaJPJP equals stripped");
}
if (!"ja-JP-x-lvariant-JP".equals(stripped.toLanguageTag())) {
error("stripped.toLanguageTag() isn't ja-JP-x-lvariant-JP");
}
Locale enUSja = Locale.forLanguageTag("en-US-u-ca-japanese");
if (!enUSja.stripExtensions().equals(Locale.US)) {
error("stripped enUSja not equals Locale.US");
}
// If a Locale has no extensions, stripExtensions() returns self.
Locale enUS = Locale.US.stripExtensions();
if (enUS != Locale.US) {
error("stripped Locale.US != Locale.US");
}
}
private static void error(String msg) {
throw new RuntimeException(msg);
}
}

View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 2018, 2023, 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 8210443
* @summary Check values() and valueOf(String name) of Locale.FilteringMode.
* @run junit FilteringModeTest
*/
import java.util.Arrays;
import java.util.List;
import java.util.Locale.FilteringMode;
import java.util.stream.Collectors;
import java.util.stream.Stream;
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 static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class FilteringModeTest {
private static final List<String> expectedModeNames = List.of(
"AUTOSELECT_FILTERING",
"EXTENDED_FILTERING",
"IGNORE_EXTENDED_RANGES",
"MAP_EXTENDED_RANGES",
"REJECT_EXTENDED_RANGES"
);
// Ensure valueOf() exceptions are thrown
@Test
public void valueOfExceptionsTest() {
assertThrows(IllegalArgumentException.class,
() -> FilteringMode.valueOf("").name());
assertThrows(NullPointerException.class,
() -> FilteringMode.valueOf(null).name());
}
// Ensure valueOf() returns expected results
@ParameterizedTest
@MethodSource("modes")
public void valueOfTest(String expectedName) {
String name = FilteringMode.valueOf(expectedName).name();
assertEquals(expectedName, name);
}
private static Stream<String> modes() {
return expectedModeNames.stream();
}
// Ensure values() returns expected results
@Test
public void valuesTest() {
FilteringMode[] modeArray = FilteringMode.values();
List<String> actualNames = Arrays.stream(modeArray)
.map(mode -> mode.name())
.collect(Collectors.toList());
assertEquals(expectedModeNames, actualNames);
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2013, 2023, 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 8004240
* @summary Verify that getAdapterPreference returns an unmodifiable list.
* @modules java.base/sun.util.locale.provider
* @compile -XDignore.symbol.file GetAdapterPreference.java
* @run junit GetAdapterPreference
*/
import java.util.List;
import sun.util.locale.provider.LocaleProviderAdapter;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class GetAdapterPreference {
/**
* Test that the list returned from getAdapterPreference()
* cannot be modified.
*/
@Test
public void immutableTest() {
List<LocaleProviderAdapter.Type> types = LocaleProviderAdapter.getAdapterPreference();
assertThrows(UnsupportedOperationException.class, () -> types.set(0, null),
"Trying to modify list returned from LocaleProviderAdapter.getAdapterPreference() did not throw UOE");
}
}

View file

@ -0,0 +1,126 @@
/*
* Copyright (c) 2007, 2023, 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 6312358
* @summary Verify that an NPE is thrown by invoking Locale.getInstance() with
* any argument being null.
* @modules java.base/java.util:open
* @run junit GetInstanceCheck
*/
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Locale;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.fail;
public class GetInstanceCheck {
static Method getInstanceMethod;
static final String NAME = "getInstance";
/**
* Initialize the non-public Locale.getInstance() method.
*/
@BeforeAll
static void initializeMethod() {
try {
// Locale.getInstance is not directly accessible.
getInstanceMethod = Locale.class.getDeclaredMethod(
NAME, String.class, String.class, String.class
);
getInstanceMethod.setAccessible(true);
} catch (java.lang.NoSuchMethodException exc) {
// The test should fail if we can not test the desired method
fail(String.format("Tried to get the method '%s' which was not found," +
" further testing is not possible, failing test", NAME));
}
}
/**
* Exists as sanity check that Locale.getInstance() will not throw
* an NPE if no arguments are null.
*/
@ParameterizedTest
@MethodSource("passingArguments")
public void noNPETest(String language, String country, String variant)
throws IllegalAccessException {
try {
getInstanceMethod.invoke(null, language, country, variant);
} catch (InvocationTargetException exc) {
// Determine underlying exception
Throwable cause = exc.getCause();
if (exc.getCause() instanceof NullPointerException) {
fail(String.format("%s should not be thrown when no args are null", cause));
} else {
fail(String.format("%s unexpectedly thrown, when no exception should be thrown", cause));
}
}
}
/**
* Make sure the Locale.getInstance() method throws an NPE
* if any given argument is null.
*/
@ParameterizedTest
@MethodSource("failingArguments")
public void throwNPETest(String language, String country, String variant)
throws IllegalAccessException {
try {
getInstanceMethod.invoke(null, language, country, variant);
fail("Should NPE with any argument set to null");
} catch (InvocationTargetException exc) {
// Determine underlying exception
Throwable cause = exc.getCause();
if (cause instanceof NullPointerException) {
System.out.println("NPE successfully thrown");
} else {
fail(cause + " is thrown, when NPE should have been thrown");
}
}
}
private static Stream<Arguments> passingArguments() {
return Stream.of(
Arguments.of("null", "GB", ""),
Arguments.of("en", "null", ""),
Arguments.of("en", "GB", "null")
);
}
private static Stream<Arguments> failingArguments() {
return Stream.of(
Arguments.of(null, "GB", ""),
Arguments.of("en", null, ""),
Arguments.of("en", "GB", null)
);
}
}

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2007, 2023, 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 4518797
* @summary Make sure that hashCode() and read/writeObject() are thread-safe.
* @run main HashCodeShouldBeThreadSafe 10
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Locale;
// Usage: java HashCodeShouldBeThreadSafe [duration]
public class HashCodeShouldBeThreadSafe {
static volatile boolean runrun = true;
static volatile String message = null;
public static void main(String[] args) {
int duration = 180;
if (args.length == 1) {
duration = Math.max(5, Integer.parseInt(args[0]));
}
final Locale loc = Locale.of("ja", "US");
final int hashcode = loc.hashCode();
System.out.println("correct hash code: " + hashcode);
Thread t1 = new Thread(new Runnable() {
public void run() {
while (runrun) {
int hc = loc.hashCode();
if (hc != hashcode) {
runrun = false;
message = "t1: wrong hashcode: " + hc;
}
}
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
// Repeat serialization and deserialization. And get the
// hash code from a deserialized Locale object.
while (runrun) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(loc);
byte[] b = baos.toByteArray();
oos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(b);
ObjectInputStream ois = new ObjectInputStream(bais);
Locale loc2 = (Locale) ois.readObject();
int hc = loc2.hashCode();
if (hc != hashcode) {
runrun = false;
message = "t2: wrong hashcode: " + hc;
}
} catch (IOException ioe) {
runrun = false;
throw new RuntimeException("t2: can't perform test", ioe);
} catch (ClassNotFoundException cnfe) {
runrun = false;
throw new RuntimeException("t2: can't perform test", cnfe);
}
}
}
});
t1.start();
t2.start();
try {
for (int i = 0; runrun && i < duration; i++) {
Thread.sleep(1000);
}
runrun = false;
t1.join();
t2.join();
} catch (InterruptedException e) {
}
if (message != null) {
throw new RuntimeException(message);
}
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2007, 2023, 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 4944561
* @summary Test hashCode() to have less than 10% of hash code conflicts.
* @modules jdk.localedata
* @run junit HashCodeTest
*/
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
public class HashCodeTest {
// Ensure Locale.hashCode() has less than 10% conflicts
@Test
public void hashConflictsTest() {
Locale[] locales = Locale.getAvailableLocales();
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
Map<Integer, Locale> map = new HashMap<>(locales.length);
int conflicts = 0;
for (Locale loc : locales) {
int hc = loc.hashCode();
min = Math.min(hc, min);
max = Math.max(hc, max);
Integer key = hc;
if (map.containsKey(key)) {
conflicts++;
System.out.println("conflict: " + map.get(key) + ", " + loc);
} else {
map.put(key, loc);
}
}
System.out.println(locales.length + " locales: conflicts=" + conflicts
+ ", min=" + min + ", max=" + max + ", diff=" + (max - min));
assertFalse(conflicts >= (locales.length / 10),
String.format("%s conflicts per %s locales", conflicts, locales.length));
}
}

View file

@ -0,0 +1,150 @@
/*
* Copyright (c) 2016, 2023, 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 8071929
* @summary Test obsolete ISO3166-1 alpha-2 country codes should not be retrieved.
* ISO3166-1 alpha-2, ISO3166-1 alpha-3, ISO3166-3 country codes
* from overloaded getISOCountries(Iso3166 type) are retrieved correctly.
* @run junit ISO3166
*/
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Locale.IsoCountryCode;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;
public class ISO3166 {
private static final List<String> ISO3166_1_ALPHA2_OBSOLETE_CODES = List.of("AN", "BU", "CS",
"NT", "SF", "TP", "YU", "ZR");
private static final Set<String> ISO3166_3EXPECTED = Set.of(
"AIDJ", "ANHH", "BQAQ", "BUMM", "BYAA", "CSHH", "CSXX", "CTKI", "DDDE",
"DYBJ", "FQHH", "FXFR", "GEHH", "HVBF", "JTUM", "MIUM", "NHVU", "NQAQ",
"NTHH", "PCHH", "PUUM", "PZPA", "RHZW", "SKIN", "SUHH", "TPTL", "VDVN",
"WKUM", "YDYE", "YUCS", "ZRCD");
private static final Set<String> ISO3166_1_ALPHA3_EXPECTED
= Set.of("ABW", "AFG", "AGO", "AIA", "ALA", "ALB", "AND",
"ARE", "ARG", "ARM", "ASM", "ATA", "ATF", "ATG",
"AUS", "AUT", "AZE", "BDI", "BEL", "BEN", "BES", "BFA",
"BGD", "BGR", "BHR", "BHS", "BIH", "BLM", "BLR", "BLZ",
"BMU", "BOL", "BRA", "BRB", "BRN", "BTN", "BVT", "BWA", "CAF", "CAN",
"CCK", "CHE", "CHL", "CHN", "CIV", "CMR", "COD", "COG", "COK", "COL",
"COM", "CPV", "CRI", "CUB", "CUW", "CXR", "CYM", "CYP", "CZE", "DEU",
"DJI", "DMA", "DNK", "DOM", "DZA", "ECU", "EGY", "ERI", "ESH", "ESP",
"EST", "ETH", "FIN", "FJI", "FLK", "FRA", "FRO", "FSM", "GAB", "GBR",
"GEO", "GGY", "GHA", "GIB", "GIN", "GLP", "GMB", "GNB", "GNQ",
"GRC", "GRD", "GRL", "GTM", "GUF", "GUM", "GUY", "HKG", "HMD", "HND",
"HRV", "HTI", "HUN", "IDN", "IMN", "IND", "IOT", "IRL", "IRN", "IRQ",
"ISL", "ISR", "ITA", "JAM", "JEY", "JOR", "JPN", "KAZ", "KEN", "KGZ",
"KHM", "KIR", "KNA", "KOR", "KWT", "LAO", "LBN", "LBR", "LBY", "LCA",
"LIE", "LKA", "LSO", "LTU", "LUX", "LVA", "MAC", "MAF", "MAR", "MCO",
"MDA", "MDG", "MDV", "MEX", "MHL", "MKD", "MLI", "MLT", "MMR", "MNE",
"MNG", "MNP", "MOZ", "MRT", "MSR", "MTQ", "MUS", "MWI", "MYS", "MYT",
"NAM", "NCL", "NER", "NFK", "NGA", "NIC", "NIU", "NLD", "NOR", "NPL",
"NRU", "NZL", "OMN", "PAK", "PAN", "PCN", "PER", "PHL", "PLW", "PNG",
"POL", "PRI", "PRK", "PRT", "PRY", "PSE", "PYF", "QAT", "REU", "ROU",
"RUS", "RWA", "SAU", "SDN", "SEN", "SGP", "SGS", "SHN", "SJM", "SLB",
"SLE", "SLV", "SMR", "SOM", "SPM", "SRB", "SSD", "STP", "SUR", "SVK",
"SVN", "SWE", "SWZ", "SXM", "SYC", "SYR", "TCA", "TCD", "TGO", "THA",
"TJK", "TKL", "TKM", "TLS", "TON", "TTO", "TUN", "TUR", "TUV", "TWN",
"TZA", "UGA", "UKR", "UMI", "URY", "USA", "UZB", "VAT", "VCT", "VEN",
"VGB", "VIR", "VNM", "VUT", "WLF", "WSM", "YEM", "ZAF", "ZMB", "ZWE");
/**
* This method checks that obsolete ISO3166-1 alpha-2 country codes are not
* retrieved in output of getISOCountries() method.
*/
@Test
public void checkISO3166_1_Alpha2ObsoleteCodes() {
Set<String> unexpectedCodes = ISO3166_1_ALPHA2_OBSOLETE_CODES.stream().
filter(Set.of(Locale.getISOCountries())::contains).collect(Collectors.toSet());
if (!unexpectedCodes.isEmpty()) {
throw new RuntimeException("Obsolete ISO3166-1 alpha2 two letter"
+ " country Codes " + unexpectedCodes + " in output of getISOCountries() method");
}
}
/**
* This method checks that ISO3166-3 country codes which are PART3 of
* IsoCountryCode enum, are retrieved correctly.
*/
@Test
public void checkISO3166_3Codes() {
Set<String> iso3166_3Codes = Locale.getISOCountries(IsoCountryCode.PART3);
if (!iso3166_3Codes.equals(ISO3166_3EXPECTED)) {
reportDifference(iso3166_3Codes, ISO3166_3EXPECTED);
}
}
/**
* This method checks that ISO3166-1 alpha-3 country codes which are
* PART1_ALPHA3 of IsoCountryCode enum, are retrieved correctly.
*/
@Test
public void checkISO3166_1_Alpha3Codes() {
Set<String> iso3166_1_Alpha3Codes = Locale.getISOCountries(IsoCountryCode.PART1_ALPHA3);
if (!iso3166_1_Alpha3Codes.equals(ISO3166_1_ALPHA3_EXPECTED)) {
reportDifference(iso3166_1_Alpha3Codes, ISO3166_1_ALPHA3_EXPECTED);
}
}
/**
* This method checks that ISO3166-1 alpha-2 country codes, which are
* PART1_ALPHA2 of IsoCountryCode enum, are retrieved correctly.
*/
@Test
public void checkISO3166_1_Alpha2Codes() {
Set<String> iso3166_1_Alpha2Codes = Locale.getISOCountries(IsoCountryCode.PART1_ALPHA2);
Set<String> ISO3166_1_ALPHA2_EXPECTED = Set.of(Locale.getISOCountries());
if (!iso3166_1_Alpha2Codes.equals(ISO3166_1_ALPHA2_EXPECTED)) {
reportDifference(iso3166_1_Alpha2Codes, ISO3166_1_ALPHA2_EXPECTED);
}
}
private static void reportDifference(Set<String> retrievedCountrySet, Set<String> expectedCountrySet) {
Set<String> retrievedSet = new HashSet<>(retrievedCountrySet);
Set<String> expectedSet = new HashSet<>(expectedCountrySet);
retrievedSet.removeAll(expectedCountrySet);
expectedSet.removeAll(retrievedCountrySet);
if ((retrievedSet.size() > 0) && (expectedSet.size() > 0)) {
throw new RuntimeException("Retrieved country codes set contains extra codes "
+ retrievedSet + " and missing codes " + expectedSet);
}
if (retrievedSet.size() > 0) {
throw new RuntimeException("Retrieved country codes set contains extra codes "
+ retrievedSet);
}
if (expectedSet.size() > 0) {
throw new RuntimeException("Retrieved country codes set is missing codes "
+ expectedSet);
}
}
}

View file

@ -0,0 +1,297 @@
/*
* Copyright (c) 2007, 2023, 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
* @summary test ISO639-2 language codes
* @library /java/text/testlib
* @compile -encoding ascii ISO639.java
* @bug 4175998 8303917
* @run junit ISO639
*/
/*
*
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* The original version of this source code and documentation is
* copyrighted and owned by IBM. These materials are provided
* under terms of a License Agreement between IBM and Sun.
* This technology is protected by multiple US and International
* patents. This notice and attribution to IBM may not be removed.
*
*/
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Locale;
import java.util.stream.Stream;
import org.junit.jupiter.api.Disabled;
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 static org.junit.jupiter.api.Assertions.assertEquals;
public class ISO639 {
/**
* This test verifies for a given locale created from the ISO639 2-letter code,
* the correct ISO639 3-letter code is returned when calling getISO3Language().
*/
@ParameterizedTest
@MethodSource("expectedISO639Codes")
public void ISO3LetterTest(String ISO2, String expectedISO3) {
Locale loc = Locale.of(ISO2);
String actualISO3 = loc.getISO3Language();
assertEquals(actualISO3, expectedISO3,
String.format("The Locale '%s' returned a bad ISO3 language code. " +
"Got '%s' instead of '%s'", loc, actualISO3, expectedISO3));
}
// expectedISO639Codes generated from https://www.loc.gov/standards/iso639-2/ISO-639-2_utf-8.txt
// on March 9th, 2023.
private static Stream<Arguments> expectedISO639Codes() {
return Stream.of(
Arguments.of("aa","aar","aar"),
Arguments.of("ab","abk","abk"),
Arguments.of("af","afr","afr"),
Arguments.of("ak","aka","aka"),
Arguments.of("sq","sqi","alb"),
Arguments.of("am","amh","amh"),
Arguments.of("ar","ara","ara"),
Arguments.of("an","arg","arg"),
Arguments.of("hy","hye","arm"),
Arguments.of("as","asm","asm"),
Arguments.of("av","ava","ava"),
Arguments.of("ae","ave","ave"),
Arguments.of("ay","aym","aym"),
Arguments.of("az","aze","aze"),
Arguments.of("ba","bak","bak"),
Arguments.of("bm","bam","bam"),
Arguments.of("eu","eus","baq"),
Arguments.of("be","bel","bel"),
Arguments.of("bn","ben","ben"),
Arguments.of("bh","bih","bih"),
Arguments.of("bi","bis","bis"),
Arguments.of("bs","bos","bos"),
Arguments.of("br","bre","bre"),
Arguments.of("bg","bul","bul"),
Arguments.of("my","mya","bur"),
Arguments.of("ca","cat","cat"),
Arguments.of("ch","cha","cha"),
Arguments.of("ce","che","che"),
Arguments.of("zh","zho","chi"),
Arguments.of("cu","chu","chu"),
Arguments.of("cv","chv","chv"),
Arguments.of("kw","cor","cor"),
Arguments.of("co","cos","cos"),
Arguments.of("cr","cre","cre"),
Arguments.of("cs","ces","cze"),
Arguments.of("da","dan","dan"),
Arguments.of("dv","div","div"),
Arguments.of("nl","nld","dut"),
Arguments.of("dz","dzo","dzo"),
Arguments.of("en","eng","eng"),
Arguments.of("eo","epo","epo"),
Arguments.of("et","est","est"),
Arguments.of("ee","ewe","ewe"),
Arguments.of("fo","fao","fao"),
Arguments.of("fj","fij","fij"),
Arguments.of("fi","fin","fin"),
Arguments.of("fr","fra","fre"),
Arguments.of("fy","fry","fry"),
Arguments.of("ff","ful","ful"),
Arguments.of("ka","kat","geo"),
Arguments.of("de","deu","ger"),
Arguments.of("gd","gla","gla"),
Arguments.of("ga","gle","gle"),
Arguments.of("gl","glg","glg"),
Arguments.of("gv","glv","glv"),
Arguments.of("el","ell","gre"),
Arguments.of("gn","grn","grn"),
Arguments.of("gu","guj","guj"),
Arguments.of("ht","hat","hat"),
Arguments.of("ha","hau","hau"),
Arguments.of("he","heb","heb"),
Arguments.of("hz","her","her"),
Arguments.of("hi","hin","hin"),
Arguments.of("ho","hmo","hmo"),
Arguments.of("hr","hrv","hrv"),
Arguments.of("hu","hun","hun"),
Arguments.of("ig","ibo","ibo"),
Arguments.of("is","isl","ice"),
Arguments.of("io","ido","ido"),
Arguments.of("ii","iii","iii"),
Arguments.of("iu","iku","iku"),
Arguments.of("ie","ile","ile"),
Arguments.of("ia","ina","ina"),
Arguments.of("id","ind","ind"),
Arguments.of("ik","ipk","ipk"),
Arguments.of("it","ita","ita"),
Arguments.of("jv","jav","jav"),
Arguments.of("ja","jpn","jpn"),
Arguments.of("kl","kal","kal"),
Arguments.of("kn","kan","kan"),
Arguments.of("ks","kas","kas"),
Arguments.of("kr","kau","kau"),
Arguments.of("kk","kaz","kaz"),
Arguments.of("km","khm","khm"),
Arguments.of("ki","kik","kik"),
Arguments.of("rw","kin","kin"),
Arguments.of("ky","kir","kir"),
Arguments.of("kv","kom","kom"),
Arguments.of("kg","kon","kon"),
Arguments.of("ko","kor","kor"),
Arguments.of("kj","kua","kua"),
Arguments.of("ku","kur","kur"),
Arguments.of("lo","lao","lao"),
Arguments.of("la","lat","lat"),
Arguments.of("lv","lav","lav"),
Arguments.of("li","lim","lim"),
Arguments.of("ln","lin","lin"),
Arguments.of("lt","lit","lit"),
Arguments.of("lb","ltz","ltz"),
Arguments.of("lu","lub","lub"),
Arguments.of("lg","lug","lug"),
Arguments.of("mk","mkd","mac"),
Arguments.of("mh","mah","mah"),
Arguments.of("ml","mal","mal"),
Arguments.of("mi","mri","mao"),
Arguments.of("mr","mar","mar"),
Arguments.of("ms","msa","may"),
Arguments.of("mg","mlg","mlg"),
Arguments.of("mt","mlt","mlt"),
Arguments.of("mn","mon","mon"),
Arguments.of("na","nau","nau"),
Arguments.of("nv","nav","nav"),
Arguments.of("nr","nbl","nbl"),
Arguments.of("nd","nde","nde"),
Arguments.of("ng","ndo","ndo"),
Arguments.of("ne","nep","nep"),
Arguments.of("nn","nno","nno"),
Arguments.of("nb","nob","nob"),
Arguments.of("no","nor","nor"),
Arguments.of("ny","nya","nya"),
Arguments.of("oc","oci","oci"),
Arguments.of("oj","oji","oji"),
Arguments.of("or","ori","ori"),
Arguments.of("om","orm","orm"),
Arguments.of("os","oss","oss"),
Arguments.of("pa","pan","pan"),
Arguments.of("fa","fas","per"),
Arguments.of("pi","pli","pli"),
Arguments.of("pl","pol","pol"),
Arguments.of("pt","por","por"),
Arguments.of("ps","pus","pus"),
Arguments.of("qu","que","que"),
Arguments.of("rm","roh","roh"),
Arguments.of("ro","ron","rum"),
Arguments.of("rn","run","run"),
Arguments.of("ru","rus","rus"),
Arguments.of("sg","sag","sag"),
Arguments.of("sa","san","san"),
Arguments.of("si","sin","sin"),
Arguments.of("sk","slk","slo"),
Arguments.of("sl","slv","slv"),
Arguments.of("se","sme","sme"),
Arguments.of("sm","smo","smo"),
Arguments.of("sn","sna","sna"),
Arguments.of("sd","snd","snd"),
Arguments.of("so","som","som"),
Arguments.of("st","sot","sot"),
Arguments.of("es","spa","spa"),
Arguments.of("sc","srd","srd"),
Arguments.of("sr","srp","srp"),
Arguments.of("ss","ssw","ssw"),
Arguments.of("su","sun","sun"),
Arguments.of("sw","swa","swa"),
Arguments.of("sv","swe","swe"),
Arguments.of("ty","tah","tah"),
Arguments.of("ta","tam","tam"),
Arguments.of("tt","tat","tat"),
Arguments.of("te","tel","tel"),
Arguments.of("tg","tgk","tgk"),
Arguments.of("tl","tgl","tgl"),
Arguments.of("th","tha","tha"),
Arguments.of("bo","bod","tib"),
Arguments.of("ti","tir","tir"),
Arguments.of("to","ton","ton"),
Arguments.of("tn","tsn","tsn"),
Arguments.of("ts","tso","tso"),
Arguments.of("tk","tuk","tuk"),
Arguments.of("tr","tur","tur"),
Arguments.of("tw","twi","twi"),
Arguments.of("ug","uig","uig"),
Arguments.of("uk","ukr","ukr"),
Arguments.of("ur","urd","urd"),
Arguments.of("uz","uzb","uzb"),
Arguments.of("ve","ven","ven"),
Arguments.of("vi","vie","vie"),
Arguments.of("vo","vol","vol"),
Arguments.of("cy","cym","wel"),
Arguments.of("wa","wln","wln"),
Arguments.of("wo","wol","wol"),
Arguments.of("xh","xho","xho"),
Arguments.of("yi","yid","yid"),
Arguments.of("yo","yor","yor"),
Arguments.of("za","zha","zha"),
Arguments.of("zu","zul","zul")
);
}
@Test
@Disabled("For updating expected ISO data, NOT an actual test")
public void getISOData() {
// Remove @Disabled to generate new ISO Data
generateTables();
}
private static final String ISO639 = "ISO-639-2_utf-8.txt";
private static void generateTables() {
try {
BufferedReader ISO639File = new BufferedReader(new FileReader(ISO639));
for (String line = ISO639File.readLine(); line != null; line = ISO639File.readLine()) {
String[] tokens= line.split("\\|");
String iso639_1 = tokens[2];
String iso639_2B = tokens[1];
String iso639_2T = tokens[0];
if (iso639_1.isEmpty()){
continue; // Skip if not both a 639-1 and 639-2 code
}
if (iso639_2B.isEmpty()){
iso639_2B = iso639_2T; // Default 639/B to 639/T if empty
}
System.out.printf("""
Arguments.of("%s","%s","%s"),
""", iso639_1, iso639_2B, iso639_2T);
}
} catch (Exception e) {
System.out.println(e);
}
}
}

View file

@ -0,0 +1,295 @@
/*
* 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 4449637 8008577 8174269 8333582
* @summary Basic acceptance test for international J2RE. Verifies that the
* most important locale data and character converters exist and are
* minimally functional.
* @modules jdk.localedata
* jdk.charsets
* @run main InternationalBAT
*/
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class InternationalBAT {
public static void main(String[] args) {
boolean pass = true;
TimeZone tz = TimeZone.getDefault();
try {
pass &= testRequiredLocales();
pass &= testRequiredEncodings();
} finally {
TimeZone.setDefault(tz);
}
if (!pass) {
System.out.println("\nSome tests failed.\n"
+ "If you installed the US-only J2RE for Windows, "
+ "failures are expected and OK.\n"
+ "If you installed the international J2RE, or any J2SDK, "
+ "or if this occurs on any platform other than Windows, "
+ "please file a bug report.\n"
+ "Unfortunately, this test cannot determine whether you "
+ "installed a US-only J2RE, an international J2RE, or "
+ "a J2SDK.\n");
throw new RuntimeException();
}
}
// We require the "fully supported locales" for java.util and java.text:
// http://webwork.eng/j2se/1.4/docs/guide/intl/locale.doc.html#util-text
private static Locale[] requiredLocales = {
Locale.of("ar", "SA"),
Locale.CHINA,
Locale.TAIWAN,
Locale.of("nl", "NL"),
Locale.of("en", "AU"),
Locale.of("en", "CA"),
Locale.UK,
Locale.US,
Locale.of("fr", "CA"),
Locale.FRANCE,
Locale.GERMANY,
Locale.of("iw", "IL"),
Locale.of("hi", "IN"),
Locale.ITALY,
Locale.JAPAN,
Locale.KOREA,
Locale.of("pt", "BR"),
Locale.of("es", "ES"),
Locale.of("sv", "SE"),
Locale.of("th", "TH"),
};
// Date strings for May 10, 2001, for the required locales
private static String[] requiredLocaleDates = {
"\u0627\u0644\u062e\u0645\u064a\u0633\u060c \u0661\u0660 \u0645\u0627\u064a\u0648 \u0662\u0660\u0660\u0661",
"2001\u5e745\u670810\u65e5\u661f\u671f\u56db",
"2001\u5E745\u670810\u65E5 \u661F\u671F\u56DB",
"donderdag 10 mei 2001",
"Thursday, 10 May 2001",
"Thursday, May 10, 2001",
"Thursday, 10 May 2001",
"Thursday, May 10, 2001",
"jeudi 10 mai 2001",
"jeudi 10 mai 2001",
"Donnerstag, 10. Mai 2001",
"\u05d9\u05d5\u05dd \u05d7\u05de\u05d9\u05e9\u05d9, 10 \u05d1\u05de\u05d0\u05d9 2001",
"\u0917\u0941\u0930\u0941\u0935\u093e\u0930, 10 \u092e\u0908 2001",
"gioved\u00EC 10 maggio 2001",
"2001\u5e745\u670810\u65e5\u6728\u66dc\u65e5", // ja_JP
"2001\uB144 5\uC6D4 10\uC77C \uBAA9\uC694\uC77C",
"quinta-feira, 10 de maio de 2001",
"jueves, 10 de mayo de 2001",
"torsdag 10 maj 2001",
"\u0e27\u0e31\u0e19\u0e1e\u0e24\u0e2b\u0e31\u0e2a\u0e1a\u0e14\u0e35\u0e17\u0e35\u0e48 10 \u0e1e\u0e24\u0e29\u0e20\u0e32\u0e04\u0e21 \u0e1e\u0e38\u0e17\u0e18\u0e28\u0e31\u0e01\u0e23\u0e32\u0e0a 2544",
};
private static boolean testRequiredLocales() {
boolean pass = true;
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
Calendar calendar = Calendar.getInstance(Locale.US);
calendar.clear();
calendar.set(2001, 4, 10, 12, 0, 0);
Date date = calendar.getTime();
Locale[] available = Locale.getAvailableLocales();
for (int i = 0; i < requiredLocales.length; i++) {
Locale locale = requiredLocales[i];
boolean found = false;
for (int j = 0; j < available.length; j++) {
if (available[j].equals(locale)) {
found = true;
break;
}
}
if (!found) {
System.out.println("Locale not available: " + locale);
pass = false;
} else {
DateFormat format =
DateFormat.getDateInstance(DateFormat.FULL, locale);
String dateString = format.format(date);
if (!dateString.equals(requiredLocaleDates[i])) {
System.out.println("Incorrect date string for locale "
+ locale + ". Expected: " + requiredLocaleDates[i]
+ ", got: " + dateString);
pass = false;
}
}
}
return pass;
}
// We require the encodings of the fully supported writing systems:
// http://webwork.eng/j2se/1.4/docs/guide/intl/locale.doc.html#jfc
private static String[] requiredEncodings = {
"Cp1256",
"MS936",
"MS950",
"Cp1255",
"MS932",
"MS949",
"Cp1252",
"MS874",
"ISO8859_6",
"EUC_CN",
"UTF8",
"GBK",
"EUC_TW",
"ISO8859_8",
"EUC_JP",
"PCK",
"EUC_KR",
"ISO8859_1",
"ISO8859_15",
"TIS620",
};
// one sample locale each for the required encodings
private static Locale[] sampleLocales = {
Locale.of("ar", "SA"),
Locale.of("zh", "CN"),
Locale.of("zh", "TW"),
Locale.of("iw", "IL"),
Locale.of("ja", "JP"),
Locale.of("ko", "KR"),
Locale.of("it", "IT"),
Locale.of("th", "TH"),
Locale.of("ar", "SA"),
Locale.of("zh", "CN"),
Locale.of("zh", "CN"),
Locale.of("zh", "CN"),
Locale.of("zh", "TW"),
Locale.of("iw", "IL"),
Locale.of("ja", "JP"),
Locale.of("ja", "JP"),
Locale.of("ko", "KR"),
Locale.of("it", "IT"),
Locale.of("it", "IT"),
Locale.of("th", "TH"),
};
// expected conversion results for the date strings of the sample locales
private static byte[][] expectedBytes = {
{ (byte) 0xC7, (byte) 0xE1, (byte) 0xCE, (byte) 0xE3, (byte) 0xED, (byte) 0xD3, (byte) 0xA1, 0x20, 0x3F, 0x3F, 0x20, (byte) 0xE3, (byte) 0xC7, (byte) 0xED, (byte) 0xE6, 0x20, 0x3F, 0x3F, 0x3F, 0x3F, },
{ 0x32, 0x30, 0x30, 0x31, (byte) 0xC4, (byte) 0xEA, 0x35, (byte) 0xD4, (byte) 0xC2, 0x31, 0x30, (byte) 0xC8, (byte) 0xD5, (byte) 0xD0, (byte) 0xC7, (byte) 0xC6, (byte) 0xDA, (byte) 0xCB, (byte) 0xC4, },
{ 0x32, 0x30, 0x30, 0x31, (byte) 0xA6, 0x7E, 0x35, (byte) 0xA4, (byte) 0xEB, 0x31, 0x30, (byte) 0xA4, (byte) 0xE9, 0x20, (byte) 0xAC, (byte)0x50, (byte) 0xB4, (byte) 0xC1, (byte) 0xA5, (byte) 0x7C},
{ (byte) 0xE9, (byte) 0xE5, (byte) 0xED, 0x20, (byte) 0xE7, (byte) 0xEE, (byte) 0xE9, (byte) 0xF9, (byte) 0xE9, 0x2C, 0x20, 0x31, 0x30, 0x20, (byte) 0xE1, (byte) 0xEE, (byte) 0xE0, (byte) 0xE9, 0x20, 0x32, 0x30, 0x30, 0x31, },
{ 0x32, 0x30, 0x30, 0x31, (byte) 0x94, 0x4E, 0x35, (byte) 0x8C, (byte) 0x8E, 0x31, 0x30, (byte) 0x93, (byte) 0xFA, (byte) 0x96, (byte) 0xD8, (byte) 0x97, 0x6A, (byte) 0x93, (byte) 0xFA, },
{ 0x32, 0x30, 0x30, 0x31, (byte) 0xB3, (byte) 0xE2, 0x20, 0x35, (byte) 0xBF, (byte) 0xF9, 0x20, 0x31, 0x30, (byte) 0xC0, (byte) 0xCF, 0x20, (byte) 0xB8, (byte) 0xF1, (byte) 0xBF, (byte) 0xE4, (byte) 0xC0, (byte) 0xCF, },
{ 0x67, 0x69, 0x6F, 0x76, 0x65, 0x64, (byte) 0xEC, 0x20, 0x31, 0x30, 0x20, 0x6D, 0x61, 0x67, 0x67, 0x69, 0x6F, 0x20, 0x32, 0x30, 0x30, 0x31, },
{ (byte) 0xC7, (byte) 0xD1, (byte) 0xB9, (byte) 0xBE, (byte) 0xC4, (byte) 0xCB, (byte) 0xD1, (byte) 0xCA, (byte) 0xBA, (byte) 0xB4, (byte) 0xD5, (byte) 0xB7, (byte) 0xD5, (byte) 0xE8, 0x20, 0x31, 0x30, 0x20, (byte) 0xBE, (byte) 0xC4, (byte) 0xC9, (byte) 0xC0, (byte) 0xD2, (byte) 0xA4, (byte) 0xC1, 0x20, (byte) 0xBE, (byte) 0xD8, (byte) 0xB7, (byte) 0xB8, (byte) 0xC8, (byte) 0xD1, (byte) 0xA1, (byte) 0xC3, (byte) 0xD2, (byte) 0xAA, 0x20, 0x32, 0x35, 0x34, 0x34, },
{ (byte) 0xC7, (byte) 0xE4, (byte) 0xCE, (byte) 0xE5, (byte) 0xEA, (byte) 0xD3, (byte) 0xAC, 0x20, 0x3F, 0x3F, 0x20, (byte) 0xE5, (byte) 0xC7, (byte) 0xEA, (byte) 0xE8, 0x20, 0x3F, 0x3F, 0x3F, 0x3F, },
{ 0x32, 0x30, 0x30, 0x31, (byte) 0xC4, (byte) 0xEA, 0x35, (byte) 0xD4, (byte) 0xC2, 0x31, 0x30, (byte) 0xC8, (byte) 0xD5, (byte) 0xD0, (byte) 0xC7, (byte) 0xC6, (byte) 0xDA, (byte) 0xCB, (byte) 0xC4, },
{ 0x32, 0x30, 0x30, 0x31, (byte) 0xE5, (byte) 0xB9, (byte) 0xB4, 0x35, (byte) 0xE6, (byte) 0x9C, (byte) 0x88, 0x31, 0x30, (byte) 0xE6, (byte) 0x97, (byte) 0xA5, (byte) 0xE6, (byte) 0x98, (byte) 0x9F, (byte) 0xE6, (byte) 0x9C, (byte) 0x9F, (byte) 0xE5, (byte) 0x9B, (byte) 0x9B, },
{ 0x32, 0x30, 0x30, 0x31, (byte) 0xC4, (byte) 0xEA, 0x35, (byte) 0xD4, (byte) 0xC2, 0x31, 0x30, (byte) 0xC8, (byte) 0xD5, (byte) 0xD0, (byte) 0xC7, (byte) 0xC6, (byte) 0xDA, (byte) 0xCB, (byte) 0xC4, },
{ 0x32, 0x30, 0x30, 0x31, (byte) 0xC8, (byte) 0xA1, 0x35, (byte) 0xC5, (byte) 0xCC, 0x31, 0x30, (byte) 0xC5, (byte) 0xCA, 0x20, (byte) 0xD1, (byte) 0xD3, (byte) 0xDF, (byte) 0xE6, (byte) 0xC6, (byte) 0xBE},
{ (byte) 0xE9, (byte) 0xE5, (byte) 0xED, 0x20, (byte) 0xE7, (byte) 0xEE, (byte) 0xE9, (byte) 0xF9, (byte) 0xE9, 0x2C, 0x20, 0x31, 0x30, 0x20, (byte) 0xE1, (byte) 0xEE, (byte) 0xE0, (byte) 0xE9, 0x20, 0x32, 0x30, 0x30, 0x31, },
{ 0x32, 0x30, 0x30, 0x31, (byte) 0xC7, (byte) 0xAF, 0x35, (byte) 0xB7, (byte) 0xEE, 0x31, 0x30, (byte) 0xC6, (byte) 0xFC, (byte) 0xCC, (byte) 0xDA, (byte) 0xCD, (byte) 0xCB, (byte) 0xC6, (byte) 0xFC, },
{ 0x32, 0x30, 0x30, 0x31, (byte) 0x94, 0x4E, 0x35, (byte) 0x8C, (byte) 0x8E, 0x31, 0x30, (byte) 0x93, (byte) 0xFA, (byte) 0x96, (byte) 0xD8, (byte) 0x97, 0x6A, (byte) 0x93, (byte) 0xFA, },
{ 0x32, 0x30, 0x30, 0x31, (byte) 0xB3, (byte) 0xE2, 0x20, 0x35, (byte) 0xBF, (byte) 0xF9, 0x20, 0x31, 0x30, (byte) 0xC0, (byte) 0xCF, 0x20, (byte) 0xB8, (byte) 0xF1, (byte) 0xBF, (byte) 0xE4, (byte) 0xC0, (byte) 0xCF, },
{ 0x67, 0x69, 0x6F, 0x76, 0x65, 0x64, (byte) 0xEC, 0x20, 0x31, 0x30, 0x20, 0x6D, 0x61, 0x67, 0x67, 0x69, 0x6F, 0x20, 0x32, 0x30, 0x30, 0x31, },
{ 0x67, 0x69, 0x6F, 0x76, 0x65, 0x64, (byte) 0xEC, 0x20, 0x31, 0x30, 0x20, 0x6D, 0x61, 0x67, 0x67, 0x69, 0x6F, 0x20, 0x32, 0x30, 0x30, 0x31, },
{ (byte) 0xC7, (byte) 0xD1, (byte) 0xB9, (byte) 0xBE, (byte) 0xC4, (byte) 0xCB, (byte) 0xD1, (byte) 0xCA, (byte) 0xBA, (byte) 0xB4, (byte) 0xD5, (byte) 0xB7, (byte) 0xD5, (byte) 0xE8, 0x20, 0x31, 0x30, 0x20, (byte) 0xBE, (byte) 0xC4, (byte) 0xC9, (byte) 0xC0, (byte) 0xD2, (byte) 0xA4, (byte) 0xC1, 0x20, (byte) 0xBE, (byte) 0xD8, (byte) 0xB7, (byte) 0xB8, (byte) 0xC8, (byte) 0xD1, (byte) 0xA1, (byte) 0xC3, (byte) 0xD2, (byte) 0xAA, 0x20, 0x32, 0x35, 0x34, 0x34, },
};
private static boolean testRequiredEncodings() {
boolean pass = true;
for (int i = 0; i < requiredEncodings.length; i++) {
String encoding = requiredEncodings[i];
Locale sampleLocale = sampleLocales[i];
try {
int index = 0;
while (!sampleLocale.equals(requiredLocales[index])) {
index++;
}
byte[] out = requiredLocaleDates[index].getBytes(encoding);
byte[] expected = expectedBytes[i];
if (out.length != expected.length) {
reportConversionError(encoding, expected, out);
pass = false;
} else {
for (int j = 0; j < out.length; j++) {
if (out[j] != expected[j]) {
reportConversionError(encoding, expected, out);
pass = false;
break;
}
}
}
} catch (UnsupportedEncodingException e) {
System.out.println("Encoding not available: " + encoding);
pass = false;
}
}
return pass;
}
private static void reportConversionError(String encoding,
byte[] expected, byte[] actual) {
System.out.println("Incorrect conversion for encoding: " + encoding);
System.out.println("Expected output:");
dumpBytes(expected);
System.out.println("Actual output:");
dumpBytes(actual);
}
private static void dumpBytes(byte[] bytes) {
System.out.print(" { ");
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
if (b < 0) {
System.out.print("(byte) ");
}
System.out.print("0x" + toHex((b & 0x00F0) >> 4)
+ toHex((b & 0x000F)) + ", ");
}
System.out.println("},");
}
private static char toHex(int i) {
if (i <= 9) {
return (char) ('0' + i);
} else {
return (char) ('A' + i - 10);
}
}
}

View file

@ -0,0 +1,128 @@
/*
* Copyright (c) 2012, 2023, 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 8001562
* @summary Verify that getAvailableLocales() in locale sensitive services
* classes return compatible set of locales as in JDK7.
* @modules jdk.localedata
* @run junit JDK7LocaleServiceDiffs
*/
import java.text.BreakIterator;
import java.text.Collator;
import java.text.DateFormat;
import java.text.DateFormatSymbols;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
public class JDK7LocaleServiceDiffs {
static final List<String> jdk7availTags = List.of(
"ar", "ar-AE", "ar-BH", "ar-DZ", "ar-EG", "ar-IQ", "ar-JO", "ar-KW",
"ar-LB", "ar-LY", "ar-MA", "ar-OM", "ar-QA", "ar-SA", "ar-SD", "ar-SY",
"ar-TN", "ar-YE", "be", "be-BY", "bg", "bg-BG", "ca", "ca-ES", "cs",
"cs-CZ", "da", "da-DK", "de", "de-AT", "de-CH", "de-DE", "de-LU", "el",
"el-CY", "el-GR", "en", "en-AU", "en-CA", "en-GB", "en-IE", "en-IN",
"en-MT", "en-NZ", "en-PH", "en-SG", "en-US", "en-ZA", "es", "es-AR",
"es-BO", "es-CL", "es-CO", "es-CR", "es-DO", "es-EC", "es-ES", "es-GT",
"es-HN", "es-MX", "es-NI", "es-PA", "es-PE", "es-PR", "es-PY", "es-SV",
"es-US", "es-UY", "es-VE", "et", "et-EE", "fi", "fi-FI", "fr", "fr-BE",
"fr-CA", "fr-CH", "fr-FR", "fr-LU", "ga", "ga-IE", "he", "he-IL",
"hi-IN", "hr", "hr-HR", "hu", "hu-HU", "id", "id-ID", "is", "is-IS",
"it", "it-CH", "it-IT", "ja", "ja-JP",
"ja-JP-u-ca-japanese-x-lvariant-JP", "ko", "ko-KR", "lt", "lt-LT", "lv",
"lv-LV", "mk", "mk-MK", "ms", "ms-MY", "mt", "mt-MT", "nl", "nl-BE",
"nl-NL", "no", "no-NO", "no-NO-x-lvariant-NY", "pl", "pl-PL", "pt",
"pt-BR", "pt-PT", "ro", "ro-RO", "ru", "ru-RU", "sk", "sk-SK", "sl",
"sl-SI", "sq", "sq-AL", "sr", "sr-BA", "sr-CS", "sr-Latn", "sr-Latn-BA",
"sr-Latn-ME", "sr-Latn-RS", "sr-ME", "sr-RS", "sv", "sv-SE", "th",
"th-TH", "th-TH-u-nu-thai-x-lvariant-TH", "tr", "tr-TR", "uk", "uk-UA",
"vi", "vi-VN", "zh", "zh-CN", "zh-HK", "zh-SG", "zh-TW");
static List<Locale> jdk7availLocs;
static {
jdk7availLocs = jdk7availTags.stream()
.map(Locale::forLanguageTag)
.collect(Collectors.toList());
}
/**
* This test compares the locales returned by getAvailableLocales() from a
* locale sensitive service to the available JDK7 locales. If the locales from
* a locale sensitive service are found to not contain a JDK7 available tag,
* the test will fail.
*/
@ParameterizedTest
@MethodSource("serviceProvider")
public void compatibleLocalesTest(Class<?> c, List<Locale> locs) {
diffLocale(c, locs);
}
static void diffLocale(Class<?> c, List<Locale> locs) {
String diff = "";
System.out.printf("Only in target locales (%s.getAvailableLocales()): ", c.getSimpleName());
for (Locale l : locs) {
if (!jdk7availLocs.contains(l)) {
diff += "\"" + l.toLanguageTag() + "\", ";
}
}
System.out.println(diff);
diff = "";
System.out.printf("Only in JDK7 (%s.getAvailableLocales()): ", c.getSimpleName());
for (Locale l : jdk7availLocs) {
if (!locs.contains(l)) {
diff += "\"" + l.toLanguageTag() + "\", ";
}
}
System.out.println(diff);
if (diff.length() > 0) {
throw new RuntimeException("Above locale(s) were not included in the target available locales");
}
}
private static Stream<Arguments> serviceProvider() {
return Stream.of(
Arguments.of(BreakIterator.class, Arrays.asList(BreakIterator.getAvailableLocales())),
Arguments.of(Collator.class, Arrays.asList(Collator.getAvailableLocales())),
Arguments.of(DateFormat.class, Arrays.asList(DateFormat.getAvailableLocales())),
Arguments.of(DateFormatSymbols.class, Arrays.asList(DateFormatSymbols.getAvailableLocales())),
Arguments.of(DecimalFormatSymbols.class, Arrays.asList(DecimalFormatSymbols.getAvailableLocales())),
Arguments.of(NumberFormat.class, Arrays.asList(NumberFormat.getAvailableLocales())),
Arguments.of(Locale.class, Arrays.asList(Locale.getAvailableLocales()))
);
}
}

View file

@ -0,0 +1,378 @@
/*
* Copyright (c) 2018, 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 8204938 8242010
* @summary Checks the IANA language subtag registry data update
* with Locale.LanguageRange parse method.
* @run main LSRDataTest
*/
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Locale;
import java.util.Locale.LanguageRange;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.Locale.LanguageRange.MAX_WEIGHT;
import static java.util.Locale.LanguageRange.MIN_WEIGHT;
public class LSRDataTest {
private static final char HYPHEN = '-';
private static final Map<String, String> singleLangEquivMap = new HashMap<>();
private static final Map<String, List<String>> multiLangEquivsMap = new HashMap<>();
private static final Map<String, String> regionVariantEquivMap = new HashMap<>();
// path to the lsr file from the data folder, this test relies on the
// relative path to the file in the data folder, considering
// test and src/.../data will always exist in the same jdk layout
private static final String LSR_FILE_PATH = System.getProperty("test.src", ".")
+ "/../../../../../src/java.base/share/data/lsrdata/language-subtag-registry.txt";
public static void main(String[] args) throws IOException {
loadLSRData(Paths.get(LSR_FILE_PATH).toRealPath());
// checking the tags with weight
String ranges = "Accept-Language: aam, adp, aue, bcg, cqu, ema,"
+ " en-gb-oed, gti, koj, kwq, kxe, lii, lmm, mtm, ngv,"
+ " oyb, phr, pub, suj, taj;q=0.9, yug;q=0.5, gfx;q=0.4";
List<LanguageRange> expected = parse(ranges);
List<LanguageRange> actual = LanguageRange.parse(ranges);
checkEquality(actual, expected);
// checking all language ranges
ranges = generateLangRanges();
expected = parse(ranges);
actual = LanguageRange.parse(ranges);
checkEquality(actual, expected);
// checking all region/variant ranges
ranges = generateRegionRanges();
expected = parse(ranges);
actual = LanguageRange.parse(ranges);
checkEquality(actual, expected);
}
// generate range string containing all equiv language tags
private static String generateLangRanges() {
return Stream.concat(singleLangEquivMap.keySet().stream(), multiLangEquivsMap
.keySet().stream()).collect(Collectors.joining(","));
}
// generate range string containing all equiv region tags
private static String generateRegionRanges() {
return regionVariantEquivMap.keySet().stream()
.map(r -> "en".concat(r)).collect(Collectors.joining(", "));
}
// load LSR data from the file
private static void loadLSRData(Path path) throws IOException {
String type = null;
String tag = null;
String preferred = null;
String prefix = null;
for (String line : Files.readAllLines(path, Charset.forName("UTF-8"))) {
line = line.toLowerCase(Locale.ROOT);
int index = line.indexOf(' ') + 1;
if (line.startsWith("type:")) {
type = line.substring(index);
} else if (line.startsWith("tag:") || line.startsWith("subtag:")) {
tag = line.substring(index);
} else if (line.startsWith("preferred-value:")) {
preferred = line.substring(index);
} else if (line.startsWith("prefix:")) {
prefix = line.substring(index);
} else if (line.equals("%%")) {
processDataAndGenerateMaps(type, tag, preferred, prefix);
type = null;
tag = null;
preferred = null;
prefix = null;
}
}
// Last entry
processDataAndGenerateMaps(type, tag, preferred, prefix);
}
private static void processDataAndGenerateMaps(String type,
String tag,
String preferred,
String prefix) {
if (type == null || tag == null || preferred == null) {
return;
}
if (type.equals("extlang") && prefix != null) {
tag = prefix + "-" + tag;
}
if (type.equals("region") || type.equals("variant")) {
if (!regionVariantEquivMap.containsKey(preferred)) {
String tPref = HYPHEN + preferred;
String tTag = HYPHEN + tag;
regionVariantEquivMap.put(tPref, tTag);
regionVariantEquivMap.put(tTag, tPref);
} else {
throw new RuntimeException("New case, need implementation."
+ " A region/variant subtag \"" + preferred
+ "\" is registered for more than one subtags.");
}
} else { // language, extlang, legacy, and redundant
if (!singleLangEquivMap.containsKey(preferred)
&& !multiLangEquivsMap.containsKey(preferred)) {
// new entry add it into single equiv map
singleLangEquivMap.put(preferred, tag);
singleLangEquivMap.put(tag, preferred);
} else if (singleLangEquivMap.containsKey(preferred)
&& !multiLangEquivsMap.containsKey(preferred)) {
String value = singleLangEquivMap.get(preferred);
List<String> subtags = List.of(preferred, value, tag);
// remove from single eqiv map before adding to multi equiv
singleLangEquivMap.keySet().removeAll(subtags);
addEntriesToMultiEquivsMap(subtags);
} else if (multiLangEquivsMap.containsKey(preferred)
&& !singleLangEquivMap.containsKey(preferred)) {
List<String> subtags = multiLangEquivsMap.get(preferred);
// should use the order preferred, subtags, tag to keep the
// expected order same as the JDK API in multi equivalent maps
subtags.add(0, preferred);
subtags.add(tag);
addEntriesToMultiEquivsMap(subtags);
}
}
}
// Add entries into the multi equivalent map from the given subtags
private static void addEntriesToMultiEquivsMap(List<String> subtags) {
// for each subtag within the given subtags, add an entry in multi
// equivalent language map with subtag as the key and the value
// as the list of all subtags excluding the one which is getting
// traversed
subtags.forEach(subtag -> multiLangEquivsMap.put(subtag, subtags.stream()
.filter(t -> !t.equals(subtag))
.collect(Collectors.toList())));
}
private static List<LanguageRange> parse(String ranges) {
ranges = ranges.replace(" ", "").toLowerCase(Locale.ROOT);
if (ranges.startsWith("accept-language:")) {
ranges = ranges.substring(16);
}
String[] langRanges = ranges.split(",");
List<LanguageRange> priorityList = new ArrayList<>(langRanges.length);
int numOfRanges = 0;
for (String range : langRanges) {
int wIndex = range.indexOf(";q=");
String tag;
double weight = 0.0;
if (wIndex == -1) {
tag = range;
weight = MAX_WEIGHT;
} else {
tag = range.substring(0, wIndex);
try {
weight = Double.parseDouble(range.substring(wIndex + 3));
} catch (RuntimeException ex) {
throw new IllegalArgumentException("weight= " + weight + " for"
+ " language range \"" + tag + "\", should be"
+ " represented as a double");
}
if (weight < MIN_WEIGHT || weight > MAX_WEIGHT) {
throw new IllegalArgumentException("weight=" + weight
+ " for language range \"" + tag
+ "\", must be between " + MIN_WEIGHT
+ " and " + MAX_WEIGHT + ".");
}
}
LanguageRange entry = new LanguageRange(tag, weight);
if (!priorityList.contains(entry)) {
int index = numOfRanges;
// find the index in the list to add the current range at the
// correct index sorted by the descending order of weight
for (int i = 0; i < priorityList.size(); i++) {
if (priorityList.get(i).getWeight() < weight) {
index = i;
break;
}
}
priorityList.add(index, entry);
numOfRanges++;
String equivalent = getEquivalentForRegionAndVariant(tag);
if (equivalent != null) {
LanguageRange equivRange = new LanguageRange(equivalent, weight);
if (!priorityList.contains(equivRange)) {
priorityList.add(index + 1, equivRange);
numOfRanges++;
}
}
List<String> equivalents = getEquivalentsForLanguage(tag);
if (equivalents != null) {
for (String equiv : equivalents) {
LanguageRange equivRange = new LanguageRange(equiv, weight);
if (!priorityList.contains(equivRange)) {
priorityList.add(index + 1, equivRange);
numOfRanges++;
}
equivalent = getEquivalentForRegionAndVariant(equiv);
if (equivalent != null) {
equivRange = new LanguageRange(equivalent, weight);
if (!priorityList.contains(equivRange)) {
priorityList.add(index + 1, equivRange);
numOfRanges++;
}
}
}
}
}
}
return priorityList;
}
/**
* A faster alternative approach to String.replaceFirst(), if the given
* string is a literal String, not a regex.
*/
private static String replaceFirstSubStringMatch(String range,
String substr, String replacement) {
int pos = range.indexOf(substr);
if (pos == -1) {
return range;
} else {
return range.substring(0, pos) + replacement
+ range.substring(pos + substr.length());
}
}
private static List<String> getEquivalentsForLanguage(String range) {
String r = range;
while (r.length() > 0) {
if (singleLangEquivMap.containsKey(r)) {
String equiv = singleLangEquivMap.get(r);
// Return immediately for performance if the first matching
// subtag is found.
return List.of(replaceFirstSubStringMatch(range, r, equiv));
} else if (multiLangEquivsMap.containsKey(r)) {
List<String> equivs = multiLangEquivsMap.get(r);
List<String> result = new ArrayList(equivs.size());
for (int i = 0; i < equivs.size(); i++) {
result.add(i, replaceFirstSubStringMatch(range,
r, equivs.get(i)));
}
return result;
}
// Truncate the last subtag simply.
int index = r.lastIndexOf(HYPHEN);
if (index == -1) {
break;
}
r = r.substring(0, index);
}
return null;
}
private static String getEquivalentForRegionAndVariant(String range) {
int extensionKeyIndex = getExtentionKeyIndex(range);
for (String subtag : regionVariantEquivMap.keySet()) {
int index;
if ((index = range.indexOf(subtag)) != -1) {
// Check if the matching text is a valid region or variant.
if (extensionKeyIndex != Integer.MIN_VALUE
&& index > extensionKeyIndex) {
continue;
}
int len = index + subtag.length();
if (range.length() == len || range.charAt(len) == HYPHEN) {
return replaceFirstSubStringMatch(range, subtag,
regionVariantEquivMap.get(subtag));
}
}
}
return null;
}
private static int getExtentionKeyIndex(String s) {
char[] c = s.toCharArray();
int index = Integer.MIN_VALUE;
for (int i = 1; i < c.length; i++) {
if (c[i] == HYPHEN) {
if (i - index == 2) {
return index;
} else {
index = i;
}
}
}
return Integer.MIN_VALUE;
}
private static void checkEquality(List<LanguageRange> expected,
List<LanguageRange> actual) {
int expectedSize = expected.size();
int actualSize = actual.size();
if (expectedSize != actualSize) {
throw new RuntimeException("[FAILED: Size of the priority list"
+ " does not match, Expected size=" + expectedSize + "]");
} else {
for (int i = 0; i < expectedSize; i++) {
LanguageRange lr1 = expected.get(i);
LanguageRange lr2 = actual.get(i);
if (!lr1.getRange().equals(lr2.getRange())
|| lr1.getWeight() != lr2.getWeight()) {
throw new RuntimeException("[FAILED: Ranges at index "
+ i + " do not match Expected: range=" + lr1.getRange()
+ ", weight=" + lr1.getWeight() + ", Actual: range="
+ lr2.getRange() + ", weight=" + lr2.getWeight() + "]");
}
}
}
}
}

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2020, 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 8026766 8253321 8349883
* @summary LanguageRange tests: toString(), hashCode()/equals(), checking
* for IAE on ill-formed ranges
* @run junit LanguageRangeTest
*/
import static java.util.Locale.LanguageRange;
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 java.util.HashMap;
import java.util.Locale;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class LanguageRangeTest {
// 8349883: Test endpoints w/ ill-formed language range fail with IAE
@ParameterizedTest
@MethodSource("illegalRanges")
public void illformedRangeTest(String range) {
// static parses
assertThrows(IllegalArgumentException.class,
() -> Locale.LanguageRange.parse(range));
assertThrows(IllegalArgumentException.class,
() -> Locale.LanguageRange.parse(range, new HashMap<>()));
// ctors
assertThrows(IllegalArgumentException.class,
() -> new Locale.LanguageRange(range));
assertThrows(IllegalArgumentException.class,
() -> new Locale.LanguageRange(range, Locale.LanguageRange.MIN_WEIGHT));
}
private static Stream<String> illegalRanges() {
return Stream.of(
// 8349883 offending range
"-",
// Other general ill-formed test cases
"-foo",
"foo-",
"foo1",
"foo-123456789",
"*-*-",
""
);
}
// 8253321: Ensure invoking hashCode does not affect equals result
@Test
public void hashCodeTest() {
var range1 = new LanguageRange("en-GB", 0);
var range2 = new LanguageRange("en-GB", 0);
assertEquals(range1, range2);
range1.hashCode();
assertEquals(range1, range2);
range2.hashCode();
assertEquals(range1, range2);
}
// 8026766: toString() should hide weight if equal to MAX_WEIGHT (1.0)
@ParameterizedTest
@MethodSource("ranges")
public void toStringTest(String range, double weight) {
LanguageRange lr = new LanguageRange(range, weight);
String expected = weight == 1.0
? range
: range+";q="+weight;
assertEquals(lr.toString(), expected);
}
private static Stream<Arguments> ranges() {
return Stream.of(
Arguments.of("ja", 1.0),
Arguments.of("de", 0.5),
Arguments.of("fr", 0.0)
);
}
}

View file

@ -0,0 +1,494 @@
/*
* Copyright (c) 2016, 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 8025703 8040211 8191404 8203872 8222980 8225435 8241082 8242010 8247432
* 8258795 8267038 8287180 8302512 8304761 8306031 8308021 8313702 8318322
* 8327631 8332424 8334418 8344589 8348328 8362428
* @summary Checks the IANA language subtag registry data update
* (LSR Revision: 2025-08-25) with Locale and Locale.LanguageRange
* class methods.
* @run main LanguageSubtagRegistryTest
*/
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Locale;
import java.util.List;
import java.util.Locale.LanguageRange;
import java.util.Locale.FilteringMode;
import static java.util.Locale.FilteringMode.EXTENDED_FILTERING;
public class LanguageSubtagRegistryTest {
static boolean err = false;
private static final String ACCEPT_LANGUAGE =
"Accept-Language: aam, adp, aeb, ajs, aog, apc, ajp, aue, bcg, bic, bpp, cey, cbr, cnp, cqu, crr, csp, csx, dif, dmw, dsz, ehs, eko, ema,"
+ " en-gb-oed, gti, hnm, iba, ilw, jks, kdz, kjh, kmb, koj, kru, ksp, kwq, kxe, kzk, lgs, lii, lmm, lsb, lsc, lsn, lsv, lsw, luh, lvi, meg, mtm,"
+ " ngv, nns, ola, oyb, pat, pcr, phr, plu, pnd, pub, rib, rnb, rsn, scv, sjc, snz, sqm, sqx, suj, szy, taj, tdg, tjj, tjp, tpn, tvx,"
+ " umi, uss, uth, xia, yos, ysm, zko, wkr;q=0.9, ar-hyw;q=0.8, yug;q=0.5, gfx;q=0.4";
private static final List<LanguageRange> EXPECTED_RANGE_LIST = List.of(
new LanguageRange("aam", 1.0),
new LanguageRange("aas", 1.0),
new LanguageRange("adp", 1.0),
new LanguageRange("dz", 1.0),
new LanguageRange("aeb", 1.0),
new LanguageRange("ar-aeb", 1.0),
new LanguageRange("ajt", 1.0),
new LanguageRange("ajs", 1.0),
new LanguageRange("sgn-ajs", 1.0),
new LanguageRange("aog", 1.0),
new LanguageRange("myd", 1.0),
new LanguageRange("apc", 1.0),
new LanguageRange("ar-apc", 1.0),
new LanguageRange("ar-ajp", 1.0),
new LanguageRange("ajp", 1.0),
new LanguageRange("aue", 1.0),
new LanguageRange("ktz", 1.0),
new LanguageRange("bcg", 1.0),
new LanguageRange("bgm", 1.0),
new LanguageRange("bic", 1.0),
new LanguageRange("bir", 1.0),
new LanguageRange("bpp", 1.0),
new LanguageRange("nxu", 1.0),
new LanguageRange("cey", 1.0),
new LanguageRange("cbr", 1.0),
new LanguageRange("nom", 1.0),
new LanguageRange("cnp", 1.0),
new LanguageRange("zh-cnp", 1.0),
new LanguageRange("cqu", 1.0),
new LanguageRange("quh", 1.0),
new LanguageRange("crr", 1.0),
new LanguageRange("pmk", 1.0),
new LanguageRange("csp", 1.0),
new LanguageRange("zh-csp", 1.0),
new LanguageRange("csx", 1.0),
new LanguageRange("sgn-csx", 1.0),
new LanguageRange("dif", 1.0),
new LanguageRange("dit", 1.0),
new LanguageRange("dmw", 1.0),
new LanguageRange("xrq", 1.0),
new LanguageRange("dsz", 1.0),
new LanguageRange("sgn-dsz", 1.0),
new LanguageRange("ehs", 1.0),
new LanguageRange("sgn-ehs", 1.0),
new LanguageRange("eko", 1.0),
new LanguageRange("nte", 1.0),
new LanguageRange("ema", 1.0),
new LanguageRange("uok", 1.0),
new LanguageRange("en-gb-oed", 1.0),
new LanguageRange("en-gb-oxendict", 1.0),
new LanguageRange("gti", 1.0),
new LanguageRange("nyc", 1.0),
new LanguageRange("hnm", 1.0),
new LanguageRange("zh-hnm", 1.0),
new LanguageRange("iba", 1.0),
new LanguageRange("snb", 1.0),
new LanguageRange("blg", 1.0),
new LanguageRange("ilw", 1.0),
new LanguageRange("gal", 1.0),
new LanguageRange("jks", 1.0),
new LanguageRange("sgn-jks", 1.0),
new LanguageRange("kdz", 1.0),
new LanguageRange("ncp", 1.0),
new LanguageRange("kjh", 1.0),
new LanguageRange("zkb", 1.0),
new LanguageRange("kmb", 1.0),
new LanguageRange("smd", 1.0),
new LanguageRange("koj", 1.0),
new LanguageRange("kwv", 1.0),
new LanguageRange("kru", 1.0),
new LanguageRange("kxl", 1.0),
new LanguageRange("ksp", 1.0),
new LanguageRange("lak", 1.0),
new LanguageRange("kwq", 1.0),
new LanguageRange("yam", 1.0),
new LanguageRange("kxe", 1.0),
new LanguageRange("tvd", 1.0),
new LanguageRange("kzk", 1.0),
new LanguageRange("gli", 1.0),
new LanguageRange("drr", 1.0),
new LanguageRange("lgs", 1.0),
new LanguageRange("sgn-lgs", 1.0),
new LanguageRange("lii", 1.0),
new LanguageRange("raq", 1.0),
new LanguageRange("lmm", 1.0),
new LanguageRange("rmx", 1.0),
new LanguageRange("lsb", 1.0),
new LanguageRange("sgn-lsb", 1.0),
new LanguageRange("lsc", 1.0),
new LanguageRange("sgn-lsc", 1.0),
new LanguageRange("lsn", 1.0),
new LanguageRange("sgn-lsn", 1.0),
new LanguageRange("lsv", 1.0),
new LanguageRange("sgn-lsv", 1.0),
new LanguageRange("lsw", 1.0),
new LanguageRange("sgn-lsw", 1.0),
new LanguageRange("luh", 1.0),
new LanguageRange("zh-luh", 1.0),
new LanguageRange("lvi", 1.0),
new LanguageRange("meg", 1.0),
new LanguageRange("cir", 1.0),
new LanguageRange("mtm", 1.0),
new LanguageRange("ymt", 1.0),
new LanguageRange("ngv", 1.0),
new LanguageRange("nnx", 1.0),
new LanguageRange("nns", 1.0),
new LanguageRange("nbr", 1.0),
new LanguageRange("ola", 1.0),
new LanguageRange("thw", 1.0),
new LanguageRange("oyb", 1.0),
new LanguageRange("thx", 1.0),
new LanguageRange("skk", 1.0),
new LanguageRange("jeg", 1.0),
new LanguageRange("pat", 1.0),
new LanguageRange("kxr", 1.0),
new LanguageRange("pcr", 1.0),
new LanguageRange("adx", 1.0),
new LanguageRange("phr", 1.0),
new LanguageRange("pmu", 1.0),
new LanguageRange("plu", 1.0),
new LanguageRange("kgm", 1.0),
new LanguageRange("pnd", 1.0),
new LanguageRange("pub", 1.0),
new LanguageRange("puz", 1.0),
new LanguageRange("rib", 1.0),
new LanguageRange("sgn-rib", 1.0),
new LanguageRange("rnb", 1.0),
new LanguageRange("sgn-rnb", 1.0),
new LanguageRange("rsn", 1.0),
new LanguageRange("sgn-rsn", 1.0),
new LanguageRange("scv", 1.0),
new LanguageRange("zir", 1.0),
new LanguageRange("sjc", 1.0),
new LanguageRange("zh-sjc", 1.0),
new LanguageRange("snz", 1.0),
new LanguageRange("asd", 1.0),
new LanguageRange("sqm", 1.0),
new LanguageRange("dek", 1.0),
new LanguageRange("sqx", 1.0),
new LanguageRange("sgn-sqx", 1.0),
new LanguageRange("suj", 1.0),
new LanguageRange("szy", 1.0),
new LanguageRange("taj", 1.0),
new LanguageRange("tsf", 1.0),
new LanguageRange("tdg", 1.0),
new LanguageRange("tmk", 1.0),
new LanguageRange("tjj", 1.0),
new LanguageRange("tjp", 1.0),
new LanguageRange("tpn", 1.0),
new LanguageRange("tpw", 1.0),
new LanguageRange("tvx", 1.0),
new LanguageRange("umi", 1.0),
new LanguageRange("szd", 1.0),
new LanguageRange("uss", 1.0),
new LanguageRange("uth", 1.0),
new LanguageRange("xia", 1.0),
new LanguageRange("acn", 1.0),
new LanguageRange("yos", 1.0),
new LanguageRange("zom", 1.0),
new LanguageRange("ysm", 1.0),
new LanguageRange("sgn-ysm", 1.0),
new LanguageRange("zko", 1.0),
new LanguageRange("xss", 1.0),
new LanguageRange("wkr", 0.9),
new LanguageRange("ar-hyw", 0.8),
new LanguageRange("yug", 0.5),
new LanguageRange("yuu", 0.5),
new LanguageRange("gfx", 0.4),
new LanguageRange("oun", 0.4),
new LanguageRange("mwj", 0.4),
new LanguageRange("vaj", 0.4)
);
public static void main(String[] args) {
testLanguageRange();
testLocale();
if (err) {
throw new RuntimeException("Failed.");
}
}
private static void testLanguageRange() {
System.out.println("Test LanguageRange class parse method...");
test_parse();
}
private static void testLocale() {
System.out.println("Test Locale class methods...");
test_filter();
test_filterTags();
test_lookup();
test_lookupTag();
}
private static void test_parse() {
boolean error = false;
List<LanguageRange> got = LanguageRange.parse(ACCEPT_LANGUAGE);
if (!areEqual(EXPECTED_RANGE_LIST, got)) {
error = true;
System.err.println(" language parse() test failed.");
}
if (error) {
err = true;
System.out.println(" test_parse() failed.");
} else {
System.out.println(" test_parse() passed.");
}
}
private static boolean areEqual(List<LanguageRange> expected,
List<LanguageRange> got) {
boolean error = false;
int expectedSize = expected.size();
int actualSize = got.size();
if (expectedSize != actualSize) {
error = true;
System.err.println(" Expected size=" + expectedSize);
for (LanguageRange lr : expected) {
if (!got.contains(lr)) {
System.err.print("Error - Actual does not contain:");
}
System.err.println(" range=" + lr.getRange()
+ ", weight=" + lr.getWeight());
}
System.err.println(" Actual size=" + actualSize);
for (LanguageRange lr : got) {
if (!expected.contains(lr)) {
System.err.print("Error - Expected does not contain:");
}
System.err.println(" range=" + lr.getRange()
+ ", weight=" + lr.getWeight());
}
} else {
for (int i = 0; i < expectedSize; i++) {
LanguageRange lr1 = expected.get(i);
LanguageRange lr2 = got.get(i);
if (!lr1.getRange().equals(lr2.getRange())
|| lr1.getWeight() != lr2.getWeight()) {
error = true;
System.err.println(" " + i + ": Expected: range=" + lr1.getRange()
+ ", weight=" + lr1.getWeight());
System.err.println(" " + i + ": Actual: range=" + lr2.getRange()
+ ", weight=" + lr2.getWeight());
}
}
}
return !error;
}
private static void test_filter() {
boolean error = false;
String ranges = "mtm-RU, en-gb-oed, coy, ar-HY";
String tags = "de-DE, en, mtm-RU, ymt-RU, en-gb-oxendict, ja-JP, pij, nts, ar-arevela";
FilteringMode mode = EXTENDED_FILTERING;
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
List<Locale> tagList = generateLocales(tags);
String actualLocales
= showLocales(Locale.filter(priorityList, tagList, mode));
String expectedLocales = "mtm-RU, ymt-RU, en-GB-oxendict, nts, pij";
if (!expectedLocales.equals(actualLocales)) {
error = true;
showErrorMessage("#1 filter(" + mode + ")",
ranges, tags, expectedLocales, actualLocales);
}
ranges = "phr-*-IN, ja-JP";
tags = "en, pmu-Guru-IN, ja-Latn-JP, iw";
mode = EXTENDED_FILTERING;
priorityList = LanguageRange.parse(ranges);
tagList = generateLocales(tags);
actualLocales = showLocales(Locale.filter(priorityList, tagList, mode));
expectedLocales = "pmu-Guru-IN, ja-Latn-JP";
if (!expectedLocales.equals(actualLocales)) {
error = true;
showErrorMessage("#2 filter(" + mode + ")",
ranges, tags, expectedLocales, actualLocales);
}
if (error) {
err = true;
System.out.println(" test_filter() failed.");
} else {
System.out.println(" test_filter() passed.");
}
}
private static void test_filterTags() {
boolean error = false;
String ranges = "gti;q=0.2, gfx, kzj";
String tags = "de-DE, gti, he, nyc, mwj, vaj, ktr, dtp";
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
List<String> tagList = generateLanguageTags(tags);
String actualTags
= showLanguageTags(Locale.filterTags(priorityList, tagList));
String expectedTags = "mwj, vaj, ktr, dtp, gti, nyc";
if (!expectedTags.equals(actualTags)) {
error = true;
showErrorMessage("filterTags()",
ranges, tags, expectedTags, actualTags);
}
if (error) {
err = true;
System.out.println(" test_filterTags() failed.");
} else {
System.out.println(" test_filterTags() passed.");
}
}
private static void test_lookup() {
boolean error = false;
String ranges = "en;q=0.2, yam, rmx;q=0.9";
String tags = "de-DE, en, kwq, lmm";
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
List<Locale> localeList = generateLocales(tags);
String actualLocale
= Locale.lookup(priorityList, localeList).toLanguageTag();
String expectedLocale = "kwq";
if (!expectedLocale.equals(actualLocale)) {
error = true;
showErrorMessage("lookup()", ranges, tags, expectedLocale, actualLocale);
}
if (error) {
err = true;
System.out.println(" test_lookup() failed.");
} else {
System.out.println(" test_lookup() passed.");
}
}
private static void test_lookupTag() {
boolean error = false;
String ranges = "en, tsf;q=0.2";
String tags = "es, ja-JP, taj";
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
List<String> tagList = generateLanguageTags(tags);
String actualTag = Locale.lookupTag(priorityList, tagList);
String expectedTag = "taj";
if (!expectedTag.equals(actualTag)) {
error = true;
showErrorMessage("lookupTag()", ranges, tags, expectedTag, actualTag);
}
if (error) {
err = true;
System.out.println(" test_lookupTag() failed.");
} else {
System.out.println(" test_lookupTag() passed.");
}
}
private static List<Locale> generateLocales(String tags) {
if (tags == null) {
return null;
}
List<Locale> localeList = new ArrayList<>();
if (tags.equals("")) {
return localeList;
}
String[] t = tags.split(", ");
for (String tag : t) {
localeList.add(Locale.forLanguageTag(tag));
}
return localeList;
}
private static List<String> generateLanguageTags(String tags) {
List<String> tagList = new ArrayList<>();
String[] t = tags.split(", ");
for (String tag : t) {
tagList.add(tag);
}
return tagList;
}
private static String showLanguageTags(List<String> tags) {
StringBuilder sb = new StringBuilder();
Iterator<String> itr = tags.iterator();
if (itr.hasNext()) {
sb.append(itr.next());
}
while (itr.hasNext()) {
sb.append(", ");
sb.append(itr.next());
}
return sb.toString().trim();
}
private static String showLocales(List<Locale> locales) {
StringBuilder sb = new StringBuilder();
java.util.Iterator<Locale> itr = locales.iterator();
if (itr.hasNext()) {
sb.append(itr.next().toLanguageTag());
}
while (itr.hasNext()) {
sb.append(", ");
sb.append(itr.next().toLanguageTag());
}
return sb.toString().trim();
}
private static void showErrorMessage(String methodName,
String priorityList,
String tags,
String expectedTags,
String actualTags) {
System.err.println("\nIncorrect " + methodName + " result.");
System.err.println(" Priority list : " + priorityList);
System.err.println(" Language tags : " + tags);
System.err.println(" Expected value : " + expectedTags);
System.err.println(" Actual value : " + actualTags);
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2007, 2023, 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 4184873
* @summary test that locale invariants are preserved across serialization.
* @run junit LegacyCodesClassInvariant
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*
* (C) Copyright IBM Corp. 1996 - 1999 - All Rights Reserved
*
* Portions copyright (c) 2007 Sun Microsystems, Inc.
* All Rights Reserved.
*
* The original version of this source code and documentation
* is copyrighted and owned by Taligent, Inc., a wholly-owned
* subsidiary of IBM. These materials are provided under terms
* of a License Agreement between Taligent and Sun. This technology
* is protected by multiple US and International patents.
*
* This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.Locale;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
/**
* A Locale can never contain the following language codes: he, yi or id.
*/
public class LegacyCodesClassInvariant {
@Test
public void testIt() throws Exception {
verify("he");
verify("yi");
verify("id");
}
private void verify(String lang) {
try {
ObjectInputStream in = getStream(lang);
if (in != null) {
final Locale loc = (Locale)in.readObject();
final Locale expected = Locale.of(lang, "XX");
assertEquals(expected, loc,
"Locale didn't maintain invariants for: "+lang);
in.close();
}
} catch (Exception e) {
fail(e.toString());
}
}
private ObjectInputStream getStream(String lang) {
try {
final File f = new File(System.getProperty("test.src", "."), "LegacyCodesClassInvariant_"+lang);
return new ObjectInputStream(new FileInputStream(f));
} catch (Exception e) {
fail(e.toString());
return null;
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,134 @@
/*
* Copyright (c) 2010, 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 4700857 6997928 7079486
* @summary tests for Locale.getDefault(Locale.Category) and
* Locale.setDefault(Locale.Category, Locale)
* @library /java/text/testlib
* @build TestUtils LocaleCategory
* @comment test user.xxx.display user.xxx.format properties
* @run junit/othervm -Duser.language.display=ja
* -Duser.language.format=zh LocaleCategory
* @comment test user.xxx properties overriding user.xxx.display/format
* @run junit/othervm -Duser.language=en
* -Duser.language.display=ja
* -Duser.language.format=zh LocaleCategory
*/
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;
import java.util.Locale;
public class LocaleCategory {
private static Locale base = null;
private static Locale disp = null;
private static Locale fmt = null;
@Test
void test() {
Locale reservedLocale = Locale.getDefault();
Assumptions.assumeFalse(TestUtils.hasSpecialVariant(reservedLocale),
reservedLocale + " has special variant");
try {
Locale.Builder builder = new Locale.Builder();
base = builder.setLanguage(System.getProperty("user.language", ""))
.setScript(System.getProperty("user.script", ""))
.setRegion(System.getProperty("user.country", ""))
.setVariant(System.getProperty("user.variant", "")).build();
disp = builder.setLanguage(
System.getProperty("user.language.display",
Locale.getDefault().getLanguage()))
.setScript(System.getProperty("user.script.display",
Locale.getDefault().getScript()))
.setRegion(System.getProperty("user.country.display",
Locale.getDefault().getCountry()))
.setVariant(System.getProperty("user.variant.display",
Locale.getDefault().getVariant())).build();
fmt = builder.setLanguage(System.getProperty("user.language.format",
Locale.getDefault().getLanguage()))
.setScript(System.getProperty("user.script.format",
Locale.getDefault().getScript()))
.setRegion(System.getProperty("user.country.format",
Locale.getDefault().getCountry()))
.setVariant(System.getProperty("user.variant.format",
Locale.getDefault().getVariant())).build();
checkDefault();
testGetSetDefault();
testBug7079486();
} finally {
// restore the reserved locale
Locale.setDefault(reservedLocale);
}
}
private static void checkDefault() {
if (!base.equals(Locale.getDefault()) ||
!disp.equals(Locale.getDefault(Locale.Category.DISPLAY)) ||
!fmt.equals(Locale.getDefault(Locale.Category.FORMAT))) {
throw new RuntimeException("Some of the return values from "
+ "getDefault() do not agree with the locale derived "
+ "from \"user.xxxx\" system properties");
}
}
private static void testGetSetDefault() {
try {
Locale.setDefault(null, null);
throw new RuntimeException("setDefault(null, null) should throw a "
+ "NullPointerException");
} catch (NullPointerException npe) {}
Locale.setDefault(Locale.CHINA);
if (!Locale.CHINA.equals(Locale.getDefault(Locale.Category.DISPLAY)) ||
!Locale.CHINA.equals(Locale.getDefault(Locale.Category.FORMAT))) {
throw new RuntimeException("setDefault() should set all default "
+ "locales for all categories");
}
}
private static void testBug7079486() {
Locale zh_Hans_CN = Locale.forLanguageTag("zh-Hans-CN");
// make sure JRE has zh_Hans_CN localized string
if (zh_Hans_CN.getDisplayScript(Locale.US)
.equals(zh_Hans_CN.getDisplayScript(zh_Hans_CN))) {
return;
}
Locale.setDefault(Locale.US);
String en_script = zh_Hans_CN.getDisplayScript();
Locale.setDefault(Locale.Category.DISPLAY, zh_Hans_CN);
String zh_script = zh_Hans_CN.getDisplayScript();
if (en_script.equals(zh_script)) {
throw new RuntimeException("Locale.getDisplayScript() (no args) "
+ "does not honor default DISPLAY locale");
}
}
}

View file

@ -0,0 +1,150 @@
/*
* Copyright (c) 2018, 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.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.List;
/*
* @test
* @modules java.management
* @summary verify that overriddes on the command line affect *.display and *.format properties
* @run main/othervm
* LocaleCmdOverrides
* @run main/othervm -Duser.language=XX
* -Duser.country=X1
* -Duser.script=X2
* -Duser.variant=X3
* LocaleCmdOverrides
* @run main/othervm -Duser.language=XX -Duser.language.display=YY
* -Duser.country=X1 -Duser.country.display=Y1
* -Duser.script=X2 -Duser.script.display=Y2
* -Duser.variant=X3 -Duser.variant.display=Y3
* LocaleCmdOverrides
* @run main/othervm -Duser.language=XX -Duser.language.display=YY -Duser.language.format=ZZ
* -Duser.country=X1 -Duser.country.display=Y1 -Duser.country.format=Z1
* -Duser.script=X2 -Duser.script.display=Y2 -Duser.script.format=Z2
* -Duser.variant=X3 -Duser.variant.display=Y3 -Duser.variant.format=Z3
* LocaleCmdOverrides
* @run main/othervm -Duser.language=XX -Duser.language.format=ZZ
* -Duser.country=X1 -Duser.country.format=Z1
* -Duser.script=X2 -Duser.script.format=Z2
* -Duser.variant=X3 -Duser.variant.format=Z3
* LocaleCmdOverrides
* @run main/othervm -Duser.language=XX -Duser.language.display=XX
* -Duser.country=X1 -Duser.country.display=X1
* -Duser.script=X2 -Duser.script.display=X2
* -Duser.variant=X3 -Duser.variant.display=X3
* LocaleCmdOverrides
* @run main/othervm -Duser.language=XX -Duser.language.display=XX -Duser.language.format=XX
* -Duser.country=X1 -Duser.country.display=X1 -Duser.country.format=X1
* -Duser.script=X2 -Duser.script.display=X2 -Duser.script.format=X2
* -Duser.variant=X3 -Duser.variant.display=X3 -Duser.variant.format=X3
* LocaleCmdOverrides
* @run main/othervm -Duser.language=XX -Duser.language.format=X1
* -Duser.country.format=X1
* -Duser.script.format=X2
* -Duser.variant.format=X3
* LocaleCmdOverrides
*/
public class LocaleCmdOverrides {
// Language, country, script, variant
public static void main(String[] args) {
Map<String, String> props = commandLineDefines();
System.out.printf("props: %s%n", props);
test("user.language", props);
test("user.country", props);
test("user.script", props);
test("user.variant", props);
}
/*
* Check each of the properties for a given basename.
*/
static void test(String baseName, Map<String, String> args) {
validateArg(baseName,"", args);
validateArg(baseName,".display", args);
validateArg(baseName,".format", args);
}
// If an argument is -D defined, the corresponding property must be equal
static void validateArg(String name, String ext, Map<String, String> args) {
String extName = name.concat(ext);
String arg = args.get(extName);
String prop = System.getProperty(extName);
if (arg == null && prop == null) {
System.out.printf("No values for %s%n", extName);
} else {
System.out.printf("validateArg %s: arg: %s, prop: %s%n", extName, arg, prop);
}
if (arg != null) {
if (!Objects.equals(arg, prop)) {
throw new RuntimeException(extName + ": -D value should match property: "
+ arg + " != " + prop);
}
} else if (prop != null) {
// no command line arg for extName and some value for prop
// Check that if a property is not overridden then it is not equal to the base
if (ext != null && !ext.isEmpty()) {
String value = System.getProperty(name);
if (Objects.equals(value, prop)) {
throw new RuntimeException(extName + " property should not be equals to "
+ name + " property: " + prop);
}
}
}
}
/**
* Extract the -D arguments from the command line and return a map of key, value.
* @return a map of key, values defined by -D on the command line.
*/
static HashMap<String, String> commandLineDefines() {
HashMap<String, String> props = new HashMap<>();
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
List<String> args = runtime.getInputArguments();
System.out.printf("args: %s%n", args);
for (String arg : args) {
if (arg.startsWith("-Duser.")) {
String[] kv = arg.substring(2).split("=");
switch (kv.length) {
case 1:
props.put(kv[0], "");
break;
case 2:
props.put(kv[0], kv[1]);
break;
default:
throw new IllegalArgumentException("Illegal property syntax: " + arg);
}
}
}
return props;
}
}

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2007, 2023, 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 4316602
* @author joconner
* @summary Verify all Locale constructors and of() methods
* @run junit LocaleConstructors
*/
import java.util.Locale;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* This class tests to ensure that the language, language/country, and
* language/country/variant Locale constructors + of() method are all allowed.
*/
public class LocaleConstructors {
static final String LANG = "en";
static final String COUNTRY = "US";
static final String VAR = "socal";
// Test Locale constructor and .of() allow (language) argument(s)
@Test
public void langTest() {
Locale aLocale = Locale.of(LANG);
Locale otherLocale = new Locale(LANG);
assertEquals(aLocale.toString(), LANG);
assertEquals(otherLocale.toString(), LANG);
}
// Test Locale constructor and .of() allow (language, constructor) argument(s)
@Test
public void langCountryTest() {
Locale aLocale = Locale.of(LANG, COUNTRY);
Locale otherLocale = new Locale(LANG, COUNTRY);
assertEquals(aLocale.toString(), String.format("%s_%s",
LANG, COUNTRY));
assertEquals(otherLocale.toString(), String.format("%s_%s",
LANG, COUNTRY));
}
// Test Locale constructor and .of() allow
// (language, constructor, variant) argument(s)
@Test
public void langCountryVariantTest() {
Locale aLocale = Locale.of(LANG, COUNTRY, VAR);
Locale otherLocale = new Locale(LANG, COUNTRY, VAR);
assertEquals(aLocale.toString(), String.format("%s_%s_%s",
LANG, COUNTRY, VAR));
assertEquals(otherLocale.toString(), String.format("%s_%s_%s",
LANG, COUNTRY, VAR));
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,533 @@
/*
* Copyright (c) 2014, 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 7069824 8042360 8032842 8175539 8210443 8242010 8276302
* @summary Verify implementation for Locale matching.
* @run junit/othervm LocaleMatchingTest
*/
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Locale.FilteringMode;
import java.util.Locale.LanguageRange;
import java.util.Map;
import static java.util.Locale.FilteringMode.*;
import static java.util.Locale.LanguageRange.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class LocaleMatchingTest {
static Object[][] LRConstructorData() {
return new Object[][] {
// Range, Weight
{"elvish", MAX_WEIGHT},
{"de-DE", MAX_WEIGHT},
{"de-Latn-DE-1996", MAX_WEIGHT},
{"zh-Hant-CN-x-private1-private2", MAX_WEIGHT},
{"ar", 0.8},
{"en-US", 0.5},
{"sr-Latn-BA", 0},
{"ja", 1},
};
}
static Object[][] LRConstructorNPEData() {
return new Object[][] {
// Range, Weight
{null, MAX_WEIGHT},
{null, 0.8},
};
}
static Object[][] LRConstructorIAEData() {
return new Object[][] {
// Range, Weight
{"ja", -0.8},
{"Elvish", 3.0},
{"-ja", MAX_WEIGHT},
{"ja--JP", MAX_WEIGHT},
{"en-US-", MAX_WEIGHT},
{"a4r", MAX_WEIGHT},
{"ar*", MAX_WEIGHT},
{"ar-*EG", MAX_WEIGHT},
{"abcdefghijklmn", MAX_WEIGHT},
{"ja-J=", MAX_WEIGHT},
{"ja-opqrstuvwxyz", MAX_WEIGHT},
{"zh_CN", MAX_WEIGHT},
{"1996-de-Latn", MAX_WEIGHT},
// Testcase for 8042360
{"en-Latn-1234567890", MAX_WEIGHT},
};
}
static Object[][] LRParseData() {
return new Object[][] {
// Ranges, Expected result
{"Accept-Language: fr-FX, de-DE;q=0.5, fr-tp-x-FOO;q=0.1, "
+ "en-X-tp;q=0.6, en-FR;q=0.7, de-de;q=0.8, iw;q=0.4, "
+ "he;q=0.4, de-de;q=0.5, ja, in-tpp, in-tp;q=0.2",
List.of(new LanguageRange("fr-fx", 1.0),
new LanguageRange("fr-fr", 1.0),
new LanguageRange("ja", 1.0),
new LanguageRange("in-tpp", 1.0),
new LanguageRange("id-tpp", 1.0),
new LanguageRange("en-fr", 0.7),
new LanguageRange("en-fx", 0.7),
new LanguageRange("en-x-tp", 0.6),
new LanguageRange("de-de", 0.5),
new LanguageRange("de-dd", 0.5),
new LanguageRange("iw", 0.4),
new LanguageRange("he", 0.4),
new LanguageRange("in-tp", 0.2),
new LanguageRange("id-tl", 0.2),
new LanguageRange("id-tp", 0.2),
new LanguageRange("in-tl", 0.2),
new LanguageRange("fr-tp-x-foo", 0.1),
new LanguageRange("fr-tl-x-foo", 0.1))},
{"Accept-Language: hak-CN;q=0.8, no-bok-NO;q=0.9, no-nyn, cmn-CN;q=0.1",
List.of(new LanguageRange("no-nyn", 1.0),
new LanguageRange("nn", 1.0),
new LanguageRange("no-bok-no", 0.9),
new LanguageRange("nb-no", 0.9),
new LanguageRange("hak-CN", 0.8),
new LanguageRange("zh-hakka-CN", 0.8),
new LanguageRange("i-hak-CN", 0.8),
new LanguageRange("zh-hak-CN", 0.8),
new LanguageRange("cmn-CN", 0.1),
new LanguageRange("zh-guoyu-CN", 0.1),
new LanguageRange("zh-cmn-CN", 0.1))},
{"Accept-Language: rki;q=0.4, no-bok-NO;q=0.9, ccq;q=0.5",
List.of(new LanguageRange("no-bok-no", 0.9),
new LanguageRange("nb-no", 0.9),
new LanguageRange("rki", 0.4),
new LanguageRange("ybd", 0.4),
new LanguageRange("ccq", 0.4))},
};
}
static Object[][] LRParseIAEData() {
return new Object[][] {
// Ranges
{""},
{"ja;q=3"},
};
}
static Object[][] LRMapEquivalentsData() {
return new Object[][] {
// Ranges, Map, Expected result
{LanguageRange.parse("zh, zh-TW;q=0.8, ar;q=0.9, EN, zh-HK, ja-JP;q=0.2, es;q=0.4"),
new HashMap<>(),
LanguageRange.parse("zh, zh-TW;q=0.8, ar;q=0.9, EN, zh-HK, ja-JP;q=0.2, es;q=0.4")},
{LanguageRange.parse("zh, zh-TW;q=0.8, ar;q=0.9, EN, zh-HK, ja-JP;q=0.2, es;q=0.4"),
null,
LanguageRange.parse("zh, zh-TW;q=0.8, ar;q=0.9, EN, zh-HK, ja-JP;q=0.2, es;q=0.4")},
{LanguageRange.parse("zh, zh-TW;q=0.8, ar;q=0.9, EN, zh-HK, ja-JP;q=0.2, es;q=0.4"),
new LinkedHashMap<String, List<String>>() {
{
put("ja", List.of("ja", "ja-Hira"));
put("zh", List.of("zh-Hans", "zh-Hans-CN", "zh-CN"));
put("zh-TW", List.of("zh-TW", "zh-Hant"));
put("es", null);
put("en", List.of());
put("zh-HK", List.of("de"));
}
},
List.of(new LanguageRange("zh-hans", 1.0),
new LanguageRange("zh-hans-cn", 1.0),
new LanguageRange("zh-cn", 1.0),
new LanguageRange("de", 1.0),
new LanguageRange("ar", 0.9),
new LanguageRange("zh-tw", 0.8),
new LanguageRange("zh-hant", 0.8),
new LanguageRange("ja-jp", 0.2),
new LanguageRange("ja-hira-jp", 0.2))},
};
}
static Object[][] LFilterData() {
return new Object[][] {
// Range, LanguageTags, FilteringMode, Expected locales
{"ja-JP, fr-FR", "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP",
EXTENDED_FILTERING, "ja-JP-hepburn, ja-Latn-JP"},
{"ja-*-JP, fr-FR", "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP",
EXTENDED_FILTERING, "ja-JP-hepburn, ja-Latn-JP"},
{"ja-*-JP, fr-FR, de-de;q=0.2", "de-DE, en, ja-JP-hepburn, de-de, fr, he, ja-Latn-JP",
AUTOSELECT_FILTERING, "ja-JP-hepburn, ja-Latn-JP, de-DE"},
{"ja-JP, fr-FR, de-de;q=0.2", "de-DE, en, ja-JP-hepburn, de-de, fr, he, ja-Latn-JP",
AUTOSELECT_FILTERING, "ja-JP-hepburn, de-DE"},
{"en;q=0.2, ja-*-JP, fr-JP", "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP",
IGNORE_EXTENDED_RANGES, "en"},
{"en;q=0.2, ja-*-JP, fr-JP", "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP",
MAP_EXTENDED_RANGES, "ja-JP-hepburn, en"},
{"en;q=0.2, ja-JP, fr-JP", "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP",
REJECT_EXTENDED_RANGES, "ja-JP-hepburn, en"},
{"en;q=0.2, ja-*-JP, fr-JP", "", REJECT_EXTENDED_RANGES, ""},
};
}
static Object[][] LFilterNPEData() {
return new Object[][] {
// Range, LanguageTags, FilteringMode
{"en;q=0.2, ja-*-JP, fr-JP", null, REJECT_EXTENDED_RANGES},
{null, "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP", REJECT_EXTENDED_RANGES},
};
}
static Object[][] LFilterTagsData() {
return new Object[][] {
// Range, LanguageTags, FilteringMode, Expected language tags
{"fr-FR, fr-BG;q=0.8, *;q=0.5, en;q=0", "en-US, fr-FR, fr-CA, fr-BG",
null, "fr-FR, fr-BG, fr-CA"},
{"fr-FR, fr-*-BG;q=0.8, *;q=0.5, en;q=0", "en-US, fr-FR, fr-CA, fr-BG",
null, "fr-FR, fr-BG, fr-CA"},
{"en;q=0.2, *;q=0.6, ja", "de-DE, en, ja-JP-hepburn, fr-JP, he",
null, "ja-JP-hepburn, de-DE, en, fr-JP, he"},
{"en;q=0.2, ja-JP, fr-JP", "de-DE, en, ja-JP-hepburn, fr, he",
null, "ja-JP-hepburn, en"},
{"en;q=0.2, ja-JP, fr-JP, iw", "de-DE, he, en, ja-JP-hepburn, fr, he-IL",
null, "ja-JP-hepburn, he, he-IL, en"},
{"en;q=0.2, ja-JP, fr-JP, he", "de-DE, en, ja-JP-hepburn, fr, iw-IL",
null, "ja-JP-hepburn, iw-IL, en"},
{"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
null, "de-DE, de-DE-x-goethe"},
{"de-*-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
null,
"de-DE, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
+ "de-Latn-DE-1996, de-Deva-DE"},
{"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
EXTENDED_FILTERING,
"de-DE, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
+ "de-Latn-DE-1996, de-Deva-DE"},
{"de-*-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
EXTENDED_FILTERING,
"de-DE, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
+ "de-Latn-DE-1996, de-Deva-DE"},
{"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
IGNORE_EXTENDED_RANGES,
"de-DE, de-DE-x-goethe"},
{"de-*-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
IGNORE_EXTENDED_RANGES,
""},
{"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
MAP_EXTENDED_RANGES, "de-DE, de-DE-x-goethe"},
{"de-*-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
MAP_EXTENDED_RANGES, "de-DE, de-DE-x-goethe"},
{"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva",
REJECT_EXTENDED_RANGES, "de-DE, de-DE-x-goethe"},
// The next test in this chain is in testLFilterTagsIAE.
};
}
static Object[][] LLookupData() {
return new Object[][] {
// Range, LanguageTags, Expected locale
{"en;q=0.2, *-JP;q=0.6, iw", "de-DE, en, ja-JP-hepburn, fr-JP, he", "he"},
{"en;q=0.2, *-JP;q=0.6, iw", "de-DE, he-IL, en, iw", "he"},
{"en;q=0.2, ja-*-JP-x-foo;q=0.6, iw", "de-DE, fr, en, ja-Latn-JP", "ja-Latn-JP"},
};
}
static Object[][] LLookupTagData() {
return new Object[][] {
// Range, LanguageTags, Expected language tag
{"en, *", "es, de, ja-JP", null},
{"en;q=0.2, *-JP", "de-DE, en, ja-JP-hepburn, fr-JP, en-JP", "fr-JP"},
{"en;q=0.2, ar-MO, iw", "de-DE, he, fr-JP", "he"},
{"en;q=0.2, ar-MO, he", "de-DE, iw, fr-JP", "iw"},
{"de-DE-1996;q=0.8, en;q=0.2, iw;q=0.9, zh-Hans-CN;q=0.7", "de-DE, zh-CN, he, iw, fr-JP", "iw"},
{"de-DE-1996;q=0.8, en;q=0.2, he;q=0.9, zh-Hans-CN;q=0.7", "de-DE, zh-CN, he, iw, fr-JP", "he"},
};
}
@Test
void testLRConstants() {
assertEquals(0.0, MIN_WEIGHT, " MIN_WEIGHT should be 0.0 but got "
+ MIN_WEIGHT);
assertEquals(1.0, MAX_WEIGHT, " MAX_WEIGHT should be 1.0 but got "
+ MAX_WEIGHT);
}
@MethodSource("LRConstructorData")
@ParameterizedTest
void testLRConstructors(String range, double weight) {
LanguageRange lr;
if (weight == MAX_WEIGHT) {
lr = new LanguageRange(range);
} else {
lr = new LanguageRange(range, weight);
}
assertEquals(range.toLowerCase(Locale.ROOT), lr.getRange(),
" LR.getRange() returned unexpected value. Expected: "
+ range.toLowerCase(Locale.ROOT) + ", got: " + lr.getRange());
assertEquals(weight, lr.getWeight(),
" LR.getWeight() returned unexpected value. Expected: "
+ weight + ", got: " + lr.getWeight());
}
@MethodSource("LRConstructorNPEData")
@ParameterizedTest
void testLRConstructorNPE(String range, double weight) {
if (weight == MAX_WEIGHT) {
assertThrows(NullPointerException.class, () -> new LanguageRange(range));
} else {
assertThrows(NullPointerException.class, () -> new LanguageRange(range, weight));
}
}
@MethodSource("LRConstructorIAEData")
@ParameterizedTest
void testLRConstructorIAE(String range, double weight) {
if (weight == MAX_WEIGHT) {
assertThrows(IllegalArgumentException.class, () -> new LanguageRange(range));
} else {
assertThrows(IllegalArgumentException.class, () -> new LanguageRange(range, weight));
}
}
@Test
void testLREquals() {
LanguageRange lr1 = new LanguageRange("ja", 1.0);
LanguageRange lr2 = new LanguageRange("ja");
LanguageRange lr3 = new LanguageRange("ja", 0.1);
LanguageRange lr4 = new LanguageRange("en", 1.0);
assertEquals(lr2, lr1, " LR(ja, 1.0).equals(LR(ja)) should return true.");
assertNotEquals(lr3, lr1, " LR(ja, 1.0).equals(LR(ja, 0.1)) should return false.");
assertNotEquals(lr4, lr1, " LR(ja, 1.0).equals(LR(en, 1.0)) should return false.");
assertNotNull(lr1, " LR(ja, 1.0).equals(null) should return false.");
assertNotEquals("", lr1, " LR(ja, 1.0).equals(\"\") should return false.");
}
@MethodSource("LRParseData")
@ParameterizedTest
void testLRParse(String ranges, List<LanguageRange> expected) {
assertEquals(expected, LanguageRange.parse(ranges),
" LR.parse(" + ranges + ") test failed.");
}
@Test
void testLRParseNPE() {
assertThrows(NullPointerException.class, () -> LanguageRange.parse(null));
}
@MethodSource("LRParseIAEData")
@ParameterizedTest
void testLRParseIAE(String ranges) {
assertThrows(IllegalArgumentException.class, () -> LanguageRange.parse(ranges));
}
@MethodSource("LRMapEquivalentsData")
@ParameterizedTest
void testLRMapEquivalents(List<Locale.LanguageRange> priorityList,
Map<String,List<String>> map, List<LanguageRange> expected) {
assertEquals(expected, LanguageRange.mapEquivalents(priorityList, map),
" LR.mapEquivalents() test failed.");
}
@Test
void testLRMapEquivalentsNPE() {
assertThrows(NullPointerException.class,
() -> LanguageRange.mapEquivalents(null, Map.of("ja", List.of("ja", "ja-Hira"))));
}
@MethodSource("LFilterData")
@ParameterizedTest
void testLFilter(String ranges, String tags, FilteringMode mode, String expectedLocales) {
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
List<Locale> tagList = generateLocales(tags);
String actualLocales =
showLocales(Locale.filter(priorityList, tagList, mode));
assertEquals(expectedLocales, actualLocales, showErrorMessage(" L.Filter(" + mode + ")",
ranges, tags, expectedLocales, actualLocales));
}
@MethodSource("LFilterNPEData")
@ParameterizedTest
void testLFilterNPE(String ranges, String tags, FilteringMode mode) {
if (ranges == null) {
// Ranges are null
assertThrows(NullPointerException.class, () -> LanguageRange.parse(ranges));
} else {
// Tags are null
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
List<Locale> tagList = generateLocales(tags);
assertThrows(NullPointerException.class,
() -> showLocales(Locale.filter(priorityList, tagList, mode)));
}
}
@Test
void testLFilterIAE() {
String ranges = "en;q=0.2, ja-*-JP, fr-JP";
String tags = "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP";
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
List<Locale> tagList = generateLocales(tags);
assertThrows(IllegalArgumentException.class,
() -> showLocales(Locale.filter(priorityList, tagList, REJECT_EXTENDED_RANGES)));
}
@MethodSource("LFilterTagsData")
@ParameterizedTest
void testLFilterTags(String ranges, String tags, FilteringMode mode, String expectedTags) {
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
List<String> tagList = generateLanguageTags(tags);
String actualTags;
if (mode == null) {
actualTags = showLanguageTags(Locale.filterTags(priorityList, tagList));
} else {
actualTags = showLanguageTags(Locale.filterTags(priorityList, tagList, mode));
}
assertEquals(expectedTags, actualTags,
showErrorMessage(" L.FilterTags(" + (mode != null ? mode : "") + ")",
ranges, tags, expectedTags, actualTags));
}
@Test
void testLFilterTagsIAE() {
String ranges = "de-*-DE";
String tags = "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "
+ "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva";
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
assertThrows(IllegalArgumentException.class,
() -> showLanguageTags(Locale.filterTags(priorityList, generateLanguageTags(tags), REJECT_EXTENDED_RANGES)));
}
@MethodSource("LLookupData")
@ParameterizedTest
void testLLookup(String ranges, String tags, String expectedLocale) {
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
List<Locale> localeList = generateLocales(tags);
String actualLocale =
Locale.lookup(priorityList, localeList).toLanguageTag();
assertEquals(expectedLocale, actualLocale, showErrorMessage(" L.Lookup()",
ranges, tags, expectedLocale, actualLocale));
}
@MethodSource("LLookupTagData")
@ParameterizedTest
void testLLookupTag(String ranges, String tags, String expectedTag) {
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
List<String> tagList = generateLanguageTags(tags);
String actualTag = Locale.lookupTag(priorityList, tagList);
assertEquals(expectedTag, actualTag, showErrorMessage(" L.LookupTag()",
ranges, tags, expectedTag, actualTag));
}
private static List<Locale> generateLocales(String tags) {
if (tags == null) {
return null;
}
List<Locale> localeList = new ArrayList<>();
if (tags.equals("")) {
return localeList;
}
String[] t = tags.split(", ");
for (String tag : t) {
localeList.add(Locale.forLanguageTag(tag));
}
return localeList;
}
private static List<String> generateLanguageTags(String tags) {
List<String> tagList = new ArrayList<>();
String[] t = tags.split(", ");
for (String tag : t) {
tagList.add(tag);
}
return tagList;
}
private static String showLanguageTags(List<String> tags) {
StringBuilder sb = new StringBuilder();
Iterator<String> itr = tags.iterator();
if (itr.hasNext()) {
sb.append(itr.next());
}
while (itr.hasNext()) {
sb.append(", ");
sb.append(itr.next());
}
return sb.toString().trim();
}
private static String showLocales(List<Locale> locales) {
StringBuilder sb = new StringBuilder();
Iterator<Locale> itr = locales.iterator();
if (itr.hasNext()) {
sb.append(itr.next().toLanguageTag());
}
while (itr.hasNext()) {
sb.append(", ");
sb.append(itr.next().toLanguageTag());
}
return sb.toString().trim();
}
private static String showErrorMessage(String methodName,
String priorityList,
String tags,
String expectedTags,
String actualTags) {
return "Incorrect " + methodName + " result."
+ " Priority list : " + priorityList
+ " Language tags : " + tags
+ " Expected value : " + expectedTags
+ " Actual value : " + actualTags;
}
}

View file

@ -0,0 +1,502 @@
/*
* 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.
*/
import java.text.*;
import java.text.spi.*;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.temporal.WeekFields;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.StreamHandler;
import java.util.spi.*;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import jdk.test.lib.Utils;
import jdk.test.lib.process.ProcessTools;
import sun.util.locale.provider.LocaleProviderAdapter;
import static java.util.logging.LogManager.*;
public class LocaleProviders {
private static final boolean IS_WINDOWS = System.getProperty("os.name").startsWith("Windows");
private static final boolean IS_MAC = System.getProperty("os.name").startsWith("Mac");
public static void main(String[] args) {
String methodName = args[0];
switch (methodName) {
case "getPlatformLocale":
if (args[1].equals("format")) {
getPlatformLocale(Locale.Category.FORMAT);
} else {
getPlatformLocale(Locale.Category.DISPLAY);
}
break;
case "adapterTest":
adapterTest(args[1], args[2], (args.length >= 4 ? args[3] : ""));
break;
case "bug7198834Test":
bug7198834Test();
break;
case "tzNameTest":
tzNameTest(args[1]);
break;
case "bug8001440Test":
bug8001440Test();
break;
case "bug8010666Test":
bug8010666Test();
break;
case "bug8013086Test":
bug8013086Test(args[1], args[2]);
break;
case "bug8013903Test":
bug8013903Test();
break;
case "bug8027289Test":
bug8027289Test(args[1]);
break;
case "bug8220227Test":
bug8220227Test();
break;
case "bug8228465Test":
bug8228465Test();
break;
case "bug8232871Test":
bug8232871Test();
break;
case "bug8232860Test":
bug8232860Test();
break;
case "bug8245241Test":
bug8245241Test(args[1]);
break;
case "bug8248695Test":
bug8248695Test();
break;
case "bug8257964Test":
bug8257964Test();
break;
default:
throw new RuntimeException("Test method '"+methodName+"' not found.");
}
}
static void getPlatformLocale(Locale.Category cat) {
Locale defloc = Locale.getDefault(cat);
System.out.printf("%s,%s\n", defloc.getLanguage(), defloc.getCountry());
}
static void adapterTest(String expected, String lang, String ctry) {
Locale testLocale = Locale.of(lang, ctry);
LocaleProviderAdapter ldaExpected =
LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.valueOf(expected));
if (!ldaExpected.getDateFormatProvider().isSupportedLocale(testLocale)) {
System.out.println("test locale: "+testLocale+" is not supported by the expected provider: "+ldaExpected+". Ignoring the test.");
return;
}
String preference = System.getProperty("java.locale.providers", "");
LocaleProviderAdapter lda = LocaleProviderAdapter.getAdapter(DateFormatProvider.class, testLocale);
LocaleProviderAdapter.Type type = lda.getAdapterType();
System.out.printf("testLocale: %s, got: %s, expected: %s\n", testLocale, type, expected);
if (!type.toString().equals(expected)) {
throw new RuntimeException("Returned locale data adapter is not correct.");
}
}
static void bug7198834Test() {
LocaleProviderAdapter lda = LocaleProviderAdapter.getAdapter(DateFormatProvider.class, Locale.US);
LocaleProviderAdapter.Type type = lda.getAdapterType();
if (type == LocaleProviderAdapter.Type.HOST && IS_WINDOWS) {
DateFormat df = DateFormat.getDateInstance(DateFormat.FULL, Locale.US);
String date = df.format(new Date());
if (date.charAt(date.length()-1) == ' ') {
throw new RuntimeException("Windows Host Locale Provider returns a trailing space.");
}
} else {
System.out.println("Windows HOST locale adapter not found. Ignoring this test.");
}
}
static void tzNameTest(String id) {
TimeZone tz = TimeZone.getTimeZone(id);
String tzName = tz.getDisplayName(false, TimeZone.SHORT, Locale.US);
if (tzName.startsWith("GMT")) {
throw new RuntimeException("JRE's localized time zone name for "+id+" could not be retrieved. Returned name was: "+tzName);
}
}
static void bug8001440Test() {
Locale locale = Locale.forLanguageTag("th-TH-u-nu-hoge");
NumberFormat nf = NumberFormat.getInstance(locale);
String nu = nf.format(1234560);
}
// This test assumes Windows localized language/country display names.
static void bug8010666Test() {
if (IS_WINDOWS) {
NumberFormat nf = NumberFormat.getInstance(Locale.US);
try {
double ver = nf.parse(System.getProperty("os.version"))
.doubleValue();
System.out.printf("Windows version: %.1f\n", ver);
if (ver >= 6.0) {
LocaleProviderAdapter lda =
LocaleProviderAdapter.getAdapter(
LocaleNameProvider.class, Locale.ENGLISH);
LocaleProviderAdapter.Type type = lda.getAdapterType();
if (type == LocaleProviderAdapter.Type.HOST) {
LocaleNameProvider lnp = lda.getLocaleNameProvider();
Locale mkmk = Locale.forLanguageTag("mk-MK");
String result = mkmk.getDisplayLanguage(Locale.ENGLISH);
String hostResult =
lnp.getDisplayLanguage(mkmk.getLanguage(),
Locale.ENGLISH);
System.out.printf(" Display language name for" +
" (mk_MK): result(HOST): \"%s\", returned: \"%s\"\n",
hostResult, result);
if (result == null ||
hostResult != null &&
!result.equals(hostResult)) {
throw new RuntimeException("Display language name" +
" mismatch for \"mk\". Returned name was" +
" \"" + result + "\", result(HOST): \"" +
hostResult + "\"");
}
result = Locale.US.getDisplayLanguage(Locale.ENGLISH);
hostResult =
lnp.getDisplayLanguage(Locale.US.getLanguage(),
Locale.ENGLISH);
System.out.printf(" Display language name for" +
" (en_US): result(HOST): \"%s\", returned: \"%s\"\n",
hostResult, result);
if (result == null ||
hostResult != null &&
!result.equals(hostResult)) {
throw new RuntimeException("Display language name" +
" mismatch for \"en\". Returned name was" +
" \"" + result + "\", result(HOST): \"" +
hostResult + "\"");
}
if (ver >= 6.1) {
result = Locale.US.getDisplayCountry(Locale.ENGLISH);
hostResult = lnp.getDisplayCountry(
Locale.US.getCountry(), Locale.ENGLISH);
System.out.printf(" Display country name for" +
" (en_US): result(HOST): \"%s\", returned: \"%s\"\n",
hostResult, result);
if (result == null ||
hostResult != null &&
!result.equals(hostResult)) {
throw new RuntimeException("Display country name" +
" mismatch for \"US\". Returned name was" +
" \"" + result + "\", result(HOST): \"" +
hostResult + "\"");
}
}
} else {
throw new RuntimeException("Windows Host" +
" LocaleProviderAdapter was not selected for" +
" English locale.");
}
}
} catch (ParseException pe) {
throw new RuntimeException("Parsing Windows version failed: "+pe.toString());
}
}
}
static void bug8013086Test(String lang, String ctry) {
try {
// Throws a NullPointerException if the test fails.
System.out.println(new SimpleDateFormat("z", Locale.of(lang, ctry)).parse("UTC"));
} catch (ParseException pe) {
// ParseException is fine in this test, as it's not "UTC"
}
}
static void bug8013903Test() {
if (IS_WINDOWS) {
Date sampleDate = new Date(0x10000000000L);
String expected = "\u5e73\u6210 16.11.03 (\u6c34) \u5348\u524d 11:53:47";
Locale l = Locale.of("ja", "JP", "JP");
SimpleDateFormat sdf = new SimpleDateFormat("GGGG yyyy.MMM.dd '('E')' a hh:mm:ss", l);
sdf.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
String result = sdf.format(sampleDate);
System.out.println(result);
// Windows display names. Subject to change if Windows changes its format.
if (!expected.equals(result)) {
throw new RuntimeException("Format failed. result: \"" +
result + "\", expected: \"" + expected);
}
}
}
static void bug8027289Test(String expectedCodePoint) {
if (IS_WINDOWS) {
char[] expectedSymbol = Character.toChars(Integer.valueOf(expectedCodePoint, 16));
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.CHINA);
char formatted = nf.format(7000).charAt(0);
System.out.println("returned: " + formatted + ", expected: " + expectedSymbol[0]);
if (formatted != expectedSymbol[0]) {
throw new RuntimeException(
"Unexpected Chinese currency symbol. returned: "
+ formatted + ", expected: " + expectedSymbol[0]);
}
}
}
static void bug8220227Test() {
if (IS_WINDOWS) {
Locale l = Locale.of("xx","XX");
String country = l.getDisplayCountry();
if (country.endsWith("(XX)")) {
throw new RuntimeException(
"Unexpected Region name: " + country);
}
}
}
static void bug8228465Test() {
LocaleProviderAdapter lda = LocaleProviderAdapter.getAdapter(CalendarNameProvider.class, Locale.US);
LocaleProviderAdapter.Type type = lda.getAdapterType();
if (type == LocaleProviderAdapter.Type.HOST && IS_WINDOWS) {
var names = new GregorianCalendar()
.getDisplayNames(Calendar.ERA, Calendar.SHORT_FORMAT, Locale.US);
if (!names.keySet().contains("AD") ||
names.get("AD").intValue() != 1) {
throw new RuntimeException(
"Short Era name for 'AD' is missing or incorrect");
} else {
System.out.println("bug8228465Test succeeded.");
}
}
}
static void bug8232871Test() {
LocaleProviderAdapter lda = LocaleProviderAdapter.getAdapter(CalendarNameProvider.class, Locale.US);
LocaleProviderAdapter.Type type = lda.getAdapterType();
var lang = Locale.getDefault().getLanguage();
var cal = Calendar.getInstance();
var calType = cal.getCalendarType();
var expected = "\u4ee4\u548c1\u5e745\u67081\u65e5 \u6c34\u66dc\u65e5 \u5348\u524d0:00:00 \u30a2\u30e1\u30ea\u30ab\u592a\u5e73\u6d0b\u590f\u6642\u9593";
if (type == LocaleProviderAdapter.Type.HOST &&
IS_MAC &&
lang.equals("ja") &&
calType.equals("japanese")) {
cal.set(1, 4, 1, 0, 0, 0);
cal.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL,
Locale.JAPAN);
df.setCalendar(cal);
var result = df.format(cal.getTime());
if (result.equals(expected)) {
System.out.println("bug8232871Test succeeded.");
} else {
throw new RuntimeException(
"Japanese calendar names mismatch. result: " +
result +
", expected: " +
expected);
}
} else {
System.out.println("Test ignored. Either :-\n" +
"OS is not macOS, or\n" +
"provider is not HOST: " + type + ", or\n" +
"Language is not Japanese: " + lang + ", or\n" +
"native calendar is not JapaneseCalendar: " + calType);
}
}
static void bug8232860Test() {
var inputList = List.of(123, 123.4);
var nfExpectedList = List.of("123", "123.4");
var ifExpectedList = List.of("123", "123");
var defLoc = Locale.getDefault(Locale.Category.FORMAT);
var type = LocaleProviderAdapter.getAdapter(CalendarNameProvider.class, Locale.US)
.getAdapterType();
if (defLoc.equals(Locale.US) &&
type == LocaleProviderAdapter.Type.HOST &&
(IS_WINDOWS || IS_MAC)) {
final var numf = NumberFormat.getNumberInstance(Locale.US);
final var intf = NumberFormat.getIntegerInstance(Locale.US);
IntStream.range(0, inputList.size())
.forEach(i -> {
var input = inputList.get(i);
var nfExpected = nfExpectedList.get(i);
var result = numf.format(input);
if (!result.equals(nfExpected)) {
throw new RuntimeException("Incorrect number format. " +
"input: " + input + ", expected: " +
nfExpected + ", result: " + result);
}
var ifExpected = ifExpectedList.get(i);
result = intf.format(input);
if (!result.equals(ifExpected)) {
throw new RuntimeException("Incorrect integer format. " +
"input: " + input + ", expected: " +
ifExpected + ", result: " + result);
}
});
System.out.println("bug8232860Test succeeded.");
} else {
System.out.println("Test ignored. Either :-\n" +
"Default format locale is not Locale.US: " + defLoc + ", or\n" +
"OS is neither macOS/Windows, or\n" +
"provider is not HOST: " + type);
}
}
static void bug8245241Test(String expected) {
// this will ensure LocaleProviderAdapter initialization
DateFormat.getDateInstance();
LogConfig.handler.flush();
if (LogConfig.logRecordList.stream()
.noneMatch(r -> r.getLevel() == Level.INFO &&
r.getMessage().equals(expected))) {
throw new RuntimeException("Expected log was not emitted.");
}
}
// Set the root logger on loading the logging class
public static class LogConfig {
final static CopyOnWriteArrayList<LogRecord> logRecordList = new CopyOnWriteArrayList<>();
final static StreamHandler handler = new StreamHandler() {
@Override
public void publish(LogRecord record) {
logRecordList.add(record);
System.out.println("LogRecord: " + record.getMessage());
}
};
static {
getLogManager().getLogger("").addHandler(handler);
}
}
static void bug8248695Test() {
Locale l = Locale.getDefault(Locale.Category.FORMAT);
LocaleProviderAdapter lda = LocaleProviderAdapter.getAdapter(DateFormatProvider.class, l);
LocaleProviderAdapter.Type type = lda.getAdapterType();
if (type == LocaleProviderAdapter.Type.HOST) {
System.out.println("Locale: " + l);
var ld = LocalDate.now();
var zdt = ZonedDateTime.now(ZoneId.of("America/Los_Angeles"));
var df = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(l);
var tf = DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL).withLocale(l);
var dtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withLocale(l);
// Checks there's no "unsupported temporal field" exception thrown, such as HourOfDay
System.out.println(df.format(ld));
System.out.println(tf.format(zdt));
// Checks there's no "Too many pattern letters: aa" exception thrown, if
// underlying OS provides the "am/pm" pattern.
System.out.println(dtf.format(zdt));
}
}
// Run only if the underlying platform locale is en-GB
// (Setting the java locale via command line properties does not substitute this)
static void bug8257964Test() {
var defLoc = Locale.getDefault(Locale.Category.FORMAT);
var type = LocaleProviderAdapter.getAdapter(CalendarNameProvider.class, Locale.UK)
.getAdapterType();
if (defLoc.equals(Locale.UK) &&
type == LocaleProviderAdapter.Type.HOST &&
(IS_WINDOWS || IS_MAC)) {
Calendar instance = Calendar.getInstance(Locale.UK);
int result = instance.getMinimalDaysInFirstWeek();
if (result != 4) {
throw new RuntimeException("MinimalDaysInFirstWeek for Locale.UK is incorrect. " +
"returned: " + result);
}
LocalDate date = LocalDate.of(2020,12,31);
result = date.get(WeekFields.of(Locale.UK).weekOfWeekBasedYear());
if (result != 53) {
throw new RuntimeException("weekNumber is incorrect. " +
"returned: " + result);
}
System.out.println("bug8257964Test succeeded.");
} else {
System.out.println("Test ignored. Either :-\n" +
"Default format locale is not Locale.UK: " + defLoc + ", or\n" +
"OS is neither macOS/Windows, or\n" +
"provider is not HOST: " + type);
}
}
/* Method is used by the LocaleProviders* related tests to launch a
* LocaleProviders test method with the appropriate LocaleProvider (e.g. CLDR,
* COMPAT, ETC.)
*/
static void test(String prefList, String methodName, String... params) throws Throwable {
List<String> command = List.of(
"-ea", "-esa",
"-cp", Utils.TEST_CLASS_PATH,
// Required for LocaleProvidersLogger
"-Djava.util.logging.config.class=LocaleProviders$LogConfig",
"-Djava.locale.providers=" + prefList,
"--add-exports=java.base/sun.util.locale.provider=ALL-UNNAMED",
"LocaleProviders", methodName);
// Build process with arguments, if required by the method
ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(
Stream.concat(command.stream(), Stream.of(params)).toList());
// Evaluate process status
int exitCode = ProcessTools.executeCommand(pb).getExitValue();
if (exitCode != 0) {
throw new RuntimeException("Unexpected exit code: " + exitCode);
}
}
}

View file

@ -0,0 +1,74 @@
/*
* 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 8228465 8232871 8257964
* @summary Test any Calendar Locale provider related issues
* @library /test/lib
* @build LocaleProviders
* @modules java.base/sun.util.locale.provider
* @run junit/othervm LocaleProvidersCalendar
*/
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
import static org.junit.jupiter.api.condition.OS.MAC;
import static org.junit.jupiter.api.condition.OS.WINDOWS;
public class LocaleProvidersCalendar {
/*
* 8228465 (Windows only): Ensure correct ERA display name under HOST Windows
*/
@Test
@EnabledOnOs(WINDOWS)
public void gregCalEraHost() throws Throwable {
LocaleProviders.test("HOST", "bug8228465Test");
}
/*
* 8232871 (macOS only): Ensure correct Japanese calendar values under
* HOST Mac.
*/
@Test
@EnabledOnOs(MAC)
public void japaneseCalValuesHost() throws Throwable {
LocaleProviders.test("HOST", "bug8232871Test");
}
/*
* 8257964 (macOS/Windows only): Ensure correct Calendar::getMinimalDaysInFirstWeek
* value under HOST Windows / Mac. Only run against machine with underlying
* OS locale of en-GB.
*/
@Test
@EnabledOnOs({WINDOWS, MAC})
@EnabledIfSystemProperty(named = "user.language", matches = "en")
@EnabledIfSystemProperty(named = "user.country", matches = "GB")
public void minDaysFirstWeekHost() throws Throwable {
LocaleProviders.test("HOST", "bug8257964Test");
}
}

View file

@ -0,0 +1,46 @@
/*
* 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 8248695
* @summary Test any java.time.DateTimeFormatter Locale provider related issues
* @library /test/lib
* @build LocaleProviders
* @modules java.base/sun.util.locale.provider
* @run junit/othervm LocaleProvidersDateTimeFormatter
*/
import org.junit.jupiter.api.Test;
public class LocaleProvidersDateTimeFormatter {
/*
* 8248695: Ensure DateTimeFormatter::ofLocalizedDate does not throw exception
* under HOST (date only pattern leaks time field)
*/
@Test
public void dateOnlyJavaTimePattern() throws Throwable {
LocaleProviders.test("HOST", "bug8248695Test");
}
}

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2012, 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 7198834 8001440 8013086 8013903 8027289 8232860 8174269
* @summary Test any java.text.Format Locale provider related issues
* @library /test/lib
* @build LocaleProviders
* providersrc.spi.src.tznp
* providersrc.spi.src.tznp8013086
* @modules java.base/sun.util.locale.provider
* @run junit/othervm LocaleProvidersFormat
*/
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
import org.junit.jupiter.api.condition.EnabledOnOs;
import static org.junit.jupiter.api.condition.OS.MAC;
import static org.junit.jupiter.api.condition.OS.WINDOWS;
public class LocaleProvidersFormat {
/*
* 7198834: Ensure under Windows/HOST, adapter does not append an extra space for date patterns.
*/
@Test
@EnabledOnOs(WINDOWS)
public void dateFormatExtraSpace() throws Throwable {
LocaleProviders.test("HOST", "bug7198834Test");
}
/*
* 8001440: Ensure under CLDR, when number extension of the language
* tag is invalid, test program does not throw exception when calling
* NumberFormat::format.
*/
@Test
public void formatWithInvalidLocaleExtension() throws Throwable {
LocaleProviders.test("CLDR", "bug8001440Test");
}
/*
* 8013086: Ensure a custom TimeZoneNameProvider does not cause an NPE
* in simpleDateFormat, as SimpleDateFormat::matchZoneString expects the
* name array is fully filled with non-null names.
*/
@Test
public void simpleDateFormatWithTZNProvider() throws Throwable {
LocaleProviders.test("FALLBACK,SPI", "bug8013086Test", "ja", "JP");
}
/*
* 8013903 (Windows only): Ensure HOST adapter with Japanese locale produces
* the correct Japanese era, month, day names.
*/
@Test
@EnabledOnOs(WINDOWS)
@EnabledIfSystemProperty(named = "user.language", matches = "ja")
@EnabledIfSystemProperty(named = "user.country", matches = "JP")
public void windowsJapaneseDateFields() throws Throwable {
LocaleProviders.test("HOST", "bug8013903Test");
}
/*
* 8027289: Ensure if underlying system format locale is zh_CN, the Window's currency
* symbol under HOST provider is ¥, the yen (yuan) sign.
*/
@Test
@EnabledOnOs(WINDOWS)
@EnabledIfSystemProperty(named = "user.language", matches = "zh")
@EnabledIfSystemProperty(named = "user.country", matches = "CN")
public void windowsChineseCurrencySymbol() throws Throwable {
LocaleProviders.test("FALLBACK,HOST", "bug8027289Test", "FFE5");
LocaleProviders.test("HOST", "bug8027289Test", "00A5");
}
/*
* 8232860 (macOS/Windows only): Ensure the Host adapter returns the number
* pattern for number/integer instances, which require optional fraction digits.
*/
@Test
@EnabledOnOs({WINDOWS, MAC})
public void hostOptionalFracDigits() throws Throwable {
LocaleProviders.test("HOST", "bug8232860Test");
}
}

View file

@ -0,0 +1,49 @@
/*
* 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 8245241 8246721 8261919
* @summary Test the Locale provider preference is logged
* @library /test/lib
* @build LocaleProviders
* @modules java.base/sun.util.locale.provider
* @run junit/othervm -Djdk.lang.Process.allowAmbiguousCommands=false LocaleProvidersLogger
*/
import org.junit.jupiter.api.Test;
public class LocaleProvidersLogger {
/*
* 8245241 8246721 8261919: Ensure if an incorrect system property for locale providers is set,
* it should be logged and presented to the user. The option
* jdk.lang.Process.allowAmbiguousCommands=false is needed for properly escaping
* double quotes in the string argument.
*/
@Test
public void logIncorrectLocaleProvider() throws Throwable {
LocaleProviders.test("FOO", "bug8245241Test",
"Invalid locale provider adapter \"FOO\" ignored.");
}
}

View file

@ -0,0 +1,172 @@
/*
* 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 6336885 7196799 7197573 8008577 8010666 8013233 8015960 8028771
* 8054482 8062006 8150432 8215913 8220227 8236495 8174269
* @summary General Locale provider test (ex: adapter loading). See the
* other LocaleProviders* test classes for more specific tests (ex:
* java.text.Format related bugs).
* @library /test/lib
* @build LocaleProviders
* @modules java.base/sun.util.locale.provider
* jdk.localedata
* @run junit/othervm LocaleProvidersRun
*/
import java.util.Locale;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.condition.OS.WINDOWS;
/*
* Note: If this test launches too many JVMs, consider increasing timeout.
* As the LocaleProvider is set during java startup time, this test and the subclasses
* will always have to launch a separate JVM for testing of different providers.
*/
public class LocaleProvidersRun {
private static String defLang;
private static String defCtry;
private static String defFmtLang;
private static String defFmtCtry;
// Get the system default locale values. Used to decide param values for tests.
@BeforeAll
static void setUp() {
Locale platDefLoc = Locale.getDefault(Locale.Category.DISPLAY);
Locale platDefFormat = Locale.getDefault(Locale.Category.FORMAT);
defLang = platDefLoc.getLanguage();
defCtry = platDefLoc.getCountry();
defFmtLang = platDefFormat.getLanguage();
defFmtCtry = platDefFormat.getCountry();
// Print out system defaults for diagnostic purposes
System.out.printf("DEFLANG = %s, DEFCTRY = %s, DEFFMTLANG = %s, DEFFMTCTRY = %s",
defLang, defCtry, defFmtLang, defFmtCtry);
}
/*
* Test the adapter loading logic in LocaleProviderAdapter.
* Ensures that correct fallbacks are implemented.
*/
@ParameterizedTest
@MethodSource
public void adapterTest(String prefList, String param1,
String param2, String param3) throws Throwable {
LocaleProviders.test(prefList, "adapterTest", param1, param2, param3);
}
/*
* Data provider which only launches against the LocaleProvider::adapterTest
* method. The arguments are dictated based off the operating system/platform
* Locale. Tests against variety of provider orders.
*/
private static Stream<Arguments> adapterTest() {
// Testing HOST is selected for the default locale if specified on Windows or MacOSX
String osName = System.getProperty("os.name");
String param1 = "FALLBACK";
if (osName.startsWith("Windows") || osName.startsWith("Mac")) {
param1 = "HOST";
}
// Testing HOST is NOT selected for the non-default locale, if specified
// try to find the locale CLDR supports which is not the platform default
// (HOST supports that one)
String param2;
String param3;
if (!defLang.equals("en") && !defFmtLang.equals("en")) {
param2 = "en";
param3 = "US";
} else if (!defLang.equals("ja") && !defFmtLang.equals("ja")) {
param2 = "ja";
param3 = "JP";
} else {
param2 = "zh";
param3 = "CN";
}
return Stream.of(
Arguments.of("HOST", param1, defLang, defCtry),
Arguments.of("HOST", "FALLBACK", param2, param3),
// Testing SPI is NOT selected, as there is none.
Arguments.of("SPI,FALLBACK", "FALLBACK", "en", "US"),
Arguments.of("SPI", "FALLBACK", "en", "US"),
// Testing the order, variant #1. This assumes root DateFormat data are
// available both in FALLBACK & CLDR
Arguments.of("CLDR,FALLBACK", "CLDR", "", ""),
Arguments.of("CLDR", "CLDR", "", ""),
// Testing the order, variant #2. This assumes root DateFormat data are
// available both in FALLBACK & CLDR
Arguments.of("FALLBACK,CLDR", "FALLBACK", "", ""),
// Testing the order, variant #3 for non-existent locale in FALLBACK
// assuming "haw" is not in FALLBACK.
Arguments.of("FALLBACK,CLDR", "CLDR", "haw", ""),
// Testing the order, variant #4 for the bug 7196799. CLDR's "zh" data
// should be used in "zh_CN"
Arguments.of("CLDR", "CLDR", "zh", "CN"),
// Testing FALLBACK provider. SPI and invalid one cases.
Arguments.of("SPI", "FALLBACK", "en", "US"),
Arguments.of("FOO", "CLDR", "en", "US"),
Arguments.of("BAR,SPI", "FALLBACK", "en", "US")
);
}
/*
* 8010666: Test to ensure correct implementation of Currency/LocaleNameProvider
* in HOST Windows provider (English locale)
*/
@Test
@EnabledOnOs(WINDOWS)
@EnabledIfSystemProperty(named = "user.language", matches = "en")
public void currencyNameProviderWindowsHost() throws Throwable {
LocaleProviders.test("HOST", "bug8010666Test");
}
/*
* 8220227: Ensure Locale::getDisplayCountry does not display error message
* under HOST Windows (non-english locale)
*/
@Test
@EnabledOnOs(WINDOWS)
@DisabledIfSystemProperty(named = "user.language", matches = "en")
public void nonEnglishDisplayCountryHost() throws Throwable {
LocaleProviders.test("HOST", "bug8220227Test");
}
}

View file

@ -0,0 +1,51 @@
/*
* 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 8000245 8000615
* @summary Test any TimeZone Locale provider related issues
* @library /test/lib
* @build LocaleProviders
* providersrc.spi.src.tznp
* providersrc.spi.src.tznp8013086
* @modules java.base/sun.util.locale.provider
* @run junit/othervm LocaleProvidersTimeZone
*/
import org.junit.jupiter.api.Test;
public class LocaleProvidersTimeZone {
/*
* 8000245 and 8000615: Ensure preference is followed, even with a custom
* SPI defined.
*/
@Test
public void timeZoneWithCustomProvider() throws Throwable {
LocaleProviders.test("JRE", "tzNameTest", "Europe/Moscow");
LocaleProviders.test("COMPAT", "tzNameTest", "Europe/Moscow");
LocaleProviders.test("JRE", "tzNameTest", "America/Los_Angeles");
LocaleProviders.test("COMPAT", "tzNameTest", "America/Los_Angeles");
}
}

View file

@ -0,0 +1,76 @@
/*
* Copyright (c) 2007, 2023, 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 4152725
* @summary Verify that the default locale can be specified from the
* command line.
* @run main/othervm -Duser.language=de -Duser.country=DE -Duser.variant=EURO
* LocaleShouldSetFromCLI de_DE_EURO
* @run main/othervm -Duser.language=ja -Duser.country= -Duser.variant=
* LocaleShouldSetFromCLI ja
* @run main/othervm -Duser.language=en -Duser.country=SG -Duser.variant=
* LocaleShouldSetFromCLI en_SG
* @run main/othervm -Duser.language= -Duser.country=DE -Duser.variant=EURO
* LocaleShouldSetFromCLI _DE_EURO
* @run main/othervm -Duser.language=ja -Duser.country= -Duser.variant=YOMI
* LocaleShouldSetFromCLI ja__YOMI
* @run main/othervm -Duser.language= -Duser.country= -Duser.variant=EURO
* LocaleShouldSetFromCLI __EURO
* @run main/othervm -Duser.language=de -Duser.region=DE_EURO
* LocaleShouldSetFromCLI de_DE_EURO
*/
import java.util.Locale;
public class LocaleShouldSetFromCLI {
public static void main(String[] args) {
if (args.length != 1) {
throw new RuntimeException("expected locale needs to be specified");
}
Locale locale = Locale.getDefault();
// don't use Locale.toString - it's bogus
String language = locale.getLanguage();
String country = locale.getCountry();
String variant = locale.getVariant();
String localeID = null;
if (variant.length() > 0) {
localeID = language + "_" + country + "_" + variant;
} else if (country.length() > 0) {
localeID = language + "_" + country;
} else {
localeID = language;
}
if (localeID.equals(args[0])) {
System.out.println("Correctly set from command line: " + localeID);
} else {
throw new RuntimeException("expected default locale: " + args[0]
+ ", actual default locale: " + localeID);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2016, 2023, 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 8135061
* @summary Checks that the Locale.lookup executes properly without throwing
* any exception for some specific language ranges
* @run junit LookupOnValidRangeTest
*/
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Locale.LanguageRange;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
public class LookupOnValidRangeTest {
/**
* Lookup should run without throwing any exception and return null as
* the language range does not match with the language tag.
*/
@Test
public void lookupReturnNullTest() {
List<LanguageRange> ranges = LanguageRange.parse("nv");
Collection<Locale> locales = Collections.singleton(Locale.ENGLISH);
try {
Locale match = Locale.lookup(ranges, locales);
assertNull(match);
} catch (Exception ex) {
throw new RuntimeException("[Locale.lookup failed on language"
+ " range: " + ranges + " and language tags "
+ locales + "]", ex);
}
}
/**
* Lookup should run without throwing any exception and return "nv"
* as the matching tag.
*/
@Test
public void lookupReturnValueTest() {
List<LanguageRange> ranges = LanguageRange.parse("i-navajo");
Collection<Locale> locales = Collections.singleton(Locale.of("nv"));
try {
Locale match = Locale.lookup(ranges, locales);
assertEquals(match.toLanguageTag(), "nv");
} catch (Exception ex) {
throw new RuntimeException("[Locale.lookup failed on language"
+ " range: " + ranges + " and language tags "
+ locales + "]", ex);
}
}
}

View file

@ -0,0 +1,144 @@
/*
* Copyright (c) 2016, 2023, 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 8035133
* @summary Checks that the tags matching the range with quality weight q=0
* e.g. en;q=0 must be elimited and must not be the part of output
* @run junit MatchEmptyWeightCorrectly
*/
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class MatchEmptyWeightCorrectly {
// Ensure weights with 'q=0' work as expected during lookup
@ParameterizedTest
@MethodSource("lookupProvider")
public void lookupTest(String ranges, String tags,
String expectedLocale) {
List<Locale.LanguageRange> priorityList = Locale.LanguageRange
.parse(ranges);
List<Locale> localeList = generateLocales(tags);
Locale loc = Locale.lookup(priorityList, localeList);
String actualLocale = loc.toLanguageTag();
assertEquals(expectedLocale, actualLocale);
}
private static Stream<Arguments> lookupProvider() {
return Stream.of(
// checking Locale.lookup with de-ch;q=0
Arguments.of("en;q=0.1, *-ch;q=0.5, de-ch;q=0",
"de-ch, en, fr-ch", "fr-CH"),
// checking Locale.lookup with *;q=0 '*' should be ignored in lookup
Arguments.of("en;q=0.1, *-ch;q=0.5, *;q=0",
"de-ch, en, fr-ch", "de-CH")
);
}
// Ensure weights with 'q=0' work as expected during filtering
@ParameterizedTest
@MethodSource("filterProvider")
public void filterTest(String ranges, String tags,
String expectedLocales) {
List<Locale.LanguageRange> priorityList = Locale.LanguageRange
.parse(ranges);
List<Locale> localeList = generateLocales(tags);
String actualLocales = getLocalesAsString(
Locale.filter(priorityList, localeList));
assertEquals(expectedLocales, actualLocales);
}
private static Stream<Arguments> filterProvider() {
return Stream.of(
// checking Locale.filter with fr-ch;q=0 in BASIC_FILTERING
Arguments.of("en;q=0.1, fr-ch;q=0.0, de-ch;q=0.5",
"de-ch, en, fr-ch", "de-CH, en"),
// checking Locale.filter with *;q=0 in BASIC_FILTERING
Arguments.of("de-ch;q=0.6, *;q=0", "de-ch, fr-ch", ""),
// checking Locale.filter with *;q=0 in BASIC_FILTERING
Arguments.of("de-ch;q=0.6, de;q=0", "de-ch", ""),
// checking Locale.filter with *;q=0.6, en;q=0 in BASIC_FILTERING
Arguments.of("*;q=0.6, en;q=0", "de-ch, hi-in, en", "de-CH, hi-IN"),
// checking Locale.filter with de-ch;q=0 in EXTENDED_FILTERING
Arguments.of("en;q=0.1, *-ch;q=0.5, de-ch;q=0",
"de-ch, en, fr-ch", "fr-CH, en"),
/* checking Locale.filter with *-ch;q=0 in EXTENDED_FILTERING which
* must make filter to return "" empty or no match
*/
Arguments.of("de-ch;q=0.5, *-ch;q=0", "de-ch, fr-ch", ""),
/* checking Locale.filter with *;q=0 in EXTENDED_FILTERING which
* must make filter to return "" empty or no match
*/
Arguments.of("*-ch;q=0.5, *;q=0", "de-ch, fr-ch", ""),
/* checking Locale.filter with *;q=0.6, *-Latn;q=0 in
* EXTENDED_FILTERING
*/
Arguments.of("*;q=0.6, *-Latn;q=0", "de-ch, hi-in, en-Latn",
"de-CH, hi-IN")
);
}
private static List<Locale> generateLocales(String tags) {
if (tags == null) {
return null;
}
List<Locale> localeList = new ArrayList<>();
if (tags.equals("")) {
return localeList;
}
String[] t = tags.split(", ");
for (String tag : t) {
localeList.add(Locale.forLanguageTag(tag));
}
return localeList;
}
private static String getLocalesAsString(List<Locale> locales) {
StringBuilder sb = new StringBuilder();
Iterator<Locale> itr = locales.iterator();
if (itr.hasNext()) {
sb.append(itr.next().toLanguageTag());
}
while (itr.hasNext()) {
sb.append(", ");
sb.append(itr.next().toLanguageTag());
}
return sb.toString().trim();
}
}

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2017, 2026, 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 8032842 8175539
* @summary Checks that the filterTags() and lookup() methods
* preserve the case of matching language tag(s).
* Before 8032842 fix these methods return the matching
* language tag(s) in lowercase.
* Also, checks the filterTags() to return only unique
* (ignoring case considerations) matching tags.
* @run junit PreserveTagCase
*/
import java.util.List;
import java.util.Locale;
import java.util.Locale.FilteringMode;
import java.util.Locale.LanguageRange;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class PreserveTagCase {
/**
* This test ensures that Locale.filterTags() preserves the case of matching
* language tag(s).
*/
@ParameterizedTest
@MethodSource("filterProvider")
public void testFilterTags(String ranges, List<String> tags,
List<String> expected, FilteringMode mode) {
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
List<String> actual = Locale.filterTags(priorityList, tags, mode);
assertEquals(actual, expected, String.format("[filterTags() failed for " +
"the language range: %s, Expected: %s, Found: %s]", ranges, expected, actual));
}
/**
* This test ensures that Locale.lookupTag() preserves the case of matching
* language tag(s).
*/
@ParameterizedTest
@MethodSource("lookupProvider")
public void testLookupTag(String ranges, List<String> tags,
String expected) {
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
String actual = Locale.lookupTag(priorityList, tags);
assertEquals(actual, expected, String.format("[lookupTags() failed for " +
"the language range: %s, Expected: %s, Found: %s]", ranges, expected, actual));
}
private static Stream<Arguments> filterProvider() {
return Stream.of(
// test filterBasic() for preserving the case of matching tags for
// the language range '*', with no duplicates in the matching tags
Arguments.of("*",
List.of("de-CH", "hi-in", "En-GB", "ja-Latn-JP", "JA-JP", "en-GB"),
List.of("de-CH", "hi-in", "En-GB", "ja-Latn-JP", "JA-JP"),
FilteringMode.AUTOSELECT_FILTERING),
// test filterBasic() for preserving the case of matching tags for
// basic ranges other than *, with no duplicates in the matching tags
Arguments.of("mtm-RU, en-GB",
List.of("En-Gb", "mTm-RU", "en-US", "en-latn", "en-GB"),
List.of("mTm-RU", "En-Gb"),
FilteringMode.AUTOSELECT_FILTERING),
// test filterExtended() for preserving the case of matching tags for
// the language range '*', with no duplicates in the matching tags
Arguments.of("*",
List.of("de-CH", "hi-in", "En-GB", "hi-IN", "ja-Latn-JP", "JA-JP"),
List.of("de-CH", "hi-in", "En-GB", "ja-Latn-JP", "JA-JP"),
FilteringMode.EXTENDED_FILTERING),
// test filterExtended() for preserving the case of matching tags for
// extended ranges other than *, with no duplicates in the matching tags
Arguments.of("*-ch;q=0.5, *-Latn;q=0.4",
List.of("fr-CH", "de-Ch", "en-latn", "en-US", "en-Latn"),
List.of("fr-CH", "de-Ch", "en-latn"),
FilteringMode.EXTENDED_FILTERING)
);
}
private static Stream<Arguments> lookupProvider() {
return Stream.of(
// test lookupTag() for preserving the case of matching tag
Arguments.of("*-ch;q=0.5", List.of("en", "fR-cH"), "fR-cH"),
Arguments.of("*-Latn;q=0.4", List.of("en", "fR-LATn"), "fR-LATn")
);
}
}

View file

@ -0,0 +1,248 @@
/*
* 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.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*
* (C) Copyright IBM Corp. 1998 - All Rights Reserved
*
* Portions copyright (c) 2007 Sun Microsystems, Inc.
* All Rights Reserved.
*
* The original version of this source code and documentation
* is copyrighted and owned by Taligent, Inc., a wholly-owned
* subsidiary of IBM. These materials are provided under terms
* of a License Agreement between Taligent and Sun. This technology
* is protected by multiple US and International patents.
*
* This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
/*
@bug 4123370 4091969 4118731 4182108 4778440
The "at-test" tag was removed from this file, because there's no way to
run this test in an automated test harness. It depends on having various
different locales installed on the machine, and on Windows it depends
on the user going to the "Regional Settings" control panel and changing
the settings before running the test for each bug. We can run this test
manually from time to time to ensure that there has been no regression,
but it's not automated. -- lwerner, 7/6/98
INSTRUCTIONS FOR RUNNING THIS TEST
==================================
This test is designed to check for problems in the JVM code that initializes the
default Java locale (the locale returned by Locale.getDefault()) from the system
locale settings (or from command-line arguments). Since detecting a regression
usually requires setting the environment up in some way prior to running the test,
this is a manual test.
The test simply prints out the internal ID and display name of the default Java locale,
and the name of the default Java character encoding. It passes if these are what
you expect them to be, and fails if they're not.
Bug #4091969:
To test for bug #4091969, run this test on a Korean-localized version of
Windows, with the default locale set to Korean. You should get "ko_KR"
as the default locale.
Bug #4123370:
One part of bug #4123370 duplicates bug #4091969, which is covered by the
instructions above.
To test the unique part of bug #4123370, use the "Regional Settings" control
panel to set the currect locale to each of the different Spanish-language locales.
Run this test once for each Spanish-language locale. You should see the appropriate
locale ID and name for each locale. Both "Spanish - Traditional Sort" and
"Spanish - Modern Sort" should produce "es_ES" and "Spanish (Spain)".
Bug #4118731:
The basic issue here was that we had changed so that calling getDisplayName()
on a locale that didn't include a country code no longer included a country
name (instead of picking a default country name, as before), which is the
right answer. The problem is we weren't always getting back a system default
locale from Solaris that includes a country code, even though we should.
To test this, set the system default locale to a locale that doesn't include
a country code, such as "fr" or "de", using (in the C shell) "setenv LC_ALL fr"
(or whatever the locale ID you want is). Running PrintDefaultLocale should
still produce a locale ID, and a locale display name, that include a country
code (and country name). [Remember to make sure the locale is actually installed
first.]
To test the specific complaint in the bug, use "setenv LC_ALL ja". Also pay
special attention to Solaris locale IDs that don't match the corresponding java
locales, such as "su" (which should turn into "fi_FI"), "cz" (which should turn
into "cs_CZ"), and "en_UK" (which should turn into "en_GB").
Bug #4079167:
Test this bug the same way you test bug #4118731. Set the locale to each of
the specified locale IDs (e.g., "setenv LC_ALL japanese"), and then run
PrintDefaultLocale. You should get the following results:
Solaris ID Java ID Java display name Encoding
========== ======= ==================== ========
japanese ja_JP Japanese (Japan) --
korean ko_KR Korean (South Korea) --
tchinese zh_TW Chinese (Taiwan) --
big5 zh_TW Chinese (Taiwan) Big5
(Where "--" is marked for "encoding," the result isn't important-- it's the
default encoding for that locale, which we don't test. It should be something
plausible. Also note that this test presupposed you actually have locales
with these names installed on your system.)
Bug #4154559, 4778440:
Set the locale to Norwegian (Bokmal) and Norwegian (Nynorsk) using the
Regional Settings control panel on Windows. For each setting, run this program.
You should see no_NO and no_NO_NY, respectively.
Bug #4182108:
Test this bug the same way you test bug #4118731. Set the locale to
each of the specified locale IDs (e.g., "setenv LC_ALL japanese"), and
then run PrintDefaultLocale. You should get the following results:
Solaris ID Java ID Encoding
========== ======= ========
cz cs_CZ --
su fi_FI --
fr.ISO8859-15 fr_FR ISO8859-15
fr.ISO8859-15@euro fr_FR ISO8859-15
Where "--" is marked for "encoding," the result isn't important-- it's
the default encoding for that locale, which we don't test. It should be
something plausible. Also note that this test presupposed you actually
have locales with these names installed on your system.
As of this writing, there is a bug in Solaris or in the 8859-15/euro
patch for 2.6 (Solaris patch 106842-01) which causes nl_langinfo() to
return the wrong value for 8859-15 locales. As a result, the encoding
returned by this test is currency ISO8859-1 for 8859-15 locales.
Bug #4778440, 5005601, 5074060, 5107154:
Run the "deflocale" tool found in "data" directory (deflocale.sh on Unix,
deflocale.exe on Windows), and check the following:
4778440: Check that iw_IL is the default locale if the OS's locale is
Hebrew, and in_ID for Indonesian.
5005601: For Norwegian locales, no_NO is selected for Bokmal, and no_NO_NY
is selected for Nynorsk.
5074060, 5107154: On Windows XP ServicePack 2, check the default locales for the
following Windows locales. Compare with the golden data (deflocale.win):
Bengali - India
Croatian - Bosnia and Herzegovina
Bosnian - Bosnia and Herzegovina
Serbian (Latin) - Bosnia and Herzegovina
Serbian (Cyrillic) - Bosnia and Herzegovina
Welsh - United Kingdom
Maori - New Zealand
Malayalam - India
Maltese - Malta
Quechua - Bolivia
Quechua - Ecuador
Quechua - Peru
Setswana (Tswana) - South Africa
isiXhosa (Xhosa) - South Africa
isiZulu ( Zulu) - South Africa
Sesotho sa Leboa (Northern Sotho) - South Africa
Sami, Northern - Norway
Sami, Northern - Sweden
Sami, Northern - Finland
Sami, Lule - Norway
Sami, Lule - Sweden
Sami, Southern - Norway
Sami, Southern - Sweden
Sami, Skolt - Finland
Sami, Inari - Finland
Bug # 6409997:
Run the "deflocale.exe" tool found in "data" directory on Windows Vista.
It contains the following new locales:
Tajik (Cyrillic) (Tajikistan) - 1251
Upper Sorbian (Germany) - 1252
Turkmen (Turkmenistan) - 1250
Oriya (India) - 0
Assamese (India) - 0
Tibetan (People's Republic of China) - 0
Khmer (Cambodia) - 0
Lao (Lao P.D.R.) - 0
Sinhala (Sri Lanka) - 0
Inuktitut (Canada) - 0
Amharic (Ethiopia) - 0
Hausa (Latin) (Nigeria) - 1252
Yoruba (Nigeria) - 1252
Bashkir (Russia) - 1251
Greenlandic (Greenland) - 1252
Igbo (Nigeria) - 1252
Yi (People's Republic of China) - 0
Breton (France) - 1252
Uighur (People's Republic of China) - 1256
Occitan (France) - 1252
Corsican (France) - 1252
Alsatian (France) - 1252
Yakut (Russia) - 1251
K'iche (Guatemala) - 1252
Kinyarwanda (Rwanda) - 1252
Wolof (Senegal) - 1252
Dari (Afghanistan) - 1256
Lower Sorbian (Germany) - 1252
Bengali (Bangladesh) - 0
Mongolian (Traditional Mongolian) (People's Republic of China) - 0
Tamazight (Latin) (Algeria) - 1252
English (India) - 1252
English (Malaysia) - 1252
English (Singapore) - 1252
Spanish (United States) - 1252
*/
import java.nio.charset.Charset;
import java.util.Locale;
public class PrintDefaultLocale {
public static void main(String[] args) {
System.out.printf("default locale: ID: %s, Name: %s\n",
Locale.getDefault().toString(),
Locale.getDefault().getDisplayName(Locale.US));
System.out.printf("display locale: ID: %s, Name: %s\n",
Locale.getDefault(Locale.Category.DISPLAY).toString(),
Locale.getDefault(Locale.Category.DISPLAY).getDisplayName(Locale.US));
System.out.printf("format locale: ID: %s, Name: %s\n",
Locale.getDefault(Locale.Category.FORMAT).toString(),
Locale.getDefault(Locale.Category.FORMAT).getDisplayName(Locale.US));
System.out.printf("default charset: %s\n", Charset.defaultCharset());
}
}

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2010, 2023, 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 6989440
* @summary Verify ConcurrentModificationException is not thrown with multiple
* thread accesses.
* @modules java.base/sun.util.locale.provider
* @compile -XDignore.symbol.file=true ProviderPoolMultiThreadAccess.java
* @run junit ProviderPoolMultiThreadAccess
*/
import java.text.spi.DateFormatProvider;
import java.util.spi.LocaleNameProvider;
import java.util.spi.LocaleServiceProvider;
import java.util.spi.TimeZoneNameProvider;
import sun.util.locale.provider.LocaleServiceProviderPool;
import org.junit.jupiter.api.Test;
public class ProviderPoolMultiThreadAccess {
static volatile boolean failed; // false
static final int THREADS = 50;
/* Multiple instances of Locale Service Provider Pool calling
* getAvailableLocales() should not throw ConcurrentModificationException
*/
@Test
public void multiThreadAccessTest() throws Exception {
Thread[] threads = new Thread[THREADS];
for (int i=0; i<threads.length; i++)
threads[i] = new TestThread();
for (int i=0; i<threads.length; i++)
threads[i].start();
for (int i=0; i<threads.length; i++)
threads[i].join();
if (failed)
throw new RuntimeException("Failed: check output");
}
static class TestThread extends Thread {
private Class<? extends LocaleServiceProvider> cls;
private static int count;
public TestThread() {
int which = count++ % 3;
switch (which) {
case 0 -> cls = LocaleNameProvider.class;
case 1 -> cls = TimeZoneNameProvider.class;
case 2 -> cls = DateFormatProvider.class;
default -> throw new AssertionError("Should not reach here");
}
}
public void run() {
try {
LocaleServiceProviderPool pool = LocaleServiceProviderPool.getPool(cls);
pool.getAvailableLocales();
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
failed = true;
}
}
}
}

View file

@ -0,0 +1,84 @@
/*
* Copyright (c) 2021, 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 8276186 8174269
* @summary Checks whether getAvailableLocales() returns at least Locale.ROOT and
* Locale.US instances.
* @run junit RequiredAvailableLocalesTest
*/
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.text.BreakIterator;
import java.text.Collator;
import java.text.DateFormat;
import java.text.DateFormatSymbols;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.time.format.DecimalStyle;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Locale;
import java.util.Set;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class RequiredAvailableLocalesTest {
private static final Set<Locale> REQUIRED_LOCALES = Set.of(Locale.ROOT, Locale.US);
private static final MethodType ARRAY_RETURN_TYPE = MethodType.methodType(Locale.class.arrayType());
private static final MethodType SET_RETURN_TYPE = MethodType.methodType(Set.class);
static Object[][] availableLocalesClasses() {
return new Object[][] {
{BreakIterator.class, ARRAY_RETURN_TYPE},
{Calendar.class, ARRAY_RETURN_TYPE},
{Collator.class, ARRAY_RETURN_TYPE},
{DateFormat.class, ARRAY_RETURN_TYPE},
{DateFormatSymbols.class, ARRAY_RETURN_TYPE},
{DecimalFormatSymbols.class, ARRAY_RETURN_TYPE},
{DecimalStyle.class, SET_RETURN_TYPE},
{Locale.class, ARRAY_RETURN_TYPE},
{NumberFormat.class, ARRAY_RETURN_TYPE},
};
}
@MethodSource("availableLocalesClasses")
@ParameterizedTest
void checkRequiredLocales(Class<?> c, MethodType mt) throws Throwable {
var ret = MethodHandles.lookup().findStatic(c, "getAvailableLocales", mt).invoke();
if (ret instanceof Locale[] a) {
assertTrue(Arrays.asList(a).containsAll(REQUIRED_LOCALES));
} else if (ret instanceof Set<?> s) {
assertTrue(s.containsAll(REQUIRED_LOCALES));
} else {
throw new RuntimeException("return type mismatch");
}
}
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2007, 2023, 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 6277243
* @summary Verify that there is Locale.ROOT constant, and it is equal to Locale("", "", "")
* @run junit RootLocale
*/
import java.util.Locale;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class RootLocale {
/**
* Locale.ROOT should exist and match an empty Locale given as
* Locale("", "", "").
*/
@Test
public void rootTest() {
Locale root = Locale.of("", "", "");
assertEquals(Locale.ROOT, root, "Locale.ROOT is not equal to Locale(\"\", \"\", \"\")");
}
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2018, 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 8196869
* @summary Make sure we deal with internal Key data being cleared properly
* @ignore This test aims to provoke NPEs, but due to the need to constrain
* memory usage it fails intermittently with OOME on various systems
* with no way to ignore such failures.
* @run main/othervm -Xms16m -Xmx16m -esa SoftKeys
*/
import java.util.*;
public class SoftKeys {
public static void main(String[] args) {
try {
// With 4 characters in "language", we'll fill up a 16M heap quickly,
// causing full GCs and SoftReference reclamation. Repeat at least two
// times to verify no NPEs appear when looking up Locale's whose
// softly referenced data in sun.util.locale.BaseLocale$Key might have
// been cleared.
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 512*1024; j++) {
Locale.of(HexFormat.of().toHexDigits((short)j));
}
}
} catch (OutOfMemoryError e) {
// Can happen on some system configurations, and while increasing heap
// size would allow GC to keep up, it also makes it impractically hard
// to reproduce NPE issues that could arise when references are being
// cleared.
// Do a System.gc() to not throw an OOME again in the jtreg wrapper.
System.gc();
}
}
}

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2016, 2023, 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 8166994
* @summary Checks the subsequent call to parse the same language ranges
* which must generate the same list of language ranges
* i.e. the priority list containing equivalents, as in the
* first call
* @run junit SubsequentRangeParsingTest
*/
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class SubsequentRangeParsingTest {
/*
* Checks that consecutive calls to parse the same language ranges
* generate the same list of language ranges.
*/
@ParameterizedTest
@MethodSource("ranges")
public void parseConsistencyTest(List<String> list, String ranges) {
// consecutive call to check the language range parse consistency
testParseConsistency(list, ranges);
testParseConsistency(list, ranges);
}
// Ensure that parsing the ranges returns the expected list.
private static void testParseConsistency(List<String> list, String ranges) {
List<String> priorityList = parseRanges(ranges);
assertEquals(list, priorityList, "Failed to parse the language range:");
}
private static List<String> parseRanges(String s) {
return Locale.LanguageRange.parse(s).stream()
.map(Locale.LanguageRange::getRange)
.collect(Collectors.toList());
}
// Ranges that have multiple equivalents and single equivalents.
private static Stream<Arguments> ranges() {
return Stream.of(
Arguments.of(Arrays.asList("ccq-aa", "ybd-aa", "rki-aa"),
"ccq-aa"),
Arguments.of(Arrays.asList("gfx-xz", "oun-xz", "mwj-xz",
"vaj-xz", "taj-xy", "tsf-xy"), "gfx-xz, taj-xy")
);
}
}

View file

@ -0,0 +1,113 @@
/*
* Copyright (c) 2022, 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 8282819
* @summary Unit tests for Locale.of() method. Those tests check the equality
* of obtained objects with ones that are gotten from other means with both
* well-formed and ill-formed arguments. Also checks the possible NPEs
* for error cases.
* @run junit TestOf
*/
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.Locale;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@SuppressWarnings("deprecation")
public class TestOf {
static Object[][] data_1Arg() {
return new Object[][]{
// well-formed
{Locale.ENGLISH, "en"},
{Locale.JAPANESE, "ja"},
// ill-formed
{Locale.ROOT, ""},
{new Locale("a"), "a"},
{new Locale("xxxxxxxxxx"), "xxxxxxxxxx"},
};
}
static Object[][] data_2Args() {
return new Object[][]{
// well-formed
{Locale.US, "en", "US"},
{Locale.JAPAN, "ja", "JP"},
// ill-formed
{new Locale("", "US"), "", "US"},
{new Locale("a", "b"), "a", "b"},
{new Locale("xxxxxxxxxx", "yyyyyyyyyy"), "xxxxxxxxxx", "yyyyyyyyyy"},
};
}
static Object[][] data_3Args() {
return new Object[][]{
// well-formed
{Locale.forLanguageTag("en-US-POSIX"), "en", "US", "POSIX"},
{Locale.forLanguageTag("ja-JP-POSIX"), "ja", "JP", "POSIX"},
// ill-formed
{new Locale("", "", "POSIX"), "", "", "POSIX"},
{new Locale("a", "b", "c"), "a", "b", "c"},
{new Locale("xxxxxxxxxx", "yyyyyyyyyy", "zzzzzzzzzz"),
"xxxxxxxxxx", "yyyyyyyyyy", "zzzzzzzzzz"},
{new Locale("ja", "JP", "JP"), "ja", "JP", "JP"},
{new Locale("th", "TH", "TH"), "th", "TH", "TH"},
{new Locale("no", "NO", "NY"), "no", "NO", "NY"},
};
}
@MethodSource("data_1Arg")
@ParameterizedTest
void test_1Arg(Locale expected, String lang) {
assertEquals(expected, Locale.of(lang));
}
@MethodSource("data_2Args")
@ParameterizedTest
void test_2Args(Locale expected, String lang, String ctry) {
assertEquals(expected, Locale.of(lang, ctry));
}
@MethodSource("data_3Args")
@ParameterizedTest
void test_3Args(Locale expected, String lang, String ctry, String vrnt) {
assertEquals(expected, Locale.of(lang, ctry, vrnt));
}
@Test
void test_NPE() {
assertThrows(NullPointerException.class, () -> Locale.of(null));
assertThrows(NullPointerException.class, () -> Locale.of("", null));
assertThrows(NullPointerException.class, () -> Locale.of("", "", null));
}
}

View file

@ -0,0 +1,89 @@
/*
* 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 4474409 8174269
* @summary Tests some localized methods with Thai locale
* @author John O'Conner
* @modules jdk.localedata
* @run junit ThaiGov
*/
import java.text.DateFormat;
import java.text.NumberFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ThaiGov {
private static final double VALUE = 12345678.234;
private static final Locale TH = Locale.of("th", "TH", "TH");
// Test number formatting for thai
@Test
public void numberTest() {
final String strExpected = "\u0E51\u0E52\u002C\u0E53\u0E54\u0E55\u002C\u0E56\u0E57\u0E58\u002E\u0E52\u0E53\u0E54";
NumberFormat nf = NumberFormat.getInstance(TH);
String str = nf.format(VALUE);
assertEquals(strExpected, str);
}
// Test currency formatting for Thai
@Test
public void currencyTest() {
final String strExpected = "\u0e3f\u00a0\u0e51\u0e52,\u0e53\u0e54\u0e55,\u0e56\u0e57\u0e58.\u0e52\u0e53";
NumberFormat nf = NumberFormat.getCurrencyInstance(TH);
String str = nf.format(VALUE);
assertEquals(strExpected, str);
}
// Test date formatting for Thai
@Test
public void dateTest() {
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
Calendar calGregorian = Calendar.getInstance(tz, Locale.US);
calGregorian.clear();
calGregorian.set(2002, 4, 1, 8, 30);
final Date date = calGregorian.getTime();
Calendar cal = Calendar.getInstance(tz, TH);
cal.clear();
cal.setTime(date);
final String strExpected = "\u0e27\u0e31\u0e19\u0e1e\u0e38\u0e18\u0e17\u0e35\u0e48 \u0e51 \u0e1e\u0e24\u0e29\u0e20\u0e32\u0e04\u0e21 \u0e1e\u0e38\u0e17\u0e18\u0e28\u0e31\u0e01\u0e23\u0e32\u0e0a \u0e52\u0e55\u0e54\u0e55 \u0e58 \u0e19\u0e32\u0e2c\u0e34\u0e01\u0e32 \u0e53\u0e50 \u0e19\u0e32\u0e17\u0e35 \u0e50\u0e50 \u0e27\u0e34\u0e19\u0e32\u0e17\u0e35 \u0e40\u0e27\u0e25\u0e32\u0e2d\u0e2d\u0e21\u0e41\u0e2a\u0e07\u0e41\u0e1b\u0e0b\u0e34\u0e1f\u0e34\u0e01\u0e43\u0e19\u0e2d\u0e40\u0e21\u0e23\u0e34\u0e01\u0e32\u0e40\u0e2b\u0e19\u0e37\u0e2d";
Date value = cal.getTime();
// th_TH_TH test
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, TH);
df.setTimeZone(tz);
String str = df.format(value);
assertEquals(strExpected, str);
}
}

View file

@ -0,0 +1,185 @@
/*
* Copyright (c) 2016, 2023, 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 8159420
* @summary Checks the proper execution of LanguageRange.parse() and
* other LocaleMatcher methods when used in the locales like
* Turkish, because the toLowerCase() method is invoked in the
* parse() and other LocaleMatcher methods.
* e.g. "HI-Deva".toLowerCase() in the Turkish locale returns
* "hı-deva", where 'ı' is the LATIN SMALL LETTER DOTLESS I character
* which is not allowed in the language ranges/tags.
* @compile -encoding utf-8 TurkishLangRangeTest.java
* @run junit/othervm -Duser.language=tr -Duser.country=TR TurkishLangRangeTest
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Locale.LanguageRange;
import java.util.Locale.FilteringMode;
import java.util.LinkedHashMap;
import java.util.stream.Stream;
import static java.util.Locale.FilteringMode.EXTENDED_FILTERING;
import static java.util.Locale.FilteringMode.AUTOSELECT_FILTERING;
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 static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class TurkishLangRangeTest {
/*
* Ensure parse() does not throw IllegalArgumentException for the Turkish Locale
* with the given input.
*/
@Test
public void parseTest() {
String ranges = "HI-Deva, ja-hIrA-JP, RKI";
assertDoesNotThrow(() -> LanguageRange.parse(ranges));
}
/*
* Ensure filter() does not return empty list for the Turkish Locale
* with the given input.
*/
@ParameterizedTest
@MethodSource("modes")
public void filterTest(FilteringMode mode) {
String ranges = "hi-IN, itc-Ital";
String tags = "hi-IN, itc-Ital";
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
List<Locale> tagList = generateLocales(tags);
String actualLocales = showLocales(Locale.filter(priorityList, tagList, mode));
String expectedLocales = "hi-IN, itc-Ital";
assertEquals(expectedLocales, actualLocales);
}
private static Stream<FilteringMode> modes() {
return Stream.of(
EXTENDED_FILTERING,
AUTOSELECT_FILTERING
);
}
/*
* Ensure lookup() does not return null for the Turkish Locale with
* the given input.
*/
@Test
public void lookupTest() {
String ranges = "hi-IN, itc-Ital";
String tags = "hi-IN, itc-Ital";
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
List<Locale> localeList = generateLocales(tags);
Locale actualLocale = Locale.lookup(priorityList, localeList);
assertNotNull(actualLocale);
String actualLocaleString = actualLocale.toLanguageTag();
String expectedLocale = "hi-IN";
assertEquals(expectedLocale, actualLocaleString);
}
/*
* Ensure mapEquivalents() does not only return "hi-in" for the Turkish
* Locale with the given input.
*/
@Test
public void mapEquivalentsTest() {
String ranges = "HI-IN";
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
HashMap<String, List<String>> map = new LinkedHashMap<>();
List<String> equivalentList = new ArrayList<>();
equivalentList.add("HI");
equivalentList.add("HI-Deva");
map.put("HI", equivalentList);
List<LanguageRange> expected = new ArrayList<>();
expected.add(new LanguageRange("hi-in"));
expected.add(new LanguageRange("hi-deva-in"));
List<LanguageRange> got =
LanguageRange.mapEquivalents(priorityList, map);
assertEquals(expected, got, getDifferences(expected, got));
}
private static String getDifferences(List<LanguageRange> expected,
List<LanguageRange> got) {
StringBuilder diffs = new StringBuilder();
List<LanguageRange> cloneExpected = new ArrayList<>(expected);
cloneExpected.removeAll(got);
if (!cloneExpected.isEmpty()) {
diffs.append("Found missing range(s): ")
.append(cloneExpected)
.append(System.lineSeparator());
}
List<LanguageRange> cloneGot = new ArrayList<>(got);
cloneGot.removeAll(expected);
if (!got.isEmpty()) {
diffs.append("Got extra range(s): ")
.append(cloneGot)
.append(System.lineSeparator());
}
return diffs.toString();
}
private static List<Locale> generateLocales(String tags) {
if (tags == null) {
return null;
}
List<Locale> localeList = new ArrayList<>();
if (tags.equals("")) {
return localeList;
}
String[] t = tags.split(", ");
for (String tag : t) {
localeList.add(Locale.forLanguageTag(tag));
}
return localeList;
}
private static String showLocales(List<Locale> locales) {
StringBuilder sb = new StringBuilder();
Iterator<Locale> itr = locales.iterator();
if (itr.hasNext()) {
sb.append(itr.next().toLanguageTag());
}
while (itr.hasNext()) {
sb.append(", ");
sb.append(itr.next().toLanguageTag());
}
return sb.toString().trim();
}
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2022, 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 8295232 8353118 8355522
* @summary Tests for the "java.locale.useOldISOCodes" system property
* @library /test/lib
* @run junit UseOldISOCodesTest
*/
import java.util.Locale;
import jdk.test.lib.process.ProcessTools;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
public class UseOldISOCodesTest {
@Test
public void testUseOldISOCodes() throws Exception {
var oa = ProcessTools.executeTestJava("-Djava.locale.useOldISOCodes=true", "UseOldISOCodesTest$Runner")
.outputTo(System.out)
.errorTo(System.err);
oa.shouldHaveExitValue(0);
oa.stderrShouldMatch("WARNING: The system property \"java.locale.useOldISOCodes\" is no longer supported. Any specified value will be ignored.");
}
static class Runner {
private static final String obsoleteCode = "iw";
private static final String newCode = "he";
public static void main(String[] args) {
// Ensure java.locale.useOldISOCodes should have no effect
assertNotEquals(obsoleteCode, Locale.of(newCode).getLanguage(),
"newCode 'he' was mapped to 'iw' with useOldISOCodes=true");
}
}
}

View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 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 8342582
* @summary Test if "user.region" system property successfully overrides
* other locale related system properties at startup
* @modules jdk.localedata
* @run junit/othervm
* -Duser.region=DE
* -Duser.language=en
* -Duser.script=Latn
* -Duser.country=US
* -Duser.variant=FOO UserRegionTest
* @run junit/othervm
* -Duser.region=DE_POSIX
* -Duser.language=en
* -Duser.script=Latn
* -Duser.country=US
* -Duser.variant=FOO UserRegionTest
* @run junit/othervm
* -Duser.region=_POSIX
* -Duser.language=en
* -Duser.script=Latn
* -Duser.country=US
* -Duser.variant=FOO UserRegionTest
*/
import java.util.Locale;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class UserRegionTest {
@Test
public void testDefaultLocale() {
var region = System.getProperty("user.region").split("_");
var expected = Locale.of(System.getProperty("user.language"),
region[0], region.length > 1 ? region[1] : "");
assertEquals(expected, Locale.getDefault());
assertEquals(expected, Locale.getDefault(Locale.Category.FORMAT));
assertEquals(expected, Locale.getDefault(Locale.Category.DISPLAY));
}
@Test
public void testNumberFormat() {
if (System.getProperty("user.region").startsWith("DE")) {
assertEquals("0,50000", String.format("%.5f", 0.5f));
} else {
assertEquals("0.50000", String.format("%.5f", 0.5f));
}
}
}

View file

@ -0,0 +1,157 @@
/*
* Copyright (c) 2017, 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 8176841
* @summary Tests Calendar class deals with Unicode extensions
* correctly.
* @modules jdk.localedata
* @run junit/othervm CalendarTests
*/
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Test Calendar with BCP47 U extensions
*/
public class CalendarTests {
private static TimeZone defaultTZ;
private static final TimeZone ASIATOKYO = TimeZone.getTimeZone("Asia/Tokyo");
private static final TimeZone AMLA = TimeZone.getTimeZone("America/Los_Angeles");
private static final Locale JPTYO = Locale.forLanguageTag("en-u-tz-jptyo");
private static final Locale USLAX = Locale.forLanguageTag("en-u-tz-uslax");
private static final Locale FW_SUN = Locale.forLanguageTag("en-US-u-fw-sun");
private static final Locale FW_MON = Locale.forLanguageTag("en-US-u-fw-mon");
private static final Locale FW_TUE = Locale.forLanguageTag("en-US-u-fw-tue");
private static final Locale FW_WED = Locale.forLanguageTag("en-US-u-fw-wed");
private static final Locale FW_THU = Locale.forLanguageTag("en-US-u-fw-thu");
private static final Locale FW_FRI = Locale.forLanguageTag("en-US-u-fw-fri");
private static final Locale FW_SAT = Locale.forLanguageTag("en-US-u-fw-sat");
@BeforeAll
static void beforeTest() {
defaultTZ = TimeZone.getDefault();
TimeZone.setDefault(AMLA);
}
@AfterAll
static void afterTest() {
TimeZone.setDefault(defaultTZ);
}
static Object[][] tz() {
return new Object[][] {
// Locale, Expected Zone,
{JPTYO, ASIATOKYO},
{USLAX, AMLA},
// invalid
{Locale.forLanguageTag("en-US-u-tz-jpzzz"), AMLA}
};
}
static Object[][] firstDayOfWeek () {
return new Object[][] {
// Locale, Expected DayOfWeek,
{Locale.US, Calendar.SUNDAY},
{FW_SUN, Calendar.SUNDAY},
{FW_MON, Calendar.MONDAY},
{FW_TUE, Calendar.TUESDAY},
{FW_WED, Calendar.WEDNESDAY},
{FW_THU, Calendar.THURSDAY},
{FW_FRI, Calendar.FRIDAY},
{FW_SAT, Calendar.SATURDAY},
// invalid case
{Locale.forLanguageTag("en-US-u-fw-xxx"), Calendar.SUNDAY},
// region override
{Locale.forLanguageTag("en-US-u-rg-gbzzzz"), Calendar.MONDAY},
{Locale.forLanguageTag("zh-CN-u-rg-eszzzz"), Calendar.MONDAY},
// "fw" and "rg".
{Locale.forLanguageTag("en-US-u-fw-wed-rg-gbzzzz"), Calendar.WEDNESDAY},
{Locale.forLanguageTag("en-US-u-fw-xxx-rg-gbzzzz"), Calendar.MONDAY},
{Locale.forLanguageTag("en-US-u-fw-xxx-rg-zzzz"), Calendar.SUNDAY},
};
}
static Object[][] minDaysInFirstWeek () {
return new Object[][] {
// Locale, Expected minDay,
{Locale.US, 1},
// region override
{Locale.forLanguageTag("en-US-u-rg-gbzzzz"), 4},
{Locale.forLanguageTag("zh-CN-u-rg-eszzzz"), 4},
};
}
@MethodSource("tz")
@ParameterizedTest
void test_tz(Locale locale, TimeZone zoneExpected) {
DateFormat df = DateFormat.getTimeInstance(DateFormat.FULL, locale);
assertEquals(zoneExpected, df.getTimeZone());
Calendar c = Calendar.getInstance(locale);
assertEquals(zoneExpected, c.getTimeZone());
c = new Calendar.Builder().setLocale(locale).build();
assertEquals(zoneExpected, c.getTimeZone());
}
@MethodSource("firstDayOfWeek")
@ParameterizedTest
void test_firstDayOfWeek(Locale locale, int dowExpected) {
Calendar c = Calendar.getInstance(locale);
assertEquals(dowExpected, c.getFirstDayOfWeek());
c = new Calendar.Builder().setLocale(locale).build();
assertEquals(dowExpected, c.getFirstDayOfWeek());
}
@MethodSource("minDaysInFirstWeek")
@ParameterizedTest
void test_minDaysInFirstWeek(Locale locale, int minDaysExpected) {
Calendar c = Calendar.getInstance(locale);
assertEquals(minDaysExpected, c.getMinimalDaysInFirstWeek());
c = new Calendar.Builder().setLocale(locale).build();
assertEquals(minDaysExpected, c.getMinimalDaysInFirstWeek());
}
}

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2019, 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 8215181 8230284 8231273 8284840
* @summary Tests the "u-cf" extension
* @modules jdk.localedata
* @run junit CurrencyFormatTests
*/
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.text.NumberFormat;
import java.util.Locale;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Test NumberFormat with BCP47 u-cf extensions. Note that this test depends
* on the particular CLDR release. Results may vary on other CLDR releases.
*/
public class CurrencyFormatTests {
static Object[][] getInstanceData() {
return new Object[][] {
// Locale, amount, expected
// US dollar
{Locale.US, -100, "-$100.00"},
{Locale.forLanguageTag("en-US-u-cf-standard"), -100, "-$100.00"},
{Locale.forLanguageTag("en-US-u-cf-account"), -100, "($100.00)"},
{Locale.forLanguageTag("en-US-u-cf-bogus"), -100, "-$100.00"},
// Euro
{Locale.forLanguageTag("en-AT"), -100, "-\u20ac\u00a0100,00"},
{Locale.forLanguageTag("en-AT-u-cf-standard"), -100, "-\u20ac\u00a0100,00"},
{Locale.forLanguageTag("en-AT-u-cf-account"), -100, "-\u20ac\u00a0100,00"},
{Locale.forLanguageTag("en-AT-u-cf-bogus"), -100, "-\u20ac\u00a0100,00"},
// Rupee
{Locale.forLanguageTag("en-IN"), -100, "-\u20b9100.00"},
{Locale.forLanguageTag("en-IN-u-cf-standard"), -100, "-\u20b9100.00"},
{Locale.forLanguageTag("en-IN-u-cf-account"), -100, "(\u20b9100.00)"},
{Locale.forLanguageTag("en-IN-u-cf-bogus"), -100, "-\u20b9100.00"},
// Swiss franc
{Locale.forLanguageTag("en-CH"), -100, "CHF-100.00"},
{Locale.forLanguageTag("en-CH-u-cf-standard"), -100, "CHF-100.00"},
{Locale.forLanguageTag("en-CH-u-cf-account"), -100, "CHF-100.00"},
{Locale.forLanguageTag("en-CH-u-cf-bogus"), -100, "CHF-100.00"},
// Region override
{Locale.forLanguageTag("en-US-u-rg-CHZZZZ"), -100, "CHF-100.00"},
{Locale.forLanguageTag("en-US-u-rg-CHZZZZ-cf-standard"), -100, "CHF-100.00"},
{Locale.forLanguageTag("en-US-u-rg-CHZZZZ-cf-account"), -100, "CHF-100.00"},
{Locale.forLanguageTag("en-US-u-rg-CHZZZZ-cf-bogus"), -100, "CHF-100.00"},
// Numbering systems
// explicit
{Locale.forLanguageTag("zh-CN-u-nu-arab"), -100, "\u061c-\u00a5\u0661\u0660\u0660\u066b\u0660\u0660"},
{Locale.forLanguageTag("zh-CN-u-nu-arab-cf-standard"), -100, "\u061c-\u00a5\u0661\u0660\u0660\u066b\u0660\u0660"},
{Locale.forLanguageTag("zh-CN-u-nu-arab-cf-account"), -100, "\u061c-\u00a5\u0661\u0660\u0660\u066b\u0660\u0660"},
{Locale.forLanguageTag("zh-CN-u-nu-arab-cf-bogus"), -100, "\u061c-\u00a5\u0661\u0660\u0660\u066b\u0660\u0660"},
// implicit
{Locale.forLanguageTag("zh-CN"), -100, "-\u00a5100.00"},
{Locale.forLanguageTag("zh-CN-u-cf-standard"), -100, "-\u00a5100.00"},
{Locale.forLanguageTag("zh-CN-u-cf-account"), -100, "(\u00a5100.00)"},
{Locale.forLanguageTag("zh-CN-u-cf-bogus"), -100, "-\u00a5100.00"},
{Locale.forLanguageTag("ar-SA"), -100, "\u061c-\u200f\u0661\u0660\u0660\u066b\u0660\u0660\u00a0\u0631.\u0633.\u200f"},
{Locale.forLanguageTag("ar-SA-u-cf-standard"), -100, "\u061c-\u200f\u0661\u0660\u0660\u066b\u0660\u0660\u00a0\u0631.\u0633.\u200f"},
{Locale.forLanguageTag("ar-SA-u-cf-account"), -100, "\u061c-\u200f\u0661\u0660\u0660\u066b\u0660\u0660\u00a0\u0631.\u0633.\u200f"},
{Locale.forLanguageTag("ar-SA-u-cf-bogus"), -100, "\u061c-\u200f\u0661\u0660\u0660\u066b\u0660\u0660\u00a0\u0631.\u0633.\u200f"},
};
}
@MethodSource("getInstanceData")
@ParameterizedTest
void test_getInstance(Locale locale, int amount, String expected) {
assertEquals(expected, NumberFormat.getCurrencyInstance(locale).format(amount));
}
}

View file

@ -0,0 +1,105 @@
/*
* Copyright (c) 2017, 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 8176841
* @summary Tests Currency class instantiates correctly with Unicode
* extensions
* @modules jdk.localedata
* @run junit/othervm CurrencyTests
*/
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.Currency;
import java.util.Locale;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Test Currency with BCP47 U extensions
*/
public class CurrencyTests {
private static final Currency USD = Currency.getInstance("USD");
private static final Currency CAD = Currency.getInstance("CAD");
private static final Currency JPY = Currency.getInstance("JPY");
static Object[][] getInstanceData() {
return new Object[][] {
// Locale, Expected Currency
// "cu"
{Locale.forLanguageTag("en-US-u-cu-jpy"), JPY},
{Locale.forLanguageTag("ja-JP-u-cu-usd"), USD},
{Locale.forLanguageTag("en-US-u-cu-foobar"), USD},
{Locale.forLanguageTag("en-US-u-cu-zzz"), USD},
// "rg"
{Locale.forLanguageTag("en-US-u-rg-jpzzzz"), JPY},
{Locale.forLanguageTag("ja-JP-u-rg-uszzzz"), USD},
{Locale.forLanguageTag("ja-JP-u-rg-001zzzz"), JPY},
{Locale.forLanguageTag("en-US-u-rg-jpz"), USD},
// "cu" and "rg". "cu" should win
{Locale.forLanguageTag("en-CA-u-cu-jpy-rg-uszzzz"), JPY},
// invaid "cu" and valid "rg". "rg" should win
{Locale.forLanguageTag("en-CA-u-cu-jpyy-rg-uszzzz"), USD},
{Locale.forLanguageTag("en-CA-u-cu-zzz-rg-uszzzz"), USD},
// invaid "cu" and invalid "rg". both should be ignored
{Locale.forLanguageTag("en-CA-u-cu-jpyy-rg-jpzz"), CAD},
};
}
static Object[][] getSymbolData() {
return new Object[][] {
// Currency, DisplayLocale, expected Symbol
{USD, Locale.forLanguageTag("en-US-u-rg-jpzzzz"), "$"},
{USD, Locale.forLanguageTag("en-US-u-rg-cazzzz"), "US$"},
{USD, Locale.forLanguageTag("en-CA-u-rg-uszzzz"), "$"},
{CAD, Locale.forLanguageTag("en-US-u-rg-jpzzzz"), "CA$"},
{CAD, Locale.forLanguageTag("en-US-u-rg-cazzzz"), "$"},
{CAD, Locale.forLanguageTag("en-CA-u-rg-uszzzz"), "CA$"},
{JPY, Locale.forLanguageTag("ja-JP-u-rg-uszzzz"), "\uffe5"},
{JPY, Locale.forLanguageTag("en-US-u-rg-jpzzzz"), "\u00a5"},
{JPY, Locale.forLanguageTag("ko-KR-u-rg-jpzzzz"), "JP\u00a5"},
};
}
@MethodSource("getInstanceData")
@ParameterizedTest
void test_getInstance(Locale locale, Currency currencyExpected) {
assertEquals(currencyExpected, Currency.getInstance(locale));
}
@MethodSource("getSymbolData")
@ParameterizedTest
void test_getSymbol(Currency c, Locale locale, String expected) {
assertEquals(expected, c.getSymbol(locale));
}
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2017, 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.util.Locale;
/*
* Test application that verifies default locales. Invoked from
* SystemPropertyTests
*/
public class DefaultLocaleTest {
public static void main(String... args) {
String defLoc = Locale.getDefault().toString();
String defFmtLoc = Locale.getDefault(Locale.Category.FORMAT).toString();
String defDspLoc = Locale.getDefault(Locale.Category.DISPLAY).toString();
if (!defLoc.equals(args[0]) ||
!defFmtLoc.equals(args[1]) ||
!defDspLoc.equals(args[2])) {
System.err.println("Some default locale(s) don't match.\n" +
"Default Locale expected: " + args[0] + ", result: " + defLoc + "\n" +
"Default Format Locale expected: " + args[1] + ", result: " + defFmtLoc + "\n" +
"Default Display Locale expected: " + args[2] + ", result: " + defDspLoc);
System.exit(-1);
}
}
}

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2017, 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 8176841 8202537 8354548
* @summary Tests the display names for BCP 47 U extensions
* @modules jdk.localedata
* @run junit DisplayNameTests
*/
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.Locale;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Test Locale.getDisplayName() with BCP47 U extensions. Note that the
* result may change depending on the CLDR releases.
*/
public class DisplayNameTests {
private static final Locale loc1 = Locale.forLanguageTag("en-Latn-US-u" +
"-ca-japanese" +
"-cf-account" +
"-co-pinyin" +
"-cu-jpy" +
"-em-emoji" +
"-fw-wed" +
"-hc-h23" +
"-lb-loose" +
"-lw-breakall" +
"-ms-uksystem" +
"-nu-roman" +
"-rg-gbzzzz" +
"-sd-gbsct" +
"-ss-standard" +
"-tz-jptyo" +
"-va-posix");
private static final Locale loc2 = Locale.of("ja", "JP", "JP");
private static final Locale loc3 = new Locale.Builder()
.setRegion("US")
.setScript("Latn")
.setUnicodeLocaleKeyword("ca", "japanese")
.build();
private static final Locale loc4 = new Locale.Builder()
.setRegion("US")
.setUnicodeLocaleKeyword("ca", "japanese")
.build();
private static final Locale loc5 = new Locale.Builder()
.setUnicodeLocaleKeyword("ca", "japanese")
.build();
private static final Locale loc6 = Locale.forLanguageTag( "zh-CN-u-ca-dddd-nu-ddd-cu-ddd-fw-moq-tz-unknown-rg-twzz");
static Object[][] locales() {
return new Object[][] {
// Locale for display, Test Locale, Expected output,
{Locale.US, loc1,
"English (Latin, United States, Japanese Calendar, Accounting Currency Format, Pinyin Sort Order, Currency: Japanese Yen, Emoji Presentation For Emoji, First day of week: Wednesday, 24 Hour System (023), Loose Line Break Style, Allow Line Breaks In All Words, Imperial Measurement System, Roman Numerals, Region For Supplemental Data: United Kingdom, Region Subdivision: gbsct, Suppress Sentence Breaks After Standard Abbreviations, Time Zone: Japan Time, POSIX Compliant Locale)"},
{Locale.JAPAN, loc1,
"英語 (ラテン文字、アメリカ合衆国、和暦、会計通貨フォーマット、ピンイン順、通貨: 日本円、絵文字表示方法: emoji、fw: wed、24時間制(0〜23)、禁則処理(弱)、単語途中の改行: breakall、ヤード・ポンド法、ローマ数字、rg: イギリス、sd: gbsct、略語の後の文分割: standard、タイムゾーン: 日本時間、ロケールのバリアント: posix)"},
{Locale.forLanguageTag("hi-IN"), loc1,
"अंग्रेज़ी (लैटिन, संयुक्त राज्य, जापानी पंचांग, लेखांकन मुद्रा प्रारूप, पिनयिन वर्गीकरण क्रम, मुद्रा: जापानी येन, इमोजी का प्रज़ेंटेशन: emoji, fw: wed, 24 घंटों की प्रणाली (023), ढीली पंक्ति विच्छेद शैली, शब्दों के बीच पंक्ति विच्छेद: breakall, इम्पीरियल मापन प्रणाली, रोमन संख्याएँ, rg: यूनाइटेड किंगडम, sd: gbsct, संक्षेपण के बाद वाक्य विच्छेद: standard, समय क्षेत्र: जापान समय, स्थानीय प्रकार: posix)"},
// cases where no localized types are available. fall back to "key: type"
{Locale.US, Locale.forLanguageTag("en-u-ca-unknown"), "English (Calendar: unknown)"},
// cases with variant, w/o language, script
{Locale.US, loc2, "Japanese (Japan, JP, Japanese Calendar)"},
{Locale.US, loc3, "Latin (United States, Japanese Calendar)"},
{Locale.US, loc4, "United States (Japanese Calendar)"},
{Locale.US, loc5, ""},
// non localizable cases
{loc6, loc6, "中文 (中国日历dddd货币dddfwmoq数字dddrgtwzz时区unknown)"},
{Locale.US, loc6, "Chinese (China, Calendar: dddd, Currency: ddd, First day of week: moq, Numbers: ddd, Region For Supplemental Data: twzz, Time Zone: unknown)"},
};
}
@MethodSource("locales")
@ParameterizedTest
void test_locales(Locale inLocale, Locale testLocale, String expected) {
String result = testLocale.getDisplayName(inLocale);
assertEquals(expected, result);
}
}

View file

@ -0,0 +1,167 @@
/*
* Copyright (c) 2017, 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 8176841 8194148 8284840 8306116 8333582 8354548
* @summary Tests *Format class deals with Unicode extensions
* correctly.
* @modules jdk.localedata
* @run junit FormatTests
*/
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Test *Format classes with BCP47 U extensions
*/
public class FormatTests {
private static TimeZone defaultTZ;
private static final TimeZone ASIATOKYO = TimeZone.getTimeZone("Asia/Tokyo");
private static final TimeZone AMLA = TimeZone.getTimeZone("America/Los_Angeles");
private static final Locale JPTYO = Locale.forLanguageTag("en-u-tz-jptyo");
private static final Locale JCAL = Locale.forLanguageTag("en-u-ca-japanese");
private static final Locale USLAX = Locale.forLanguageTag("en-u-tz-uslax");
private static final Locale RG_GB = Locale.forLanguageTag("en-US-u-rg-gbzzzz");
private static final Locale RG_DE = Locale.forLanguageTag("en-US-u-rg-dezzzz");
private static final Locale NU_DEVA = Locale.forLanguageTag("en-US-u-nu-deva");
private static final Locale NU_SINH = Locale.forLanguageTag("en-US-u-nu-sinh");
private static final Locale NU_ZZZZ = Locale.forLanguageTag("en-US-u-nu-zzzz");
private static final double testNum = 12345.6789;
private static final String NUM_US = "12,345.6789";
private static final String NUM_DE = "12.345,6789";
private static final String NUM_DEVA = "\u0967\u0968,\u0969\u096a\u096b.\u096c\u096d\u096e\u096f";
private static final String NUM_SINH = "\u0de7\u0de8,\u0de9\u0dea\u0deb.\u0dec\u0ded\u0dee\u0def";
private static final Date testDate = new Calendar.Builder()
.setCalendarType("gregory")
.setDate(2017, 7, 10)
.setTimeOfDay(15, 15, 0)
.setTimeZone(AMLA)
.build()
.getTime();
@BeforeAll
static void beforeTest() {
defaultTZ = TimeZone.getDefault();
TimeZone.setDefault(AMLA);
}
@AfterAll
static void afterTest() {
TimeZone.setDefault(defaultTZ);
}
static Object[][] dateFormatData() {
return new Object[][] {
// Locale, Expected calendar, Expected timezone, Expected formatted string
// -ca
{JCAL, "java.util.JapaneseImperialCalendar", null,
"Thursday, August 10, 29 Heisei at 3:15:00\u202fPM Pacific Daylight Time"
},
// -tz
{JPTYO, null, ASIATOKYO,
"Friday, August 11, 2017, 7:15:00\u202fAM Japan Standard Time"
},
{USLAX, null, AMLA,
"Thursday, August 10, 2017, 3:15:00\u202fPM Pacific Daylight Time"
},
// -rg
{RG_GB, null, null,
"Thursday, 10 August 2017, 15:15:00 Pacific Daylight Time"
},
};
}
static Object[][] numberFormatData() {
return new Object[][] {
// Locale, number, expected format
// -nu
{NU_DEVA, testNum, NUM_DEVA},
{NU_SINH, testNum, NUM_SINH},
{NU_ZZZZ, testNum, NUM_US},
// -rg
{RG_DE, testNum, NUM_DE},
// -nu & -rg, valid & invalid
{Locale.forLanguageTag("en-US-u-nu-deva-rg-dezzzz"), testNum, NUM_DEVA},
{Locale.forLanguageTag("en-US-u-nu-zzzz-rg-dezzzz"), testNum, NUM_US},
{Locale.forLanguageTag("en-US-u-nu-zzzz-rg-zzzz"), testNum, NUM_US},
};
}
@MethodSource("dateFormatData")
@ParameterizedTest
void test_DateFormat(Locale locale, String calClass, TimeZone tz,
String formatExpected) throws Exception {
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locale);
if (calClass != null) {
try {
Class expected = Class.forName(calClass);
assertEquals(expected, df.getCalendar().getClass());
} catch (Exception e) {
throw e;
}
}
if (tz != null) {
assertEquals(tz, df.getTimeZone());
}
String formatted = df.format(testDate);
assertEquals(formatExpected, formatted);
assertEquals(testDate, df.parse(formatted));
}
@MethodSource("numberFormatData")
@ParameterizedTest
void test_NumberFormat(Locale locale, double num,
String formatExpected) throws Exception {
NumberFormat nf = NumberFormat.getNumberInstance(locale);
nf.setMaximumFractionDigits(4);
String formatted = nf.format(num);
assertEquals(formatExpected, nf.format(num));
assertEquals(num, nf.parse(formatted));
}
}

View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 2017, 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 8176841 8194148
* @summary Tests *FormatSymbols class deals with Unicode extensions
* correctly.
* @modules jdk.localedata
* @run junit SymbolsTests
*/
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.text.DateFormatSymbols;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Test *FormatSymbols classes with BCP47 U extensions
*/
public class SymbolsTests {
private static final Locale RG_GB = Locale.forLanguageTag("en-US-u-rg-gbzzzz");
private static final Locale RG_IE = Locale.forLanguageTag("en-US-u-rg-iezzzz");
private static final Locale RG_AT = Locale.forLanguageTag("en-US-u-rg-atzzzz");
static Object[][] dateFormatSymbolsData() {
return new Object[][] {
// Locale, expected AM string, expected PM string
{RG_GB, "am", "pm"},
{RG_IE, "a.m.", "p.m."},
{Locale.US, "AM", "PM"},
};
}
static Object[][] decimalFormatSymbolsData() {
return new Object[][] {
// Locale, expected decimal separator, expected grouping separator
{RG_AT, ',', '.'},
{Locale.US, '.', ','},
// -nu & -rg mixed. -nu should win
{Locale.forLanguageTag("ar-EG-u-nu-latn-rg-mazzzz"), '.', ','},
};
}
@MethodSource("dateFormatSymbolsData")
@ParameterizedTest
void test_DateFormatSymbols(Locale locale, String amExpected, String pmExpected) {
DateFormatSymbols dfs = DateFormatSymbols.getInstance(locale);
String[] ampm = dfs.getAmPmStrings();
assertEquals(amExpected, ampm[0]);
assertEquals(pmExpected, ampm[1]);
}
@MethodSource("decimalFormatSymbolsData")
@ParameterizedTest
void test_DecimalFormatSymbols(Locale locale, char decimal, char grouping) {
DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(locale);
assertEquals(decimal, dfs.getDecimalSeparator());
assertEquals(grouping, dfs.getGroupingSeparator());
}
}

View file

@ -0,0 +1,97 @@
/*
* Copyright (c) 2017, 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
* @library /test/lib
* @bug 8189134
* @summary Tests the system properties
* @modules jdk.localedata
* @build DefaultLocaleTest
* @run junit/othervm SystemPropertyTests
*/
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static jdk.test.lib.process.ProcessTools.executeTestJava;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Test Locale.getDefault() reflects the system property. Note that the
* result may change depending on the CLDR releases.
*/
public class SystemPropertyTests {
private static String LANGPROP = "-Duser.language=en";
private static String SCPTPROP = "-Duser.script=";
private static String CTRYPROP = "-Duser.country=US";
static Object[][] data() {
return new Object[][] {
// system property, expected default, expected format, expected display
{"-Duser.extensions=u-ca-japanese",
"en_US_#u-ca-japanese",
"en_US_#u-ca-japanese",
"en_US_#u-ca-japanese",
},
{"-Duser.extensions=u-ca-japanese-nu-thai",
"en_US_#u-ca-japanese-nu-thai",
"en_US_#u-ca-japanese-nu-thai",
"en_US_#u-ca-japanese-nu-thai",
},
{"-Duser.extensions=foo",
"en_US",
"en_US",
"en_US",
},
{"-Duser.extensions.format=u-ca-japanese",
"en_US",
"en_US_#u-ca-japanese",
"en_US",
},
{"-Duser.extensions.display=u-ca-japanese",
"en_US",
"en_US",
"en_US_#u-ca-japanese",
},
};
}
@MethodSource("data")
@ParameterizedTest
void runTest(String extprop, String defLoc,
String defFmtLoc, String defDspLoc) throws Exception {
int exitValue = executeTestJava(LANGPROP, SCPTPROP, CTRYPROP,
extprop, "DefaultLocaleTest", defLoc, defFmtLoc, defDspLoc)
.outputTo(System.out)
.errorTo(System.out)
.getExitValue();
assertEquals(0, exitValue);
}
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2018, 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 8208080
* @summary Tests DateFormatSymbols provider implementations
* @library provider
* @build provider/module-info provider/foo.DateFormatSymbolsProviderImpl
* @run main/othervm -Djava.locale.providers=SPI,CLDR DateFormatSymbolsProviderTests
*/
import java.text.DateFormatSymbols;
import java.util.Locale;
import java.util.Map;
/**
* Test DateFormatSymbolsProvider SPI with BCP47 U extensions
*/
public class DateFormatSymbolsProviderTests {
private static final Map<Locale, String> data = Map.of(
Locale.forLanguageTag("en-AA"), "foo",
Locale.forLanguageTag("en-US-u-rg-aazzzz"), "foo",
Locale.forLanguageTag("en-US-u-ca-japanese"), "bar"
);
public static void main(String... args) {
data.forEach((l, e) -> {
DateFormatSymbols dfs = DateFormatSymbols.getInstance(l);
String[] months = dfs.getMonths();
System.out.printf("January string for locale %s is %s.%n", l.toString(), months[0]);
if (!months[0].equals(e)) {
throw new RuntimeException("DateFormatSymbols provider is not called for" + l);
}
});
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2017, 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 8176841 8354548
* @summary Tests LocaleNameProvider SPIs
* @library provider
* @build provider/module-info provider/foo.LocaleNameProviderImpl
* @run main/othervm -Djava.locale.providers=SPI LocaleNameProviderTests
*/
import java.util.Locale;
/**
* Test LocaleNameProvider SPI with BCP47 U extensions
*
* Verifies getUnicodeExtensionKey() and getUnicodeExtensionType() methods in
* LocaleNameProvider works.
*/
public class LocaleNameProviderTests {
private static final String expected = "foo (foo_ca=foo_japanese)";
public static void main(String... args) {
String name = Locale.forLanguageTag("foo-u-ca-japanese").getDisplayName(Locale.of("foo"));
if (!name.equals(expected)) {
throw new RuntimeException("Unicode extension key and/or type name(s) is incorrect. " +
"Expected: \"" + expected + "\", got: \"" + name + "\"");
}
}
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2018, 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 foo;
import java.text.DateFormatSymbols;
import java.text.spi.DateFormatSymbolsProvider;
import java.util.Locale;
/*
* Implements DateFormatSymbolsProvider SPI, in order to check if the
* extensions work correctly.
*/
public class DateFormatSymbolsProviderImpl extends DateFormatSymbolsProvider {
private static final Locale AA = Locale.forLanguageTag("en-AA");
private static final Locale USJCAL = Locale.forLanguageTag("en-US-u-ca-japanese");
private static final Locale[] avail = {AA, Locale.US};
@Override
public Locale[] getAvailableLocales() {
return avail;
}
@Override
public boolean isSupportedLocale(Locale l) {
// Overriding to check the relation between
// isSupportedLocale/getAvailableLocales works correctly
if (l.equals(AA)) {
// delegates to super, as if isSupportedLocale didn't exist.
return super.isSupportedLocale(l);
} else {
return (l.equals(USJCAL));
}
}
@Override
public DateFormatSymbols getInstance(Locale l) {
return new MyDateFormatSymbols(l);
}
class MyDateFormatSymbols extends DateFormatSymbols {
Locale locale;
public MyDateFormatSymbols(Locale l) {
super(l);
locale = l;
}
@Override
public String[] getMonths() {
String[] ret = super.getMonths();
// replace the first item with some unique value
if (locale.stripExtensions().equals(AA)) {
ret[0] = "foo";
} else if (locale.equals(USJCAL)) {
ret[0] = "bar";
} else {
throw new RuntimeException("Unsupported locale: " + locale);
}
return ret;
}
}
}

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2017, 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.
*/
package foo;
import java.util.Locale;
import java.util.spi.LocaleNameProvider;
/*
* Implements LocaleNameProvider SPI, augmenting the default
* values for Unicode Locale Extension key/type names.
*/
public class LocaleNameProviderImpl extends LocaleNameProvider {
private static final Locale[] avail = {Locale.of("foo")};
@Override
public Locale[] getAvailableLocales() {
return avail;
}
@Override
public String getDisplayLanguage(String lang, Locale target) {
return null;
}
@Override
public String getDisplayCountry(String ctry, Locale target) {
return null;
}
@Override
public String getDisplayVariant(String vrnt, Locale target) {
return null;
}
@Override
public String getDisplayUnicodeExtensionKey(String key, Locale target) {
return "foo_" + key;
}
@Override
public String getDisplayUnicodeExtensionType(String extType, String key, Locale target) {
return "foo_" + key + "=foo_" + extType;
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2017, 2018, 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.
*/
module provider {
exports foo;
provides java.text.spi.DateFormatSymbolsProvider with foo.DateFormatSymbolsProviderImpl;
provides java.util.spi.LocaleNameProvider with foo.LocaleNameProviderImpl;
}

View file

@ -0,0 +1,24 @@
#
# Copyright (c) 2023, 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.
#
handlers=CompatWarning$CheckWarning

View file

@ -0,0 +1,261 @@
/*
* Copyright (c) 2007, 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.
*/
/*
*
*
* A simple tool to output all the installed locales on a Windows machine, and
* corresponding Java default locale/file.encoding using PrintDefaultLocale
*
* WARNING: This tool directly modifies the locale info in the Windows registry.
* It may not work with the Windows versions after Windows XP SP2. Also,
* if the test did not complete or was manually killed, you will need to reset
* the user default locale in the Control Panel manually. This executable has
* to be run with the "Administrator" privilege.
*
* Usage: "deflocale.exe <java launcher> PrintDefaultLocale
*
* How to compile: "cl -DUNICODE -D_UNICODE deflocale.c user32.lib advapi32.lib"
*/
#include <windows.h>
#include <stdio.h>
#include <memory.h>
wchar_t* launcher;
wchar_t szBuffer[MAX_PATH];
LCID LCIDArray[1024];
int numLCIDs = 0;
BOOL isWin7orUp = FALSE;
// for Windows 7
BOOL (WINAPI * pfnEnumSystemLocalesEx)(LPVOID, DWORD, LPARAM, LPVOID);
BOOL (WINAPI * pfnEnumUILanguages)(LPVOID, DWORD, LPARAM);
LCID (WINAPI * pfnLocaleNameToLCID)(LPCWSTR, DWORD);
int (WINAPI * pfnLCIDToLocaleName)(LCID, LPWSTR, int, DWORD);
wchar_t* LocaleNamesArray[1024];
wchar_t* UILangNamesArray[1024];
int numLocaleNames = 0;
int numUILangNames = 0;
void launchAndWait() {
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (CreateProcess(NULL, launcher, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)==0) {
wprintf(L"CreateProcess failed with the error code: %x\n", GetLastError());
}
WaitForSingleObject( pi.hProcess, INFINITE );
}
void testLocale(int anLCID, wchar_t* pName) {
HKEY hk;
if (pName != NULL && wcslen(pName) == 2) {
// ignore language only locale.
return;
}
wprintf(L"\n");
wprintf(L"OS Locale (lcid: %x", anLCID);
if (pName != NULL) {
wprintf(L", name: %s", pName);
}
GetLocaleInfo(anLCID, LOCALE_SENGLANGUAGE, szBuffer, MAX_PATH);
wprintf(L"): %s (", szBuffer);
GetLocaleInfo(anLCID, LOCALE_SENGCOUNTRY, szBuffer, MAX_PATH);
wprintf(L"%s) - ", szBuffer);
GetLocaleInfo(anLCID, LOCALE_IDEFAULTANSICODEPAGE, szBuffer, MAX_PATH);
wprintf(L"%s\n", szBuffer);
fflush(0);
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Control Panel\\International", 0, KEY_READ | KEY_WRITE, &hk) == ERROR_SUCCESS) {
wchar_t originalLocale[16];
wchar_t testLocale[16];
wchar_t* pKeyName;
DWORD cb = sizeof(originalLocale);
DWORD cbTest;
if (isWin7orUp) {
pKeyName = L"LocaleName";
wcscpy(testLocale, pName);
cbTest = wcslen(pName) * sizeof(wchar_t);
} else {
pKeyName = L"Locale";
swprintf(testLocale, L"%08x", anLCID);
cbTest = sizeof(wchar_t) * 8;
}
RegQueryValueEx(hk, pKeyName, 0, 0, (LPBYTE)originalLocale, &cb);
RegSetValueEx(hk, pKeyName, 0, REG_SZ, (LPBYTE)testLocale, cbTest );
launchAndWait();
RegSetValueEx(hk, pKeyName, 0, REG_SZ, (LPBYTE)originalLocale, cb);
RegCloseKey(hk);
}
}
void testUILang(wchar_t* pName) {
HKEY hk;
wprintf(L"\n");
wprintf(L"OS UI Language (name: %s)\n", pName);
fflush(0);
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Control Panel\\Desktop", 0, KEY_READ | KEY_WRITE, &hk) == ERROR_SUCCESS) {
wchar_t originalUILang[16];
wchar_t testUILang[16];
wchar_t* pKeyName;
DWORD cb = sizeof(originalUILang);
DWORD cbTest = wcslen(pName) * sizeof(wchar_t);
pKeyName = L"PreferredUILanguages";
wcscpy(testUILang, pName);
cbTest = wcslen(pName) * sizeof(wchar_t);
RegQueryValueEx(hk, pKeyName, 0, 0, (LPBYTE)originalUILang, &cb);
RegSetValueEx(hk, pKeyName, 0, REG_SZ, (LPBYTE)testUILang, cbTest);
launchAndWait();
RegSetValueEx(hk, pKeyName, 0, REG_SZ, (LPBYTE)originalUILang, cb);
RegCloseKey(hk);
}
}
BOOL CALLBACK EnumLocalesProc(LPWSTR lpLocaleStr) {
swscanf(lpLocaleStr, L"%08x", &LCIDArray[numLCIDs]);
numLCIDs ++;
return TRUE;
}
BOOL CALLBACK EnumLocalesProcEx(LPWSTR lpLocaleStr, DWORD flags, LPARAM lp) {
wchar_t* pName = malloc((wcslen(lpLocaleStr) + 1) * sizeof(wchar_t *));
wcscpy(pName, lpLocaleStr);
LocaleNamesArray[numLocaleNames] = pName;
numLocaleNames ++;
return TRUE;
}
BOOL CALLBACK EnumUILanguagesProc(LPWSTR lpUILangStr, LPARAM lp) {
wchar_t* pName = malloc((wcslen(lpUILangStr) + 1) * sizeof(wchar_t *));
wcscpy(pName, lpUILangStr);
UILangNamesArray[numUILangNames] = pName;
numUILangNames ++;
return TRUE;
}
int sortLCIDs(LCID * pLCID1, LCID * pLCID2) {
if (*pLCID1 < *pLCID2) return (-1);
if (*pLCID1 == *pLCID2) return 0;
return 1;
}
int sortLocaleNames(wchar_t** ppName1, wchar_t** ppName2) {
LCID l1 = pfnLocaleNameToLCID(*ppName1, 0);
LCID l2 = pfnLocaleNameToLCID(*ppName2, 0);
return sortLCIDs(&l1, &l2);
}
int main(int argc, char** argv) {
OSVERSIONINFO osvi;
LPWSTR commandline = GetCommandLine();
int i;
osvi.dwOSVersionInfoSize = sizeof(osvi);
GetVersionEx(&osvi);
wprintf(L"# OSVersionInfo\n");
wprintf(L"# MajorVersion: %d\n", osvi.dwMajorVersion);
wprintf(L"# MinorVersion: %d\n", osvi.dwMinorVersion);
wprintf(L"# BuildNumber: %d\n", osvi.dwBuildNumber);
wprintf(L"# CSDVersion: %s\n", osvi.szCSDVersion);
wprintf(L"\n");
fflush(0);
launcher = wcschr(commandline, L' ')+1;
while (*launcher == L' ') {
launcher++;
}
isWin7orUp = (osvi.dwMajorVersion > 6) ||
(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion >= 1);
if (!isWin7orUp) {
// Enumerate locales
EnumSystemLocales(EnumLocalesProc, LCID_INSTALLED);
// Sort LCIDs
qsort(LCIDArray, numLCIDs, sizeof(LCID), (void *)sortLCIDs);
} else {
// For Windows 7, use "LocaleName" registry key for the user locale
// as they seem to switch from "Locale".
HMODULE hmod = GetModuleHandle(L"kernel32");
*(FARPROC*)&pfnEnumSystemLocalesEx =
GetProcAddress(hmod, "EnumSystemLocalesEx");
*(FARPROC*)&pfnEnumUILanguages =
GetProcAddress(hmod, "EnumUILanguagesW");
*(FARPROC*)&pfnLocaleNameToLCID =
GetProcAddress(hmod, "LocaleNameToLCID");
*(FARPROC*)&pfnLCIDToLocaleName =
GetProcAddress(hmod, "LCIDToLocaleName");
if (pfnEnumSystemLocalesEx != NULL &&
pfnEnumUILanguages != NULL &&
pfnLocaleNameToLCID != NULL &&
pfnLCIDToLocaleName != NULL) {
// Enumerate locales
pfnEnumSystemLocalesEx(EnumLocalesProcEx,
1, // LOCALE_WINDOWS
(LPARAM)NULL, NULL);
// Enumerate UI Languages.
pfnEnumUILanguages(EnumUILanguagesProc,
0x8, // MUI_LANGUAGE_NAME
(LPARAM)NULL);
} else {
wprintf(L"Could not get needed entry points. quitting.\n");
exit(-1);
}
// Sort LocaleNames
qsort(LocaleNamesArray, numLocaleNames,
sizeof(wchar_t*), (void *)sortLocaleNames);
qsort(UILangNamesArray, numUILangNames,
sizeof(wchar_t*), (void *)sortLocaleNames);
}
// Execute enumeration of Java default locales
if (isWin7orUp) {
for (i = 0; i < numLocaleNames; i ++) {
testLocale(pfnLocaleNameToLCID(LocaleNamesArray[i], 0),
LocaleNamesArray[i]);
}
for (i = 0; i < numUILangNames; i ++) {
testUILang(UILangNamesArray[i]);
}
} else {
for (i = 0; i < numLCIDs; i ++) {
testLocale(LCIDArray[i], NULL);
}
}
}

View file

@ -0,0 +1,7 @@
# data file for deflocale.sh. Each line must have two locales in the following order.
#
# LC_CTYPE LC_MESSAGES
ja_JP.UTF-8 zh_CN.UTF-8
zh_CN.UTF-8 en_US.UTF-8
C zh_CN.UTF-8

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,51 @@
#!/bin/sh
#
# Copyright (c) 2007, 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.
#
#
#
#
# A simple tool to output all the installed locales on a Unix machine, and
# corresponding Java default locale/file.encoding using PrintDefaultLocale
#
# Usage: "deflocale.sh <java launcher>
#
cat /etc/*release
uname -a
echo "Testing all available locales"
/usr/bin/locale -a | while read line; do
echo ""
echo "OS Locale: " $line
env LC_ALL= LC_CTYPE= LC_MESSAGES= LANG=$line $1 $2 $3 $4 $5 $6 $7 $8 $9 PrintDefaultLocale
done
echo ""
echo "Testing some typical combinations"
echo ""
while read lcctype lcmessages; do
if [ "$lcctype" = "#" -o "$lcctype" = "" ]; then
continue
fi
echo ""
echo "OS Locale (LC_CTYPE: "$lcctype", LC_MESSAGES: "$lcmessages")"
env LC_ALL= LC_CTYPE=$lcctype LC_MESSAGES=$lcmessages $1 $2 $3 $4 $5 $6 $7 $8 $9 PrintDefaultLocale
done < deflocale.input

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,292 @@
af
af-NA
af-ZA
am
am-ET
ar
ar-AE
ar-BH
ar-DZ
ar-EG
ar-IQ
ar-JO
ar-KW
ar-LB
ar-LY
ar-MA
ar-OM
ar-QA
ar-SA
ar-SD
ar-SY
ar-TN
ar-YE
as
as-IN
az
az-Cyrl
az-Cyrl-AZ
az-Latn
az-Latn-AZ
be
be-BY
bg
bg-BG
bn
bn-BD
bn-IN
bo
bo-CN
bo-IN
ca
ca-ES
cs
cs-CZ
cy
cy-GB
da
da-DK
de
de-AT
de-BE
de-CH
de-DE
de-LI
de-LU
el
el-CY
el-GR
en
en-AU
en-BE
en-BW
en-BZ
en-CA
en-GB
en-HK
en-IE
en-IN
en-JM
en-MH
en-MT
en-NA
en-NZ
en-PH
en-PK
en-SG
en-TT
en-US
en-US-posix
en-VI
en-ZA
en-ZW
eo
es
es-AR
es-BO
es-CL
es-CO
es-CR
es-DO
es-EC
es-ES
es-GT
es-HN
es-MX
es-NI
es-PA
es-PE
es-PR
es-PY
es-SV
es-US
es-UY
es-VE
et
et-EE
eu
eu-ES
fa
fa-AF
fa-IR
fi
fi-FI
fo
fo-FO
fr
fr-BE
fr-CA
fr-CH
fr-FR
fr-LU
fr-MC
fr-SN
ga
ga-IE
gl
gl-ES
gsw
gsw-CH
gu
gu-IN
gv
gv-GB
ha
ha-Latn
ha-Latn-GH
ha-Latn-NE
ha-Latn-NG
haw
haw-US
he
he-IL
hi
hi-IN
hr
hr-HR
hu
hu-HU
hy
hy-AM
hy-AM-revised
id
id-ID
ii
ii-CN
is
is-IS
it
it-CH
it-IT
ja
ja-JP
ka
ka-GE
kk
kk-Cyrl
kk-Cyrl-KZ
kl
kl-GL
km
km-KH
kn
kn-IN
ko
ko-KR
kok
kok-IN
kw
kw-GB
lt
lt-LT
lv
lv-LV
mk
mk-MK
ml
ml-IN
mr
mr-IN
ms
ms-BN
ms-MY
mt
mt-MT
nb
nb-NO
ne
ne-IN
ne-NP
nl
nl-BE
nl-NL
nn
nn-NO
om
om-ET
om-KE
or
or-IN
pa
pa-Arab
pa-Arab-PK
pa-Guru
pa-Guru-IN
pl
pl-PL
ps
ps-AF
pt
pt-BR
pt-PT
ro
ro-MD
ro-RO
ru
ru-RU
ru-UA
si
si-LK
sk
sk-SK
sl
sl-SI
so
so-DJ
so-ET
so-KE
so-SO
sq
sq-AL
sr
sr-Cyrl
sr-Cyrl-BA
sr-Cyrl-ME
sr-Cyrl-RS
sr-Latn
sr-Latn-BA
sr-Latn-ME
sr-Latn-RS
sv
sv-FI
sv-SE
sw
sw-KE
sw-TZ
ta
ta-IN
te
te-IN
th
th-TH
ti
ti-ER
ti-ET
tr
tr-TR
uk
uk-UA
ur
ur-IN
ur-PK
uz
uz-Arab
uz-Arab-AF
uz-Cyrl
uz-Cyrl-UZ
uz-Latn
uz-Latn-UZ
vi
vi-VN
zh
zh-Hans
zh-Hans-CN
zh-Hans-HK
zh-Hans-MO
zh-Hans-SG
zh-Hant
zh-Hant-HK
zh-Hant-MO
zh-Hant-TW
zu
zu-ZA

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2012, 2018, 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 providersrc.spi.src;
import java.util.spi.TimeZoneNameProvider;
import java.util.Locale;
public class tznp extends TimeZoneNameProvider {
public String getDisplayName(String ID, boolean daylight, int style,
Locale locale) {
return "tznp";
}
public Locale[] getAvailableLocales() {
Locale[] locales = {Locale.US};
return locales;
}
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2012, 2018, 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 providersrc.spi.src;
import java.util.spi.TimeZoneNameProvider;
import java.util.Locale;
import java.util.TimeZone;
public class tznp8013086 extends TimeZoneNameProvider {
public String getDisplayName(String ID, boolean daylight, int style,
Locale locale) {
if (!daylight && style == TimeZone.LONG) {
return "tznp8013086";
} else {
return null;
}
}
public Locale[] getAvailableLocales() {
Locale[] locales = {Locale.JAPAN};
return locales;
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.