--- a/jdk/src/share/classes/java/time/format/DateTimeTextProvider.java Thu Apr 11 19:15:24 2013 -0700
+++ b/jdk/src/share/classes/java/time/format/DateTimeTextProvider.java Fri Apr 12 07:57:35 2013 -0700
@@ -70,6 +70,7 @@
import java.time.chrono.IsoChronology;
import java.time.chrono.JapaneseChronology;
import java.time.temporal.ChronoField;
+import java.time.temporal.IsoFields;
import java.time.temporal.TemporalField;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayList;
@@ -82,10 +83,13 @@
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.ResourceBundle;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import sun.util.locale.provider.CalendarDataUtility;
+import sun.util.locale.provider.LocaleProviderAdapter;
+import sun.util.locale.provider.LocaleResources;
/**
* A provider to obtain the textual form of a date-time field.
@@ -141,15 +145,6 @@
return null;
}
- private static int toStyle(TextStyle style) {
- if (style == TextStyle.FULL) {
- return Calendar.LONG_FORMAT;
- } else if (style == TextStyle.SHORT) {
- return Calendar.SHORT_FORMAT;
- }
- return Calendar.NARROW_STANDALONE;
- }
-
/**
* Gets the text for the specified chrono, field, locale and style
* for the purpose of formatting.
@@ -158,7 +153,7 @@
* The null return value should be used if there is no applicable text, or
* if the text would be a numeric representation of the value.
*
- * @param chrono the Chronology to get text for, not null
+ * @param chrono the Chronology to get text for, not null
* @param field the field to get text for, not null
* @param value the field value to get text for, not null
* @param style the style to get text for, not null
@@ -200,8 +195,8 @@
} else {
return null;
}
- return CalendarDataUtility.retrieveCldrFieldValueName(
- chrono.getCalendarType(), fieldIndex, fieldValue, toStyle(style), locale);
+ return CalendarDataUtility.retrieveJavaTimeFieldValueName(
+ chrono.getCalendarType(), fieldIndex, fieldValue, style.toCalendarStyle(), locale);
}
/**
@@ -238,7 +233,7 @@
* if the text would be a numeric representation of the value.
* Text can only be parsed if all the values for that field-style-locale combination are unique.
*
- * @param chrono the Chronology to get text for, not null
+ * @param chrono the Chronology to get text for, not null
* @param field the field to get text for, not null
* @param style the style to get text for, null for all parsable text
* @param locale the locale to get text for, not null
@@ -270,17 +265,17 @@
return null;
}
- Map<String, Integer> map = CalendarDataUtility.retrieveCldrFieldValueNames(
- chrono.getCalendarType(), fieldIndex, toStyle(style), locale);
+ int calendarStyle = (style == null) ? Calendar.ALL_STYLES : style.toCalendarStyle();
+ Map<String, Integer> map = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
+ chrono.getCalendarType(), fieldIndex, calendarStyle, locale);
if (map == null) {
return null;
}
-
List<Entry<String, Long>> list = new ArrayList<>(map.size());
switch (fieldIndex) {
case Calendar.ERA:
- for (String key : map.keySet()) {
- int era = map.get(key);
+ for (Map.Entry<String, Integer> entry : map.entrySet()) {
+ int era = entry.getValue();
if (chrono == JapaneseChronology.INSTANCE) {
if (era == 0) {
era = -999;
@@ -288,22 +283,22 @@
era -= 2;
}
}
- list.add(createEntry(key, (long) era));
+ list.add(createEntry(entry.getKey(), (long)era));
}
break;
case Calendar.MONTH:
- for (String key : map.keySet()) {
- list.add(createEntry(key, (long)(map.get(key) + 1)));
+ for (Map.Entry<String, Integer> entry : map.entrySet()) {
+ list.add(createEntry(entry.getKey(), (long)(entry.getValue() + 1)));
}
break;
case Calendar.DAY_OF_WEEK:
- for (String key : map.keySet()) {
- list.add(createEntry(key, (long)toWeekDay(map.get(key))));
+ for (Map.Entry<String, Integer> entry : map.entrySet()) {
+ list.add(createEntry(entry.getKey(), (long)toWeekDay(entry.getValue())));
}
break;
default:
- for (String key : map.keySet()) {
- list.add(createEntry(key, (long)map.get(key)));
+ for (Map.Entry<String, Integer> entry : map.entrySet()) {
+ list.add(createEntry(entry.getKey(), (long)entry.getValue()));
}
break;
}
@@ -333,11 +328,47 @@
Map<TextStyle, Map<Long, String>> styleMap = new HashMap<>();
if (field == ERA) {
for (TextStyle textStyle : TextStyle.values()) {
+ if (textStyle.isStandalone()) {
+ // Stand-alone isn't applicable to era names.
+ continue;
+ }
+ Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
+ "gregory", Calendar.ERA, textStyle.toCalendarStyle(), locale);
+ if (displayNames != null) {
+ Map<Long, String> map = new HashMap<>();
+ for (Entry<String, Integer> entry : displayNames.entrySet()) {
+ map.put((long) entry.getValue(), entry.getKey());
+ }
+ if (!map.isEmpty()) {
+ styleMap.put(textStyle, map);
+ }
+ }
+ }
+ return new LocaleStore(styleMap);
+ }
+
+ if (field == MONTH_OF_YEAR) {
+ for (TextStyle textStyle : TextStyle.values()) {
+ Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
+ "gregory", Calendar.MONTH, textStyle.toCalendarStyle(), locale);
Map<Long, String> map = new HashMap<>();
- for (Entry<String, Integer> entry :
- CalendarDataUtility.retrieveCldrFieldValueNames(
- "gregory", Calendar.ERA, toStyle(textStyle), locale).entrySet()) {
- map.put((long) entry.getValue(), entry.getKey());
+ if (displayNames != null) {
+ for (Entry<String, Integer> entry : displayNames.entrySet()) {
+ map.put((long) (entry.getValue() + 1), entry.getKey());
+ }
+
+ } else {
+ // Narrow names may have duplicated names, such as "J" for January, Jun, July.
+ // Get names one by one in that case.
+ for (int month = Calendar.JANUARY; month <= Calendar.DECEMBER; month++) {
+ String name;
+ name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
+ "gregory", Calendar.MONTH, month, textStyle.toCalendarStyle(), locale);
+ if (name == null) {
+ break;
+ }
+ map.put((long) (month + 1), name);
+ }
}
if (!map.isEmpty()) {
styleMap.put(textStyle, map);
@@ -346,72 +377,77 @@
return new LocaleStore(styleMap);
}
- if (field == MONTH_OF_YEAR) {
- Map<Long, String> map = new HashMap<>();
- for (Entry<String, Integer> entry :
- CalendarDataUtility.retrieveCldrFieldValueNames(
- "gregory", Calendar.MONTH, Calendar.LONG_FORMAT, locale).entrySet()) {
- map.put((long) (entry.getValue() + 1), entry.getKey());
- }
- styleMap.put(TextStyle.FULL, map);
+ if (field == DAY_OF_WEEK) {
+ for (TextStyle textStyle : TextStyle.values()) {
+ Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
+ "gregory", Calendar.DAY_OF_WEEK, textStyle.toCalendarStyle(), locale);
+ Map<Long, String> map = new HashMap<>();
+ if (displayNames != null) {
+ for (Entry<String, Integer> entry : displayNames.entrySet()) {
+ map.put((long)toWeekDay(entry.getValue()), entry.getKey());
+ }
- map = new HashMap<>();
- for (Entry<String, Integer> entry :
- CalendarDataUtility.retrieveCldrFieldValueNames(
- "gregory", Calendar.MONTH, Calendar.SHORT_FORMAT, locale).entrySet()) {
- map.put((long) (entry.getValue() + 1), entry.getKey());
- }
- styleMap.put(TextStyle.SHORT, map);
-
- map = new HashMap<>();
- for (int month = Calendar.JANUARY; month <= Calendar.DECEMBER; month++) {
- String name;
- name = CalendarDataUtility.retrieveCldrFieldValueName(
- "gregory", Calendar.MONTH, month, Calendar.NARROW_STANDALONE, locale);
- if (name != null) {
- map.put((long)(month + 1), name);
+ } else {
+ // Narrow names may have duplicated names, such as "S" for Sunday and Saturday.
+ // Get names one by one in that case.
+ for (int wday = Calendar.SUNDAY; wday <= Calendar.SATURDAY; wday++) {
+ String name;
+ name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
+ "gregory", Calendar.DAY_OF_WEEK, wday, textStyle.toCalendarStyle(), locale);
+ if (name == null) {
+ break;
+ }
+ map.put((long)toWeekDay(wday), name);
+ }
}
- }
- if (!map.isEmpty()) {
- styleMap.put(TextStyle.NARROW, map);
+ if (!map.isEmpty()) {
+ styleMap.put(textStyle, map);
+ }
}
return new LocaleStore(styleMap);
}
- if (field == DAY_OF_WEEK) {
- Map<Long, String> map = new HashMap<>();
- for (Entry<String, Integer> entry :
- CalendarDataUtility.retrieveCldrFieldValueNames(
- "gregory", Calendar.DAY_OF_WEEK, Calendar.LONG_FORMAT, locale).entrySet()) {
- map.put((long)toWeekDay(entry.getValue()), entry.getKey());
+ if (field == AMPM_OF_DAY) {
+ for (TextStyle textStyle : TextStyle.values()) {
+ if (textStyle.isStandalone()) {
+ // Stand-alone isn't applicable to AM/PM.
+ continue;
+ }
+ Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
+ "gregory", Calendar.AM_PM, textStyle.toCalendarStyle(), locale);
+ if (displayNames != null) {
+ Map<Long, String> map = new HashMap<>();
+ for (Entry<String, Integer> entry : displayNames.entrySet()) {
+ map.put((long) entry.getValue(), entry.getKey());
+ }
+ if (!map.isEmpty()) {
+ styleMap.put(textStyle, map);
+ }
+ }
}
- styleMap.put(TextStyle.FULL, map);
- map = new HashMap<>();
- for (Entry<String, Integer> entry :
- CalendarDataUtility.retrieveCldrFieldValueNames(
- "gregory", Calendar.DAY_OF_WEEK, Calendar.SHORT_FORMAT, locale).entrySet()) {
- map.put((long) toWeekDay(entry.getValue()), entry.getKey());
- }
- styleMap.put(TextStyle.SHORT, map);
- map = new HashMap<>();
- for (int wday = Calendar.SUNDAY; wday <= Calendar.SATURDAY; wday++) {
- map.put((long) toWeekDay(wday),
- CalendarDataUtility.retrieveCldrFieldValueName(
- "gregory", Calendar.DAY_OF_WEEK, wday, Calendar.NARROW_FORMAT, locale));
- }
- styleMap.put(TextStyle.NARROW, map);
return new LocaleStore(styleMap);
}
- if (field == AMPM_OF_DAY) {
- Map<Long, String> map = new HashMap<>();
- for (Entry<String, Integer> entry :
- CalendarDataUtility.retrieveCldrFieldValueNames(
- "gregory", Calendar.AM_PM, Calendar.LONG_FORMAT, locale).entrySet()) {
- map.put((long) entry.getValue(), entry.getKey());
+ if (field == IsoFields.QUARTER_OF_YEAR) {
+ // The order of keys must correspond to the TextStyle.values() order.
+ final String[] keys = {
+ "QuarterNames",
+ "standalone.QuarterNames",
+ "QuarterAbbreviations",
+ "standalone.QuarterAbbreviations",
+ "QuarterNarrows",
+ "standalone.QuarterNarrows",
+ };
+ for (int i = 0; i < keys.length; i++) {
+ String[] names = getLocalizedResource(keys[i], locale);
+ if (names != null) {
+ Map<Long, String> map = new HashMap<>();
+ for (int q = 0; q < names.length; q++) {
+ map.put((long) (q + 1), names[q]);
+ }
+ styleMap.put(TextStyle.values()[i], map);
+ }
}
- styleMap.put(TextStyle.FULL, map);
- styleMap.put(TextStyle.SHORT, map); // re-use, as we don't have different data
return new LocaleStore(styleMap);
}
@@ -430,6 +466,23 @@
}
/**
+ * Returns the localized resource of the given key and locale, or null
+ * if no localized resource is available.
+ *
+ * @param key the key of the localized resource, not null
+ * @param locale the locale, not null
+ * @return the localized resource, or null if not available
+ * @throws NullPointerException if key or locale is null
+ */
+ @SuppressWarnings("unchecked")
+ static <T> T getLocalizedResource(String key, Locale locale) {
+ LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased()
+ .getLocaleResources(locale);
+ ResourceBundle rb = lr.getJavaTimeFormatData();
+ return rb.containsKey(key) ? (T) rb.getObject(key) : null;
+ }
+
+ /**
* Stores the text for a single locale.
* <p>
* Some fields have a textual representation, such as day-of-week or month-of-year.
@@ -457,9 +510,9 @@
this.valueTextMap = valueTextMap;
Map<TextStyle, List<Entry<String, Long>>> map = new HashMap<>();
List<Entry<String, Long>> allList = new ArrayList<>();
- for (TextStyle style : valueTextMap.keySet()) {
+ for (Map.Entry<TextStyle, Map<Long, String>> vtmEntry : valueTextMap.entrySet()) {
Map<String, Entry<String, Long>> reverse = new HashMap<>();
- for (Map.Entry<Long, String> entry : valueTextMap.get(style).entrySet()) {
+ for (Map.Entry<Long, String> entry : vtmEntry.getValue().entrySet()) {
if (reverse.put(entry.getValue(), createEntry(entry.getValue(), entry.getKey())) != null) {
// TODO: BUG: this has no effect
continue; // not parsable, try next style
@@ -467,7 +520,7 @@
}
List<Entry<String, Long>> list = new ArrayList<>(reverse.values());
Collections.sort(list, COMPARATOR);
- map.put(style, list);
+ map.put(vtmEntry.getKey(), list);
allList.addAll(list);
map.put(null, allList);
}