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
11 public final class BaseLocale {
\r
13 private static final boolean JDKIMPL = false;
\r
15 private String _language = "";
\r
16 private String _script = "";
\r
17 private String _region = "";
\r
18 private String _variant = "";
\r
20 private transient volatile int _hash = 0;
\r
22 private static final LocaleObjectCache<Key, BaseLocale> BASELOCALE_CACHE
\r
23 = new LocaleObjectCache<Key, BaseLocale>();
\r
25 public static final BaseLocale ROOT = BaseLocale.getInstance("", "", "", "");
\r
27 private BaseLocale(String language, String script, String region, String variant) {
\r
28 if (language != null) {
\r
29 _language = AsciiUtil.toLowerString(language).intern();
\r
31 if (script != null) {
\r
32 _script = AsciiUtil.toTitleString(script).intern();
\r
34 if (region != null) {
\r
35 _region = AsciiUtil.toUpperString(region).intern();
\r
37 if (variant != null) {
\r
39 // preserve upper/lower cases
\r
40 _variant = variant.intern();
\r
42 _variant = AsciiUtil.toUpperString(variant).intern();
\r
47 public static BaseLocale getInstance(String language, String script, String region, String variant) {
\r
49 // JDK uses deprecated ISO639.1 language codes for he, yi and id
\r
50 if (AsciiUtil.caseIgnoreMatch(language, "he")) {
\r
52 } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) {
\r
54 } else if (AsciiUtil.caseIgnoreMatch(language, "id")) {
\r
58 Key key = new Key(language, script, region, variant);
\r
59 BaseLocale baseLocale = BASELOCALE_CACHE.get(key);
\r
60 if (baseLocale == null) {
\r
61 baseLocale = new BaseLocale(language, script, region, variant);
\r
62 baseLocale = BASELOCALE_CACHE.put(baseLocale.createKey(), baseLocale);
\r
67 public String getLanguage() {
\r
71 public String getScript() {
\r
75 public String getRegion() {
\r
79 public String getVariant() {
\r
83 public String toString() {
\r
84 StringBuilder buf = new StringBuilder();
\r
85 if (_language.length() > 0) {
\r
86 buf.append("language=");
\r
87 buf.append(_language);
\r
89 if (_script.length() > 0) {
\r
90 if (buf.length() > 0) {
\r
93 buf.append("script=");
\r
94 buf.append(_script);
\r
96 if (_region.length() > 0) {
\r
97 if (buf.length() > 0) {
\r
100 buf.append("region=");
\r
101 buf.append(_region);
\r
103 if (_variant.length() > 0) {
\r
104 if (buf.length() > 0) {
\r
107 buf.append("variant=");
\r
108 buf.append(_variant);
\r
110 return buf.toString();
\r
113 public int hashCode() {
\r
116 // Generating a hash value from language, script, region and variant
\r
117 for (int i = 0; i < _language.length(); i++) {
\r
118 h = 31*h + _language.charAt(i);
\r
120 for (int i = 0; i < _script.length(); i++) {
\r
121 h = 31*h + _script.charAt(i);
\r
123 for (int i = 0; i < _region.length(); i++) {
\r
124 h = 31*h + _region.charAt(i);
\r
126 for (int i = 0; i < _variant.length(); i++) {
\r
127 h = 31*h + _variant.charAt(i);
\r
134 private Key createKey() {
\r
135 return new Key(_language, _script, _region, _variant);
\r
138 private static class Key implements Comparable<Key> {
\r
139 private String _lang = "";
\r
140 private String _scrt = "";
\r
141 private String _regn = "";
\r
142 private String _vart = "";
\r
144 private volatile int _hash; // Default to 0
\r
146 public Key(String language, String script, String region, String variant) {
\r
147 if (language != null) {
\r
150 if (script != null) {
\r
153 if (region != null) {
\r
156 if (variant != null) {
\r
161 public boolean equals(Object obj) {
\r
163 return (this == obj) ||
\r
164 (obj instanceof Key)
\r
165 && AsciiUtil.caseIgnoreMatch(((Key)obj)._lang, this._lang)
\r
166 && AsciiUtil.caseIgnoreMatch(((Key)obj)._scrt, this._scrt)
\r
167 && AsciiUtil.caseIgnoreMatch(((Key)obj)._regn, this._regn)
\r
168 && ((Key)obj)._vart.equals(_vart); // variant is case sensitive in JDK!
\r
170 return (this == obj) ||
\r
171 (obj instanceof Key)
\r
172 && AsciiUtil.caseIgnoreMatch(((Key)obj)._lang, this._lang)
\r
173 && AsciiUtil.caseIgnoreMatch(((Key)obj)._scrt, this._scrt)
\r
174 && AsciiUtil.caseIgnoreMatch(((Key)obj)._regn, this._regn)
\r
175 && AsciiUtil.caseIgnoreMatch(((Key)obj)._vart, this._vart);
\r
178 public int compareTo(Key other) {
\r
179 int res = AsciiUtil.caseIgnoreCompare(this._lang, other._lang);
\r
181 res = AsciiUtil.caseIgnoreCompare(this._scrt, other._scrt);
\r
183 res = AsciiUtil.caseIgnoreCompare(this._regn, other._regn);
\r
186 res = this._vart.compareTo(other._vart);
\r
188 res = AsciiUtil.caseIgnoreCompare(this._vart, other._vart);
\r
196 public int hashCode() {
\r
199 // Generating a hash value from language, script, region and variant
\r
200 for (int i = 0; i < _lang.length(); i++) {
\r
201 h = 31*h + AsciiUtil.toLower(_lang.charAt(i));
\r
203 for (int i = 0; i < _scrt.length(); i++) {
\r
204 h = 31*h + AsciiUtil.toLower(_scrt.charAt(i));
\r
206 for (int i = 0; i < _regn.length(); i++) {
\r
207 h = 31*h + AsciiUtil.toLower(_regn.charAt(i));
\r
209 for (int i = 0; i < _vart.length(); i++) {
\r
211 h = 31*h + _vart.charAt(i);
\r
213 h = 31*h + AsciiUtil.toLower(_vart.charAt(i));
\r