jdk/src/share/classes/sun/util/locale/InternalLocaleBuilder.java
author okutsu
Thu, 14 Apr 2011 15:59:47 +0900
changeset 9224 75c0420badef
parent 6501 684810d882b3
permissions -rw-r--r--
7028818: (lc) Lazily initialize locale extension 7029740: (lc) New Locale class implementation doesn't follow the Java coding conventions 7032820: (lc) sun.util.locale.InternalLocaleBuilder.CaseInsensitiveChar.equals problems 7033503: (lc) Restore optimization code for Locale class initialization 7033504: (lc) incompatible behavior change for ja_JP_JP and th_TH_TH locales Reviewed-by: naoto
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
     1
/*
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
     2
 * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
     4
 *
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    10
 *
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    15
 * accompanied this code).
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    16
 *
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    20
 *
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    23
 * questions.
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    24
 */
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    25
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    26
/*
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    27
 *******************************************************************************
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    28
 * Copyright (C) 2009-2010, International Business Machines Corporation and    *
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    29
 * others. All Rights Reserved.                                                *
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    30
 *******************************************************************************
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    31
 */
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    32
package sun.util.locale;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    33
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    34
import java.util.ArrayList;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    35
import java.util.HashMap;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    36
import java.util.HashSet;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    37
import java.util.List;
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    38
import java.util.Map;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    39
import java.util.Set;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    40
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    41
public final class InternalLocaleBuilder {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    42
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    43
    private static final CaseInsensitiveChar PRIVATEUSE_KEY
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    44
        = new CaseInsensitiveChar(LanguageTag.PRIVATEUSE);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    45
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    46
    private String language = "";
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    47
    private String script = "";
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    48
    private String region = "";
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    49
    private String variant = "";
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    50
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    51
    private Map<CaseInsensitiveChar, String> extensions;
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    52
    private Set<CaseInsensitiveString> uattributes;
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    53
    private Map<CaseInsensitiveString, String> ukeywords;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    54
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    55
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    56
    public InternalLocaleBuilder() {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    57
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    58
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    59
    public InternalLocaleBuilder setLanguage(String language) throws LocaleSyntaxException {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    60
        if (LocaleUtils.isEmpty(language)) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    61
            this.language = "";
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    62
        } else {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    63
            if (!LanguageTag.isLanguage(language)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    64
                throw new LocaleSyntaxException("Ill-formed language: " + language, 0);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    65
            }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    66
            this.language = language;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    67
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    68
        return this;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    69
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    70
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    71
    public InternalLocaleBuilder setScript(String script) throws LocaleSyntaxException {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    72
        if (LocaleUtils.isEmpty(script)) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    73
            this.script = "";
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    74
        } else {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    75
            if (!LanguageTag.isScript(script)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    76
                throw new LocaleSyntaxException("Ill-formed script: " + script, 0);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    77
            }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    78
            this.script = script;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    79
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    80
        return this;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    81
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    82
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    83
    public InternalLocaleBuilder setRegion(String region) throws LocaleSyntaxException {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    84
        if (LocaleUtils.isEmpty(region)) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    85
            this.region = "";
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    86
        } else {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    87
            if (!LanguageTag.isRegion(region)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    88
                throw new LocaleSyntaxException("Ill-formed region: " + region, 0);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    89
            }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    90
            this.region = region;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    91
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    92
        return this;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    93
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    94
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    95
    public InternalLocaleBuilder setVariant(String variant) throws LocaleSyntaxException {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    96
        if (LocaleUtils.isEmpty(variant)) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
    97
            this.variant = "";
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    98
        } else {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
    99
            // normalize separators to "_"
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   100
            String var = variant.replaceAll(LanguageTag.SEP, BaseLocale.SEP);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   101
            int errIdx = checkVariants(var, BaseLocale.SEP);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   102
            if (errIdx != -1) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   103
                throw new LocaleSyntaxException("Ill-formed variant: " + variant, errIdx);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   104
            }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   105
            this.variant = var;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   106
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   107
        return this;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   108
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   109
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   110
    public InternalLocaleBuilder addUnicodeLocaleAttribute(String attribute) throws LocaleSyntaxException {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   111
        if (!UnicodeLocaleExtension.isAttribute(attribute)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   112
            throw new LocaleSyntaxException("Ill-formed Unicode locale attribute: " + attribute);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   113
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   114
        // Use case insensitive string to prevent duplication
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   115
        if (uattributes == null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   116
            uattributes = new HashSet<>(4);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   117
        }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   118
        uattributes.add(new CaseInsensitiveString(attribute));
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   119
        return this;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   120
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   121
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   122
    public InternalLocaleBuilder removeUnicodeLocaleAttribute(String attribute) throws LocaleSyntaxException {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   123
        if (attribute == null || !UnicodeLocaleExtension.isAttribute(attribute)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   124
            throw new LocaleSyntaxException("Ill-formed Unicode locale attribute: " + attribute);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   125
        }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   126
        if (uattributes != null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   127
            uattributes.remove(new CaseInsensitiveString(attribute));
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   128
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   129
        return this;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   130
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   131
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   132
    public InternalLocaleBuilder setUnicodeLocaleKeyword(String key, String type) throws LocaleSyntaxException {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   133
        if (!UnicodeLocaleExtension.isKey(key)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   134
            throw new LocaleSyntaxException("Ill-formed Unicode locale keyword key: " + key);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   135
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   136
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   137
        CaseInsensitiveString cikey = new CaseInsensitiveString(key);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   138
        if (type == null) {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   139
            if (ukeywords != null) {
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   140
                // null type is used for remove the key
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   141
                ukeywords.remove(cikey);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   142
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   143
        } else {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   144
            if (type.length() != 0) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   145
                // normalize separator to "-"
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   146
                String tp = type.replaceAll(BaseLocale.SEP, LanguageTag.SEP);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   147
                // validate
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   148
                StringTokenIterator itr = new StringTokenIterator(tp, LanguageTag.SEP);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   149
                while (!itr.isDone()) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   150
                    String s = itr.current();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   151
                    if (!UnicodeLocaleExtension.isTypeSubtag(s)) {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   152
                        throw new LocaleSyntaxException("Ill-formed Unicode locale keyword type: "
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   153
                                                        + type,
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   154
                                                        itr.currentStart());
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   155
                    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   156
                    itr.next();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   157
                }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   158
            }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   159
            if (ukeywords == null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   160
                ukeywords = new HashMap<>(4);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   161
            }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   162
            ukeywords.put(cikey, type);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   163
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   164
        return this;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   165
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   166
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   167
    public InternalLocaleBuilder setExtension(char singleton, String value) throws LocaleSyntaxException {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   168
        // validate key
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   169
        boolean isBcpPrivateuse = LanguageTag.isPrivateusePrefixChar(singleton);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   170
        if (!isBcpPrivateuse && !LanguageTag.isExtensionSingletonChar(singleton)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   171
            throw new LocaleSyntaxException("Ill-formed extension key: " + singleton);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   172
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   173
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   174
        boolean remove = LocaleUtils.isEmpty(value);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   175
        CaseInsensitiveChar key = new CaseInsensitiveChar(singleton);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   176
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   177
        if (remove) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   178
            if (UnicodeLocaleExtension.isSingletonChar(key.value())) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   179
                // clear entire Unicode locale extension
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   180
                if (uattributes != null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   181
                    uattributes.clear();
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   182
                }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   183
                if (ukeywords != null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   184
                    ukeywords.clear();
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   185
                }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   186
            } else {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   187
                if (extensions != null && extensions.containsKey(key)) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   188
                    extensions.remove(key);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   189
                }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   190
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   191
        } else {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   192
            // validate value
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   193
            String val = value.replaceAll(BaseLocale.SEP, LanguageTag.SEP);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   194
            StringTokenIterator itr = new StringTokenIterator(val, LanguageTag.SEP);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   195
            while (!itr.isDone()) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   196
                String s = itr.current();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   197
                boolean validSubtag;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   198
                if (isBcpPrivateuse) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   199
                    validSubtag = LanguageTag.isPrivateuseSubtag(s);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   200
                } else {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   201
                    validSubtag = LanguageTag.isExtensionSubtag(s);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   202
                }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   203
                if (!validSubtag) {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   204
                    throw new LocaleSyntaxException("Ill-formed extension value: " + s,
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   205
                                                    itr.currentStart());
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   206
                }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   207
                itr.next();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   208
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   209
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   210
            if (UnicodeLocaleExtension.isSingletonChar(key.value())) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   211
                setUnicodeLocaleExtension(val);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   212
            } else {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   213
                if (extensions == null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   214
                    extensions = new HashMap<>(4);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   215
                }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   216
                extensions.put(key, val);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   217
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   218
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   219
        return this;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   220
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   221
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   222
    /*
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   223
     * Set extension/private subtags in a single string representation
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   224
     */
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   225
    public InternalLocaleBuilder setExtensions(String subtags) throws LocaleSyntaxException {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   226
        if (LocaleUtils.isEmpty(subtags)) {
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   227
            clearExtensions();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   228
            return this;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   229
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   230
        subtags = subtags.replaceAll(BaseLocale.SEP, LanguageTag.SEP);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   231
        StringTokenIterator itr = new StringTokenIterator(subtags, LanguageTag.SEP);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   232
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   233
        List<String> extensions = null;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   234
        String privateuse = null;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   235
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   236
        int parsed = 0;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   237
        int start;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   238
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   239
        // Make a list of extension subtags
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   240
        while (!itr.isDone()) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   241
            String s = itr.current();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   242
            if (LanguageTag.isExtensionSingleton(s)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   243
                start = itr.currentStart();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   244
                String singleton = s;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   245
                StringBuilder sb = new StringBuilder(singleton);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   246
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   247
                itr.next();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   248
                while (!itr.isDone()) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   249
                    s = itr.current();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   250
                    if (LanguageTag.isExtensionSubtag(s)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   251
                        sb.append(LanguageTag.SEP).append(s);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   252
                        parsed = itr.currentEnd();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   253
                    } else {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   254
                        break;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   255
                    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   256
                    itr.next();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   257
                }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   258
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   259
                if (parsed < start) {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   260
                    throw new LocaleSyntaxException("Incomplete extension '" + singleton + "'",
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   261
                                                    start);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   262
                }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   263
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   264
                if (extensions == null) {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   265
                    extensions = new ArrayList<>(4);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   266
                }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   267
                extensions.add(sb.toString());
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   268
            } else {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   269
                break;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   270
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   271
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   272
        if (!itr.isDone()) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   273
            String s = itr.current();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   274
            if (LanguageTag.isPrivateusePrefix(s)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   275
                start = itr.currentStart();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   276
                StringBuilder sb = new StringBuilder(s);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   277
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   278
                itr.next();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   279
                while (!itr.isDone()) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   280
                    s = itr.current();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   281
                    if (!LanguageTag.isPrivateuseSubtag(s)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   282
                        break;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   283
                    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   284
                    sb.append(LanguageTag.SEP).append(s);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   285
                    parsed = itr.currentEnd();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   286
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   287
                    itr.next();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   288
                }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   289
                if (parsed <= start) {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   290
                    throw new LocaleSyntaxException("Incomplete privateuse:"
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   291
                                                    + subtags.substring(start),
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   292
                                                    start);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   293
                } else {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   294
                    privateuse = sb.toString();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   295
                }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   296
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   297
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   298
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   299
        if (!itr.isDone()) {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   300
            throw new LocaleSyntaxException("Ill-formed extension subtags:"
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   301
                                            + subtags.substring(itr.currentStart()),
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   302
                                            itr.currentStart());
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   303
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   304
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   305
        return setExtensions(extensions, privateuse);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   306
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   307
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   308
    /*
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   309
     * Set a list of BCP47 extensions and private use subtags
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   310
     * BCP47 extensions are already validated and well-formed, but may contain duplicates
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   311
     */
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   312
    private InternalLocaleBuilder setExtensions(List<String> bcpExtensions, String privateuse) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   313
        clearExtensions();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   314
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   315
        if (!LocaleUtils.isEmpty(bcpExtensions)) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   316
            Set<CaseInsensitiveChar> done = new HashSet<>(bcpExtensions.size());
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   317
            for (String bcpExt : bcpExtensions) {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   318
                CaseInsensitiveChar key = new CaseInsensitiveChar(bcpExt);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   319
                // ignore duplicates
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   320
                if (!done.contains(key)) {
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   321
                    // each extension string contains singleton, e.g. "a-abc-def"
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   322
                    if (UnicodeLocaleExtension.isSingletonChar(key.value())) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   323
                        setUnicodeLocaleExtension(bcpExt.substring(2));
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   324
                    } else {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   325
                        if (extensions == null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   326
                            extensions = new HashMap<>(4);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   327
                        }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   328
                        extensions.put(key, bcpExt.substring(2));
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   329
                    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   330
                }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   331
                done.add(key);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   332
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   333
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   334
        if (privateuse != null && privateuse.length() > 0) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   335
            // privateuse string contains prefix, e.g. "x-abc-def"
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   336
            if (extensions == null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   337
                extensions = new HashMap<>(1);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   338
            }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   339
            extensions.put(new CaseInsensitiveChar(privateuse), privateuse.substring(2));
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   340
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   341
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   342
        return this;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   343
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   344
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   345
    /*
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   346
     * Reset Builder's internal state with the given language tag
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   347
     */
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   348
    public InternalLocaleBuilder setLanguageTag(LanguageTag langtag) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   349
        clear();
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   350
        if (!langtag.getExtlangs().isEmpty()) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   351
            language = langtag.getExtlangs().get(0);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   352
        } else {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   353
            String lang = langtag.getLanguage();
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   354
            if (!lang.equals(LanguageTag.UNDETERMINED)) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   355
                language = lang;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   356
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   357
        }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   358
        script = langtag.getScript();
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   359
        region = langtag.getRegion();
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   360
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   361
        List<String> bcpVariants = langtag.getVariants();
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   362
        if (!bcpVariants.isEmpty()) {
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   363
            StringBuilder var = new StringBuilder(bcpVariants.get(0));
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   364
            int size = bcpVariants.size();
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   365
            for (int i = 1; i < size; i++) {
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   366
                var.append(BaseLocale.SEP).append(bcpVariants.get(i));
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   367
            }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   368
            variant = var.toString();
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   369
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   370
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   371
        setExtensions(langtag.getExtensions(), langtag.getPrivateuse());
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   372
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   373
        return this;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   374
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   375
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   376
    public InternalLocaleBuilder setLocale(BaseLocale base, LocaleExtensions localeExtensions) throws LocaleSyntaxException {
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   377
        String language = base.getLanguage();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   378
        String script = base.getScript();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   379
        String region = base.getRegion();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   380
        String variant = base.getVariant();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   381
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   382
        // Special backward compatibility support
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   383
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   384
        // Exception 1 - ja_JP_JP
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   385
        if (language.equals("ja") && region.equals("JP") && variant.equals("JP")) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   386
            // When locale ja_JP_JP is created, ca-japanese is always there.
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   387
            // The builder ignores the variant "JP"
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   388
            assert("japanese".equals(localeExtensions.getUnicodeLocaleType("ca")));
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   389
            variant = "";
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   390
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   391
        // Exception 2 - th_TH_TH
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   392
        else if (language.equals("th") && region.equals("TH") && variant.equals("TH")) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   393
            // When locale th_TH_TH is created, nu-thai is always there.
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   394
            // The builder ignores the variant "TH"
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   395
            assert("thai".equals(localeExtensions.getUnicodeLocaleType("nu")));
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   396
            variant = "";
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   397
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   398
        // Exception 3 - no_NO_NY
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   399
        else if (language.equals("no") && region.equals("NO") && variant.equals("NY")) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   400
            // no_NO_NY is a valid locale and used by Java 6 or older versions.
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   401
            // The build ignores the variant "NY" and change the language to "nn".
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   402
            language = "nn";
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   403
            variant = "";
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   404
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   405
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   406
        // Validate base locale fields before updating internal state.
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   407
        // LocaleExtensions always store validated/canonicalized values,
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   408
        // so no checks are necessary.
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   409
        if (language.length() > 0 && !LanguageTag.isLanguage(language)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   410
            throw new LocaleSyntaxException("Ill-formed language: " + language);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   411
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   412
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   413
        if (script.length() > 0 && !LanguageTag.isScript(script)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   414
            throw new LocaleSyntaxException("Ill-formed script: " + script);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   415
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   416
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   417
        if (region.length() > 0 && !LanguageTag.isRegion(region)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   418
            throw new LocaleSyntaxException("Ill-formed region: " + region);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   419
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   420
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   421
        if (variant.length() > 0) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   422
            int errIdx = checkVariants(variant, BaseLocale.SEP);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   423
            if (errIdx != -1) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   424
                throw new LocaleSyntaxException("Ill-formed variant: " + variant, errIdx);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   425
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   426
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   427
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   428
        // The input locale is validated at this point.
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   429
        // Now, updating builder's internal fields.
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   430
        this.language = language;
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   431
        this.script = script;
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   432
        this.region = region;
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   433
        this.variant = variant;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   434
        clearExtensions();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   435
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   436
        Set<Character> extKeys = (localeExtensions == null) ? null : localeExtensions.getKeys();
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   437
        if (extKeys != null) {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   438
            // map localeExtensions back to builder's internal format
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   439
            for (Character key : extKeys) {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   440
                Extension e = localeExtensions.getExtension(key);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   441
                if (e instanceof UnicodeLocaleExtension) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   442
                    UnicodeLocaleExtension ue = (UnicodeLocaleExtension)e;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   443
                    for (String uatr : ue.getUnicodeLocaleAttributes()) {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   444
                        if (uattributes == null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   445
                            uattributes = new HashSet<>(4);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   446
                        }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   447
                        uattributes.add(new CaseInsensitiveString(uatr));
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   448
                    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   449
                    for (String ukey : ue.getUnicodeLocaleKeys()) {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   450
                        if (ukeywords == null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   451
                            ukeywords = new HashMap<>(4);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   452
                        }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   453
                        ukeywords.put(new CaseInsensitiveString(ukey), ue.getUnicodeLocaleType(ukey));
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   454
                    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   455
                } else {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   456
                    if (extensions == null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   457
                        extensions = new HashMap<>(4);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   458
                    }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   459
                    extensions.put(new CaseInsensitiveChar(key), e.getValue());
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   460
                }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   461
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   462
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   463
        return this;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   464
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   465
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   466
    public InternalLocaleBuilder clear() {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   467
        language = "";
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   468
        script = "";
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   469
        region = "";
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   470
        variant = "";
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   471
        clearExtensions();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   472
        return this;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   473
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   474
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   475
    public InternalLocaleBuilder clearExtensions() {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   476
        if (extensions != null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   477
            extensions.clear();
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   478
        }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   479
        if (uattributes != null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   480
            uattributes.clear();
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   481
        }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   482
        if (ukeywords != null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   483
            ukeywords.clear();
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   484
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   485
        return this;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   486
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   487
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   488
    public BaseLocale getBaseLocale() {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   489
        String language = this.language;
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   490
        String script = this.script;
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   491
        String region = this.region;
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   492
        String variant = this.variant;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   493
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   494
        // Special private use subtag sequence identified by "lvariant" will be
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   495
        // interpreted as Java variant.
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   496
        if (extensions != null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   497
            String privuse = extensions.get(PRIVATEUSE_KEY);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   498
            if (privuse != null) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   499
                StringTokenIterator itr = new StringTokenIterator(privuse, LanguageTag.SEP);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   500
                boolean sawPrefix = false;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   501
                int privVarStart = -1;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   502
                while (!itr.isDone()) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   503
                    if (sawPrefix) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   504
                        privVarStart = itr.currentStart();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   505
                        break;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   506
                    }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   507
                    if (LocaleUtils.caseIgnoreMatch(itr.current(), LanguageTag.PRIVUSE_VARIANT_PREFIX)) {
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   508
                        sawPrefix = true;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   509
                    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   510
                    itr.next();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   511
                }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   512
                if (privVarStart != -1) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   513
                    StringBuilder sb = new StringBuilder(variant);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   514
                    if (sb.length() != 0) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   515
                        sb.append(BaseLocale.SEP);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   516
                    }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   517
                    sb.append(privuse.substring(privVarStart).replaceAll(LanguageTag.SEP,
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   518
                                                                         BaseLocale.SEP));
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   519
                    variant = sb.toString();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   520
                }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   521
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   522
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   523
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   524
        return BaseLocale.getInstance(language, script, region, variant);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   525
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   526
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   527
    public LocaleExtensions getLocaleExtensions() {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   528
        if (LocaleUtils.isEmpty(extensions) && LocaleUtils.isEmpty(uattributes)
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   529
            && LocaleUtils.isEmpty(ukeywords)) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   530
            return null;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   531
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   532
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   533
        LocaleExtensions lext = new LocaleExtensions(extensions, uattributes, ukeywords);
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   534
        return lext.isEmpty() ? null : lext;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   535
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   536
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   537
    /*
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   538
     * Remove special private use subtag sequence identified by "lvariant"
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   539
     * and return the rest. Only used by LocaleExtensions
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   540
     */
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   541
    static String removePrivateuseVariant(String privuseVal) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   542
        StringTokenIterator itr = new StringTokenIterator(privuseVal, LanguageTag.SEP);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   543
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   544
        // Note: privateuse value "abc-lvariant" is unchanged
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   545
        // because no subtags after "lvariant".
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   546
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   547
        int prefixStart = -1;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   548
        boolean sawPrivuseVar = false;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   549
        while (!itr.isDone()) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   550
            if (prefixStart != -1) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   551
                // Note: privateuse value "abc-lvariant" is unchanged
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   552
                // because no subtags after "lvariant".
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   553
                sawPrivuseVar = true;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   554
                break;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   555
            }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   556
            if (LocaleUtils.caseIgnoreMatch(itr.current(), LanguageTag.PRIVUSE_VARIANT_PREFIX)) {
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   557
                prefixStart = itr.currentStart();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   558
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   559
            itr.next();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   560
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   561
        if (!sawPrivuseVar) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   562
            return privuseVal;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   563
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   564
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   565
        assert(prefixStart == 0 || prefixStart > 1);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   566
        return (prefixStart == 0) ? null : privuseVal.substring(0, prefixStart -1);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   567
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   568
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   569
    /*
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   570
     * Check if the given variant subtags separated by the given
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   571
     * separator(s) are valid
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   572
     */
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   573
    private int checkVariants(String variants, String sep) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   574
        StringTokenIterator itr = new StringTokenIterator(variants, sep);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   575
        while (!itr.isDone()) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   576
            String s = itr.current();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   577
            if (!LanguageTag.isVariant(s)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   578
                return itr.currentStart();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   579
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   580
            itr.next();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   581
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   582
        return -1;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   583
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   584
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   585
    /*
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   586
     * Private methods parsing Unicode Locale Extension subtags.
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   587
     * Duplicated attributes/keywords will be ignored.
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   588
     * The input must be a valid extension subtags (excluding singleton).
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   589
     */
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   590
    private void setUnicodeLocaleExtension(String subtags) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   591
        // wipe out existing attributes/keywords
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   592
        if (uattributes != null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   593
            uattributes.clear();
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   594
        }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   595
        if (ukeywords != null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   596
            ukeywords.clear();
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   597
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   598
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   599
        StringTokenIterator itr = new StringTokenIterator(subtags, LanguageTag.SEP);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   600
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   601
        // parse attributes
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   602
        while (!itr.isDone()) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   603
            if (!UnicodeLocaleExtension.isAttribute(itr.current())) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   604
                break;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   605
            }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   606
            if (uattributes == null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   607
                uattributes = new HashSet<>(4);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   608
            }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   609
            uattributes.add(new CaseInsensitiveString(itr.current()));
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   610
            itr.next();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   611
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   612
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   613
        // parse keywords
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   614
        CaseInsensitiveString key = null;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   615
        String type;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   616
        int typeStart = -1;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   617
        int typeEnd = -1;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   618
        while (!itr.isDone()) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   619
            if (key != null) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   620
                if (UnicodeLocaleExtension.isKey(itr.current())) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   621
                    // next keyword - emit previous one
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   622
                    assert(typeStart == -1 || typeEnd != -1);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   623
                    type = (typeStart == -1) ? "" : subtags.substring(typeStart, typeEnd);
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   624
                    if (ukeywords == null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   625
                        ukeywords = new HashMap<>(4);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   626
                    }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   627
                    ukeywords.put(key, type);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   628
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   629
                    // reset keyword info
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   630
                    CaseInsensitiveString tmpKey = new CaseInsensitiveString(itr.current());
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   631
                    key = ukeywords.containsKey(tmpKey) ? null : tmpKey;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   632
                    typeStart = typeEnd = -1;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   633
                } else {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   634
                    if (typeStart == -1) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   635
                        typeStart = itr.currentStart();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   636
                    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   637
                    typeEnd = itr.currentEnd();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   638
                }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   639
            } else if (UnicodeLocaleExtension.isKey(itr.current())) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   640
                // 1. first keyword or
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   641
                // 2. next keyword, but previous one was duplicate
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   642
                key = new CaseInsensitiveString(itr.current());
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   643
                if (ukeywords != null && ukeywords.containsKey(key)) {
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   644
                    // duplicate
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   645
                    key = null;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   646
                }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   647
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   648
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   649
            if (!itr.hasNext()) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   650
                if (key != null) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   651
                    // last keyword
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   652
                    assert(typeStart == -1 || typeEnd != -1);
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   653
                    type = (typeStart == -1) ? "" : subtags.substring(typeStart, typeEnd);
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   654
                    if (ukeywords == null) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   655
                        ukeywords = new HashMap<>(4);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   656
                    }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   657
                    ukeywords.put(key, type);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   658
                }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   659
                break;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   660
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   661
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   662
            itr.next();
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   663
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   664
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   665
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   666
    static final class CaseInsensitiveString {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   667
        private final String str, lowerStr;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   668
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   669
        CaseInsensitiveString(String s) {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   670
            str = s;
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   671
            lowerStr = LocaleUtils.toLowerString(s);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   672
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   673
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   674
        public String value() {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   675
            return str;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   676
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   677
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   678
        @Override
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   679
        public int hashCode() {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   680
            return lowerStr.hashCode();
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   681
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   682
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   683
        @Override
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   684
        public boolean equals(Object obj) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   685
            if (this == obj) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   686
                return true;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   687
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   688
            if (!(obj instanceof CaseInsensitiveString)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   689
                return false;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   690
            }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   691
            return lowerStr.equals(((CaseInsensitiveString)obj).lowerStr);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   692
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   693
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   694
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   695
    static final class CaseInsensitiveChar {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   696
        private final char ch, lowerCh;
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   697
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   698
        /**
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   699
         * Constructs a CaseInsensitiveChar with the first char of the
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   700
         * given s.
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   701
         */
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   702
        private CaseInsensitiveChar(String s) {
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   703
            this(s.charAt(0));
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   704
        }
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   705
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   706
        CaseInsensitiveChar(char c) {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   707
            ch = c;
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   708
            lowerCh = LocaleUtils.toLower(ch);
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   709
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   710
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   711
        public char value() {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   712
            return ch;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   713
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   714
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   715
        @Override
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   716
        public int hashCode() {
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   717
            return lowerCh;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   718
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   719
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   720
        @Override
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   721
        public boolean equals(Object obj) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   722
            if (this == obj) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   723
                return true;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   724
            }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   725
            if (!(obj instanceof CaseInsensitiveChar)) {
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   726
                return false;
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   727
            }
9224
75c0420badef 7028818: (lc) Lazily initialize locale extension
okutsu
parents: 6501
diff changeset
   728
            return lowerCh == ((CaseInsensitiveChar)obj).lowerCh;
6501
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   729
        }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   730
    }
684810d882b3 6875847: Java Locale Enhancement
naoto
parents:
diff changeset
   731
}