alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (CLDRConverter.java)

This example Java source code file (CLDRConverter.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

cldr_base, drafttype, exception, file, formatdata, hashmap, keycomparator, list, localenames, map, object, parser, sax, saxparser, string, treeset, util, xml

The CLDRConverter.java Java example source code

/*
 * Copyright (c) 2012, 2013, 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
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package build.tools.cldrconverter;

import build.tools.cldrconverter.BundleGenerator.BundleType;
import java.io.File;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;


/**
 * Converts locale data from "Locale Data Markup Language" format to
 * JRE resource bundle format. LDML is the format used by the Common
 * Locale Data Repository maintained by the Unicode Consortium.
 */
public class CLDRConverter {

    static final String LDML_DTD_SYSTEM_ID = "http://www.unicode.org/cldr/dtd/2.0/ldml.dtd";
    static final String SPPL_LDML_DTD_SYSTEM_ID = "http://www.unicode.org/cldr/dtd/2.0/ldmlSupplemental.dtd";

    private static String CLDR_BASE = "../CLDR/21.0.1/";
    static String LOCAL_LDML_DTD;
    static String LOCAL_SPPL_LDML_DTD;
    private static String SOURCE_FILE_DIR;
    private static String SPPL_SOURCE_FILE;
    private static String NUMBERING_SOURCE_FILE;
    private static String METAZONES_SOURCE_FILE;
    static String DESTINATION_DIR = "build/gensrc";

    static final String LOCALE_NAME_PREFIX = "locale.displayname.";
    static final String CURRENCY_SYMBOL_PREFIX = "currency.symbol.";
    static final String CURRENCY_NAME_PREFIX = "currency.displayname.";
    static final String CALENDAR_NAME_PREFIX = "calendarname.";
    static final String TIMEZONE_ID_PREFIX = "timezone.id.";
    static final String ZONE_NAME_PREFIX = "timezone.displayname.";
    static final String METAZONE_ID_PREFIX = "metazone.id.";

    private static SupplementDataParseHandler handlerSuppl;
    static NumberingSystemsParseHandler handlerNumbering;
    static MetaZonesParseHandler handlerMetaZones;
    private static BundleGenerator bundleGenerator;

    static enum DraftType {
        UNCONFIRMED,
        PROVISIONAL,
        CONTRIBUTED,
        APPROVED;

        private static final Map<String, DraftType> map = new HashMap<>();
        static {
            for (DraftType dt : values()) {
                map.put(dt.getKeyword(), dt);
            }
        }
        static private DraftType defaultType = CONTRIBUTED;

        private final String keyword;

        private DraftType() {
            keyword = this.name().toLowerCase(Locale.ROOT);

        }

        static DraftType forKeyword(String keyword) {
            return map.get(keyword);
        }

        static DraftType getDefault() {
            return defaultType;
        }

        static void setDefault(String keyword) {
            defaultType = Objects.requireNonNull(forKeyword(keyword));
        }

        String getKeyword() {
            return keyword;
        }
    }

    static boolean USE_UTF8 = false;
    private static boolean verbose;

    private CLDRConverter() {
       // no instantiation
    }

    @SuppressWarnings("AssignmentToForLoopParameter")
    public static void main(String[] args) throws Exception {
        if (args.length != 0) {
            String currentArg = null;
            try {
                for (int i = 0; i < args.length; i++) {
                    currentArg = args[i];
                    switch (currentArg) {
                    case "-draft":
                        String draftDataType = args[++i];
                        try {
                            DraftType.setDefault(draftDataType);
                        } catch (NullPointerException e) {
                            severe("Error: incorrect draft value: %s%n", draftDataType);
                            System.exit(1);
                        }
                        info("Using the specified data type: %s%n", draftDataType);
                        break;

                    case "-base":
                        // base directory for input files
                        CLDR_BASE = args[++i];
                        if (!CLDR_BASE.endsWith("/")) {
                            CLDR_BASE += "/";
                        }
                        break;

                    case "-o":
                        // output directory
                        DESTINATION_DIR = args[++i];
                        break;

                    case "-utf8":
                        USE_UTF8 = true;
                        break;

                    case "-verbose":
                        verbose = true;
                        break;

                    case "-help":
                        usage();
                        System.exit(0);
                        break;

                    default:
                        throw new RuntimeException();
                    }
                }
            } catch (RuntimeException e) {
                severe("unknown or imcomplete arg(s): " + currentArg);
                usage();
                System.exit(1);
            }
        }

        // Set up path names
        LOCAL_LDML_DTD = CLDR_BASE + "common/dtd/ldml.dtd";
        LOCAL_SPPL_LDML_DTD = CLDR_BASE + "common/dtd/ldmlSupplemental.dtd";
        SOURCE_FILE_DIR = CLDR_BASE + "common/main";
        SPPL_SOURCE_FILE = CLDR_BASE + "common/supplemental/supplementalData.xml";
        NUMBERING_SOURCE_FILE = CLDR_BASE + "common/supplemental/numberingSystems.xml";
        METAZONES_SOURCE_FILE = CLDR_BASE + "common/supplemental/metaZones.xml";

        bundleGenerator = new ResourceBundleGenerator();

        List<Bundle> bundles = readBundleList();
        convertBundles(bundles);
    }

    private static void usage() {
        errout("Usage: java CLDRConverter [options]%n"
                + "\t-help          output this usage message and exit%n"
                + "\t-verbose       output information%n"
                + "\t-draft [approved | provisional | unconfirmed]%n"
                + "\t\t       draft level for using data (default: approved)%n"
                + "\t-base dir      base directory for CLDR input files%n"
                + "\t-o dir         output directory (defaut: ./build/gensrc)%n"
                + "\t-utf8          use UTF-8 rather than \\uxxxx (for debug)%n");
    }

    static void info(String fmt, Object... args) {
        if (verbose) {
            System.out.printf(fmt, args);
        }
    }

    static void info(String msg) {
        if (verbose) {
            System.out.println(msg);
        }
    }

    static void warning(String fmt, Object... args) {
        System.err.print("Warning: ");
        System.err.printf(fmt, args);
    }

    static void warning(String msg) {
        System.err.print("Warning: ");
        errout(msg);
    }

    static void severe(String fmt, Object... args) {
        System.err.print("Error: ");
        System.err.printf(fmt, args);
    }

    static void severe(String msg) {
        System.err.print("Error: ");
        errout(msg);
    }

    private static void errout(String msg) {
        if (msg.contains("%n")) {
            System.err.printf(msg);
        } else {
            System.err.println(msg);
        }
    }

    /**
     * Configure the parser to allow access to DTDs on the file system.
     */
    private static void enableFileAccess(SAXParser parser) throws SAXNotSupportedException {
        try {
            parser.setProperty("http://javax.xml.XMLConstants/property/accessExternalDTD", "file");
        } catch (SAXNotRecognizedException ignore) {
            // property requires >= JAXP 1.5
        }
    }

    private static List<Bundle> readBundleList() throws Exception {
        ResourceBundle.Control defCon = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT);
        List<Bundle> retList = new ArrayList<>();
        Path path = FileSystems.getDefault().getPath(SOURCE_FILE_DIR);
        try (DirectoryStream<Path> dirStr = Files.newDirectoryStream(path)) {
            for (Path entry : dirStr) {
                String fileName = entry.getFileName().toString();
                if (fileName.endsWith(".xml")) {
                    String id = fileName.substring(0, fileName.indexOf('.'));
                    Locale cldrLoc = Locale.forLanguageTag(toLanguageTag(id));
                    List<Locale> candList = defCon.getCandidateLocales("", cldrLoc);
                    StringBuilder sb = new StringBuilder();
                    for (Locale loc : candList) {
                        if (!loc.equals(Locale.ROOT)) {
                            sb.append(toLocaleName(loc.toLanguageTag()));
                            sb.append(",");
                        }
                    }
                    if (sb.indexOf("root") == -1) {
                        sb.append("root");
                    }
                    Bundle b = new Bundle(id, sb.toString(), null, null);
                    // Insert the bundle for en at the top so that it will get
                    // processed first.
                    if ("en".equals(id)) {
                        retList.add(0, b);
                    } else {
                        retList.add(b);
                    }
                }
            }
        }
        return retList;
    }

    private static Map<String, Map cldrBundles = new HashMap<>();

    static Map<String, Object> getCLDRBundle(String id) throws Exception {
        Map<String, Object> bundle = cldrBundles.get(id);
        if (bundle != null) {
            return bundle;
        }
        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setValidating(true);
        SAXParser parser = factory.newSAXParser();
        enableFileAccess(parser);
        LDMLParseHandler handler = new LDMLParseHandler(id);
        File file = new File(SOURCE_FILE_DIR + File.separator + id + ".xml");
        if (!file.exists()) {
            // Skip if the file doesn't exist.
            return Collections.emptyMap();
        }

        info("..... main directory .....");
        info("Reading file " + file);
        parser.parse(file, handler);

        bundle = handler.getData();
        cldrBundles.put(id, bundle);
        String country = getCountryCode(id);
        if (country != null) {
            bundle = handlerSuppl.getData(country);
            if (bundle != null) {
                //merge two maps into one map
                Map<String, Object> temp = cldrBundles.remove(id);
                bundle.putAll(temp);
                cldrBundles.put(id, bundle);
            }
        }
        return bundle;
    }

    private static void convertBundles(List<Bundle> bundles) throws Exception {
        // Parse SupplementalData file and store the information in the HashMap
        // Calendar information such as firstDay and minDay are stored in
        // supplementalData.xml as of CLDR1.4. Individual territory is listed
        // with its ISO 3166 country code while default is listed using UNM49
        // region and composition numerical code (001 for World.)
        SAXParserFactory factorySuppl = SAXParserFactory.newInstance();
        factorySuppl.setValidating(true);
        SAXParser parserSuppl = factorySuppl.newSAXParser();
        enableFileAccess(parserSuppl);
        handlerSuppl = new SupplementDataParseHandler();
        File fileSupply = new File(SPPL_SOURCE_FILE);
        parserSuppl.parse(fileSupply, handlerSuppl);

        // Parse numberingSystems to get digit zero character information.
        SAXParserFactory numberingParser = SAXParserFactory.newInstance();
        numberingParser.setValidating(true);
        SAXParser parserNumbering = numberingParser.newSAXParser();
        enableFileAccess(parserNumbering);
        handlerNumbering = new NumberingSystemsParseHandler();
        File fileNumbering = new File(NUMBERING_SOURCE_FILE);
        parserNumbering.parse(fileNumbering, handlerNumbering);

        // Parse metaZones to create mappings between Olson tzids and CLDR meta zone names
        SAXParserFactory metazonesParser = SAXParserFactory.newInstance();
        metazonesParser.setValidating(true);
        SAXParser parserMetaZones = metazonesParser.newSAXParser();
        enableFileAccess(parserMetaZones);
        handlerMetaZones = new MetaZonesParseHandler();
        File fileMetaZones = new File(METAZONES_SOURCE_FILE);
        parserNumbering.parse(fileMetaZones, handlerMetaZones);

        // For generating information on supported locales.
        Map<String, SortedSet metaInfo = new HashMap<>();
        metaInfo.put("LocaleNames", new TreeSet<String>());
        metaInfo.put("CurrencyNames", new TreeSet<String>());
        metaInfo.put("TimeZoneNames", new TreeSet<String>());
        metaInfo.put("CalendarData", new TreeSet<String>());
        metaInfo.put("FormatData", new TreeSet<String>());

        for (Bundle bundle : bundles) {
            // Get the target map, which contains all the data that should be
            // visible for the bundle's locale

            Map<String, Object> targetMap = bundle.getTargetMap();

            EnumSet<Bundle.Type> bundleTypes = bundle.getBundleTypes();

            // Fill in any missing resources in the base bundle from en and en-US data.
            // This is because CLDR root.xml is supposed to be language neutral and doesn't
            // provide some resource data. Currently, the runtime assumes that there are all
            // resources though the parent resource bundle chain.
            if (bundle.isRoot()) {
                Map<String, Object> enData = new HashMap<>();
                // Create a superset of en-US and en bundles data in order to
                // fill in any missing resources in the base bundle.
                enData.putAll(Bundle.getBundle("en").getTargetMap());
                enData.putAll(Bundle.getBundle("en_US").getTargetMap());
                for (String key : enData.keySet()) {
                    if (!targetMap.containsKey(key)) {
                        targetMap.put(key, enData.get(key));
                    }
                }
                // Add DateTimePatternChars because CLDR no longer supports localized patterns.
                targetMap.put("DateTimePatternChars", "GyMdkHmsSEDFwWahKzZ");
            }

            // Now the map contains just the entries that need to be in the resources bundles.
            // Go ahead and generate them.
            if (bundleTypes.contains(Bundle.Type.LOCALENAMES)) {
                Map<String, Object> localeNamesMap = extractLocaleNames(targetMap, bundle.getID());
                if (!localeNamesMap.isEmpty() || bundle.isRoot()) {
                    metaInfo.get("LocaleNames").add(toLanguageTag(bundle.getID()));
                    bundleGenerator.generateBundle("util", "LocaleNames", bundle.getID(), true, localeNamesMap, BundleType.OPEN);
                }
            }
            if (bundleTypes.contains(Bundle.Type.CURRENCYNAMES)) {
                Map<String, Object> currencyNamesMap = extractCurrencyNames(targetMap, bundle.getID(), bundle.getCurrencies());
                if (!currencyNamesMap.isEmpty() || bundle.isRoot()) {
                    metaInfo.get("CurrencyNames").add(toLanguageTag(bundle.getID()));
                    bundleGenerator.generateBundle("util", "CurrencyNames", bundle.getID(), true, currencyNamesMap, BundleType.OPEN);
                }
            }
            if (bundleTypes.contains(Bundle.Type.TIMEZONENAMES)) {
                Map<String, Object> zoneNamesMap = extractZoneNames(targetMap, bundle.getID());
                if (!zoneNamesMap.isEmpty() || bundle.isRoot()) {
                    metaInfo.get("TimeZoneNames").add(toLanguageTag(bundle.getID()));
                    bundleGenerator.generateBundle("util", "TimeZoneNames", bundle.getID(), true, zoneNamesMap, BundleType.TIMEZONE);
                }
            }
            if (bundleTypes.contains(Bundle.Type.CALENDARDATA)) {
                Map<String, Object> calendarDataMap = extractCalendarData(targetMap, bundle.getID());
                if (!calendarDataMap.isEmpty() || bundle.isRoot()) {
                    metaInfo.get("CalendarData").add(toLanguageTag(bundle.getID()));
                    bundleGenerator.generateBundle("util", "CalendarData", bundle.getID(), true, calendarDataMap, BundleType.PLAIN);
                }
            }
            if (bundleTypes.contains(Bundle.Type.FORMATDATA)) {
                Map<String, Object> formatDataMap = extractFormatData(targetMap, bundle.getID());
                // LocaleData.getAvailableLocales depends on having FormatData bundles around
                if (!formatDataMap.isEmpty() || bundle.isRoot()) {
                    metaInfo.get("FormatData").add(toLanguageTag(bundle.getID()));
                    bundleGenerator.generateBundle("text", "FormatData", bundle.getID(), true, formatDataMap, BundleType.PLAIN);
                }
            }

            // For testing
            SortedSet<String> allLocales = new TreeSet<>();
            allLocales.addAll(metaInfo.get("CurrencyNames"));
            allLocales.addAll(metaInfo.get("LocaleNames"));
            allLocales.addAll(metaInfo.get("CalendarData"));
            allLocales.addAll(metaInfo.get("FormatData"));
            metaInfo.put("All", allLocales);
        }

        bundleGenerator.generateMetaInfo(metaInfo);
    }

    /*
     * Returns the language portion of the given id.
     * If id is "root", "" is returned.
     */
    static String getLanguageCode(String id) {
        int index = id.indexOf('_');
        String lang = null;
        if (index != -1) {
            lang = id.substring(0, index);
        } else {
            lang = "root".equals(id) ? "" : id;
        }
        return lang;
    }

    /**
     * Examine if the id includes the country (territory) code. If it does, it returns
     * the country code.
     * Otherwise, it returns null. eg. when the id is "zh_Hans_SG", it return "SG".
     */
    private static String getCountryCode(String id) {
        //Truncate a variant code with '@' if there is any
        //(eg. de_DE@collation=phonebook,currency=DOM)
        if (id.indexOf('@') != -1) {
            id = id.substring(0, id.indexOf('@'));
        }
        String[] tokens = id.split("_");
        for (int index = 1; index < tokens.length; ++index) {
            if (tokens[index].length() == 2
                    && Character.isLetter(tokens[index].charAt(0))
                    && Character.isLetter(tokens[index].charAt(1))) {
                return tokens[index];
            }
        }
        return null;
    }

    private static class KeyComparator implements Comparator<String> {
        static KeyComparator INSTANCE = new KeyComparator();

        private KeyComparator() {
        }

        @Override
        public int compare(String o1, String o2) {
            int len1 = o1.length();
            int len2 = o2.length();
            if (!isDigit(o1.charAt(0)) && !isDigit(o2.charAt(0))) {
                // Shorter string comes first unless either starts with a digit.
                if (len1 < len2) {
                    return -1;
                }
                if (len1 > len2) {
                    return 1;
                }
            }
            return o1.compareTo(o2);
        }

        private boolean isDigit(char c) {
            return c >= '0' && c <= '9';
        }
    }

    private static Map<String, Object> extractLocaleNames(Map map, String id) {
        Map<String, Object> localeNames = new TreeMap<>(KeyComparator.INSTANCE);
        for (String key : map.keySet()) {
            if (key.startsWith(LOCALE_NAME_PREFIX)) {
                localeNames.put(key.substring(LOCALE_NAME_PREFIX.length()), map.get(key));
            }
        }
        return localeNames;
    }

    @SuppressWarnings("AssignmentToForLoopParameter")
    private static Map<String, Object> extractCurrencyNames(Map map, String id, String names)
            throws Exception {
        Map<String, Object> currencyNames = new TreeMap<>(KeyComparator.INSTANCE);
        for (String key : map.keySet()) {
            if (key.startsWith(CURRENCY_NAME_PREFIX)) {
                currencyNames.put(key.substring(CURRENCY_NAME_PREFIX.length()), map.get(key));
            } else if (key.startsWith(CURRENCY_SYMBOL_PREFIX)) {
                currencyNames.put(key.substring(CURRENCY_SYMBOL_PREFIX.length()), map.get(key));
            }
        }
        return currencyNames;
    }

    private static Map<String, Object> extractZoneNames(Map map, String id) {
        Map<String, Object> names = new HashMap<>();
        for (String tzid : handlerMetaZones.keySet()) {
            String tzKey = TIMEZONE_ID_PREFIX + tzid;
            Object data = map.get(tzKey);
            if (data instanceof String[]) {
                names.put(tzid, data);
            } else {
                String meta = handlerMetaZones.get(tzid);
                if (meta != null) {
                    String metaKey = METAZONE_ID_PREFIX + meta;
                    data = map.get(metaKey);
                    if (data instanceof String[]) {
                        // Keep the metazone prefix here.
                        names.put(metaKey, data);
                        names.put(tzid, meta);
                    }
                }
            }
        }
        return names;
    }

    private static Map<String, Object> extractCalendarData(Map map, String id) {
        Map<String, Object> calendarData = new LinkedHashMap<>();
        copyIfPresent(map, "firstDayOfWeek", calendarData);
        copyIfPresent(map, "minimalDaysInFirstWeek", calendarData);
        return calendarData;
    }

    static final String[] FORMAT_DATA_ELEMENTS = {
        "MonthNames",
        "standalone.MonthNames",
        "MonthAbbreviations",
        "standalone.MonthAbbreviations",
        "MonthNarrows",
        "standalone.MonthNarrows",
        "DayNames",
        "standalone.DayNames",
        "DayAbbreviations",
        "standalone.DayAbbreviations",
        "DayNarrows",
        "standalone.DayNarrows",
        "QuarterNames",
        "standalone.QuarterNames",
        "QuarterAbbreviations",
        "standalone.QuarterAbbreviations",
        "QuarterNarrows",
        "standalone.QuarterNarrows",
        "AmPmMarkers",
        "narrow.AmPmMarkers",
        "long.Eras",
        "Eras",
        "narrow.Eras",
        "field.era",
        "field.year",
        "field.month",
        "field.week",
        "field.weekday",
        "field.dayperiod",
        "field.hour",
        "field.minute",
        "field.second",
        "field.zone",
        "TimePatterns",
        "DatePatterns",
        "DateTimePatterns",
        "DateTimePatternChars"
    };

    private static Map<String, Object> extractFormatData(Map map, String id) {
        Map<String, Object> formatData = new LinkedHashMap<>();
        for (CalendarType calendarType : CalendarType.values()) {
            String prefix = calendarType.keyElementName();
            for (String element : FORMAT_DATA_ELEMENTS) {
                String key = prefix + element;
                copyIfPresent(map, "java.time." + key, formatData);
                copyIfPresent(map, key, formatData);
            }
        }
        // Workaround for islamic-umalqura name support (JDK-8015986)
        switch (id) {
        case "ar":
            map.put(CLDRConverter.CALENDAR_NAME_PREFIX
                    + CalendarType.ISLAMIC_UMALQURA.lname(),
                    // derived from CLDR 24 draft
                    "\u0627\u0644\u062a\u0642\u0648\u064a\u0645 "
                    +"\u0627\u0644\u0625\u0633\u0644\u0627\u0645\u064a "
                    +"[\u0623\u0645 \u0627\u0644\u0642\u0631\u0649]");
            break;
        case "en":
            map.put(CLDRConverter.CALENDAR_NAME_PREFIX
                    + CalendarType.ISLAMIC_UMALQURA.lname(),
                    // derived from CLDR 24 draft
                    "Islamic Calendar [Umm al-Qura]");
            break;
        }
        // Copy available calendar names
        for (String key : map.keySet()) {
            if (key.startsWith(CLDRConverter.CALENDAR_NAME_PREFIX)) {
                String type = key.substring(CLDRConverter.CALENDAR_NAME_PREFIX.length());
                for (CalendarType calendarType : CalendarType.values()) {
                    if (type.equals(calendarType.lname())) {
                        Object value = map.get(key);
                        formatData.put(key, value);
                        String ukey = CLDRConverter.CALENDAR_NAME_PREFIX + calendarType.uname();
                        if (!key.equals(ukey)) {
                            formatData.put(ukey, value);
                        }
                    }
                }
            }
        }

        copyIfPresent(map, "DefaultNumberingSystem", formatData);

        @SuppressWarnings("unchecked")
        List<String> numberingScripts = (List) map.remove("numberingScripts");
        if (numberingScripts != null) {
            for (String script : numberingScripts) {
                copyIfPresent(map, script + "." + "NumberElements", formatData);
            }
        } else {
            copyIfPresent(map, "NumberElements", formatData);
        }
        copyIfPresent(map, "NumberPatterns", formatData);
        return formatData;
    }

    private static void copyIfPresent(Map<String, Object> src, String key, Map dest) {
        Object value = src.get(key);
        if (value != null) {
            dest.put(key, value);
        }
    }

    // --- code below here is adapted from java.util.Properties ---
    private static final String specialSaveCharsJava = "\"";
    private static final String specialSaveCharsProperties = "=: \t\r\n\f#!";

    /*
     * Converts unicodes to encoded \uxxxx
     * and writes out any of the characters in specialSaveChars
     * with a preceding slash
     */
    static String saveConvert(String theString, boolean useJava) {
        if (theString == null) {
            return "";
        }

        String specialSaveChars;
        if (useJava) {
            specialSaveChars = specialSaveCharsJava;
        } else {
            specialSaveChars = specialSaveCharsProperties;
        }
        boolean escapeSpace = false;

        int len = theString.length();
        StringBuilder outBuffer = new StringBuilder(len * 2);
        Formatter formatter = new Formatter(outBuffer, Locale.ROOT);

        for (int x = 0; x < len; x++) {
            char aChar = theString.charAt(x);
            switch (aChar) {
            case ' ':
                if (x == 0 || escapeSpace) {
                    outBuffer.append('\\');
                }
                outBuffer.append(' ');
                break;
            case '\\':
                outBuffer.append('\\');
                outBuffer.append('\\');
                break;
            case '\t':
                outBuffer.append('\\');
                outBuffer.append('t');
                break;
            case '\n':
                outBuffer.append('\\');
                outBuffer.append('n');
                break;
            case '\r':
                outBuffer.append('\\');
                outBuffer.append('r');
                break;
            case '\f':
                outBuffer.append('\\');
                outBuffer.append('f');
                break;
            default:
                if (aChar < 0x0020 || (!USE_UTF8 && aChar > 0x007e)) {
                    formatter.format("\\u%04x", (int)aChar);
                } else {
                    if (specialSaveChars.indexOf(aChar) != -1) {
                        outBuffer.append('\\');
                    }
                    outBuffer.append(aChar);
                }
            }
        }
        return outBuffer.toString();
    }

    private static String toLanguageTag(String locName) {
        if (locName.indexOf('_') == -1) {
            return locName;
        }
        String tag = locName.replaceAll("_", "-");
        Locale loc = Locale.forLanguageTag(tag);
        return loc.toLanguageTag();
    }

    private static String toLocaleName(String tag) {
        if (tag.indexOf('-') == -1) {
            return tag;
        }
        return tag.replaceAll("-", "_");
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java CLDRConverter.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.