2
*******************************************************************************
3
* Copyright (C) 2009, International Business Machines Corporation and *
4
* others. All Rights Reserved. *
5
*******************************************************************************
7
package com.ibm.icu.impl.locale;
9
import java.util.Collections;
11
import java.util.SortedMap;
12
import java.util.TreeMap;
13
import java.util.Map.Entry;
15
import com.ibm.icu.impl.locale.LanguageTag.ParseStatus;
18
public class LocaleExtensions {
20
private SortedMap<Character, Extension> _map = EMPTY_MAP;
21
private String _id = "";
23
private static final SortedMap<Character, Extension> EMPTY_MAP =
24
Collections.unmodifiableSortedMap(new TreeMap<Character, Extension>());
26
private static final LocaleObjectCache<String, LocaleExtensions> LOCALEEXTENSIONS_CACHE =
27
new LocaleObjectCache<String, LocaleExtensions>();
30
public static LocaleExtensions EMPTY_EXTENSIONS = new LocaleExtensions();
32
public static final LocaleExtensions CALENDAR_JAPANESE;
33
public static final LocaleExtensions NUMBER_THAI;
36
CALENDAR_JAPANESE = new LocaleExtensions();
37
CALENDAR_JAPANESE._id = UnicodeLocaleExtension.CA_JAPANESE.getID();
38
CALENDAR_JAPANESE._map = new TreeMap<Character, Extension>();
39
CALENDAR_JAPANESE._map.put(Character.valueOf(UnicodeLocaleExtension.CA_JAPANESE.getKey()), UnicodeLocaleExtension.CA_JAPANESE);
40
LOCALEEXTENSIONS_CACHE.put(CALENDAR_JAPANESE._id, CALENDAR_JAPANESE);
42
NUMBER_THAI = new LocaleExtensions();
43
NUMBER_THAI._id = UnicodeLocaleExtension.NU_THAI.getID();
44
NUMBER_THAI._map = new TreeMap<Character, Extension>();
45
NUMBER_THAI._map.put(Character.valueOf(UnicodeLocaleExtension.NU_THAI.getKey()), UnicodeLocaleExtension.NU_THAI);
46
LOCALEEXTENSIONS_CACHE.put(NUMBER_THAI._id, NUMBER_THAI);
50
private LocaleExtensions() {
53
public static LocaleExtensions getInstance(String str) throws LocaleSyntaxException {
54
if (str == null || str.length() == 0) {
55
return EMPTY_EXTENSIONS;
57
LocaleExtensions exts = LOCALEEXTENSIONS_CACHE.get(str);
59
StringTokenIterator itr = new StringTokenIterator(str, LanguageTag.SEP);
60
ParseStatus sts = new ParseStatus();
61
TreeMap<Character, Extension> map = new TreeMap<Character, Extension>();
63
while (!itr.isDone()) {
64
int startOffset = itr.currentEnd();
65
Extension ext = Extension.create(itr, sts);
67
throw new LocaleSyntaxException(sts.errorMsg, sts.errorIndex);
70
throw new LocaleSyntaxException("Invalid extension subtag: " + itr.current(), startOffset);
73
Character keyChar = Character.valueOf(ext.getKey());
74
if (map.containsKey(keyChar)) {
75
throw new LocaleSyntaxException("Duplicated extension: " + keyChar, startOffset);
78
map.put(keyChar, ext);
81
String id = toID(map);
82
// check the cache with canonicalized ID
83
exts = LOCALEEXTENSIONS_CACHE.get(id);
85
exts = new LocaleExtensions();
89
exts = LOCALEEXTENSIONS_CACHE.put(id, exts);
95
static LocaleExtensions getInstance(SortedMap<Character, Extension> map) {
96
if (map == null || map.isEmpty()) {
97
return EMPTY_EXTENSIONS;
99
String id = toID(map);
100
LocaleExtensions exts = LOCALEEXTENSIONS_CACHE.get(id);
102
exts = new LocaleExtensions();
103
exts._map = new TreeMap<Character, Extension>(map);
106
exts = LOCALEEXTENSIONS_CACHE.put(id, exts);
111
private static String toID(SortedMap<Character, Extension> map) {
112
StringBuilder buf = new StringBuilder();
113
Extension privuse = null;
114
if (map != null && !map.isEmpty()) {
115
Set<Entry<Character, Extension>> entries = map.entrySet();
116
for (Entry<Character, Extension> entry : entries) {
117
Character key = entry.getKey();
118
if (key.charValue() == LanguageTag.PRIVATEUSE.charAt(0)) {
119
privuse = entry.getValue();
122
if (buf.length() > 0) {
123
buf.append(LanguageTag.SEP);
125
buf.append(entry.getKey());
126
buf.append(LanguageTag.SEP);
127
buf.append(entry.getValue().getValue());
130
if (privuse != null) {
131
if (buf.length() > 0) {
132
buf.append(LanguageTag.SEP);
134
buf.append(LanguageTag.PRIVATEUSE);
135
buf.append(LanguageTag.SEP);
136
buf.append(privuse.getValue());
138
return buf.toString();
141
public Set<Character> getKeys() {
142
return Collections.unmodifiableSet(_map.keySet());
145
public Extension getExtension(Character key) {
146
return _map.get(key);
149
public String getExtensionValue(Character key) {
150
Extension ext = _map.get(key);
154
return ext.getValue();
157
public Set<String> getUnicodeLocaleKeys() {
158
Extension ext = _map.get(Character.valueOf(UnicodeLocaleExtension.SINGLETON));
160
return Collections.emptySet();
162
assert (ext instanceof UnicodeLocaleExtension);
163
return ((UnicodeLocaleExtension)ext).getKeys();
166
public String getUnicodeLocaleType(String unicodeLocaleKey) {
167
Extension ext = _map.get(Character.valueOf(UnicodeLocaleExtension.SINGLETON));
171
assert (ext instanceof UnicodeLocaleExtension);
172
return ((UnicodeLocaleExtension)ext).getType(unicodeLocaleKey);
175
public String toString() {
179
public String getID() {
183
public int hashCode() {
184
return _id.hashCode();
187
public static boolean isValidKey(String key) {
188
return LanguageTag.isExtensionSingleton(key) || LanguageTag.isPrivateuseSingleton(key);