Path: blob/master/src/java.base/share/classes/sun/util/locale/LocaleExtensions.java
41159 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*/31package sun.util.locale;3233import java.util.Collections;34import java.util.Map;35import java.util.Map.Entry;36import java.util.Set;37import java.util.SortedMap;38import java.util.SortedSet;39import java.util.TreeMap;40import java.util.TreeSet;4142import sun.util.locale.InternalLocaleBuilder.CaseInsensitiveChar;43import sun.util.locale.InternalLocaleBuilder.CaseInsensitiveString;444546public class LocaleExtensions {4748private final Map<Character, Extension> extensionMap;49private final String id;5051public static final LocaleExtensions CALENDAR_JAPANESE52= new LocaleExtensions("u-ca-japanese",53UnicodeLocaleExtension.SINGLETON,54UnicodeLocaleExtension.CA_JAPANESE);5556public static final LocaleExtensions NUMBER_THAI57= new LocaleExtensions("u-nu-thai",58UnicodeLocaleExtension.SINGLETON,59UnicodeLocaleExtension.NU_THAI);6061private LocaleExtensions(String id, Character key, Extension value) {62this.id = id;63this.extensionMap = Collections.singletonMap(key, value);64}6566/*67* Package private constructor, only used by InternalLocaleBuilder.68*/69LocaleExtensions(Map<CaseInsensitiveChar, String> extensions,70Set<CaseInsensitiveString> uattributes,71Map<CaseInsensitiveString, String> ukeywords) {72boolean hasExtension = !LocaleUtils.isEmpty(extensions);73boolean hasUAttributes = !LocaleUtils.isEmpty(uattributes);74boolean hasUKeywords = !LocaleUtils.isEmpty(ukeywords);7576if (!hasExtension && !hasUAttributes && !hasUKeywords) {77id = "";78extensionMap = Collections.emptyMap();79return;80}8182// Build extension map83SortedMap<Character, Extension> map = new TreeMap<>();84if (hasExtension) {85for (Entry<CaseInsensitiveChar, String> ext : extensions.entrySet()) {86char key = LocaleUtils.toLower(ext.getKey().value());87String value = ext.getValue();8889if (LanguageTag.isPrivateusePrefixChar(key)) {90// we need to exclude special variant in privuateuse, e.g. "x-abc-lvariant-DEF"91value = InternalLocaleBuilder.removePrivateuseVariant(value);92if (value == null) {93continue;94}95}9697map.put(key, new Extension(key, LocaleUtils.toLowerString(value)));98}99}100101if (hasUAttributes || hasUKeywords) {102SortedSet<String> uaset = null;103SortedMap<String, String> ukmap = null;104105if (hasUAttributes) {106uaset = new TreeSet<>();107for (CaseInsensitiveString cis : uattributes) {108uaset.add(LocaleUtils.toLowerString(cis.value()));109}110}111112if (hasUKeywords) {113ukmap = new TreeMap<>();114for (Entry<CaseInsensitiveString, String> kwd : ukeywords.entrySet()) {115String key = LocaleUtils.toLowerString(kwd.getKey().value());116String type = LocaleUtils.toLowerString(kwd.getValue());117ukmap.put(key, type);118}119}120121UnicodeLocaleExtension ule = new UnicodeLocaleExtension(uaset, ukmap);122map.put(UnicodeLocaleExtension.SINGLETON, ule);123}124125if (map.isEmpty()) {126// this could happen when only privuateuse with special variant127id = "";128extensionMap = Collections.emptyMap();129} else {130id = toID(map);131extensionMap = map;132}133}134135public Set<Character> getKeys() {136if (extensionMap.isEmpty()) {137return Collections.emptySet();138}139return Collections.unmodifiableSet(extensionMap.keySet());140}141142public Extension getExtension(Character key) {143return extensionMap.get(LocaleUtils.toLower(key));144}145146public String getExtensionValue(Character key) {147Extension ext = extensionMap.get(LocaleUtils.toLower(key));148if (ext == null) {149return null;150}151return ext.getValue();152}153154public Set<String> getUnicodeLocaleAttributes() {155Extension ext = extensionMap.get(UnicodeLocaleExtension.SINGLETON);156if (ext == null) {157return Collections.emptySet();158}159assert (ext instanceof UnicodeLocaleExtension);160return ((UnicodeLocaleExtension)ext).getUnicodeLocaleAttributes();161}162163public Set<String> getUnicodeLocaleKeys() {164Extension ext = extensionMap.get(UnicodeLocaleExtension.SINGLETON);165if (ext == null) {166return Collections.emptySet();167}168assert (ext instanceof UnicodeLocaleExtension);169return ((UnicodeLocaleExtension)ext).getUnicodeLocaleKeys();170}171172public String getUnicodeLocaleType(String unicodeLocaleKey) {173Extension ext = extensionMap.get(UnicodeLocaleExtension.SINGLETON);174if (ext == null) {175return null;176}177assert (ext instanceof UnicodeLocaleExtension);178return ((UnicodeLocaleExtension)ext).getUnicodeLocaleType(LocaleUtils.toLowerString(unicodeLocaleKey));179}180181public boolean isEmpty() {182return extensionMap.isEmpty();183}184185public static boolean isValidKey(char c) {186return LanguageTag.isExtensionSingletonChar(c) || LanguageTag.isPrivateusePrefixChar(c);187}188189public static boolean isValidUnicodeLocaleKey(String ukey) {190return UnicodeLocaleExtension.isKey(ukey);191}192193private static String toID(SortedMap<Character, Extension> map) {194StringBuilder buf = new StringBuilder();195Extension privuse = null;196for (Entry<Character, Extension> entry : map.entrySet()) {197char singleton = entry.getKey();198Extension extension = entry.getValue();199if (LanguageTag.isPrivateusePrefixChar(singleton)) {200privuse = extension;201} else {202if (buf.length() > 0) {203buf.append(LanguageTag.SEP);204}205buf.append(extension);206}207}208if (privuse != null) {209if (buf.length() > 0) {210buf.append(LanguageTag.SEP);211}212buf.append(privuse);213}214return buf.toString();215}216217@Override218public String toString() {219return id;220}221222public String getID() {223return id;224}225226@Override227public int hashCode() {228return id.hashCode();229}230231@Override232public boolean equals(Object other) {233if (this == other) {234return true;235}236if (!(other instanceof LocaleExtensions)) {237return false;238}239return id.equals(((LocaleExtensions)other).id);240}241}242243244