1c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com/*
2c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com * Copyright (C) 2010 Google Inc.
3c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com *
4c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com * Licensed under the Apache License, Version 2.0 (the "License");
5c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com * you may not use this file except in compliance with the License.
6c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com * You may obtain a copy of the License at
7c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com *
8c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com * http://www.apache.org/licenses/LICENSE-2.0
9c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com *
10c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com * Unless required by applicable law or agreed to in writing, software
11c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com * distributed under the License is distributed on an "AS IS" BASIS,
12c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com * See the License for the specific language governing permissions and
14c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com * limitations under the License.
15c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com */
16c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com
17c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.compackage com.android.i18n.addressinput;
18c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com
19e581f4e9ec75938f121408ee600436c8ea865facjeanine@google.comimport java.util.HashMap;
20d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.comimport java.util.Locale;
21e581f4e9ec75938f121408ee600436c8ea865facjeanine@google.comimport java.util.Map;
22c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.comimport java.util.regex.Matcher;
23c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.comimport java.util.regex.Pattern;
24c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com
25c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com/**
26c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com * Utility functions used by the address widget.
27c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com */
28dc4cdad9dd71a57be66262d1d6d46a09c0973818lararennie@google.comclass Util {
29d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com    /**
30d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com     * This variable is in upper-case, since we convert the language code to upper case before doing
31d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com     * string comparison.
32d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com     */
338e2da504b1faa2c9de66e363fc77e60a2a766a77shaopengjia@google.com    private static final String LATIN_SCRIPT = "LATN";
342c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
35d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com    /**
365637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com     * Map of countries that have non-latin local names, with the language that their local names
375637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com     * are in. We only list a country here if we have the appropriate data. Only language sub-tags
385637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com     * are listed.
395637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com     */
405637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com     private static final Map<String, String> nonLatinLocalLanguageCountries =
415637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com             new HashMap<String, String>();
425637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com     static {
435637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com       nonLatinLocalLanguageCountries.put("AM", "hy");
445637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com       nonLatinLocalLanguageCountries.put("CN", "zh");
455637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com       nonLatinLocalLanguageCountries.put("HK", "zh");
465637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com       nonLatinLocalLanguageCountries.put("JP", "ja");
475637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com       nonLatinLocalLanguageCountries.put("KP", "ko");
485637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com       nonLatinLocalLanguageCountries.put("KR", "ko");
495637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com       nonLatinLocalLanguageCountries.put("MO", "zh");
505637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com       nonLatinLocalLanguageCountries.put("TH", "th");
515637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com       nonLatinLocalLanguageCountries.put("TW", "zh");
525637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com       nonLatinLocalLanguageCountries.put("VN", "vi");
535637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com     }
545637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com
555637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com    /**
56d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com     * Cannot instantiate this class - private constructor.
57d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com     */
582c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    private Util() {
599d0dbefd0fd3cfdccb2509ccbd7c216b01dd44d4lararennie@google.com    }
602c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
612c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    /**
622c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * Returns true if the language code is explicitly marked to be in the latin script. For
632c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * example, "zh-Latn" would return true, but "zh-TW", "en" and "zh" would all return false.
642c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     */
65dc4cdad9dd71a57be66262d1d6d46a09c0973818lararennie@google.com    static boolean isExplicitLatinScript(String languageCode) {
662c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        // Convert to upper-case for easier comparison.
672c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        languageCode = languageCode.toUpperCase();
682c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        // Check to see if the language code contains a script modifier.
692c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        final Pattern languageCodePattern = Pattern.compile("\\w{2,3}[-_](\\w{4})");
702c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        Matcher m = languageCodePattern.matcher(languageCode);
712c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        if (m.lookingAt()) {
722c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            String script = m.group(1);
738e2da504b1faa2c9de66e363fc77e60a2a766a77shaopengjia@google.com            if (script.equals(LATIN_SCRIPT)) {
742c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com                return true;
752c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            }
769d0dbefd0fd3cfdccb2509ccbd7c216b01dd44d4lararennie@google.com        }
772c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        return false;
789d0dbefd0fd3cfdccb2509ccbd7c216b01dd44d4lararennie@google.com    }
79e581f4e9ec75938f121408ee600436c8ea865facjeanine@google.com
802c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    /**
812c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * Returns the language subtag of a language code. For example, returns "zh" if given "zh-Hans",
822c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * "zh-CN" or other "zh" variants. If no language subtag can be found or the language tag is
832c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * malformed, returns "und".
842c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     */
85dc4cdad9dd71a57be66262d1d6d46a09c0973818lararennie@google.com    static String getLanguageSubtag(String languageCode) {
862c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        final Pattern languageCodePattern = Pattern
872c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com                .compile("(\\w{2,3})(?:[-_]\\w{4})?(?:[-_]\\w{2})?");
882c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        Matcher m = languageCodePattern.matcher(languageCode);
892c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        if (m.matches()) {
902c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            return m.group(1).toLowerCase();
912c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        }
922c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        return "und";
93e581f4e9ec75938f121408ee600436c8ea865facjeanine@google.com    }
94e581f4e9ec75938f121408ee600436c8ea865facjeanine@google.com
952c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    /**
962c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * Trims the string. If the field is empty after trimming, returns null instead. Note that this
972c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * only trims ASCII white-space.
982c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     */
99dc4cdad9dd71a57be66262d1d6d46a09c0973818lararennie@google.com    static String trimToNull(String originalStr) {
1002c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        if (originalStr == null) {
1012c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            return null;
1022c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        }
1032c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        String trimmedString = originalStr.trim();
1042c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        return (trimmedString.length() == 0) ? null : trimmedString;
1052c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    }
106e581f4e9ec75938f121408ee600436c8ea865facjeanine@google.com
1072c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    /**
1082c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * Throws an exception if the object is null, with a generic error message.
1092c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     */
110dc4cdad9dd71a57be66262d1d6d46a09c0973818lararennie@google.com    static void checkNotNull(Object o) throws NullPointerException {
1112c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        checkNotNull(o, "This object should not be null.");
112e581f4e9ec75938f121408ee600436c8ea865facjeanine@google.com    }
1132c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
1142c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    /**
1152c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * Throws an exception if the object is null, with the error message supplied.
1162c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     */
117dc4cdad9dd71a57be66262d1d6d46a09c0973818lararennie@google.com    static void checkNotNull(Object o, String message) throws NullPointerException {
1182c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        if (o == null) {
1192c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            throw new NullPointerException(message);
1202c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        }
121e581f4e9ec75938f121408ee600436c8ea865facjeanine@google.com    }
1222c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
1232c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    /**
1242c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     * Joins input string with the given separator. If an input string is null, it will be skipped.
1252c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com     */
126dc4cdad9dd71a57be66262d1d6d46a09c0973818lararennie@google.com    static String joinAndSkipNulls(String separator, String... strings) {
1272c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        StringBuilder sb = null;
1282c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        for (String s : strings) {
1292c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            if (s != null) {
1302c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com                s = s.trim();
1312c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com                if (s.length() > 0) {
1322c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com                    if (sb == null) {
1332c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com                        sb = new StringBuilder(s);
1342c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com                    } else {
1352c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com                        sb.append(separator).append(s);
1362c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com                    }
1372c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com                }
1382c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            }
1392c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        }
1402c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        return sb == null ? null : sb.toString();
141e581f4e9ec75938f121408ee600436c8ea865facjeanine@google.com    }
142e581f4e9ec75938f121408ee600436c8ea865facjeanine@google.com
143c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com    /**
144c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com     * Builds a map of the lower-cased values of the keys, names and local names provided. Each name
145c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com     * and local name is mapped to its respective key in the map.
146c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com     *
147c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com     * @throws IllegalStateException if the names or lnames array is greater than the keys array.
148c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com     */
149c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com    static Map<String, String> buildNameToKeyMap(String[] keys, String[] names, String[] lnames) {
1502c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        if (keys == null) {
1512c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            return null;
1522c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        }
1532c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
1542c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        Map<String, String> nameToKeyMap = new HashMap<String, String>();
1552c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com
156c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com        int keyLength = keys.length;
1572c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        for (String k : keys) {
1582c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            nameToKeyMap.put(k.toLowerCase(), k);
1592c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        }
1602c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        if (names != null) {
161c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com            if (names.length > keyLength) {
162c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com                throw new IllegalStateException(
163c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com                        "names length (" + names.length + ") is greater than keys length (" +
164c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com                        keys.length + ")");
1652c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            }
166c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com            for (int i = 0; i < keyLength; i++) {
1674846244b97f572c866738a8eef50e530cd73257ashaopengjia@google.com                // If we have less names than keys, we ignore all missing names. This happens
1684846244b97f572c866738a8eef50e530cd73257ashaopengjia@google.com                // generally because reg-ex splitting methods on different platforms (java, js etc)
1694846244b97f572c866738a8eef50e530cd73257ashaopengjia@google.com                // behave differently in the default case. Since missing names are fine, we opt to
1704846244b97f572c866738a8eef50e530cd73257ashaopengjia@google.com                // be more robust here.
171c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com                if (i < names.length && names[i].length() > 0) {
172c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com                    nameToKeyMap.put(names[i].toLowerCase(), keys[i]);
173c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com                }
1742c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            }
1752c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        }
1762c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        if (lnames != null) {
177c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com            if (lnames.length > keyLength) {
178c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com                throw new IllegalStateException(
179c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com                        "lnames length (" + lnames.length + ") is greater than keys length (" +
180c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com                        keys.length + ")");
1812c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            }
182c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com            for (int i = 0; i < keyLength; i++) {
183c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com                if (i < lnames.length && lnames[i].length() > 0) {
184c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com                    nameToKeyMap.put(lnames[i].toLowerCase(), keys[i]);
185c2ef0718b060e48a0be3614812418a099ce14e94lararennie@google.com                }
1862c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com            }
1872c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        }
1882c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com        return nameToKeyMap;
1892c25a6f4922225b619b0e389befde8b941e78834jeanine@google.com    }
190d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com
191d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com    /**
192d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com     * Returns a language code that the widget can use when fetching data, based on a {@link
193d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com     * java.util.Locale} language and the current selected country in the address widget. This
194d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com     * method is necessary since we have to determine later whether a language is "local" or "latin"
195d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com     * for certain countries.
196d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com     *
197d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com     * @param language the current user language
198d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com     * @param currentCountry the current selected country
199d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com     * @return a language code string in BCP-47 format (e.g. "en", "zh-Latn", "zh-Hans" or
200d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com     * "en-US").
201d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com     */
202dc4cdad9dd71a57be66262d1d6d46a09c0973818lararennie@google.com    static String getWidgetCompatibleLanguageCode(Locale language, String currentCountry) {
203d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com        String country = currentCountry.toUpperCase();
2045637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com        // Only do something if the country is one of those where we have names in the local
2055637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com        // language as well as in latin script.
206ef78db0965d48e641b59b3c6869a67498b527aaclararennie@google.com        if (nonLatinLocalLanguageCountries.containsKey(country)) {
207d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com            String languageTag = language.getLanguage();
2085637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com            // Only do something if the language tag is _not_ the local language.
209ef78db0965d48e641b59b3c6869a67498b527aaclararennie@google.com            if (!languageTag.equals(nonLatinLocalLanguageCountries.get(country))) {
210d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com                // Build up the language tag with the country and language specified, and add in the
2115637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com                // script-tag of "Latn" explicitly, since this is _not_ a local language. This means
2125637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com                // that we might create a language tag of "th-Latn", which is not what the actual
2135637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com                // language being used is, but it indicates that we prefer "Latn" names to whatever
2145637f80bc647fd2f977a78bd04c5ceb051203cb9lararennie@google.com                // the local alternative was.
215d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com                StringBuilder languageTagBuilder = new StringBuilder(languageTag);
216d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com                languageTagBuilder.append("_latn");
217d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com                if (language.getCountry().length() > 0) {
218d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com                    languageTagBuilder.append("_");
219d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com                    languageTagBuilder.append(language.getCountry());
220d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com                }
221d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com                return languageTagBuilder.toString();
222d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com            }
223d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com        }
224d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com        return language.toString();
225d6349bee985853d29d828e3f7ceee28763155a93lararennie@google.com    }
226c629d1d3e5a20c48141c73e5495959b7785e74bblararennie@google.com}
227