2 *******************************************************************************
3 * Copyright (C) 2009-2010, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
8 package com.ibm.icu.impl.locale;
11 public final class BaseLocale {
13 private static final boolean JDKIMPL = false;
15 public static final String SEP = "_";
17 private static final Cache CACHE = new Cache();
18 public static final BaseLocale ROOT = BaseLocale.getInstance("", "", "", "");
20 private String _language = "";
21 private String _script = "";
22 private String _region = "";
23 private String _variant = "";
25 private transient volatile int _hash = 0;
27 private BaseLocale(String language, String script, String region, String variant) {
28 if (language != null) {
29 _language = AsciiUtil.toLowerString(language).intern();
32 _script = AsciiUtil.toTitleString(script).intern();
35 _region = AsciiUtil.toUpperString(region).intern();
37 if (variant != null) {
39 // preserve upper/lower cases
40 _variant = variant.intern();
42 _variant = AsciiUtil.toUpperString(variant).intern();
47 public static BaseLocale getInstance(String language, String script, String region, String variant) {
49 // JDK uses deprecated ISO639.1 language codes for he, yi and id
50 if (AsciiUtil.caseIgnoreMatch(language, "he")) {
52 } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) {
54 } else if (AsciiUtil.caseIgnoreMatch(language, "id")) {
58 Key key = new Key(language, script, region, variant);
59 BaseLocale baseLocale = CACHE.get(key);
63 public String getLanguage() {
67 public String getScript() {
71 public String getRegion() {
75 public String getVariant() {
79 public boolean equals(Object obj) {
83 if (!(obj instanceof BaseLocale)) {
86 BaseLocale other = (BaseLocale)obj;
87 return hashCode() == other.hashCode()
88 && _language.equals(other._language)
89 && _script.equals(other._script)
90 && _region.equals(other._region)
91 && _variant.equals(other._variant);
94 public String toString() {
95 StringBuilder buf = new StringBuilder();
96 if (_language.length() > 0) {
97 buf.append("language=");
98 buf.append(_language);
100 if (_script.length() > 0) {
101 if (buf.length() > 0) {
104 buf.append("script=");
107 if (_region.length() > 0) {
108 if (buf.length() > 0) {
111 buf.append("region=");
114 if (_variant.length() > 0) {
115 if (buf.length() > 0) {
118 buf.append("variant=");
119 buf.append(_variant);
121 return buf.toString();
124 public int hashCode() {
127 // Generating a hash value from language, script, region and variant
128 for (int i = 0; i < _language.length(); i++) {
129 h = 31*h + _language.charAt(i);
131 for (int i = 0; i < _script.length(); i++) {
132 h = 31*h + _script.charAt(i);
134 for (int i = 0; i < _region.length(); i++) {
135 h = 31*h + _region.charAt(i);
137 for (int i = 0; i < _variant.length(); i++) {
138 h = 31*h + _variant.charAt(i);
145 private static class Key implements Comparable<Key> {
146 private String _lang = "";
147 private String _scrt = "";
148 private String _regn = "";
149 private String _vart = "";
151 private volatile int _hash; // Default to 0
153 public Key(String language, String script, String region, String variant) {
154 if (language != null) {
157 if (script != null) {
160 if (region != null) {
163 if (variant != null) {
168 public boolean equals(Object obj) {
170 return (this == obj) ||
172 && AsciiUtil.caseIgnoreMatch(((Key)obj)._lang, this._lang)
173 && AsciiUtil.caseIgnoreMatch(((Key)obj)._scrt, this._scrt)
174 && AsciiUtil.caseIgnoreMatch(((Key)obj)._regn, this._regn)
175 && ((Key)obj)._vart.equals(_vart); // variant is case sensitive in JDK!
177 return (this == obj) ||
179 && AsciiUtil.caseIgnoreMatch(((Key)obj)._lang, this._lang)
180 && AsciiUtil.caseIgnoreMatch(((Key)obj)._scrt, this._scrt)
181 && AsciiUtil.caseIgnoreMatch(((Key)obj)._regn, this._regn)
182 && AsciiUtil.caseIgnoreMatch(((Key)obj)._vart, this._vart);
185 public int compareTo(Key other) {
186 int res = AsciiUtil.caseIgnoreCompare(this._lang, other._lang);
188 res = AsciiUtil.caseIgnoreCompare(this._scrt, other._scrt);
190 res = AsciiUtil.caseIgnoreCompare(this._regn, other._regn);
193 res = this._vart.compareTo(other._vart);
195 res = AsciiUtil.caseIgnoreCompare(this._vart, other._vart);
203 public int hashCode() {
206 // Generating a hash value from language, script, region and variant
207 for (int i = 0; i < _lang.length(); i++) {
208 h = 31*h + AsciiUtil.toLower(_lang.charAt(i));
210 for (int i = 0; i < _scrt.length(); i++) {
211 h = 31*h + AsciiUtil.toLower(_scrt.charAt(i));
213 for (int i = 0; i < _regn.length(); i++) {
214 h = 31*h + AsciiUtil.toLower(_regn.charAt(i));
216 for (int i = 0; i < _vart.length(); i++) {
218 h = 31*h + _vart.charAt(i);
220 h = 31*h + AsciiUtil.toLower(_vart.charAt(i));
228 public static Key normalize(Key key) {
229 String lang = AsciiUtil.toLowerString(key._lang).intern();
230 String scrt = AsciiUtil.toTitleString(key._scrt).intern();
231 String regn = AsciiUtil.toUpperString(key._regn).intern();
234 // preserve upper/lower cases
235 vart = key._vart.intern();
237 vart = AsciiUtil.toUpperString(key._vart).intern();
239 return new Key(lang, scrt, regn, vart);
243 private static class Cache extends LocaleObjectCache<Key, BaseLocale> {
248 protected Key normalizeKey(Key key) {
249 return Key.normalize(key);
252 protected BaseLocale createObject(Key key) {
253 return new BaseLocale(key._lang, key._scrt, key._regn, key._vart);