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.util.Collections;
21 import java.util.EnumMap;
22 import java.util.HashSet;
23 import java.util.Map;
24 import java.util.NoSuchElementException;
25 import java.util.Scanner;
26 import java.util.Set;
27 import java.util.stream.Collectors;
28
29 import org.apache.commons.codec.Resources;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public class Languages {
61
62
63
64
65
66
67
68
69
70
71 public abstract static class LanguageSet {
72
73
74
75
76
77
78
79 public static LanguageSet from(final Set<String> languages) {
80 return languages.isEmpty() ? NO_LANGUAGES : new SomeLanguages(languages);
81 }
82
83
84
85
86 public LanguageSet() {
87
88 }
89
90
91
92
93
94
95
96 public abstract boolean contains(String language);
97
98
99
100
101
102
103 public abstract String getAny();
104
105
106
107
108
109
110 public abstract boolean isEmpty();
111
112
113
114
115
116
117 public abstract boolean isSingleton();
118
119 abstract LanguageSet merge(LanguageSet other);
120
121
122
123
124
125
126
127 public abstract LanguageSet restrictTo(LanguageSet other);
128 }
129
130
131
132
133 public static final class SomeLanguages extends LanguageSet {
134 private final Set<String> languages;
135
136 private SomeLanguages(final Set<String> languages) {
137 this.languages = Collections.unmodifiableSet(languages);
138 }
139
140 @Override
141 public boolean contains(final String language) {
142 return this.languages.contains(language);
143 }
144
145 @Override
146 public String getAny() {
147 return this.languages.iterator().next();
148 }
149
150
151
152
153
154
155 public Set<String> getLanguages() {
156 return this.languages;
157 }
158
159 @Override
160 public boolean isEmpty() {
161 return this.languages.isEmpty();
162 }
163
164 @Override
165 public boolean isSingleton() {
166 return this.languages.size() == 1;
167 }
168
169 @Override
170 public LanguageSet merge(final LanguageSet other) {
171 if (other == NO_LANGUAGES) {
172 return this;
173 }
174 if (other == ANY_LANGUAGE) {
175 return other;
176 }
177 final SomeLanguages someLanguages = (SomeLanguages) other;
178 final Set<String> set = new HashSet<>(languages);
179 set.addAll(someLanguages.languages);
180 return from(set);
181 }
182
183 @Override
184 public LanguageSet restrictTo(final LanguageSet other) {
185 if (other == NO_LANGUAGES) {
186 return other;
187 }
188 if (other == ANY_LANGUAGE) {
189 return this;
190 }
191 final SomeLanguages someLanguages = (SomeLanguages) other;
192 return from(languages.stream().filter(lang -> someLanguages.languages.contains(lang)).collect(Collectors.toSet()));
193 }
194
195 @Override
196 public String toString() {
197 return "Languages(" + languages.toString() + ")";
198 }
199
200 }
201
202
203
204
205 public static final String ANY = "any";
206
207 private static final Map<NameType, Languages> LANGUAGES = new EnumMap<>(NameType.class);
208
209
210
211
212 public static final LanguageSet NO_LANGUAGES = new LanguageSet() {
213
214 @Override
215 public boolean contains(final String language) {
216 return false;
217 }
218
219 @Override
220 public String getAny() {
221 throw new NoSuchElementException("Can't fetch any language from the empty language set.");
222 }
223
224 @Override
225 public boolean isEmpty() {
226 return true;
227 }
228
229 @Override
230 public boolean isSingleton() {
231 return false;
232 }
233
234 @Override
235 public LanguageSet merge(final LanguageSet other) {
236 return other;
237 }
238
239 @Override
240 public LanguageSet restrictTo(final LanguageSet other) {
241 return this;
242 }
243
244 @Override
245 public String toString() {
246 return "NO_LANGUAGES";
247 }
248 };
249
250
251
252
253 public static final LanguageSet ANY_LANGUAGE = new LanguageSet() {
254
255 @Override
256 public boolean contains(final String language) {
257 return true;
258 }
259
260 @Override
261 public String getAny() {
262 throw new NoSuchElementException("Can't fetch any language from the any language set.");
263 }
264
265 @Override
266 public boolean isEmpty() {
267 return false;
268 }
269
270 @Override
271 public boolean isSingleton() {
272 return false;
273 }
274
275 @Override
276 public LanguageSet merge(final LanguageSet other) {
277 return other;
278 }
279
280 @Override
281 public LanguageSet restrictTo(final LanguageSet other) {
282 return other;
283 }
284
285 @Override
286 public String toString() {
287 return "ANY_LANGUAGE";
288 }
289 };
290
291 static {
292 for (final NameType s : NameType.values()) {
293 LANGUAGES.put(s, getInstance(langResourceName(s)));
294 }
295 }
296
297
298
299
300
301
302
303 public static Languages getInstance(final NameType nameType) {
304 return LANGUAGES.get(nameType);
305 }
306
307
308
309
310
311
312
313 public static Languages getInstance(final String languagesResourceName) {
314
315 final Set<String> ls = new HashSet<>();
316 try (Scanner lsScanner = new Scanner(Resources.getInputStream(languagesResourceName),
317 ResourceConstants.ENCODING)) {
318 boolean inExtendedComment = false;
319 while (lsScanner.hasNextLine()) {
320 final String line = lsScanner.nextLine().trim();
321 if (inExtendedComment) {
322 if (line.endsWith(ResourceConstants.EXT_CMT_END)) {
323 inExtendedComment = false;
324 }
325 } else if (line.startsWith(ResourceConstants.EXT_CMT_START)) {
326 inExtendedComment = true;
327 } else if (!line.isEmpty()) {
328 ls.add(line);
329 }
330 }
331 return new Languages(Collections.unmodifiableSet(ls));
332 }
333 }
334
335 private static String langResourceName(final NameType nameType) {
336 return String.format("/org/apache/commons/codec/language/bm/%s_languages.txt", nameType.getName());
337 }
338
339 private final Set<String> languages;
340
341 private Languages(final Set<String> languages) {
342 this.languages = languages;
343 }
344
345
346
347
348
349
350 public Set<String> getLanguages() {
351 return this.languages;
352 }
353 }