/* ******************************************************************************* * Copyright (C) 2009, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ package com.ibm.icu.impl.locale; public final class BaseLocale { private static final boolean JDKIMPL = false; private String _language = ""; private String _script = ""; private String _region = ""; private String _variant = ""; private transient volatile int _hash = 0; private static final LocaleObjectCache BASELOCALE_CACHE = new LocaleObjectCache(); public static final BaseLocale ROOT = BaseLocale.getInstance("", "", "", ""); private BaseLocale(String language, String script, String region, String variant) { if (language != null) { _language = AsciiUtil.toLowerString(language).intern(); } if (script != null) { _script = AsciiUtil.toTitleString(script).intern(); } if (region != null) { _region = AsciiUtil.toUpperString(region).intern(); } if (variant != null) { if (JDKIMPL) { // preserve upper/lower cases _variant = variant.intern(); } else { _variant = AsciiUtil.toUpperString(variant).intern(); } } } public static BaseLocale getInstance(String language, String script, String region, String variant) { if (JDKIMPL) { // JDK uses deprecated ISO639.1 language codes for he, yi and id if (AsciiUtil.caseIgnoreMatch(language, "he")) { language = "iw"; } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) { language = "ji"; } else if (AsciiUtil.caseIgnoreMatch(language, "id")) { language = "in"; } } Key key = new Key(language, script, region, variant); BaseLocale baseLocale = BASELOCALE_CACHE.get(key); if (baseLocale == null) { baseLocale = new BaseLocale(language, script, region, variant); baseLocale = BASELOCALE_CACHE.put(baseLocale.createKey(), baseLocale); } return baseLocale; } public String getLanguage() { return _language; } public String getScript() { return _script; } public String getRegion() { return _region; } public String getVariant() { return _variant; } public String toString() { StringBuilder buf = new StringBuilder(); if (_language.length() > 0) { buf.append("language="); buf.append(_language); } if (_script.length() > 0) { if (buf.length() > 0) { buf.append(", "); } buf.append("script="); buf.append(_script); } if (_region.length() > 0) { if (buf.length() > 0) { buf.append(", "); } buf.append("region="); buf.append(_region); } if (_variant.length() > 0) { if (buf.length() > 0) { buf.append(", "); } buf.append("variant="); buf.append(_variant); } return buf.toString(); } public int hashCode() { int h = _hash; if (h == 0) { // Generating a hash value from language, script, region and variant for (int i = 0; i < _language.length(); i++) { h = 31*h + _language.charAt(i); } for (int i = 0; i < _script.length(); i++) { h = 31*h + _script.charAt(i); } for (int i = 0; i < _region.length(); i++) { h = 31*h + _region.charAt(i); } for (int i = 0; i < _variant.length(); i++) { h = 31*h + _variant.charAt(i); } _hash = h; } return h; } private Key createKey() { return new Key(_language, _script, _region, _variant); } private static class Key implements Comparable { private String _lang = ""; private String _scrt = ""; private String _regn = ""; private String _vart = ""; private volatile int _hash; // Default to 0 public Key(String language, String script, String region, String variant) { if (language != null) { _lang = language; } if (script != null) { _scrt = script; } if (region != null) { _regn = region; } if (variant != null) { _vart = variant; } } public boolean equals(Object obj) { if (JDKIMPL) { return (this == obj) || (obj instanceof Key) && AsciiUtil.caseIgnoreMatch(((Key)obj)._lang, this._lang) && AsciiUtil.caseIgnoreMatch(((Key)obj)._scrt, this._scrt) && AsciiUtil.caseIgnoreMatch(((Key)obj)._regn, this._regn) && ((Key)obj)._vart.equals(_vart); // variant is case sensitive in JDK! } return (this == obj) || (obj instanceof Key) && AsciiUtil.caseIgnoreMatch(((Key)obj)._lang, this._lang) && AsciiUtil.caseIgnoreMatch(((Key)obj)._scrt, this._scrt) && AsciiUtil.caseIgnoreMatch(((Key)obj)._regn, this._regn) && AsciiUtil.caseIgnoreMatch(((Key)obj)._vart, this._vart); } public int compareTo(Key other) { int res = AsciiUtil.caseIgnoreCompare(this._lang, other._lang); if (res == 0) { res = AsciiUtil.caseIgnoreCompare(this._scrt, other._scrt); if (res == 0) { res = AsciiUtil.caseIgnoreCompare(this._regn, other._regn); if (res == 0) { if (JDKIMPL) { res = this._vart.compareTo(other._vart); } else { res = AsciiUtil.caseIgnoreCompare(this._vart, other._vart); } } } } return res; } public int hashCode() { int h = _hash; if (h == 0) { // Generating a hash value from language, script, region and variant for (int i = 0; i < _lang.length(); i++) { h = 31*h + AsciiUtil.toLower(_lang.charAt(i)); } for (int i = 0; i < _scrt.length(); i++) { h = 31*h + AsciiUtil.toLower(_scrt.charAt(i)); } for (int i = 0; i < _regn.length(); i++) { h = 31*h + AsciiUtil.toLower(_regn.charAt(i)); } for (int i = 0; i < _vart.length(); i++) { if (JDKIMPL) { h = 31*h + _vart.charAt(i); } else { h = 31*h + AsciiUtil.toLower(_vart.charAt(i)); } } _hash = h; } return h; } } }