8276302: Locale.filterTags methods ignore actual weight when matching "*" (as if it is 1)
Reviewed-by: naoto
This commit is contained in:
parent
214f98f6b0
commit
87cc4e5009
src/java.base/share/classes/sun/util/locale
test/jdk/java/util/Locale
@ -124,8 +124,18 @@ public final class LocaleMatcher {
|
||||
for (LanguageRange lr : nonZeroRanges) {
|
||||
String range = lr.getRange();
|
||||
if (range.equals("*")) {
|
||||
tags = removeTagsMatchingBasicZeroRange(zeroRanges, tags);
|
||||
return new ArrayList<String>(tags);
|
||||
for (String tag : tags) {
|
||||
// change to lowercase for case-insensitive matching
|
||||
String lowerCaseTag = tag.toLowerCase(Locale.ROOT);
|
||||
|
||||
if (!caseInsensitiveMatch(list, lowerCaseTag)
|
||||
&& !shouldIgnoreFilterBasicMatch(zeroRanges, lowerCaseTag)) {
|
||||
// preserving the case of the input tag
|
||||
list.add(tag);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
} else {
|
||||
for (String tag : tags) {
|
||||
// change to lowercase for case-insensitive matching
|
||||
@ -148,44 +158,6 @@ public final class LocaleMatcher {
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the tag(s) which are falling in the basic exclusion range(s) i.e
|
||||
* range(s) with q=0 and returns the updated collection. If the basic
|
||||
* language ranges contains '*' as one of its non zero range then instead of
|
||||
* returning all the tags, remove those which are matching the range with
|
||||
* quality weight q=0.
|
||||
*/
|
||||
private static Collection<String> removeTagsMatchingBasicZeroRange(
|
||||
List<LanguageRange> zeroRange, Collection<String> tags) {
|
||||
if (zeroRange.isEmpty()) {
|
||||
tags = removeDuplicates(tags);
|
||||
return tags;
|
||||
}
|
||||
|
||||
List<String> matchingTags = new ArrayList<>();
|
||||
for (String tag : tags) {
|
||||
// change to lowercase for case-insensitive matching
|
||||
String lowerCaseTag = tag.toLowerCase(Locale.ROOT);
|
||||
if (!shouldIgnoreFilterBasicMatch(zeroRange, lowerCaseTag)
|
||||
&& !caseInsensitiveMatch(matchingTags, lowerCaseTag)) {
|
||||
matchingTags.add(tag); // preserving the case of the input tag
|
||||
}
|
||||
}
|
||||
|
||||
return matchingTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove duplicate tags from the given {@code tags} by
|
||||
* ignoring case considerations.
|
||||
*/
|
||||
private static Collection<String> removeDuplicates(
|
||||
Collection<String> tags) {
|
||||
Set<String> distinctTags = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
|
||||
return tags.stream().filter(x -> distinctTags.add(x))
|
||||
.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given {@code list} contains an element which matches
|
||||
* with the given {@code tag} ignoring case considerations.
|
||||
@ -240,8 +212,18 @@ public final class LocaleMatcher {
|
||||
for (LanguageRange lr : nonZeroRanges) {
|
||||
String range = lr.getRange();
|
||||
if (range.equals("*")) {
|
||||
tags = removeTagsMatchingExtendedZeroRange(zeroRanges, tags);
|
||||
return new ArrayList<String>(tags);
|
||||
for (String tag : tags) {
|
||||
// change to lowercase for case-insensitive matching
|
||||
String lowerCaseTag = tag.toLowerCase(Locale.ROOT);
|
||||
|
||||
if (!caseInsensitiveMatch(list, lowerCaseTag)
|
||||
&& !shouldIgnoreFilterExtendedMatch(zeroRanges, lowerCaseTag)) {
|
||||
// preserving the case of the input tag
|
||||
list.add(tag);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
String[] rangeSubtags = range.split("-");
|
||||
for (String tag : tags) {
|
||||
@ -267,33 +249,6 @@ public final class LocaleMatcher {
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the tag(s) which are falling in the extended exclusion range(s)
|
||||
* i.e range(s) with q=0 and returns the updated collection. If the extended
|
||||
* language ranges contains '*' as one of its non zero range then instead of
|
||||
* returning all the tags, remove those which are matching the range with
|
||||
* quality weight q=0.
|
||||
*/
|
||||
private static Collection<String> removeTagsMatchingExtendedZeroRange(
|
||||
List<LanguageRange> zeroRange, Collection<String> tags) {
|
||||
if (zeroRange.isEmpty()) {
|
||||
tags = removeDuplicates(tags);
|
||||
return tags;
|
||||
}
|
||||
|
||||
List<String> matchingTags = new ArrayList<>();
|
||||
for (String tag : tags) {
|
||||
// change to lowercase for case-insensitive matching
|
||||
String lowerCaseTag = tag.toLowerCase(Locale.ROOT);
|
||||
if (!shouldIgnoreFilterExtendedMatch(zeroRange, lowerCaseTag)
|
||||
&& !caseInsensitiveMatch(matchingTags, lowerCaseTag)) {
|
||||
matchingTags.add(tag); // preserve the case of the input tag
|
||||
}
|
||||
}
|
||||
|
||||
return matchingTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* The tag which is falling in the extended exclusion range(s) should
|
||||
* not be considered as the matching tag. Ignores the tag matching with the
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7069824 8042360 8032842 8175539 8210443 8242010
|
||||
* @bug 7069824 8042360 8032842 8175539 8210443 8242010 8276302
|
||||
* @summary Verify implementation for Locale matching.
|
||||
* @run testng/othervm Bug7069824
|
||||
*/
|
||||
@ -208,27 +208,61 @@ public class Bug7069824 {
|
||||
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, "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",
|
||||
MAP_EXTENDED_RANGES, "de-DE, de-DE-x-goethe"},
|
||||
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-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-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.
|
||||
};
|
||||
}
|
||||
|
||||
@ -380,6 +414,15 @@ public class Bug7069824 {
|
||||
ranges, tags, expectedTags, actualTags));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public 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);
|
||||
showLanguageTags(Locale.filterTags(priorityList, generateLanguageTags(tags), REJECT_EXTENDED_RANGES));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "LLookupData")
|
||||
public void testLLookup(String ranges, String tags, String expectedLocale) {
|
||||
List<LanguageRange> priorityList = LanguageRange.parse(ranges);
|
||||
|
Loading…
x
Reference in New Issue
Block a user