mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 23:34:52 +02:00
8247781: Day periods support
Reviewed-by: scolebourne, rriggs, joehw
This commit is contained in:
parent
0357db3581
commit
bf84dac4cf
20 changed files with 1155 additions and 203 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2020, 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
|
||||
|
@ -68,7 +68,7 @@ public class CalendarNameProviderImpl extends CalendarNameProvider implements Av
|
|||
|
||||
// If standalone names are requested and no "standalone." resources are found,
|
||||
// try the default ones instead.
|
||||
if (strings == null && key.indexOf("standalone.") != -1) {
|
||||
if (strings == null && key.contains("standalone.")) {
|
||||
key = key.replaceFirst("standalone.", "");
|
||||
strings = javatime ? lr.getJavaTimeNames(key) : lr.getCalendarNames(key);
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ public class CalendarNameProviderImpl extends CalendarNameProvider implements Av
|
|||
return name;
|
||||
}
|
||||
|
||||
private static int[] REST_OF_STYLES = {
|
||||
private static final int[] REST_OF_STYLES = {
|
||||
SHORT_STANDALONE, LONG_FORMAT, LONG_STANDALONE,
|
||||
NARROW_FORMAT, NARROW_STANDALONE
|
||||
};
|
||||
|
@ -166,23 +166,26 @@ public class CalendarNameProviderImpl extends CalendarNameProvider implements Av
|
|||
|
||||
// If standalone names are requested and no "standalone." resources are found,
|
||||
// try the default ones instead.
|
||||
if (strings == null && key.indexOf("standalone.") != -1) {
|
||||
if (strings == null && key.contains("standalone.")) {
|
||||
key = key.replaceFirst("standalone.", "");
|
||||
strings = javatime ? lr.getJavaTimeNames(key) : lr.getCalendarNames(key);
|
||||
}
|
||||
|
||||
if (strings != null) {
|
||||
if (!hasDuplicates(strings)) {
|
||||
if (!hasDuplicates(strings) || field == AM_PM) {
|
||||
if (field == YEAR) {
|
||||
if (strings.length > 0) {
|
||||
map.put(strings[0], 1);
|
||||
}
|
||||
} else {
|
||||
int base = (field == DAY_OF_WEEK) ? 1 : 0;
|
||||
for (int i = 0; i < strings.length; i++) {
|
||||
// Duplicates can happen with AM_PM field. In such a case,
|
||||
// am/pm (index 0 and 1) have precedence over day
|
||||
// periods.
|
||||
for (int i = strings.length - 1; i >= 0; i--) {
|
||||
String name = strings[i];
|
||||
// Ignore any empty string (some standalone month names
|
||||
// are not defined)
|
||||
// or flexible day periods are not defined)
|
||||
if (name.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2020, 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
|
||||
|
@ -49,7 +49,6 @@ import java.util.Calendar;
|
|||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
|
@ -91,6 +90,7 @@ public class LocaleResources {
|
|||
private static final String NUMBER_PATTERNS_CACHEKEY = "NP";
|
||||
private static final String COMPACT_NUMBER_PATTERNS_CACHEKEY = "CNP";
|
||||
private static final String DATE_TIME_PATTERN = "DTP.";
|
||||
private static final String RULES_CACHEKEY = "RULE";
|
||||
|
||||
// TimeZoneNamesBundle exemplar city prefix
|
||||
private static final String TZNB_EXCITY_PREFIX = "timezone.excity.";
|
||||
|
@ -125,7 +125,6 @@ public class LocaleResources {
|
|||
return biInfo;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
byte[] getBreakIteratorResources(String key) {
|
||||
return (byte[]) localeData.getBreakIteratorResources(locale).getObject(key);
|
||||
}
|
||||
|
@ -162,7 +161,7 @@ public class LocaleResources {
|
|||
coldata = rb.getString(key);
|
||||
}
|
||||
cache.put(COLLATION_DATA_CACHEKEY,
|
||||
new ResourceReference(COLLATION_DATA_CACHEKEY, (Object) coldata, referenceQueue));
|
||||
new ResourceReference(COLLATION_DATA_CACHEKEY, coldata, referenceQueue));
|
||||
}
|
||||
|
||||
return coldata;
|
||||
|
@ -181,7 +180,7 @@ public class LocaleResources {
|
|||
dfsdata[0] = getNumberStrings(rb, "NumberElements");
|
||||
|
||||
cache.put(DECIMAL_FORMAT_SYMBOLS_DATA_CACHEKEY,
|
||||
new ResourceReference(DECIMAL_FORMAT_SYMBOLS_DATA_CACHEKEY, (Object) dfsdata, referenceQueue));
|
||||
new ResourceReference(DECIMAL_FORMAT_SYMBOLS_DATA_CACHEKEY, dfsdata, referenceQueue));
|
||||
}
|
||||
|
||||
return dfsdata;
|
||||
|
@ -314,7 +313,7 @@ public class LocaleResources {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<String> getZoneIDs() {
|
||||
Set<String> zoneIDs = null;
|
||||
Set<String> zoneIDs;
|
||||
|
||||
removeEmptyReferences();
|
||||
ResourceReference data = cache.get(ZONE_IDS_CACHEKEY);
|
||||
|
@ -322,7 +321,7 @@ public class LocaleResources {
|
|||
TimeZoneNamesBundle rb = localeData.getTimeZoneNames(locale);
|
||||
zoneIDs = rb.keySet();
|
||||
cache.put(ZONE_IDS_CACHEKEY,
|
||||
new ResourceReference(ZONE_IDS_CACHEKEY, (Object) zoneIDs, referenceQueue));
|
||||
new ResourceReference(ZONE_IDS_CACHEKEY, zoneIDs, referenceQueue));
|
||||
}
|
||||
|
||||
return zoneIDs;
|
||||
|
@ -380,7 +379,7 @@ public class LocaleResources {
|
|||
if (rb.containsKey(key)) {
|
||||
names = rb.getStringArray(key);
|
||||
cache.put(cacheKey,
|
||||
new ResourceReference(cacheKey, (Object) names, referenceQueue));
|
||||
new ResourceReference(cacheKey, names, referenceQueue));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,7 +398,7 @@ public class LocaleResources {
|
|||
if (rb.containsKey(key)) {
|
||||
names = rb.getStringArray(key);
|
||||
cache.put(cacheKey,
|
||||
new ResourceReference(cacheKey, (Object) names, referenceQueue));
|
||||
new ResourceReference(cacheKey, names, referenceQueue));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -463,17 +462,11 @@ public class LocaleResources {
|
|||
if (dateTimePattern == null) {
|
||||
dateTimePattern = getDateTimePattern(null, "DateTimePatterns", dateTimeStyle, calType);
|
||||
}
|
||||
switch (dateTimePattern) {
|
||||
case "{1} {0}":
|
||||
pattern = datePattern + " " + timePattern;
|
||||
break;
|
||||
case "{0} {1}":
|
||||
pattern = timePattern + " " + datePattern;
|
||||
break;
|
||||
default:
|
||||
pattern = MessageFormat.format(dateTimePattern.replaceAll("'", "''"), timePattern, datePattern);
|
||||
break;
|
||||
}
|
||||
pattern = switch (Objects.requireNonNull(dateTimePattern)) {
|
||||
case "{1} {0}" -> datePattern + " " + timePattern;
|
||||
case "{0} {1}" -> timePattern + " " + datePattern;
|
||||
default -> MessageFormat.format(dateTimePattern.replaceAll("'", "''"), timePattern, datePattern);
|
||||
};
|
||||
} else {
|
||||
pattern = timePattern;
|
||||
}
|
||||
|
@ -486,7 +479,7 @@ public class LocaleResources {
|
|||
}
|
||||
|
||||
public String[] getNumberPatterns() {
|
||||
String[] numberPatterns = null;
|
||||
String[] numberPatterns;
|
||||
|
||||
removeEmptyReferences();
|
||||
ResourceReference data = cache.get(NUMBER_PATTERNS_CACHEKEY);
|
||||
|
@ -495,7 +488,7 @@ public class LocaleResources {
|
|||
ResourceBundle resource = localeData.getNumberFormatData(locale);
|
||||
numberPatterns = getNumberStrings(resource, "NumberPatterns");
|
||||
cache.put(NUMBER_PATTERNS_CACHEKEY,
|
||||
new ResourceReference(NUMBER_PATTERNS_CACHEKEY, (Object) numberPatterns, referenceQueue));
|
||||
new ResourceReference(NUMBER_PATTERNS_CACHEKEY, numberPatterns, referenceQueue));
|
||||
}
|
||||
|
||||
return numberPatterns;
|
||||
|
@ -506,11 +499,10 @@ public class LocaleResources {
|
|||
* @param formatStyle the style for formatting a number
|
||||
* @return an array of compact number patterns
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public String[] getCNPatterns(NumberFormat.Style formatStyle) {
|
||||
|
||||
Objects.requireNonNull(formatStyle);
|
||||
String[] compactNumberPatterns = null;
|
||||
String[] compactNumberPatterns;
|
||||
removeEmptyReferences();
|
||||
String width = (formatStyle == NumberFormat.Style.LONG) ? "long" : "short";
|
||||
String cacheKey = width + "." + COMPACT_NUMBER_PATTERNS_CACHEKEY;
|
||||
|
@ -520,8 +512,7 @@ public class LocaleResources {
|
|||
ResourceBundle resource = localeData.getNumberFormatData(locale);
|
||||
compactNumberPatterns = (String[]) resource
|
||||
.getObject(width + ".CompactNumberPatterns");
|
||||
cache.put(cacheKey, new ResourceReference(cacheKey,
|
||||
(Object) compactNumberPatterns, referenceQueue));
|
||||
cache.put(cacheKey, new ResourceReference(cacheKey, compactNumberPatterns, referenceQueue));
|
||||
}
|
||||
return compactNumberPatterns;
|
||||
}
|
||||
|
@ -579,6 +570,28 @@ public class LocaleResources {
|
|||
return (styles.length > 1 ? styles[styleIndex] : styles[0]);
|
||||
}
|
||||
|
||||
public String[] getRules() {
|
||||
String[] rules;
|
||||
|
||||
removeEmptyReferences();
|
||||
ResourceReference data = cache.get(RULES_CACHEKEY);
|
||||
|
||||
if (data == null || ((rules = (String[]) data.get()) == null)) {
|
||||
ResourceBundle rb = localeData.getDateFormatData(locale);
|
||||
rules = new String[2];
|
||||
rules[0] = rules[1] = "";
|
||||
if (rb.containsKey("PluralRules")) {
|
||||
rules[0] = rb.getString("PluralRules");
|
||||
}
|
||||
if (rb.containsKey("DayPeriodRules")) {
|
||||
rules[1] = rb.getString("DayPeriodRules");
|
||||
}
|
||||
cache.put(RULES_CACHEKEY, new ResourceReference(RULES_CACHEKEY, rules, referenceQueue));
|
||||
}
|
||||
|
||||
return rules;
|
||||
}
|
||||
|
||||
private static class ResourceReference extends SoftReference<Object> {
|
||||
private final String cacheKey;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2020, 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
|
||||
|
@ -45,14 +45,10 @@ import java.text.DecimalFormat;
|
|||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.spi.NumberFormatProvider;
|
||||
import java.util.Arrays;
|
||||
import java.util.Currency;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import sun.text.resources.PluralRules;
|
||||
|
||||
/**
|
||||
* Concrete implementation of the {@link java.text.spi.NumberFormatProvider
|
||||
|
@ -73,12 +69,6 @@ public class NumberFormatProviderImpl extends NumberFormatProvider implements Av
|
|||
private final LocaleProviderAdapter.Type type;
|
||||
private final Set<String> langtags;
|
||||
|
||||
private static Map<String, String> rulesMap =
|
||||
Arrays.stream(PluralRules.rulesArray).collect(Collectors.toMap(
|
||||
sa -> sa[0],
|
||||
sa -> sa[1])
|
||||
);
|
||||
|
||||
public NumberFormatProviderImpl(LocaleProviderAdapter.Type type, Set<String> langtags) {
|
||||
this.type = type;
|
||||
this.langtags = langtags;
|
||||
|
@ -282,12 +272,10 @@ public class NumberFormatProviderImpl extends NumberFormatProvider implements Av
|
|||
String[] cnPatterns = resource.getCNPatterns(formatStyle);
|
||||
|
||||
// plural rules
|
||||
String pluralRules = rulesMap.getOrDefault(override.toString(),
|
||||
rulesMap.getOrDefault(override.getLanguage(), ""));
|
||||
String[] rules = resource.getRules();
|
||||
|
||||
CompactNumberFormat format = new CompactNumberFormat(numberPatterns[0],
|
||||
symbols, cnPatterns, pluralRules);
|
||||
return format;
|
||||
return new CompactNumberFormat(numberPatterns[0],
|
||||
symbols, cnPatterns, rules[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue