Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/util/locale/BaseLocale.java
38918 views
/*1* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26*******************************************************************************27* Copyright (C) 2009-2010, International Business Machines Corporation and *28* others. All Rights Reserved. *29*******************************************************************************30*/3132package sun.util.locale;33import java.lang.ref.SoftReference;343536public final class BaseLocale {3738public static final String SEP = "_";3940private static final Cache CACHE = new Cache();4142private final String language;43private final String script;44private final String region;45private final String variant;4647private volatile int hash = 0;4849// This method must be called only when creating the Locale.* constants.50private BaseLocale(String language, String region) {51this.language = language;52this.script = "";53this.region = region;54this.variant = "";55}5657private BaseLocale(String language, String script, String region, String variant) {58this.language = (language != null) ? LocaleUtils.toLowerString(language).intern() : "";59this.script = (script != null) ? LocaleUtils.toTitleString(script).intern() : "";60this.region = (region != null) ? LocaleUtils.toUpperString(region).intern() : "";61this.variant = (variant != null) ? variant.intern() : "";62}6364// Called for creating the Locale.* constants. No argument65// validation is performed.66public static BaseLocale createInstance(String language, String region) {67BaseLocale base = new BaseLocale(language, region);68CACHE.put(new Key(language, region), base);69return base;70}7172public static BaseLocale getInstance(String language, String script,73String region, String variant) {74// JDK uses deprecated ISO639.1 language codes for he, yi and id75if (language != null) {76if (LocaleUtils.caseIgnoreMatch(language, "he")) {77language = "iw";78} else if (LocaleUtils.caseIgnoreMatch(language, "yi")) {79language = "ji";80} else if (LocaleUtils.caseIgnoreMatch(language, "id")) {81language = "in";82}83}8485Key key = new Key(language, script, region, variant);86BaseLocale baseLocale = CACHE.get(key);87return baseLocale;88}8990public String getLanguage() {91return language;92}9394public String getScript() {95return script;96}9798public String getRegion() {99return region;100}101102public String getVariant() {103return variant;104}105106@Override107public boolean equals(Object obj) {108if (this == obj) {109return true;110}111if (!(obj instanceof BaseLocale)) {112return false;113}114BaseLocale other = (BaseLocale)obj;115return language == other.language116&& script == other.script117&& region == other.region118&& variant == other.variant;119}120121@Override122public String toString() {123StringBuilder buf = new StringBuilder();124if (language.length() > 0) {125buf.append("language=");126buf.append(language);127}128if (script.length() > 0) {129if (buf.length() > 0) {130buf.append(", ");131}132buf.append("script=");133buf.append(script);134}135if (region.length() > 0) {136if (buf.length() > 0) {137buf.append(", ");138}139buf.append("region=");140buf.append(region);141}142if (variant.length() > 0) {143if (buf.length() > 0) {144buf.append(", ");145}146buf.append("variant=");147buf.append(variant);148}149return buf.toString();150}151152@Override153public int hashCode() {154int h = hash;155if (h == 0) {156// Generating a hash value from language, script, region and variant157h = language.hashCode();158h = 31 * h + script.hashCode();159h = 31 * h + region.hashCode();160h = 31 * h + variant.hashCode();161hash = h;162}163return h;164}165166private static final class Key {167private final SoftReference<String> lang;168private final SoftReference<String> scrt;169private final SoftReference<String> regn;170private final SoftReference<String> vart;171private final boolean normalized;172private final int hash;173174/**175* Creates a Key. language and region must be normalized176* (intern'ed in the proper case).177*/178private Key(String language, String region) {179assert language.intern() == language180&& region.intern() == region;181182lang = new SoftReference(language);183scrt = new SoftReference("");184regn = new SoftReference(region);185vart = new SoftReference("");186this.normalized = true;187188int h = language.hashCode();189if (region != "") {190int len = region.length();191for (int i = 0; i < len; i++) {192h = 31 * h + LocaleUtils.toLower(region.charAt(i));193}194}195hash = h;196}197198public Key(String language, String script, String region, String variant) {199this(language, script, region, variant, false);200}201202private Key(String language, String script, String region,203String variant, boolean normalized) {204int h = 0;205if (language != null) {206lang = new SoftReference(language);207int len = language.length();208for (int i = 0; i < len; i++) {209h = 31*h + LocaleUtils.toLower(language.charAt(i));210}211} else {212lang = new SoftReference("");213}214if (script != null) {215scrt = new SoftReference(script);216int len = script.length();217for (int i = 0; i < len; i++) {218h = 31*h + LocaleUtils.toLower(script.charAt(i));219}220} else {221scrt = new SoftReference("");222}223if (region != null) {224regn = new SoftReference(region);225int len = region.length();226for (int i = 0; i < len; i++) {227h = 31*h + LocaleUtils.toLower(region.charAt(i));228}229} else {230regn = new SoftReference("");231}232if (variant != null) {233vart = new SoftReference(variant);234int len = variant.length();235for (int i = 0; i < len; i++) {236h = 31*h + variant.charAt(i);237}238} else {239vart = new SoftReference("");240}241hash = h;242this.normalized = normalized;243}244245@Override246public boolean equals(Object obj) {247if (this == obj) {248return true;249}250251if (obj instanceof Key && this.hash == ((Key)obj).hash) {252String tl = this.lang.get();253String ol = ((Key)obj).lang.get();254if (tl != null && ol != null &&255LocaleUtils.caseIgnoreMatch(ol, tl)) {256String ts = this.scrt.get();257String os = ((Key)obj).scrt.get();258if (ts != null && os != null &&259LocaleUtils.caseIgnoreMatch(os, ts)) {260String tr = this.regn.get();261String or = ((Key)obj).regn.get();262if (tr != null && or != null &&263LocaleUtils.caseIgnoreMatch(or, tr)) {264String tv = this.vart.get();265String ov = ((Key)obj).vart.get();266return (ov != null && ov.equals(tv));267}268}269}270}271return false;272}273274@Override275public int hashCode() {276return hash;277}278279public static Key normalize(Key key) {280if (key.normalized) {281return key;282}283284String lang = LocaleUtils.toLowerString(key.lang.get()).intern();285String scrt = LocaleUtils.toTitleString(key.scrt.get()).intern();286String regn = LocaleUtils.toUpperString(key.regn.get()).intern();287String vart = key.vart.get().intern(); // preserve upper/lower cases288289return new Key(lang, scrt, regn, vart, true);290}291}292293private static class Cache extends LocaleObjectCache<Key, BaseLocale> {294295public Cache() {296}297298@Override299protected Key normalizeKey(Key key) {300assert key.lang.get() != null &&301key.scrt.get() != null &&302key.regn.get() != null &&303key.vart.get() != null;304305return Key.normalize(key);306}307308@Override309protected BaseLocale createObject(Key key) {310return new BaseLocale(key.lang.get(), key.scrt.get(),311key.regn.get(), key.vart.get());312}313}314}315316317