From 8780a13ab32cd4bf9228ad0726eb39152ca51687 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Mon, 16 Jun 2014 17:39:25 +0400 Subject: [PATCH] Adds support of day periods and months to DateFormatSymbols --- .../classlib/impl/unicode/CLDRHelper.java | 32 +++++++++++++--- .../classlib/impl/unicode/CLDRLocale.java | 10 +++++ .../classlib/impl/unicode/CLDRReader.java | 38 +++++++++++++++---- .../unicode/DateSymbolsMetadataGenerator.java | 30 +++++++++++---- .../java/text/TDateFormatSymbols.java | 9 +++++ .../main/java/org/teavm/samples/DateTime.java | 6 +++ 6 files changed, 105 insertions(+), 20 deletions(-) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java index 4ea21e664..c2510b32f 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java @@ -37,16 +37,38 @@ public class CLDRHelper { private static native ResourceMap getLikelySubtagsMap(); public static String[] resolveEras(String language, String country) { - ResourceMap> map = getErasMap(); - String localeCode = getCode(language, country); - ResourceArray arrayRes = map.has(localeCode) ? map.get(localeCode) : - map.has(language) ? map.get(language) : map.get("root"); - return new String[] { arrayRes.get(0).getValue(), arrayRes.get(1).getValue() }; + return resolveDateFormatSymbols(getErasMap(), language, country); } @MetadataProvider(DateSymbolsMetadataGenerator.class) private static native ResourceMap> getErasMap(); + public static String[] resolveAmPm(String language, String country) { + return resolveDateFormatSymbols(getAmPmMap(), language, country); + } + + @MetadataProvider(DateSymbolsMetadataGenerator.class) + private static native ResourceMap> getAmPmMap(); + + public static String[] resolveMonths(String language, String country) { + return resolveDateFormatSymbols(getMonthMap(), language, country); + } + + @MetadataProvider(DateSymbolsMetadataGenerator.class) + private static native ResourceMap> getMonthMap(); + + private static String[] resolveDateFormatSymbols(ResourceMap> map, String language, + String country) { + String localeCode = getCode(language, country); + ResourceArray arrayRes = map.has(localeCode) ? map.get(localeCode) : + map.has(language) ? map.get(language) : map.get("root"); + String[] result = new String[arrayRes.size()]; + for (int i = 0; i < result.length; ++i) { + result[i] = arrayRes.get(i).getValue(); + } + return result; + } + @MetadataProvider(LanguageMetadataGenerator.class) public static native ResourceMap> getLanguagesMap(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRLocale.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRLocale.java index 575df5c71..4345a90bb 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRLocale.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRLocale.java @@ -28,6 +28,8 @@ public class CLDRLocale { final Map languages = new LinkedHashMap<>(); final Map territories = new LinkedHashMap<>(); String[] eras; + String[] dayPeriods; + String[] months; public Map getLanguages() { return Collections.unmodifiableMap(languages); @@ -40,4 +42,12 @@ public class CLDRLocale { public String[] getEras() { return Arrays.copyOf(eras, eras.length); } + + public String[] getDayPeriods() { + return Arrays.copyOf(dayPeriods, dayPeriods.length); + } + + public String[] getMonths() { + return Arrays.copyOf(months, months.length); + } } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRReader.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRReader.java index 17ed965f5..2260b7731 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRReader.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRReader.java @@ -99,9 +99,13 @@ public class CLDRReader { case "territories.json": readCountries(localeName, localeInfo, input); break; - case "ca-gregorian.json": - readEras(localeName, localeInfo, input); + case "ca-gregorian.json": { + JsonObject root = (JsonObject)new JsonParser().parse(new InputStreamReader(input)); + readEras(localeName, localeInfo, root); + readAmPms(localeName, localeInfo, root); + readMonths(localeName, localeInfo, root); break; + } } } } catch (IOException e) { @@ -133,14 +137,34 @@ public class CLDRReader { } } - private void readEras(String localeCode, CLDRLocale locale, InputStream input) { - JsonObject root = (JsonObject)new JsonParser().parse(new InputStreamReader(input)); + private void readEras(String localeCode, CLDRLocale locale, JsonObject root) { JsonObject erasJson = root.get("main").getAsJsonObject().get(localeCode).getAsJsonObject() .get("dates").getAsJsonObject().get("calendars").getAsJsonObject() .get("gregorian").getAsJsonObject().get("eras").getAsJsonObject().get("eraNames").getAsJsonObject(); - String am = erasJson.get("0").getAsString(); - String pm = erasJson.get("1").getAsString(); - locale.eras = new String[] { am, pm }; + String bc = erasJson.get("0").getAsString(); + String ac = erasJson.get("1").getAsString(); + locale.eras = new String[] { bc, ac }; + } + + private void readAmPms(String localeCode, CLDRLocale locale, JsonObject root) { + JsonObject ampmJson = root.get("main").getAsJsonObject().get(localeCode).getAsJsonObject() + .get("dates").getAsJsonObject().get("calendars").getAsJsonObject() + .get("gregorian").getAsJsonObject().get("dayPeriods").getAsJsonObject() + .get("format").getAsJsonObject().get("abbreviated").getAsJsonObject(); + String am = ampmJson.get("am").getAsString(); + String pm = ampmJson.get("pm").getAsString(); + locale.dayPeriods = new String[] { am, pm }; + } + + private void readMonths(String localeCode, CLDRLocale locale, JsonObject root) { + JsonObject monthsJson = root.get("main").getAsJsonObject().get(localeCode).getAsJsonObject() + .get("dates").getAsJsonObject().get("calendars").getAsJsonObject() + .get("gregorian").getAsJsonObject().get("months").getAsJsonObject() + .get("stand-alone").getAsJsonObject().get("wide").getAsJsonObject(); + locale.months = new String[12]; + for (int i = 0; i < 12; ++i) { + locale.months[i] = monthsJson.get(String.valueOf(i + 1)).getAsString(); + } } private void readWeekData(InputStream input) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/DateSymbolsMetadataGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/DateSymbolsMetadataGenerator.java index 52ede4d19..617cdaa06 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/DateSymbolsMetadataGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/DateSymbolsMetadataGenerator.java @@ -28,24 +28,38 @@ public class DateSymbolsMetadataGenerator implements MetadataGenerator { public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) { switch (method.getName()) { case "getErasMap": - return generateEras(context); + return generateSymbols(context, new ResourceExtractor() { + @Override public String[] extract(CLDRLocale locale) { return locale.getEras(); } + }); + case "getAmPmMap": + return generateSymbols(context, new ResourceExtractor() { + @Override public String[] extract(CLDRLocale locale) { return locale.getDayPeriods(); } + }); + case "getMonthMap": + return generateSymbols(context, new ResourceExtractor() { + @Override public String[] extract(CLDRLocale locale) { return locale.getMonths(); } + }); default: throw new AssertionError("Unsupported method: " + method); } } - private Resource generateEras(MetadataGeneratorContext context) { + private Resource generateSymbols(MetadataGeneratorContext context, ResourceExtractor extractor) { CLDRReader reader = context.getService(CLDRReader.class); ResourceMap> result = context.createResourceMap(); for (Map.Entry localeEntry : reader.getKnownLocales().entrySet()) { - ResourceArray erasRes = context.createResourceArray(); - result.put(localeEntry.getKey(), erasRes); - for (String era : localeEntry.getValue().getEras()) { - StringResource eraRes = context.createResource(StringResource.class); - eraRes.setValue(era); - erasRes.add(eraRes); + ResourceArray symbolsRes = context.createResourceArray(); + result.put(localeEntry.getKey(), symbolsRes); + for (String symbol : extractor.extract(localeEntry.getValue())) { + StringResource symbolRes = context.createResource(StringResource.class); + symbolRes.setValue(symbol); + symbolsRes.add(symbolRes); } } return result; } + + private static interface ResourceExtractor { + String[] extract(CLDRLocale locale); + } } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatSymbols.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatSymbols.java index a1eb98f2b..15b647abf 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatSymbols.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatSymbols.java @@ -119,6 +119,9 @@ public class TDateFormatSymbols implements TSerializable, TCloneable { } public String[] getAmPmStrings() { + if (ampms == null) { + ampms = CLDRHelper.resolveAmPm(locale.getLanguage(), locale.getCountry()); + } return ampms.clone(); } @@ -130,10 +133,16 @@ public class TDateFormatSymbols implements TSerializable, TCloneable { } public String getLocalPatternChars() { + if (localPatternChars == null) { + localPatternChars = ""; + } return localPatternChars; } public String[] getMonths() { + if (months == null) { + months = CLDRHelper.resolveMonths(locale.getLanguage(), locale.getCountry()); + } return months.clone(); } diff --git a/teavm-samples/src/main/java/org/teavm/samples/DateTime.java b/teavm-samples/src/main/java/org/teavm/samples/DateTime.java index 75c751e7a..8c32b9f27 100644 --- a/teavm-samples/src/main/java/org/teavm/samples/DateTime.java +++ b/teavm-samples/src/main/java/org/teavm/samples/DateTime.java @@ -166,6 +166,12 @@ public class DateTime { case Calendar.ERA: text = symbols.getEras()[value]; break; + case Calendar.AM_PM: + text = symbols.getAmPmStrings()[value]; + break; + case Calendar.MONTH: + text = symbols.getMonths()[value]; + break; default: text = ""; break;