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);
             }