]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/main/classes/core/src/com/ibm/icu/impl/locale/UnicodeLocaleExtension.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / main / classes / core / src / com / ibm / icu / impl / locale / UnicodeLocaleExtension.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.Collections;\r
10 import java.util.Set;\r
11 import java.util.SortedMap;\r
12 import java.util.TreeMap;\r
13 import java.util.Map.Entry;\r
14 \r
15 import com.ibm.icu.impl.locale.LanguageTag.ParseStatus;\r
16 \r
17 public class UnicodeLocaleExtension extends Extension {\r
18     public static final char SINGLETON = 'u';\r
19 \r
20     public static final UnicodeLocaleExtension CA_JAPANESE = new UnicodeLocaleExtension().put("ca", "japanese");\r
21     public static final UnicodeLocaleExtension NU_THAI = new UnicodeLocaleExtension().put("nu", "thai");\r
22 \r
23     private SortedMap<String, String> _keyTypeMap;\r
24 \r
25     protected UnicodeLocaleExtension() {\r
26         super(SINGLETON);\r
27     }\r
28 \r
29     /*\r
30      * Package local constructor only used by InternalLocaleBuilder\r
31      */\r
32     UnicodeLocaleExtension(SortedMap<String, String> keyTypeMap) {\r
33         super(SINGLETON);\r
34         _keyTypeMap = keyTypeMap;\r
35         updateStringValue();\r
36     }\r
37 \r
38     protected void setExtensionValue(StringTokenIterator itr, ParseStatus sts) {\r
39         if (sts.isError() || itr.isDone()) {\r
40             _value = null;\r
41             return;\r
42         }\r
43 \r
44         SortedMap<String, String> keyTypeMap = new TreeMap<String, String>();\r
45         String ukey = null;\r
46         StringBuilder buf = new StringBuilder();\r
47         int typeEnd = -1;\r
48 \r
49         while (!itr.isDone()) {\r
50             String s = itr.current();\r
51 \r
52             if (isTypeSubtag(s)) {\r
53                 if (ukey == null) {\r
54                     // key is expected\r
55                     sts.errorIndex = itr.currentStart();\r
56                     sts.errorMsg = "Invalid Unicode locale extension key: " + s;\r
57                     break;\r
58                 }\r
59                 if (buf.length() > 0) {\r
60                     buf.append(LanguageTag.SEP);\r
61                 }\r
62                 buf.append(canonicalizeTypeSubtag(s));\r
63                 typeEnd = itr.currentEnd();\r
64 \r
65                 if (!itr.hasNext()) {\r
66                     // emit the last key/type\r
67                     keyTypeMap.put(ukey, buf.toString());\r
68                     sts.parseLength = typeEnd;\r
69                     itr.next();\r
70                     break;\r
71                 }\r
72             } else {\r
73                 // key or others\r
74                 if (ukey != null) {\r
75                     if (buf.length() > 0) {\r
76                         // emit previous key and value\r
77                         keyTypeMap.put(ukey, buf.toString());\r
78                         sts.parseLength = typeEnd;\r
79                     } else {\r
80                         // type is expected\r
81                         sts.errorIndex = itr.currentStart();\r
82                         sts.errorMsg = "Invalid Unicode locale extension type: " + s;\r
83                         break;\r
84                     }\r
85                 }\r
86                 if (isKey(s)) {\r
87                     if (itr.hasNext()) {\r
88                         ukey = canonicalizeKey(s);\r
89                         if (keyTypeMap.containsKey(ukey)) {\r
90                             // duplicated key\r
91                             sts.errorIndex = itr.currentStart();\r
92                             sts.errorMsg = "Duplicate Unicode locale extension key: " + s;\r
93                             break;\r
94                         }\r
95                         buf.setLength(0);\r
96                         typeEnd = -1;\r
97                     } else {\r
98                         // missing type\r
99                         sts.errorIndex = itr.currentStart();\r
100                         sts.errorMsg = "Missing subtag for Unicode locale extension: " + s;\r
101                         itr.next();\r
102                         break;\r
103                     }\r
104                 } else {\r
105                     // others\r
106                     if (keyTypeMap.size() == 0) {\r
107                         // key is expected\r
108                         sts.errorIndex = itr.currentStart();\r
109                         sts.errorMsg = "Invalid Unicode locale extension key: " + s;\r
110                     }\r
111                     break;\r
112                 }\r
113             }\r
114             itr.next();\r
115         }\r
116 \r
117         if (keyTypeMap.size() == 0) {\r
118             _value = null;\r
119             return;\r
120         }\r
121 \r
122         _keyTypeMap = keyTypeMap;\r
123         updateStringValue();\r
124     }\r
125 \r
126     public Set<String> getKeys() {\r
127         if (_keyTypeMap == null) {\r
128             return Collections.emptySet();\r
129         }\r
130         return Collections.unmodifiableSet(_keyTypeMap.keySet());\r
131     }\r
132 \r
133     public String getType(String key) {\r
134         String type = null;\r
135         if (_keyTypeMap != null) {\r
136             type = _keyTypeMap.get(canonicalizeKey(key));\r
137         }\r
138 \r
139         return (type == null ? "" : type);\r
140     }\r
141 \r
142     public static boolean isKey(String s) {\r
143         // 2alphanum\r
144         return (s.length() == 2) && AsciiUtil.isAlphaNumericString(s);\r
145     }\r
146 \r
147     public static boolean isTypeSubtag(String s) {\r
148         // 3*8alphanum\r
149         return (s.length() >= 3) && (s.length() <= 8) && AsciiUtil.isAlphaNumericString(s);\r
150     }\r
151 \r
152     public static String canonicalizeKey(String s) {\r
153         return LanguageTag.canonicalizeExtensionSubtag(s);\r
154     }\r
155 \r
156     public static String canonicalizeTypeSubtag(String s) {\r
157         return LanguageTag.canonicalizeExtensionSubtag(s);\r
158     }\r
159 \r
160     // These methods are only used by InterlaLocaleBuilder\r
161     UnicodeLocaleExtension remove(String key) {\r
162         if (_keyTypeMap != null) {\r
163             _keyTypeMap.remove(key);\r
164             updateStringValue();\r
165         }\r
166         return this;\r
167     }\r
168 \r
169     UnicodeLocaleExtension put(String key, String type) {\r
170         if (_keyTypeMap == null) {\r
171             _keyTypeMap = new TreeMap<String, String>();\r
172         }\r
173         _keyTypeMap.put(key, type);\r
174         updateStringValue();\r
175         return this;\r
176     }\r
177 \r
178     boolean isEmpty() {\r
179         return (_keyTypeMap.size() == 0);\r
180     }\r
181 \r
182     private void updateStringValue() {\r
183         _value = null;\r
184 \r
185         if (_keyTypeMap != null) {\r
186             // re-construct string representation\r
187             StringBuilder valBuf = new StringBuilder();\r
188             Set<Entry<String, String>> entries = _keyTypeMap.entrySet();\r
189             boolean isFirst = true;\r
190             for (Entry<String, String> e : entries) {\r
191                 if (isFirst) {\r
192                     isFirst = false;\r
193                 } else {\r
194                     valBuf.append(LanguageTag.SEP);\r
195                 }\r
196                 valBuf.append(e.getKey());\r
197                 valBuf.append(LanguageTag.SEP);\r
198                 valBuf.append(e.getValue());\r
199             }\r
200 \r
201             if (valBuf.length() > 0) {\r
202                 _value = valBuf.toString();\r
203             }\r
204         }\r
205     }\r
206 }\r
207 \r