]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/impl/locale/BaseLocale.java
go
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / impl / locale / BaseLocale.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 \r
8 package com.ibm.icu.impl.locale;\r
9 \r
10 \r
11 \r
12 public final class BaseLocale {\r
13 \r
14     private String _language = "";\r
15     private String _script = "";\r
16     private String _region = "";\r
17     private String _variant = "";\r
18 \r
19     private transient String _id = "";\r
20     private transient String _java6string = "";\r
21     private transient BaseLocale _parent;\r
22 \r
23     private static final char SEPCHAR = '_';\r
24 \r
25 //    private static final LocaleObjectCache<BaseLocaleKey,BaseLocale> BASELOCALECACHE\r
26 //        = new LocaleObjectCache<BaseLocaleKey,BaseLocale>();\r
27 \r
28     private static final LocaleObjectCache BASELOCALECACHE\r
29         = new LocaleObjectCache();\r
30 \r
31         public static final BaseLocale ROOT = new BaseLocale("", "", "", "");\r
32 \r
33     private BaseLocale(String language, String script, String region, String variant) {\r
34         if (language != null) {\r
35             _language = language;\r
36         }\r
37         if (script != null) {\r
38             _script = script;\r
39         }\r
40         if (region != null) {\r
41             _region = region;\r
42         }\r
43         if (variant != null) {\r
44             _variant = variant;\r
45         }\r
46     }\r
47 \r
48     public static BaseLocale getInstance(String language, String script, String region, String variant) {\r
49         BaseLocaleKey key = new BaseLocaleKey(language, script, region, variant);\r
50 //        BaseLocale baseLocale = BASELOCALECACHE.get(key);\r
51         BaseLocale baseLocale = (BaseLocale)BASELOCALECACHE.get(key);\r
52         if (baseLocale == null) {\r
53             // Create a canonical BaseLocale instance\r
54             baseLocale = new BaseLocale(language, script, region, variant).canonicalize();\r
55             BASELOCALECACHE.put(baseLocale.createKey(), baseLocale);\r
56         }\r
57         return baseLocale;\r
58     }\r
59 \r
60     public boolean equals(Object obj) {\r
61         return (this == obj) ||\r
62                 ((obj instanceof BaseLocale) && _id == (((BaseLocale)obj)._id));\r
63     }\r
64 \r
65     public int hashCode() {\r
66         return _id.hashCode();\r
67     }\r
68 \r
69     public String getJava6String() {\r
70         return _java6string;\r
71     }\r
72 \r
73     public String getLanguage() {\r
74         return _language;\r
75     }\r
76 \r
77     public String getScript() {\r
78         return _script;\r
79     }\r
80 \r
81     public String getRegion() {\r
82         return _region;\r
83     }\r
84 \r
85     public String getVariant() {\r
86         return _variant;\r
87     }\r
88 \r
89     public BaseLocale getParent() {\r
90         return _parent;\r
91     }\r
92 \r
93     public String getID() {\r
94         return _id;\r
95     }\r
96 \r
97     public String toString() {\r
98         return _id;\r
99     }\r
100 \r
101     private BaseLocale canonicalize() {\r
102 \r
103 //        StringBuilder id = new StringBuilder();\r
104         StringBuffer id = new StringBuffer();\r
105 \r
106         int languageLen = _language.length();\r
107         int scriptLen = _script.length();\r
108         int regionLen = _region.length();\r
109         int variantLen = _variant.length();\r
110 \r
111         if (languageLen > 0) {\r
112             // language to lower case\r
113             _language = AsciiUtil.toLowerString(_language).intern();\r
114 \r
115             id.append(_language);\r
116         }\r
117 \r
118         if (scriptLen > 0) {\r
119             // script - the first letter to upper case, the rest to lower case\r
120 //            StringBuilder buf = new StringBuilder();\r
121             StringBuffer buf = new StringBuffer();\r
122             buf.append(AsciiUtil.toUpper(_script.charAt(0)));\r
123             for (int i = 1; i < _script.length(); i++) {\r
124                 buf.append(AsciiUtil.toLower(_script.charAt(i)));\r
125             }\r
126             _script = buf.toString().intern();\r
127 \r
128             id.append(SEPCHAR);\r
129             id.append(_script);\r
130         }\r
131 \r
132         if (regionLen > 0) {\r
133             // region to upper case\r
134             _region = AsciiUtil.toUpperString(_region).intern();\r
135 \r
136             id.append(SEPCHAR);\r
137             id.append(_region);\r
138         }\r
139 \r
140         if (variantLen > 0) {\r
141             // variant is case sensitive in JDK\r
142             _variant = _variant.intern();\r
143 \r
144             if (regionLen == 0) {\r
145                 id.append(SEPCHAR);\r
146             }\r
147             id.append(SEPCHAR);\r
148             id.append(_variant);\r
149         }\r
150 \r
151         _id = id.toString().intern();\r
152 \r
153         // Compose legacy JDK ID string if required\r
154         if (languageLen == 0 && regionLen == 0 && variantLen > 0) {\r
155             _java6string = "";\r
156         } else if (scriptLen > 0 || (regionLen == 0 && variantLen > 0)) {\r
157 //            StringBuilder buf = new StringBuilder(_language);\r
158             StringBuffer buf = new StringBuffer(_language);\r
159             if (regionLen > 0) {\r
160                 buf.append(SEPCHAR);\r
161                 buf.append(_region);\r
162             } else if (variantLen > 0) {\r
163                 buf.append(SEPCHAR);\r
164             }\r
165             if (variantLen > 0) {\r
166                 buf.append(SEPCHAR);\r
167                 buf.append(_variant);\r
168             }\r
169             _java6string = buf.toString().intern();\r
170         } else {\r
171             _java6string = _id;\r
172         }\r
173 \r
174         // Resolve parent\r
175         if (variantLen > 0) {\r
176             // variant field in Java Locale may contain multiple\r
177             // subtags\r
178             int lastSep = _variant.lastIndexOf(SEPCHAR);\r
179             if (lastSep == -1) {\r
180                 _parent = getInstance(_language, _script, _region, "");\r
181             } else {\r
182                 _parent = getInstance(_language, _script, _region, _variant.substring(0, lastSep));\r
183             }\r
184         } else if (regionLen > 0) {\r
185             _parent = getInstance(_language, _script, "", "");\r
186         } else if (scriptLen > 0) {\r
187             _parent = getInstance(_language, "", "", "");\r
188         } else if (languageLen > 0) {\r
189             _parent = ROOT;\r
190         } else {\r
191             // This is the root\r
192             // We should never get here, because ROOT is pre-populated.\r
193             _parent = null;\r
194         }\r
195         return this;\r
196     }\r
197 \r
198     private BaseLocaleKey createKey() {\r
199         return new BaseLocaleKey(_language, _script, _region, _variant);\r
200     }\r
201 \r
202 //    public static class BaseLocaleKey implements Comparable<BaseLocaleKey> {\r
203     public static class BaseLocaleKey implements Comparable {\r
204         private String _lang = "";\r
205         private String _scrt = "";\r
206         private String _regn = "";\r
207         private String _vart = "";\r
208 \r
209         private int _hash; // Default to 0\r
210 \r
211         public BaseLocaleKey(String language, String script, String region, String variant) {\r
212             if (language != null) {\r
213                 _lang = language;\r
214             }\r
215             if (script != null) {\r
216                 _scrt = script;\r
217             }\r
218             if (region != null) {\r
219                 _regn = region;\r
220             }\r
221             if (variant != null) {\r
222                 _vart = variant;\r
223             }\r
224         }\r
225 \r
226         public boolean equals(Object obj) {\r
227             return (this == obj) ||\r
228                     (obj instanceof BaseLocaleKey)\r
229                     && AsciiUtil.caseIgnoreMatch(((BaseLocaleKey)obj)._lang, this._lang)\r
230                     && AsciiUtil.caseIgnoreMatch(((BaseLocaleKey)obj)._scrt, this._scrt)\r
231                     && AsciiUtil.caseIgnoreMatch(((BaseLocaleKey)obj)._regn, this._regn)\r
232                     && ((BaseLocaleKey)obj)._vart.equals(_vart); // variant is case sensitive in JDK!\r
233         }\r
234 \r
235         public int compareTo(BaseLocaleKey other) {\r
236             int res = AsciiUtil.caseIgnoreCompare(this._lang, other._lang);\r
237             if (res == 0) {\r
238                 res = AsciiUtil.caseIgnoreCompare(this._scrt, other._scrt);\r
239                 if (res == 0) {\r
240                     res = AsciiUtil.caseIgnoreCompare(this._regn, other._regn);\r
241                     if (res == 0) {\r
242                         res = AsciiUtil.caseIgnoreCompare(this._vart, other._vart);\r
243                     }\r
244                 }\r
245             }\r
246             return res;\r
247         }\r
248 \r
249         public int compareTo(Object obj) {\r
250             return compareTo((BaseLocaleKey)obj);\r
251         }\r
252 \r
253         public int hashCode() {\r
254             int h = _hash;\r
255             if (h == 0) {\r
256                 // Generating a hash value from language, script, region and variant\r
257                 for (int i = 0; i < _lang.length(); i++) {\r
258                     h = 31*h + AsciiUtil.toLower(_lang.charAt(i));\r
259                 }\r
260                 for (int i = 0; i < _scrt.length(); i++) {\r
261                     h = 31*h + AsciiUtil.toLower(_scrt.charAt(i));\r
262                 }\r
263                 for (int i = 0; i < _regn.length(); i++) {\r
264                     h = 31*h + AsciiUtil.toLower(_regn.charAt(i));\r
265                 }\r
266                 for (int i = 0; i < _vart.length(); i++) {\r
267                     h = 31*h + AsciiUtil.toLower(_vart.charAt(i));\r
268                 }\r
269                 _hash = h;\r
270             }\r
271             return h;\r
272         }\r
273     }\r
274 }\r