]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/impl/locale/InternalLocaleBuilder.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / 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.HashMap;\r
10 import java.util.Iterator;\r
11 import java.util.Map;\r
12 import java.util.Set;\r
13 import java.util.TreeMap;\r
14 \r
15 import com.ibm.icu.impl.Utility;\r
16 \r
17 public final class InternalLocaleBuilder {\r
18 \r
19     public static final char PRIVATEUSEKEY = 'x';\r
20 \r
21     private String _language = "";\r
22     private String _script = "";\r
23     private String _region = "";\r
24     private String _variant = "";\r
25 \r
26     private FieldHandler _handler = FieldHandler.DEFAULT;\r
27 \r
28 //    private HashMap<Character, String> _extMap;\r
29     private HashMap _extMap;\r
30 //    private HashMap<String, String> _kwdMap;\r
31     private HashMap _kwdMap;\r
32 \r
33     private static final char LDMLSINGLETON = 'u';\r
34 \r
35     private static final String LANGTAGSEP = "-";\r
36     private static final String LOCALESEP = "_";\r
37 \r
38     private static final int DEFAULTMAPCAPACITY = 4;\r
39 \r
40     public InternalLocaleBuilder() {\r
41     }\r
42 \r
43     public InternalLocaleBuilder(FieldHandler handler) {\r
44         _handler = handler;\r
45     }\r
46 \r
47     public InternalLocaleBuilder setLanguage(String language) throws LocaleSyntaxException {\r
48         String newval = "";\r
49         if (language.length() > 0) {\r
50             newval = _handler.process(FieldType.LANGUAGE, language);\r
51             if (newval == null) {\r
52                 throw new LocaleSyntaxException("Ill-formed language: " + language);\r
53             }\r
54         }\r
55         _language = newval;\r
56         return this;\r
57     }\r
58 \r
59     public InternalLocaleBuilder setScript(String script) throws LocaleSyntaxException {\r
60         String newval = "";\r
61         if (script.length() > 0) {\r
62             newval = _handler.process(FieldType.SCRIPT, script);\r
63             if (newval == null) {\r
64                 throw new LocaleSyntaxException("Ill-formed script: " + script);\r
65             }\r
66         }\r
67         _script = newval;\r
68         return this;\r
69     }\r
70 \r
71     public InternalLocaleBuilder setRegion(String region) throws LocaleSyntaxException {\r
72         String newval = "";\r
73         if (region.length() > 0) {\r
74             newval = _handler.process(FieldType.REGION, region);\r
75             if (newval == null) {\r
76                 throw new LocaleSyntaxException("Ill-formed region: " + region);\r
77             }\r
78         }\r
79         _region = newval;\r
80         return this;\r
81     }\r
82 \r
83     public InternalLocaleBuilder setVariant(String variant) throws LocaleSyntaxException {\r
84         String newval = "";\r
85         if (variant.length() > 0) {\r
86             newval = _handler.process(FieldType.VARIANT, variant);\r
87             if (newval == null) {\r
88                 throw new LocaleSyntaxException("Ill-formed variant: " + variant);\r
89             }\r
90         }\r
91         _variant = newval;\r
92         return this;\r
93     }\r
94 \r
95     public InternalLocaleBuilder setLDMLExtensionValue(String key, String type) throws LocaleSyntaxException {\r
96         if (key.length() == 0) {\r
97             throw new LocaleSyntaxException("Empty LDML extension key");\r
98         }\r
99         String kwdkey = _handler.process(FieldType.LDMLKEY, key);\r
100         if (kwdkey == null) {\r
101             throw new LocaleSyntaxException("Ill-formed LDML extension key: " + key);\r
102         }\r
103 \r
104         if (type.length() == 0) {\r
105             if (_kwdMap != null) {\r
106                 _kwdMap.remove(kwdkey);\r
107             }\r
108         } else {\r
109             String kwdtype = _handler.process(FieldType.LDMLTYPE, type);\r
110             if (kwdtype == null) {\r
111                 throw new LocaleSyntaxException("Ill-formed LDML extension value: " + type);\r
112             }\r
113             if (_kwdMap == null) {\r
114 //                _kwdMap = new HashMap<String, String>(DEFAULTMAPCAPACITY);\r
115                 _kwdMap = new HashMap(DEFAULTMAPCAPACITY);\r
116             }\r
117             _kwdMap.put(kwdkey, kwdtype);\r
118         }\r
119 \r
120         return this;\r
121     }\r
122 \r
123     public InternalLocaleBuilder setExtension(char singleton, String value) throws LocaleSyntaxException {\r
124         if (!LocaleExtensions.isValidExtensionKey(singleton)) {\r
125             throw new LocaleSyntaxException("Ill-formed extension key: " + singleton);\r
126         }\r
127 \r
128         // singleton char to lower case\r
129         singleton = AsciiUtil.toLower(singleton);\r
130 \r
131         if (singleton == LDMLSINGLETON) {\r
132             // 'u' extension reserved for locale keywords\r
133             if (_kwdMap != null) {\r
134                 // blow out the keywords currently set\r
135                 _kwdMap.clear();\r
136             }\r
137             // parse locale keyword extension subtags\r
138 //            String[] kwdtags = (value.replaceAll(LOCALESEP, LANGTAGSEP)).split(LANGTAGSEP);\r
139             String[] kwdtags = Utility.split(Utility.replaceAll(value, LOCALESEP, LANGTAGSEP), '-');\r
140             if ((kwdtags.length % 2) != 0) {\r
141                 // number of keyword subtags must be even number\r
142                 throw new LocaleSyntaxException("Ill-formed LDML extension key/value pairs: " + value);\r
143             }\r
144             int idx = 0;\r
145             while (idx < kwdtags.length) {\r
146                 String kwdkey = _handler.process(FieldType.LDMLKEY, kwdtags[idx++]);\r
147                 String kwdtype = _handler.process(FieldType.LDMLTYPE, kwdtags[idx++]);\r
148                 if (kwdkey == null || kwdkey.length() == 0\r
149                         || kwdtype == null || kwdtype.length() == 0) {\r
150                     throw new LocaleSyntaxException("Ill-formed LDML extension key/value pairs: " + value);\r
151                 }\r
152                 if (_kwdMap == null) {\r
153 //                    _kwdMap = new HashMap<String, String>(kwdtags.length / 2);\r
154                     _kwdMap = new HashMap(kwdtags.length / 2);\r
155                 }\r
156                 _kwdMap.put(kwdkey, kwdtype);\r
157             }\r
158         } else {\r
159             // other extensions including privateuse\r
160             if (value.length() == 0) {\r
161                 if (_extMap != null) {\r
162 //                    _extMap.remove(Character.valueOf(singleton));\r
163                     _extMap.remove(new Character(singleton));\r
164                 }\r
165             } else {\r
166 //                FieldType ftype = (singleton == PRIVATEUSEKEY) ? FieldType.PRIVATEUSE : FieldType.EXTENSION;\r
167                 int ftype = (singleton == PRIVATEUSEKEY) ? FieldType.PRIVATEUSE : FieldType.EXTENSION;\r
168                 String extval = _handler.process(ftype, value);\r
169                 if (extval == null) {\r
170                     throw new LocaleSyntaxException("Ill-formed LDML extension value: " + value);\r
171                 }\r
172                 if (_extMap == null) {\r
173 //                    _extMap = new HashMap<Character, String>(DEFAULTMAPCAPACITY);\r
174                     _extMap = new HashMap(DEFAULTMAPCAPACITY);\r
175                 }\r
176 //                _extMap.put(Character.valueOf(singleton), extval);\r
177                 _extMap.put(new Character(singleton), extval);\r
178             }\r
179         }\r
180         return this;\r
181     }\r
182 \r
183     public InternalLocaleBuilder clear() {\r
184         _language = "";\r
185         _script = "";\r
186         _region = "";\r
187         _variant = "";\r
188         removeLocaleExtensions();\r
189         return this;\r
190     }\r
191 \r
192     public InternalLocaleBuilder removeLocaleExtensions() {\r
193         if (_extMap != null) {\r
194             _extMap.clear();\r
195         }\r
196         if (_kwdMap != null) {\r
197             _kwdMap.clear();\r
198         }\r
199         return this;\r
200     }\r
201 \r
202     public BaseLocale getBaseLocale() {\r
203         return BaseLocale.getInstance(_language, _script, _region, _variant);\r
204     }\r
205 \r
206     public LocaleExtensions getLocaleExtensions() {\r
207 //        TreeMap<Character, String> extMap = null;\r
208         TreeMap extMap = null;\r
209 //        TreeMap<String, String> kwdMap = null;\r
210         TreeMap kwdMap = null;\r
211 \r
212         // process keywords\r
213         if (_kwdMap != null && _kwdMap.size() > 0) {\r
214 //            Set<Map.Entry<String, String>> kwds = _kwdMap.entrySet();\r
215 //            for (Map.Entry<String, String> kwd : kwds) {\r
216 //                String key = kwd.getKey();\r
217 //                String type = kwd.getValue();\r
218 //                if (kwdMap == null) {\r
219 //                    kwdMap = new TreeMap<String, String>();\r
220 //                }\r
221 //                kwdMap.put(key.intern(), type.intern());\r
222 //            }\r
223             Set kwds = _kwdMap.entrySet();\r
224             Iterator itr = kwds.iterator();\r
225             while (itr.hasNext()) {\r
226                 Map.Entry kwd = (Map.Entry)itr.next();\r
227                 String key = (String)kwd.getKey();\r
228                 String type = (String)kwd.getValue();\r
229                 if (kwdMap == null) {\r
230                     kwdMap = new TreeMap();\r
231                 }\r
232                 kwdMap.put(key.intern(), type.intern());\r
233             }\r
234         }\r
235 \r
236         // process extensions and privateuse\r
237         if (_extMap != null) {\r
238 //            Set<Map.Entry<Character, String>> exts = _extMap.entrySet();\r
239 //            for (Map.Entry<Character, String> ext : exts) {\r
240 //                Character key = ext.getKey();\r
241 //                String value = ext.getValue();\r
242 //                if (extMap == null) {\r
243 //                    extMap = new TreeMap<Character, String>();\r
244 //                }\r
245 //                extMap.put(key, value.intern());\r
246 //            }\r
247             Set exts = _extMap.entrySet();\r
248             Iterator itr = exts.iterator();\r
249             while (itr.hasNext()) {\r
250                 Map.Entry ext = (Map.Entry)itr.next();\r
251                 Character key = (Character)ext.getKey();\r
252                 String value = (String)ext.getValue();\r
253                 if (extMap == null) {\r
254                     extMap = new TreeMap();\r
255                 }\r
256                 extMap.put(key, value.intern());\r
257             }\r
258         }\r
259 \r
260         // set canonical locale keyword extension string to the extension map\r
261         if (kwdMap != null) {\r
262 //            StringBuilder buf = new StringBuilder();\r
263             StringBuffer buf = new StringBuffer();\r
264             LocaleExtensions.keywordsToString(kwdMap, buf);\r
265             if (extMap == null) {\r
266 //                extMap = new TreeMap<Character, String>();\r
267                 extMap = new TreeMap();\r
268             }\r
269 //            extMap.put(Character.valueOf(LDMLSINGLETON), buf.toString().intern());\r
270             extMap.put(new Character(LDMLSINGLETON), buf.toString().intern());\r
271         }\r
272 \r
273         return LocaleExtensions.getInstance(extMap, kwdMap);\r
274     }\r
275 \r
276 //    protected enum FieldType {\r
277 //        LANGUAGE,\r
278 //        SCRIPT,\r
279 //        REGION,\r
280 //        VARIANT,\r
281 //        LDMLKEY,\r
282 //        LDMLTYPE,\r
283 //        EXTENSION,\r
284 //        PRIVATEUSE\r
285 //    }\r
286 \r
287     private static class FieldType {\r
288         public static final int LANGUAGE = 0;\r
289         public static final int SCRIPT = 1;\r
290         public static final int REGION = 2;\r
291         public static final int VARIANT = 3;\r
292         public static final int LDMLKEY = 4;\r
293         public static final int LDMLTYPE = 5;\r
294         public static final int EXTENSION = 6;\r
295         public static final int PRIVATEUSE = 7;\r
296     }\r
297 \r
298     public static class FieldHandler {\r
299         public static FieldHandler DEFAULT = new FieldHandler();\r
300 \r
301         protected FieldHandler() {\r
302         }\r
303 \r
304 //        public String process(FieldType type, String value) {\r
305         public String process(int type, String value) {\r
306             value = map(type, value);\r
307             if (value.length() > 0 && !validate(type, value)) {\r
308                 return null;\r
309             }\r
310             return value;\r
311         }\r
312 \r
313 //        protected String map(FieldType type, String value) {\r
314         protected String map(int type, String value) {\r
315             switch (type) {\r
316             case FieldType.LANGUAGE:\r
317                 value = AsciiUtil.toLowerString(value);\r
318                 break;\r
319             case FieldType.SCRIPT:\r
320                 if (value.length() > 0) {\r
321 //                    StringBuilder buf = new StringBuilder();\r
322                     StringBuffer buf = new StringBuffer();\r
323                     buf.append(AsciiUtil.toUpper(value.charAt(0)));\r
324                     for (int i = 1; i < value.length(); i++) {\r
325                         buf.append(AsciiUtil.toLower(value.charAt(i)));\r
326                     }\r
327                     value = buf.toString();\r
328                 }\r
329                 break;\r
330             case FieldType.REGION:\r
331                 value = AsciiUtil.toUpperString(value);\r
332                 break;\r
333             case FieldType.VARIANT:\r
334                 // Java variant is case sensitive - so no case mapping here\r
335 //                value = value.replaceAll(LANGTAGSEP, LOCALESEP);\r
336                 value = Utility.replaceAll(value, LANGTAGSEP, LOCALESEP);\r
337                 break;\r
338             case FieldType.LDMLKEY:\r
339             case FieldType.LDMLTYPE:\r
340             case FieldType.EXTENSION:\r
341             case FieldType.PRIVATEUSE:\r
342 //                value = AsciiUtil.toLowerString(value).replaceAll(LOCALESEP, LANGTAGSEP);\r
343                 value = Utility.replaceAll(AsciiUtil.toLowerString(value), LOCALESEP, LANGTAGSEP);\r
344                 break;\r
345             }\r
346             return value;\r
347         }\r
348 \r
349 //        protected boolean validate(FieldType type, String value) {\r
350         protected boolean validate(int type, String value) {\r
351             boolean isValid = false;\r
352             String[] subtags;\r
353 \r
354             switch (type) {\r
355             case FieldType.LANGUAGE:\r
356                 isValid = LanguageTag.isLanguageSubtag(value);\r
357                 break;\r
358             case FieldType.SCRIPT:\r
359                 isValid = LanguageTag.isScriptSubtag(value);\r
360                 break;\r
361             case FieldType.REGION:\r
362                 isValid = LanguageTag.isRegionSubtag(value);\r
363                 break;\r
364             case FieldType.VARIANT:\r
365                 // variant field could have multiple subtags\r
366 //                subtags = value.split(LOCALESEP);\r
367                 subtags = Utility.split(value, '_');\r
368 //                for (String subtag : subtags) {\r
369                 for (int i = 0; i < subtags.length; i++) {\r
370                     String subtag = subtags[i];\r
371                     isValid = LanguageTag.isVariantSubtag(subtag);\r
372                     if (!isValid) {\r
373                         break;\r
374                     }\r
375                 }\r
376                 break;\r
377             case FieldType.LDMLKEY:\r
378                 isValid = LocaleExtensions.isValidLDMLKey(value);\r
379                 break;\r
380             case FieldType.LDMLTYPE:\r
381                 isValid = LocaleExtensions.isValidLDMLType(value);\r
382                 break;\r
383             case FieldType.EXTENSION:\r
384 //                subtags = value.split(LANGTAGSEP);\r
385                 subtags = Utility.split(value, '-');\r
386 //              for (String subtag : subtags) {\r
387                 for (int i = 0; i < subtags.length; i++) {\r
388                     String subtag = subtags[i];\r
389                     isValid = LanguageTag.isExtensionSubtag(subtag);\r
390                     if (!isValid) {\r
391                         break;\r
392                     }\r
393                 }\r
394                 break;\r
395             case FieldType.PRIVATEUSE:\r
396 //                subtags = value.split(LANGTAGSEP);\r
397                 subtags = Utility.split(value, '-');\r
398 //              for (String subtag : subtags) {\r
399                 for (int i = 0; i < subtags.length; i++) {\r
400                     String subtag = subtags[i];\r
401                     isValid = LanguageTag.isPrivateuseValueSubtag(subtag);\r
402                     if (!isValid) {\r
403                         break;\r
404                     }\r
405                 }\r
406                 break;\r
407             }\r
408             return isValid;\r
409         }\r
410     }\r
411 }\r