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