~ubuntu-branches/ubuntu/vivid/icu4j-4.4/vivid

« back to all changes in this revision

Viewing changes to main/classes/core/src/com/ibm/icu/impl/locale/InternalLocaleBuilder.java

  • Committer: Bazaar Package Importer
  • Author(s): Niels Thykier
  • Date: 2011-08-02 15:50:33 UTC
  • Revision ID: james.westby@ubuntu.com-20110802155033-itjzsl21y2lqdonn
Tags: upstream-4.4.2
ImportĀ upstreamĀ versionĀ 4.4.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *******************************************************************************
 
3
 * Copyright (C) 2009, International Business Machines Corporation and         *
 
4
 * others. All Rights Reserved.                                                *
 
5
 *******************************************************************************
 
6
 */
 
7
package com.ibm.icu.impl.locale;
 
8
 
 
9
import java.util.List;
 
10
import java.util.Set;
 
11
import java.util.SortedMap;
 
12
import java.util.TreeMap;
 
13
 
 
14
import com.ibm.icu.impl.locale.LanguageTag.ParseStatus;
 
15
 
 
16
public final class InternalLocaleBuilder {
 
17
 
 
18
    private String _language = "";
 
19
    private String _script = "";
 
20
    private String _region = "";
 
21
    private String _variant = "";
 
22
    private SortedMap<Character, Extension> _extMap;
 
23
 
 
24
    private final boolean _lenientVariant;
 
25
 
 
26
    private static final String LOCALESEP = "_";
 
27
 
 
28
    public InternalLocaleBuilder() {
 
29
        this(false);
 
30
    }
 
31
 
 
32
    public InternalLocaleBuilder(boolean lenientVariant) {
 
33
        _lenientVariant = lenientVariant;
 
34
    }
 
35
 
 
36
    public boolean isLenientVariant() {
 
37
        return _lenientVariant;
 
38
    }
 
39
 
 
40
    public InternalLocaleBuilder setLanguage(String language) throws LocaleSyntaxException {
 
41
        String newval = "";
 
42
        if (language.length() > 0) {
 
43
            if (!LanguageTag.isLanguage(language)) {
 
44
                throw new LocaleSyntaxException("Ill-formed language: " + language, 0);
 
45
            }
 
46
            newval = LanguageTag.canonicalizeLanguage(language);
 
47
        }
 
48
        _language = newval;
 
49
        return this;
 
50
    }
 
51
 
 
52
    public InternalLocaleBuilder setScript(String script) throws LocaleSyntaxException {
 
53
        String newval = "";
 
54
        if (script.length() > 0) {
 
55
            if (!LanguageTag.isScript(script)) {
 
56
                throw new LocaleSyntaxException("Ill-formed script: " + script, 0);
 
57
            }
 
58
            newval = LanguageTag.canonicalizeScript(script);
 
59
        }
 
60
        _script = newval;
 
61
        return this;
 
62
    }
 
63
 
 
64
    public InternalLocaleBuilder setRegion(String region) throws LocaleSyntaxException {
 
65
        String newval = "";
 
66
        if (region.length() > 0) {
 
67
            if (!LanguageTag.isRegion(region)) {
 
68
                throw new LocaleSyntaxException("Ill-formed region: " + region);
 
69
            }
 
70
            newval = LanguageTag.canonicalizeRegion(region);
 
71
        }
 
72
        _region = newval;
 
73
        return this;
 
74
    }
 
75
 
 
76
    public InternalLocaleBuilder setVariant(String variant) throws LocaleSyntaxException {
 
77
        String newval = "";
 
78
        if (variant.length() > 0) {
 
79
            if (_lenientVariant) {
 
80
                newval = variant;
 
81
            } else {
 
82
                newval = processVariant(variant);
 
83
            }
 
84
        }
 
85
        _variant = newval;
 
86
        return this;
 
87
    }
 
88
 
 
89
    public InternalLocaleBuilder setUnicodeLocaleExtension(String key, String type) throws LocaleSyntaxException {
 
90
        if (key.length() == 0) {
 
91
            throw new LocaleSyntaxException("Empty Unicode locale extension key");
 
92
        }
 
93
        if (!UnicodeLocaleExtension.isKey(key)) {
 
94
            throw new LocaleSyntaxException("Ill-formed Unicode locale extension key: " + key, 0);
 
95
        }
 
96
 
 
97
        key = UnicodeLocaleExtension.canonicalizeKey(key);
 
98
 
 
99
        UnicodeLocaleExtension ulext = null;
 
100
        if (_extMap != null) {
 
101
            ulext = (UnicodeLocaleExtension)_extMap.get(Character.valueOf(UnicodeLocaleExtension.SINGLETON));
 
102
        }
 
103
 
 
104
        if (type.length() == 0) {
 
105
            if (ulext != null) {
 
106
                ulext.remove(key);
 
107
                if (ulext.isEmpty()) {
 
108
                    _extMap.remove(Character.valueOf(UnicodeLocaleExtension.SINGLETON));
 
109
                }
 
110
            }
 
111
        } else {
 
112
            StringBuilder buf = new StringBuilder();
 
113
            StringTokenIterator sti = new StringTokenIterator(type, LanguageTag.SEP);
 
114
            for (String subtag = sti.first(); !sti.isDone(); subtag = sti.next()) {
 
115
                if (!UnicodeLocaleExtension.isTypeSubtag(subtag)) {
 
116
                    throw new LocaleSyntaxException("Ill-formed Unicode locale extension type: " + type, sti.currentStart());
 
117
                }
 
118
                if (buf.length() > 0) {
 
119
                    buf.append(LanguageTag.SEP);
 
120
                }
 
121
                buf.append(UnicodeLocaleExtension.canonicalizeTypeSubtag(subtag));
 
122
            }
 
123
            if (ulext == null) {
 
124
                SortedMap<String, String> ktmap = new TreeMap<String, String>();
 
125
                ktmap.put(key, buf.toString());
 
126
                ulext = new UnicodeLocaleExtension(ktmap);
 
127
                if (_extMap == null) {
 
128
                    _extMap = new TreeMap<Character, Extension>();
 
129
                }
 
130
                _extMap.put(Character.valueOf(UnicodeLocaleExtension.SINGLETON), ulext);
 
131
            } else {
 
132
                ulext.put(key, buf.toString());
 
133
            }
 
134
        }
 
135
 
 
136
        return this;
 
137
    }
 
138
 
 
139
    public InternalLocaleBuilder setExtension(char singleton, String value) throws LocaleSyntaxException {
 
140
        String strSingleton = String.valueOf(singleton);
 
141
        if (!LanguageTag.isExtensionSingleton(strSingleton) && !LanguageTag.isPrivateuseSingleton(strSingleton)) {
 
142
            throw new LocaleSyntaxException("Ill-formed extension key: " + singleton);
 
143
        }
 
144
 
 
145
        strSingleton = LanguageTag.canonicalizeExtensionSingleton(strSingleton);
 
146
        Character key = Character.valueOf(strSingleton.charAt(0));
 
147
 
 
148
        if (value.length() == 0) {
 
149
            if (_extMap != null) {
 
150
                _extMap.remove(key);
 
151
            }
 
152
        } else {
 
153
            StringTokenIterator sti = new StringTokenIterator(value, LanguageTag.SEP);
 
154
            ParseStatus sts = new ParseStatus();
 
155
 
 
156
            Extension ext = Extension.create(key.charValue(), sti, sts);
 
157
            if (sts.isError()) {
 
158
                throw new LocaleSyntaxException(sts.errorMsg, sts.errorIndex);
 
159
            }
 
160
            if (sts.parseLength != value.length() || ext == null) {
 
161
                throw new LocaleSyntaxException("Ill-formed extension value: " + value, sti.currentStart());
 
162
            }
 
163
            if (_extMap == null) {
 
164
                _extMap = new TreeMap<Character, Extension>();
 
165
            }
 
166
            _extMap.put(key, ext);
 
167
        }
 
168
        return this;
 
169
    }
 
170
 
 
171
    public InternalLocaleBuilder setLocale(BaseLocale base, LocaleExtensions extensions) throws LocaleSyntaxException {
 
172
        String language = base.getLanguage();
 
173
        String script = base.getScript();
 
174
        String region = base.getRegion();
 
175
        String variant = base.getVariant();
 
176
 
 
177
        // Validate base locale fields before updating internal state.
 
178
        // LocaleExtensions always store validated/canonicalized values,
 
179
        // so no checks are necessary.
 
180
        if (language.length() > 0) {
 
181
            if (!LanguageTag.isLanguage(language)) {
 
182
                throw new LocaleSyntaxException("Ill-formed language: " + language);
 
183
            }
 
184
            language = LanguageTag.canonicalizeLanguage(language);
 
185
        }
 
186
        if (script.length() > 0) {
 
187
            if (!LanguageTag.isScript(script)) {
 
188
                throw new LocaleSyntaxException("Ill-formed script: " + script);
 
189
            }
 
190
            script = LanguageTag.canonicalizeScript(script);
 
191
        }
 
192
        if (region.length() > 0) {
 
193
            if (!LanguageTag.isRegion(region)) {
 
194
                throw new LocaleSyntaxException("Ill-formed region: " + region);
 
195
            }
 
196
            region = LanguageTag.canonicalizeRegion(region);
 
197
        }
 
198
        if (_lenientVariant) {
 
199
            // In lenient variant mode, parse special private use value
 
200
            // reserved for Java Locale.
 
201
            String privuse = extensions.getExtensionValue(Character.valueOf(LanguageTag.PRIVATEUSE.charAt(0)));
 
202
            if (privuse != null) {
 
203
                variant = LanguageTag.getJavaCompatibleVariant(variant, privuse);
 
204
            }
 
205
        } else {
 
206
            if (variant.length() > 0) {
 
207
                variant = processVariant(variant);
 
208
            }
 
209
        }
 
210
 
 
211
        // update builder's internal fields
 
212
        _language = language;
 
213
        _script = script;
 
214
        _region = region;
 
215
        _variant = variant;
 
216
 
 
217
        // empty extensions
 
218
        if (_extMap == null) {
 
219
            _extMap = new TreeMap<Character, Extension>();
 
220
        } else {
 
221
            _extMap.clear();
 
222
        }
 
223
 
 
224
        Set<Character> extKeys = extensions.getKeys();
 
225
        for (Character key : extKeys) {
 
226
            Extension ext = extensions.getExtension(key);
 
227
            if (_lenientVariant && (ext instanceof PrivateuseExtension)) {
 
228
                String modPrivuse = LanguageTag.getJavaCompatiblePrivateuse(ext.getValue());
 
229
                if (!modPrivuse.equals(ext.getValue())) {
 
230
                    ext = new PrivateuseExtension(modPrivuse);
 
231
                }
 
232
            }
 
233
            _extMap.put(key, ext);
 
234
        }
 
235
 
 
236
        return this;
 
237
    }
 
238
 
 
239
    public InternalLocaleBuilder clear() {
 
240
        _language = "";
 
241
        _script = "";
 
242
        _region = "";
 
243
        _variant = "";
 
244
        removeLocaleExtensions();
 
245
        return this;
 
246
    }
 
247
 
 
248
    public InternalLocaleBuilder removeLocaleExtensions() {
 
249
        if (_extMap != null) {
 
250
            _extMap.clear();
 
251
        }
 
252
        return this;
 
253
    }
 
254
 
 
255
    public BaseLocale getBaseLocale() {
 
256
        return BaseLocale.getInstance(_language, _script, _region, _variant);
 
257
    }
 
258
 
 
259
    public LocaleExtensions getLocaleExtensions() {
 
260
        if (_extMap != null && _extMap.size() > 0) {
 
261
            return LocaleExtensions.getInstance(_extMap);
 
262
        }
 
263
        return LocaleExtensions.EMPTY_EXTENSIONS;
 
264
    }
 
265
 
 
266
    private String processVariant(String variant) throws LocaleSyntaxException {
 
267
        StringTokenIterator sti = new StringTokenIterator(variant, LOCALESEP);
 
268
        ParseStatus sts = new ParseStatus();
 
269
 
 
270
        List<String> variants = LanguageTag.DEFAULT_PARSER.parseVariants(sti, sts);
 
271
        if (sts.parseLength != variant.length()) {
 
272
            throw new LocaleSyntaxException("Ill-formed variant: " + variant, sti.currentStart());
 
273
        }
 
274
 
 
275
        StringBuilder buf = new StringBuilder();
 
276
        for (String var : variants) {
 
277
            if (buf.length() != 0) {
 
278
                buf.append(LOCALESEP);
 
279
            }
 
280
            buf.append(var);
 
281
        }
 
282
        return buf.toString();
 
283
    }
 
284
}