1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.codec.language.bm;
19
20 import java.io.InputStream;
21 import java.util.Collections;
22 import java.util.EnumMap;
23 import java.util.HashSet;
24 import java.util.Map;
25 import java.util.NoSuchElementException;
26 import java.util.Scanner;
27 import java.util.Set;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public class Languages {
54
55
56
57
58
59
60
61 public static abstract class LanguageSet {
62
63 public static LanguageSet from(final Set<String> langs) {
64 return langs.isEmpty() ? NO_LANGUAGES : new SomeLanguages(langs);
65 }
66
67 public abstract boolean contains(String language);
68
69 public abstract String getAny();
70
71 public abstract boolean isEmpty();
72
73 public abstract boolean isSingleton();
74
75 public abstract LanguageSet restrictTo(LanguageSet other);
76
77 abstract LanguageSet merge(LanguageSet other);
78 }
79
80
81
82
83 public static final class SomeLanguages extends LanguageSet {
84 private final Set<String> languages;
85
86 private SomeLanguages(final Set<String> languages) {
87 this.languages = Collections.unmodifiableSet(languages);
88 }
89
90 @Override
91 public boolean contains(final String language) {
92 return this.languages.contains(language);
93 }
94
95 @Override
96 public String getAny() {
97 return this.languages.iterator().next();
98 }
99
100 public Set<String> getLanguages() {
101 return this.languages;
102 }
103
104 @Override
105 public boolean isEmpty() {
106 return this.languages.isEmpty();
107 }
108
109 @Override
110 public boolean isSingleton() {
111 return this.languages.size() == 1;
112 }
113
114 @Override
115 public LanguageSet restrictTo(final LanguageSet other) {
116 if (other == NO_LANGUAGES) {
117 return other;
118 } else if (other == ANY_LANGUAGE) {
119 return this;
120 } else {
121 final SomeLanguages sl = (SomeLanguages) other;
122 final Set<String> ls = new HashSet<String>(Math.min(languages.size(), sl.languages.size()));
123 for (String lang : languages) {
124 if (sl.languages.contains(lang)) {
125 ls.add(lang);
126 }
127 }
128 return from(ls);
129 }
130 }
131
132 @Override
133 public LanguageSet merge(final LanguageSet other) {
134 if (other == NO_LANGUAGES) {
135 return this;
136 } else if (other == ANY_LANGUAGE) {
137 return other;
138 } else {
139 final SomeLanguages sl = (SomeLanguages) other;
140 final Set<String> ls = new HashSet<String>(languages);
141 for (String lang : sl.languages) {
142 ls.add(lang);
143 }
144 return from(ls);
145 }
146 }
147
148 @Override
149 public String toString() {
150 return "Languages(" + languages.toString() + ")";
151 }
152
153 }
154
155 public static final String ANY = "any";
156
157 private static final Map<NameType, Languages> LANGUAGES = new EnumMap<NameType, Languages>(NameType.class);
158
159 static {
160 for (final NameType s : NameType.values()) {
161 LANGUAGES.put(s, getInstance(langResourceName(s)));
162 }
163 }
164
165 public static Languages getInstance(final NameType nameType) {
166 return LANGUAGES.get(nameType);
167 }
168
169 public static Languages getInstance(final String languagesResourceName) {
170
171 final Set<String> ls = new HashSet<String>();
172 final InputStream langIS = Languages.class.getClassLoader().getResourceAsStream(languagesResourceName);
173
174 if (langIS == null) {
175 throw new IllegalArgumentException("Unable to resolve required resource: " + languagesResourceName);
176 }
177
178 final Scanner lsScanner = new Scanner(langIS, ResourceConstants.ENCODING);
179 try {
180 boolean inExtendedComment = false;
181 while (lsScanner.hasNextLine()) {
182 final String line = lsScanner.nextLine().trim();
183 if (inExtendedComment) {
184 if (line.endsWith(ResourceConstants.EXT_CMT_END)) {
185 inExtendedComment = false;
186 }
187 } else {
188 if (line.startsWith(ResourceConstants.EXT_CMT_START)) {
189 inExtendedComment = true;
190 } else if (line.length() > 0) {
191 ls.add(line);
192 }
193 }
194 }
195 } finally {
196 lsScanner.close();
197 }
198
199 return new Languages(Collections.unmodifiableSet(ls));
200 }
201
202 private static String langResourceName(final NameType nameType) {
203 return String.format("org/apache/commons/codec/language/bm/%s_languages.txt", nameType.getName());
204 }
205
206 private final Set<String> languages;
207
208
209
210
211 public static final LanguageSet NO_LANGUAGES = new LanguageSet() {
212 @Override
213 public boolean contains(final String language) {
214 return false;
215 }
216
217 @Override
218 public String getAny() {
219 throw new NoSuchElementException("Can't fetch any language from the empty language set.");
220 }
221
222 @Override
223 public boolean isEmpty() {
224 return true;
225 }
226
227 @Override
228 public boolean isSingleton() {
229 return false;
230 }
231
232 @Override
233 public LanguageSet restrictTo(final LanguageSet other) {
234 return this;
235 }
236
237 @Override
238 public LanguageSet merge(final LanguageSet other) {
239 return other;
240 }
241
242 @Override
243 public String toString() {
244 return "NO_LANGUAGES";
245 }
246 };
247
248
249
250
251 public static final LanguageSet ANY_LANGUAGE = new LanguageSet() {
252 @Override
253 public boolean contains(final String language) {
254 return true;
255 }
256
257 @Override
258 public String getAny() {
259 throw new NoSuchElementException("Can't fetch any language from the any language set.");
260 }
261
262 @Override
263 public boolean isEmpty() {
264 return false;
265 }
266
267 @Override
268 public boolean isSingleton() {
269 return false;
270 }
271
272 @Override
273 public LanguageSet restrictTo(final LanguageSet other) {
274 return other;
275 }
276
277 @Override
278 public LanguageSet merge(final LanguageSet other) {
279 return other;
280 }
281
282 @Override
283 public String toString() {
284 return "ANY_LANGUAGE";
285 }
286 };
287
288 private Languages(final Set<String> languages) {
289 this.languages = languages;
290 }
291
292 public Set<String> getLanguages() {
293 return this.languages;
294 }
295 }