34 import java.util.Collections; |
34 import java.util.Collections; |
35 import java.util.Map; |
35 import java.util.Map; |
36 import java.util.Map.Entry; |
36 import java.util.Map.Entry; |
37 import java.util.Set; |
37 import java.util.Set; |
38 import java.util.SortedMap; |
38 import java.util.SortedMap; |
|
39 import java.util.SortedSet; |
39 import java.util.TreeMap; |
40 import java.util.TreeMap; |
40 import java.util.TreeSet; |
41 import java.util.TreeSet; |
41 |
42 |
42 import sun.util.locale.InternalLocaleBuilder.CaseInsensitiveChar; |
43 import sun.util.locale.InternalLocaleBuilder.CaseInsensitiveChar; |
43 import sun.util.locale.InternalLocaleBuilder.CaseInsensitiveString; |
44 import sun.util.locale.InternalLocaleBuilder.CaseInsensitiveString; |
44 |
45 |
45 |
46 |
46 public class LocaleExtensions { |
47 public class LocaleExtensions { |
47 |
48 |
48 private SortedMap<Character, Extension> _map; |
49 private final Map<Character, Extension> extensionMap; |
49 private String _id; |
50 private final String id; |
50 |
51 |
51 private static final SortedMap<Character, Extension> EMPTY_MAP = |
52 public static final LocaleExtensions CALENDAR_JAPANESE |
52 Collections.unmodifiableSortedMap(new TreeMap<Character, Extension>()); |
53 = new LocaleExtensions("u-ca-japanese", |
53 |
54 UnicodeLocaleExtension.SINGLETON, |
54 public static final LocaleExtensions EMPTY_EXTENSIONS; |
55 UnicodeLocaleExtension.CA_JAPANESE); |
55 public static final LocaleExtensions CALENDAR_JAPANESE; |
56 |
56 public static final LocaleExtensions NUMBER_THAI; |
57 public static final LocaleExtensions NUMBER_THAI |
57 |
58 = new LocaleExtensions("u-nu-thai", |
58 static { |
59 UnicodeLocaleExtension.SINGLETON, |
59 EMPTY_EXTENSIONS = new LocaleExtensions(); |
60 UnicodeLocaleExtension.NU_THAI); |
60 EMPTY_EXTENSIONS._id = ""; |
61 |
61 EMPTY_EXTENSIONS._map = EMPTY_MAP; |
62 private LocaleExtensions(String id, Character key, Extension value) { |
62 |
63 this.id = id; |
63 CALENDAR_JAPANESE = new LocaleExtensions(); |
64 this.extensionMap = Collections.singletonMap(key, value); |
64 CALENDAR_JAPANESE._id = "u-ca-japanese"; |
|
65 CALENDAR_JAPANESE._map = new TreeMap<Character, Extension>(); |
|
66 CALENDAR_JAPANESE._map.put(Character.valueOf(UnicodeLocaleExtension.SINGLETON), UnicodeLocaleExtension.CA_JAPANESE); |
|
67 |
|
68 NUMBER_THAI = new LocaleExtensions(); |
|
69 NUMBER_THAI._id = "u-nu-thai"; |
|
70 NUMBER_THAI._map = new TreeMap<Character, Extension>(); |
|
71 NUMBER_THAI._map.put(Character.valueOf(UnicodeLocaleExtension.SINGLETON), UnicodeLocaleExtension.NU_THAI); |
|
72 } |
|
73 |
|
74 private LocaleExtensions() { |
|
75 } |
65 } |
76 |
66 |
77 /* |
67 /* |
78 * Package local constructor, only used by InternalLocaleBuilder. |
68 * Package private constructor, only used by InternalLocaleBuilder. |
79 */ |
69 */ |
80 LocaleExtensions(Map<CaseInsensitiveChar, String> extensions, |
70 LocaleExtensions(Map<CaseInsensitiveChar, String> extensions, |
81 Set<CaseInsensitiveString> uattributes, Map<CaseInsensitiveString, String> ukeywords) { |
71 Set<CaseInsensitiveString> uattributes, |
82 boolean hasExtension = (extensions != null && extensions.size() > 0); |
72 Map<CaseInsensitiveString, String> ukeywords) { |
83 boolean hasUAttributes = (uattributes != null && uattributes.size() > 0); |
73 boolean hasExtension = !LocaleUtils.isEmpty(extensions); |
84 boolean hasUKeywords = (ukeywords != null && ukeywords.size() > 0); |
74 boolean hasUAttributes = !LocaleUtils.isEmpty(uattributes); |
|
75 boolean hasUKeywords = !LocaleUtils.isEmpty(ukeywords); |
85 |
76 |
86 if (!hasExtension && !hasUAttributes && !hasUKeywords) { |
77 if (!hasExtension && !hasUAttributes && !hasUKeywords) { |
87 _map = EMPTY_MAP; |
78 id = ""; |
88 _id = ""; |
79 extensionMap = Collections.emptyMap(); |
89 return; |
80 return; |
90 } |
81 } |
91 |
82 |
92 // Build extension map |
83 // Build extension map |
93 _map = new TreeMap<Character, Extension>(); |
84 SortedMap<Character, Extension> map = new TreeMap<>(); |
94 if (hasExtension) { |
85 if (hasExtension) { |
95 for (Entry<CaseInsensitiveChar, String> ext : extensions.entrySet()) { |
86 for (Entry<CaseInsensitiveChar, String> ext : extensions.entrySet()) { |
96 char key = AsciiUtil.toLower(ext.getKey().value()); |
87 char key = LocaleUtils.toLower(ext.getKey().value()); |
97 String value = ext.getValue(); |
88 String value = ext.getValue(); |
98 |
89 |
99 if (LanguageTag.isPrivateusePrefixChar(key)) { |
90 if (LanguageTag.isPrivateusePrefixChar(key)) { |
100 // we need to exclude special variant in privuateuse, e.g. "x-abc-lvariant-DEF" |
91 // we need to exclude special variant in privuateuse, e.g. "x-abc-lvariant-DEF" |
101 value = InternalLocaleBuilder.removePrivateuseVariant(value); |
92 value = InternalLocaleBuilder.removePrivateuseVariant(value); |
102 if (value == null) { |
93 if (value == null) { |
103 continue; |
94 continue; |
104 } |
95 } |
105 } |
96 } |
106 |
97 |
107 Extension e = new Extension(key, AsciiUtil.toLowerString(value)); |
98 map.put(key, new Extension(key, LocaleUtils.toLowerString(value))); |
108 _map.put(Character.valueOf(key), e); |
|
109 } |
99 } |
110 } |
100 } |
111 |
101 |
112 if (hasUAttributes || hasUKeywords) { |
102 if (hasUAttributes || hasUKeywords) { |
113 TreeSet<String> uaset = null; |
103 SortedSet<String> uaset = null; |
114 TreeMap<String, String> ukmap = null; |
104 SortedMap<String, String> ukmap = null; |
115 |
105 |
116 if (hasUAttributes) { |
106 if (hasUAttributes) { |
117 uaset = new TreeSet<String>(); |
107 uaset = new TreeSet<>(); |
118 for (CaseInsensitiveString cis : uattributes) { |
108 for (CaseInsensitiveString cis : uattributes) { |
119 uaset.add(AsciiUtil.toLowerString(cis.value())); |
109 uaset.add(LocaleUtils.toLowerString(cis.value())); |
120 } |
110 } |
121 } |
111 } |
122 |
112 |
123 if (hasUKeywords) { |
113 if (hasUKeywords) { |
124 ukmap = new TreeMap<String, String>(); |
114 ukmap = new TreeMap<>(); |
125 for (Entry<CaseInsensitiveString, String> kwd : ukeywords.entrySet()) { |
115 for (Entry<CaseInsensitiveString, String> kwd : ukeywords.entrySet()) { |
126 String key = AsciiUtil.toLowerString(kwd.getKey().value()); |
116 String key = LocaleUtils.toLowerString(kwd.getKey().value()); |
127 String type = AsciiUtil.toLowerString(kwd.getValue()); |
117 String type = LocaleUtils.toLowerString(kwd.getValue()); |
128 ukmap.put(key, type); |
118 ukmap.put(key, type); |
129 } |
119 } |
130 } |
120 } |
131 |
121 |
132 UnicodeLocaleExtension ule = new UnicodeLocaleExtension(uaset, ukmap); |
122 UnicodeLocaleExtension ule = new UnicodeLocaleExtension(uaset, ukmap); |
133 _map.put(Character.valueOf(UnicodeLocaleExtension.SINGLETON), ule); |
123 map.put(UnicodeLocaleExtension.SINGLETON, ule); |
134 } |
124 } |
135 |
125 |
136 if (_map.size() == 0) { |
126 if (map.isEmpty()) { |
137 // this could happen when only privuateuse with special variant |
127 // this could happen when only privuateuse with special variant |
138 _map = EMPTY_MAP; |
128 id = ""; |
139 _id = ""; |
129 extensionMap = Collections.emptyMap(); |
140 } else { |
130 } else { |
141 _id = toID(_map); |
131 id = toID(map); |
|
132 extensionMap = map; |
142 } |
133 } |
143 } |
134 } |
144 |
135 |
145 public Set<Character> getKeys() { |
136 public Set<Character> getKeys() { |
146 return Collections.unmodifiableSet(_map.keySet()); |
137 if (extensionMap.isEmpty()) { |
|
138 return Collections.emptySet(); |
|
139 } |
|
140 return Collections.unmodifiableSet(extensionMap.keySet()); |
147 } |
141 } |
148 |
142 |
149 public Extension getExtension(Character key) { |
143 public Extension getExtension(Character key) { |
150 return _map.get(Character.valueOf(AsciiUtil.toLower(key.charValue()))); |
144 return extensionMap.get(LocaleUtils.toLower(key)); |
151 } |
145 } |
152 |
146 |
153 public String getExtensionValue(Character key) { |
147 public String getExtensionValue(Character key) { |
154 Extension ext = _map.get(Character.valueOf(AsciiUtil.toLower(key.charValue()))); |
148 Extension ext = extensionMap.get(LocaleUtils.toLower(key)); |
155 if (ext == null) { |
149 if (ext == null) { |
156 return null; |
150 return null; |
157 } |
151 } |
158 return ext.getValue(); |
152 return ext.getValue(); |
159 } |
153 } |
160 |
154 |
161 public Set<String> getUnicodeLocaleAttributes() { |
155 public Set<String> getUnicodeLocaleAttributes() { |
162 Extension ext = _map.get(Character.valueOf(UnicodeLocaleExtension.SINGLETON)); |
156 Extension ext = extensionMap.get(UnicodeLocaleExtension.SINGLETON); |
163 if (ext == null) { |
157 if (ext == null) { |
164 return Collections.emptySet(); |
158 return Collections.emptySet(); |
165 } |
159 } |
166 assert (ext instanceof UnicodeLocaleExtension); |
160 assert (ext instanceof UnicodeLocaleExtension); |
167 return ((UnicodeLocaleExtension)ext).getUnicodeLocaleAttributes(); |
161 return ((UnicodeLocaleExtension)ext).getUnicodeLocaleAttributes(); |
168 } |
162 } |
169 |
163 |
170 public Set<String> getUnicodeLocaleKeys() { |
164 public Set<String> getUnicodeLocaleKeys() { |
171 Extension ext = _map.get(Character.valueOf(UnicodeLocaleExtension.SINGLETON)); |
165 Extension ext = extensionMap.get(UnicodeLocaleExtension.SINGLETON); |
172 if (ext == null) { |
166 if (ext == null) { |
173 return Collections.emptySet(); |
167 return Collections.emptySet(); |
174 } |
168 } |
175 assert (ext instanceof UnicodeLocaleExtension); |
169 assert (ext instanceof UnicodeLocaleExtension); |
176 return ((UnicodeLocaleExtension)ext).getUnicodeLocaleKeys(); |
170 return ((UnicodeLocaleExtension)ext).getUnicodeLocaleKeys(); |
177 } |
171 } |
178 |
172 |
179 public String getUnicodeLocaleType(String unicodeLocaleKey) { |
173 public String getUnicodeLocaleType(String unicodeLocaleKey) { |
180 Extension ext = _map.get(Character.valueOf(UnicodeLocaleExtension.SINGLETON)); |
174 Extension ext = extensionMap.get(UnicodeLocaleExtension.SINGLETON); |
181 if (ext == null) { |
175 if (ext == null) { |
182 return null; |
176 return null; |
183 } |
177 } |
184 assert (ext instanceof UnicodeLocaleExtension); |
178 assert (ext instanceof UnicodeLocaleExtension); |
185 return ((UnicodeLocaleExtension)ext).getUnicodeLocaleType(AsciiUtil.toLowerString(unicodeLocaleKey)); |
179 return ((UnicodeLocaleExtension)ext).getUnicodeLocaleType(LocaleUtils.toLowerString(unicodeLocaleKey)); |
186 } |
180 } |
187 |
181 |
188 public boolean isEmpty() { |
182 public boolean isEmpty() { |
189 return _map.isEmpty(); |
183 return extensionMap.isEmpty(); |
190 } |
184 } |
191 |
185 |
192 public static boolean isValidKey(char c) { |
186 public static boolean isValidKey(char c) { |
193 return LanguageTag.isExtensionSingletonChar(c) || LanguageTag.isPrivateusePrefixChar(c); |
187 return LanguageTag.isExtensionSingletonChar(c) || LanguageTag.isPrivateusePrefixChar(c); |
194 } |
188 } |