]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/main/classes/core/src/com/ibm/icu/impl/locale/LocaleExtensions.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / main / classes / core / src / com / ibm / icu / impl / locale / LocaleExtensions.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 2009, International Business Machines Corporation and         *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 package com.ibm.icu.impl.locale;\r
8 \r
9 import java.util.Collections;\r
10 import java.util.Set;\r
11 import java.util.SortedMap;\r
12 import java.util.TreeMap;\r
13 import java.util.Map.Entry;\r
14 \r
15 import com.ibm.icu.impl.locale.LanguageTag.ParseStatus;\r
16 \r
17 \r
18 public class LocaleExtensions {\r
19 \r
20     private SortedMap<Character, Extension> _map = EMPTY_MAP;\r
21     private String _id = "";\r
22 \r
23     private static final SortedMap<Character, Extension> EMPTY_MAP =\r
24         Collections.unmodifiableSortedMap(new TreeMap<Character, Extension>());\r
25 \r
26     private static final LocaleObjectCache<String, LocaleExtensions> LOCALEEXTENSIONS_CACHE =\r
27         new LocaleObjectCache<String, LocaleExtensions>();\r
28 \r
29 \r
30     public static LocaleExtensions EMPTY_EXTENSIONS = new LocaleExtensions();\r
31 \r
32     public static final LocaleExtensions CALENDAR_JAPANESE;\r
33     public static final LocaleExtensions NUMBER_THAI;\r
34 \r
35     static {\r
36         CALENDAR_JAPANESE = new LocaleExtensions();\r
37         CALENDAR_JAPANESE._id = UnicodeLocaleExtension.CA_JAPANESE.getID();\r
38         CALENDAR_JAPANESE._map = new TreeMap<Character, Extension>();\r
39         CALENDAR_JAPANESE._map.put(Character.valueOf(UnicodeLocaleExtension.CA_JAPANESE.getKey()), UnicodeLocaleExtension.CA_JAPANESE);\r
40         LOCALEEXTENSIONS_CACHE.put(CALENDAR_JAPANESE._id, CALENDAR_JAPANESE);\r
41 \r
42         NUMBER_THAI = new LocaleExtensions();\r
43         NUMBER_THAI._id = UnicodeLocaleExtension.NU_THAI.getID();\r
44         NUMBER_THAI._map = new TreeMap<Character, Extension>();\r
45         NUMBER_THAI._map.put(Character.valueOf(UnicodeLocaleExtension.NU_THAI.getKey()), UnicodeLocaleExtension.NU_THAI);\r
46         LOCALEEXTENSIONS_CACHE.put(NUMBER_THAI._id, NUMBER_THAI);\r
47     }\r
48 \r
49 \r
50     private LocaleExtensions() {\r
51     }\r
52 \r
53     public static LocaleExtensions getInstance(String str) throws LocaleSyntaxException {\r
54         if (str == null || str.length() == 0) {\r
55             return EMPTY_EXTENSIONS;\r
56         }\r
57         LocaleExtensions exts = LOCALEEXTENSIONS_CACHE.get(str);\r
58         if (exts == null) {\r
59             StringTokenIterator itr = new StringTokenIterator(str, LanguageTag.SEP);\r
60             ParseStatus sts = new ParseStatus();\r
61             TreeMap<Character, Extension> map = new TreeMap<Character, Extension>();\r
62 \r
63             while (!itr.isDone()) {\r
64                 int startOffset = itr.currentEnd();\r
65                 Extension ext = Extension.create(itr, sts);\r
66                 if (sts.isError()) {\r
67                     throw new LocaleSyntaxException(sts.errorMsg, sts.errorIndex);\r
68                 }\r
69                 if (ext == null) {\r
70                     throw new LocaleSyntaxException("Invalid extension subtag: " + itr.current(), startOffset);\r
71                 }\r
72 \r
73                 Character keyChar = Character.valueOf(ext.getKey());\r
74                 if (map.containsKey(keyChar)) {\r
75                     throw new LocaleSyntaxException("Duplicated extension: " + keyChar, startOffset);\r
76                 }\r
77 \r
78                 map.put(keyChar, ext);\r
79             }\r
80 \r
81             String id = toID(map);\r
82             // check the cache with canonicalized ID\r
83             exts = LOCALEEXTENSIONS_CACHE.get(id);\r
84             if (exts == null) {\r
85                 exts = new LocaleExtensions();\r
86                 exts._map = map;\r
87                 exts._id = id;\r
88 \r
89                 exts = LOCALEEXTENSIONS_CACHE.put(id, exts);\r
90             }\r
91         }\r
92         return exts;\r
93     }\r
94 \r
95     static LocaleExtensions getInstance(SortedMap<Character, Extension> map) {\r
96         if (map == null || map.isEmpty()) {\r
97             return EMPTY_EXTENSIONS;\r
98         }\r
99         String id = toID(map);\r
100         LocaleExtensions exts = LOCALEEXTENSIONS_CACHE.get(id);\r
101         if (exts == null) {\r
102             exts = new LocaleExtensions();\r
103             exts._map = new TreeMap<Character, Extension>(map);\r
104             exts._id = id;\r
105 \r
106             exts = LOCALEEXTENSIONS_CACHE.put(id, exts);\r
107         }\r
108         return exts;\r
109     }\r
110 \r
111     private static String toID(SortedMap<Character, Extension> map) {\r
112         StringBuilder buf = new StringBuilder();\r
113         Extension privuse = null;\r
114         if (map != null && !map.isEmpty()) {\r
115             Set<Entry<Character, Extension>> entries = map.entrySet();\r
116             for (Entry<Character, Extension> entry : entries) {\r
117                 Character key = entry.getKey();\r
118                 if (key.charValue() == LanguageTag.PRIVATEUSE.charAt(0)) {\r
119                     privuse = entry.getValue();\r
120                     continue;\r
121                 }\r
122                 if (buf.length() > 0) {\r
123                     buf.append(LanguageTag.SEP);\r
124                 }\r
125                 buf.append(entry.getKey());\r
126                 buf.append(LanguageTag.SEP);\r
127                 buf.append(entry.getValue().getValue());\r
128             }\r
129         }\r
130         if (privuse != null) {\r
131             if (buf.length() > 0) {\r
132                 buf.append(LanguageTag.SEP);\r
133             }\r
134             buf.append(LanguageTag.PRIVATEUSE);\r
135             buf.append(LanguageTag.SEP);\r
136             buf.append(privuse.getValue());\r
137         }\r
138         return buf.toString();\r
139     }\r
140 \r
141     public Set<Character> getKeys() {\r
142         return Collections.unmodifiableSet(_map.keySet());\r
143     }\r
144 \r
145     public Extension getExtension(Character key) {\r
146         return _map.get(key);\r
147     }\r
148 \r
149     public String getExtensionValue(Character key) {\r
150         Extension ext = _map.get(key);\r
151         if (ext == null) {\r
152             return "";\r
153         }\r
154         return ext.getValue();\r
155     }\r
156 \r
157     public Set<String> getUnicodeLocaleKeys() {\r
158         Extension ext = _map.get(Character.valueOf(UnicodeLocaleExtension.SINGLETON));\r
159         if (ext == null) {\r
160             return Collections.emptySet();\r
161         }\r
162         assert (ext instanceof UnicodeLocaleExtension);\r
163         return ((UnicodeLocaleExtension)ext).getKeys();\r
164     }\r
165 \r
166     public String getUnicodeLocaleType(String unicodeLocaleKey) {\r
167         Extension ext = _map.get(Character.valueOf(UnicodeLocaleExtension.SINGLETON));\r
168         if (ext == null) {\r
169             return "";\r
170         }\r
171         assert (ext instanceof UnicodeLocaleExtension);\r
172         return ((UnicodeLocaleExtension)ext).getType(unicodeLocaleKey);\r
173     }\r
174 \r
175     public String toString() {\r
176         return _id;\r
177     }\r
178 \r
179     public String getID() {\r
180         return _id;\r
181     }\r
182 \r
183     public int hashCode() {\r
184         return _id.hashCode();\r
185     }\r
186 \r
187     public static boolean isValidKey(String key) {\r
188         return LanguageTag.isExtensionSingleton(key) || LanguageTag.isPrivateuseSingleton(key);\r
189     }\r
190 }\r