2 *******************************************************************************
\r
3 * Copyright (C) 2009, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
8 package com.ibm.icu.impl.locale;
\r
12 public final class BaseLocale {
\r
14 private String _language = "";
\r
15 private String _script = "";
\r
16 private String _region = "";
\r
17 private String _variant = "";
\r
19 private transient String _id = "";
\r
20 private transient String _java6string = "";
\r
21 private transient BaseLocale _parent;
\r
23 private static final char SEPCHAR = '_';
\r
25 // private static final LocaleObjectCache<BaseLocaleKey,BaseLocale> BASELOCALECACHE
\r
26 // = new LocaleObjectCache<BaseLocaleKey,BaseLocale>();
\r
28 private static final LocaleObjectCache BASELOCALECACHE
\r
29 = new LocaleObjectCache();
\r
31 public static final BaseLocale ROOT = new BaseLocale("", "", "", "");
\r
33 private BaseLocale(String language, String script, String region, String variant) {
\r
34 if (language != null) {
\r
35 _language = language;
\r
37 if (script != null) {
\r
40 if (region != null) {
\r
43 if (variant != null) {
\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
60 public boolean equals(Object obj) {
\r
61 return (this == obj) ||
\r
62 ((obj instanceof BaseLocale) && _id == (((BaseLocale)obj)._id));
\r
65 public int hashCode() {
\r
66 return _id.hashCode();
\r
69 public String getJava6String() {
\r
70 return _java6string;
\r
73 public String getLanguage() {
\r
77 public String getScript() {
\r
81 public String getRegion() {
\r
85 public String getVariant() {
\r
89 public BaseLocale getParent() {
\r
93 public String getID() {
\r
97 public String toString() {
\r
101 private BaseLocale canonicalize() {
\r
103 // StringBuilder id = new StringBuilder();
\r
104 StringBuffer id = new StringBuffer();
\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
111 if (languageLen > 0) {
\r
112 // language to lower case
\r
113 _language = AsciiUtil.toLowerString(_language).intern();
\r
115 id.append(_language);
\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
126 _script = buf.toString().intern();
\r
128 id.append(SEPCHAR);
\r
129 id.append(_script);
\r
132 if (regionLen > 0) {
\r
133 // region to upper case
\r
134 _region = AsciiUtil.toUpperString(_region).intern();
\r
136 id.append(SEPCHAR);
\r
137 id.append(_region);
\r
140 if (variantLen > 0) {
\r
141 // variant is case sensitive in JDK
\r
142 _variant = _variant.intern();
\r
144 if (regionLen == 0) {
\r
145 id.append(SEPCHAR);
\r
147 id.append(SEPCHAR);
\r
148 id.append(_variant);
\r
151 _id = id.toString().intern();
\r
153 // Compose legacy JDK ID string if required
\r
154 if (languageLen == 0 && regionLen == 0 && variantLen > 0) {
\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
165 if (variantLen > 0) {
\r
166 buf.append(SEPCHAR);
\r
167 buf.append(_variant);
\r
169 _java6string = buf.toString().intern();
\r
171 _java6string = _id;
\r
175 if (variantLen > 0) {
\r
176 // variant field in Java Locale may contain multiple
\r
178 int lastSep = _variant.lastIndexOf(SEPCHAR);
\r
179 if (lastSep == -1) {
\r
180 _parent = getInstance(_language, _script, _region, "");
\r
182 _parent = getInstance(_language, _script, _region, _variant.substring(0, lastSep));
\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
191 // This is the root
\r
192 // We should never get here, because ROOT is pre-populated.
\r
198 private BaseLocaleKey createKey() {
\r
199 return new BaseLocaleKey(_language, _script, _region, _variant);
\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
209 private int _hash; // Default to 0
\r
211 public BaseLocaleKey(String language, String script, String region, String variant) {
\r
212 if (language != null) {
\r
215 if (script != null) {
\r
218 if (region != null) {
\r
221 if (variant != null) {
\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
235 public int compareTo(BaseLocaleKey other) {
\r
236 int res = AsciiUtil.caseIgnoreCompare(this._lang, other._lang);
\r
238 res = AsciiUtil.caseIgnoreCompare(this._scrt, other._scrt);
\r
240 res = AsciiUtil.caseIgnoreCompare(this._regn, other._regn);
\r
242 res = AsciiUtil.caseIgnoreCompare(this._vart, other._vart);
\r
249 public int compareTo(Object obj) {
\r
250 return compareTo((BaseLocaleKey)obj);
\r
253 public int hashCode() {
\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
260 for (int i = 0; i < _scrt.length(); i++) {
\r
261 h = 31*h + AsciiUtil.toLower(_scrt.charAt(i));
\r
263 for (int i = 0; i < _regn.length(); i++) {
\r
264 h = 31*h + AsciiUtil.toLower(_regn.charAt(i));
\r
266 for (int i = 0; i < _vart.length(); i++) {
\r
267 h = 31*h + AsciiUtil.toLower(_vart.charAt(i));
\r