make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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. Oracle designates this
@@ -28,26 +28,66 @@
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Formatter;
import java.util.HashSet;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.Locale;
+import java.util.Objects;
import java.util.Set;
import java.util.SortedSet;
class ResourceBundleGenerator implements BundleGenerator {
+ // preferred timezones - keeping compatibility with JDK1.1 3 letter abbreviations
+ private static final String[] preferredTZIDs = {
+ "America/Los_Angeles",
+ "America/Denver",
+ "America/Phoenix",
+ "America/Chicago",
+ "America/New_York",
+ "America/Indianapolis",
+ "Pacific/Honolulu",
+ "America/Anchorage",
+ "America/Halifax",
+ "America/Sitka",
+ "America/St_Johns",
+ "Europe/Paris",
+ // Although CLDR does not support abbreviated zones, handle "GMT" as a
+ // special case here, as it is specified in the javadoc.
+ "GMT",
+ "Africa/Casablanca",
+ "Asia/Jerusalem",
+ "Asia/Tokyo",
+ "Europe/Bucharest",
+ "Asia/Shanghai",
+ };
+
+ // For duplicated values
+ private static final String META_VALUE_PREFIX = "metaValue_";
+
@Override
public void generateBundle(String packageName, String baseName, String localeID, boolean useJava,
Map<String, ?> map, BundleType type) throws IOException {
String suffix = useJava ? ".java" : ".properties";
String lang = CLDRConverter.getLanguageCode(localeID);
+ String ctry = CLDRConverter.getCountryCode(localeID);
String dirName = CLDRConverter.DESTINATION_DIR + File.separator + "sun" + File.separator
+ packageName + File.separator + "resources" + File.separator + "cldr";
if (lang.length() > 0) {
- dirName = dirName + File.separator + lang;
- packageName = packageName + ".resources.cldr." + lang;
+ if (CLDRConverter.isBaseModule ^ isBaseLocale(localeID)) {
+ return;
+ }
+ dirName = dirName + File.separator + lang +
+ (ctry != null && ctry.length() > 0 ? File.separator + ctry : "");
+ packageName = packageName + ".resources.cldr." + lang +
+ (ctry != null && ctry.length() > 0 ? "." + ctry : "");
} else {
+ if (!CLDRConverter.isBaseModule) {
+ return;
+ }
packageName = packageName + ".resources.cldr";
}
File dir = new File(dirName);
if (!dir.exists()) {
dir.mkdirs();
@@ -87,10 +127,69 @@
}
}
for (String key : metaKeys) {
map.remove(key);
}
+
+ // Make it preferred ordered
+ LinkedHashMap<String, Object> newMap = new LinkedHashMap<>();
+ for (String preferred : preferredTZIDs) {
+ if (map.containsKey(preferred)) {
+ newMap.put(preferred, map.remove(preferred));
+ } else if ("GMT".equals(preferred) &&
+ metaKeys.contains(CLDRConverter.METAZONE_ID_PREFIX+preferred)) {
+ newMap.put(preferred, preferred);
+ }
+ }
+ newMap.putAll(map);
+ map = newMap;
+ } else {
+ // generic reduction of duplicated values
+ Map<String, Object> newMap = null;
+ for (String key : map.keySet()) {
+ Object val = map.get(key);
+ String metaVal = null;
+
+ for (Map.Entry<String, ?> entry : map.entrySet()) {
+ String k = entry.getKey();
+ if (!k.equals(key) &&
+ Objects.deepEquals(val, entry.getValue()) &&
+ !(Objects.nonNull(newMap) && newMap.containsKey(k))) {
+ if (Objects.isNull(newMap)) {
+ newMap = new HashMap<>();
+ fmt = new Formatter();
+ }
+
+ if (Objects.isNull(metaVal)) {
+ metaVal = META_VALUE_PREFIX + key.replaceAll("\\.", "_");
+
+ if (val instanceof String[]) {
+ fmt.format(" final String[] %s = new String[] {\n", metaVal);
+ for (String s : (String[])val) {
+ fmt.format(" \"%s\",\n", CLDRConverter.saveConvert(s, useJava));
+ }
+ fmt.format(" };\n");
+ } else {
+ fmt.format(" final String %s = \"%s\";\n", metaVal, CLDRConverter.saveConvert((String)val, useJava));
+ }
+ }
+
+ newMap.put(k, metaVal);
+ }
+ }
+
+ if (Objects.nonNull(metaVal)) {
+ newMap.put(key, metaVal);
+ }
+ }
+
+ if (Objects.nonNull(newMap)) {
+ for (String key : map.keySet()) {
+ newMap.putIfAbsent(key, map.get(key));
+ }
+ map = newMap;
+ }
}
try (PrintWriter out = new PrintWriter(file, encoding)) {
// Output copyright headers
out.println(CopyrightHeaders.getOpenJDKCopyright());
@@ -112,11 +211,12 @@
if (useJava) {
Object value = map.get(key);
if (value == null) {
CLDRConverter.warning("null value for " + key);
} else if (value instanceof String) {
- if (type == BundleType.TIMEZONE) {
+ if (type == BundleType.TIMEZONE ||
+ ((String)value).startsWith(META_VALUE_PREFIX)) {
out.printf(" { \"%s\", %s },\n", key, CLDRConverter.saveConvert((String) value, useJava));
} else {
out.printf(" { \"%s\", \"%s\" },\n", key, CLDRConverter.saveConvert((String) value, useJava));
}
} else if (value instanceof String[]) {
@@ -137,58 +237,99 @@
out.println(" };\n return data;\n }\n}");
}
}
}
- private static final String METAINFO_CLASS = "CLDRLocaleDataMetaInfo";
-
@Override
public void generateMetaInfo(Map<String, SortedSet<String>> metaInfo) throws IOException {
String dirName = CLDRConverter.DESTINATION_DIR + File.separator + "sun" + File.separator + "util" +
- File.separator + "resources" + File.separator + "cldr" + File.separator +
- "provider" + File.separator ;
+ File.separator +
+ (CLDRConverter.isBaseModule ? "cldr" + File.separator + File.separator :
+ "resources" + File.separator + "cldr" + File.separator + "provider" + File.separator);
File dir = new File(dirName);
if (!dir.exists()) {
dir.mkdirs();
}
- File file = new File(dir, METAINFO_CLASS + ".java");
+ String className =
+ (CLDRConverter.isBaseModule ? "CLDRBaseLocaleDataMetaInfo" :
+ "CLDRLocaleDataMetaInfo_" +
+ CLDRConverter.DESTINATION_DIR.substring(CLDRConverter.DESTINATION_DIR.lastIndexOf('/')+1)
+ .replaceAll("\\.", "_"));
+ File file = new File(dir, className + ".java");
if (!file.exists()) {
file.createNewFile();
}
CLDRConverter.info("Generating file " + file);
try (PrintWriter out = new PrintWriter(file, "us-ascii")) {
out.println(CopyrightHeaders.getOpenJDKCopyright());
- out.println("package sun.util.resources.cldr.provider;\n\n"
+ out.println((CLDRConverter.isBaseModule ? "package sun.util.cldr;\n\n" :
+ "package sun.util.resources.cldr.provider;\n\n")
+ + "import java.util.HashMap;\n"
+ + "import java.util.Map;\n"
+ "import java.util.ListResourceBundle;\n"
+ "import sun.util.locale.provider.LocaleProviderAdapter;\n"
+ "import sun.util.locale.provider.LocaleDataMetaInfo;\n");
- out.printf("public class %s extends ListResourceBundle implements LocaleDataMetaInfo {\n", METAINFO_CLASS);
+ out.printf("public class %s extends ListResourceBundle implements LocaleDataMetaInfo {\n", className);
out.println(" @Override\n" +
" protected final Object[][] getContents() {\n" +
" final Object[][] data = new Object[][] {");
for (String key : metaInfo.keySet()) {
out.printf(" { \"%s\",\n", key);
- out.printf(" \"%s\" },\n", toLocaleList(metaInfo.get(key)));
+ out.printf(" \"%s\" },\n",
+ toLocaleList(key.equals("FormatData") ? metaInfo.get("AvailableLocales") :
+ metaInfo.get(key),
+ key.startsWith(CLDRConverter.PARENT_LOCALE_PREFIX)));
}
out.println(" };\n return data;\n }\n\n");
- out.println(" public LocaleProviderAdapter.Type getType() {\n" +
+ out.println(" @Override\n" +
+ " public LocaleProviderAdapter.Type getType() {\n" +
" return LocaleProviderAdapter.Type.CLDR;\n" +
" }\n\n");
- out.println(" public String availableLanguageTags(String category) {\n" +
+ out.println(" @Override\n" +
+ " public String availableLanguageTags(String category) {\n" +
" return getString(category);\n" +
- " };\n}");
+ " };\n\n");
+
+ if (CLDRConverter.isBaseModule) {
+ out.printf(" public Map<String, String> parentLocales() {\n" +
+ " Map<String, String> ret = new HashMap<>();\n" +
+ " keySet().stream()\n" +
+ " .filter(key -> key.startsWith(\"%s\"))\n" +
+ " .forEach(key -> ret.put(key.substring(%d), getString(key)));\n" +
+ " return ret.isEmpty() ? null : ret;\n" +
+ " };\n}",
+ CLDRConverter.PARENT_LOCALE_PREFIX,
+ CLDRConverter.PARENT_LOCALE_PREFIX.length());
+ } else {
+ out.println("}");
+ }
}
}
- private static String toLocaleList(SortedSet<String> set) {
+ private static final Locale.Builder LOCALE_BUILDER = new Locale.Builder();
+ private static boolean isBaseLocale(String localeID) {
+ localeID = localeID.replaceAll("-", "_");
+ // ignore script here
+ Locale locale = LOCALE_BUILDER
+ .clear()
+ .setLanguage(CLDRConverter.getLanguageCode(localeID))
+ .setRegion(CLDRConverter.getCountryCode(localeID))
+ .build();
+ return CLDRConverter.BASE_LOCALES.contains(locale);
+ }
+
+ private static String toLocaleList(SortedSet<String> set, boolean all) {
StringBuilder sb = new StringBuilder(set.size() * 6);
for (String id : set) {
if (!"root".equals(id)) {
+ if (!all && CLDRConverter.isBaseModule ^ isBaseLocale(id)) {
+ continue;
+ }
if (sb.length() > 0) {
sb.append(' ');
}
sb.append(id);
}