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 static abstract class LanguageSet {
72
73 public static LanguageSet from(final Set<String> langs) {
74 return langs.isEmpty() ? NO_LANGUAGES : new SomeLanguages(langs);
75 }
76
77 public abstract boolean contains(String language);
78
79 public abstract String getAny();
80
81 public abstract boolean isEmpty();
82
83 public abstract boolean isSingleton();
84
85 abstract LanguageSet merge(LanguageSet other);
86
87 public abstract LanguageSet restrictTo(LanguageSet other);
88 }
89
90
91
92
93 public static final class SomeLanguages extends LanguageSet {
94 private final Set<String> languages;
95
96 private SomeLanguages(final Set<String> languages) {
97 this.languages = Collections.unmodifiableSet(languages);
98 }
99
100 @Override
101 public boolean contains(final String language) {
102 return this.languages.contains(language);
103 }
104
105 @Override
106 public String getAny() {
107 return this.languages.iterator().next();
108 }
109
110 public Set<String> getLanguages() {
111 return this.languages;
112 }
113
114 @Override
115 public boolean isEmpty() {
116 return this.languages.isEmpty();
117 }
118
119 @Override
120 public boolean isSingleton() {
121 return this.languages.size() == 1;
122 }
123
124 @Override
125 public LanguageSet merge(final LanguageSet other) {
126 if (other == NO_LANGUAGES) {
127 return this;
128 }
129 if (other == ANY_LANGUAGE) {
130 return other;
131 }
132 final SomeLanguages someLanguages = (SomeLanguages) other;
133 final Set<String> set = new HashSet<>(languages);
134 set.addAll(someLanguages.languages);
135 return from(set);
136 }
137
138 @Override
139 public LanguageSet restrictTo(final LanguageSet other) {
140 if (other == NO_LANGUAGES) {
141 return other;
142 }
143 if (other == ANY_LANGUAGE) {
144 return this;
145 }
146 final SomeLanguages someLanguages = (SomeLanguages) other;
147 return from(languages.stream().filter(lang -> someLanguages.languages.contains(lang)).collect(Collectors.toSet()));
148 }
149
150 @Override
151 public String toString() {
152 return "Languages(" + languages.toString() + ")";
153 }
154
155 }
156
157 public static final String ANY = "any";
158
159 private static final Map<NameType, Languages> LANGUAGES = new EnumMap<>(NameType.class);
160
161
162
163
164 public static final LanguageSet NO_LANGUAGES = new LanguageSet() {
165 @Override
166 public boolean contains(final String language) {
167 return false;
168 }
169
170 @Override
171 public String getAny() {
172 throw new NoSuchElementException("Can't fetch any language from the empty language set.");
173 }
174
175 @Override
176 public boolean isEmpty() {
177 return true;
178 }
179
180 @Override
181 public boolean isSingleton() {
182 return false;
183 }
184
185 @Override
186 public LanguageSet merge(final LanguageSet other) {
187 return other;
188 }
189
190 @Override
191 public LanguageSet restrictTo(final LanguageSet other) {
192 return this;
193 }
194
195 @Override
196 public String toString() {
197 return "NO_LANGUAGES";
198 }
199 };
200
201
202
203
204 public static final LanguageSet ANY_LANGUAGE = new LanguageSet() {
205 @Override
206 public boolean contains(final String language) {
207 return true;
208 }
209
210 @Override
211 public String getAny() {
212 throw new NoSuchElementException("Can't fetch any language from the any language set.");
213 }
214
215 @Override
216 public boolean isEmpty() {
217 return false;
218 }
219
220 @Override
221 public boolean isSingleton() {
222 return false;
223 }
224
225 @Override
226 public LanguageSet merge(final LanguageSet other) {
227 return other;
228 }
229
230 @Override
231 public LanguageSet restrictTo(final LanguageSet other) {
232 return other;
233 }
234
235 @Override
236 public String toString() {
237 return "ANY_LANGUAGE";
238 }
239 };
240
241 static {
242 for (final NameType s : NameType.values()) {
243 LANGUAGES.put(s, getInstance(langResourceName(s)));
244 }
245 }
246
247 public static Languages getInstance(final NameType nameType) {
248 return LANGUAGES.get(nameType);
249 }
250
251 public static Languages getInstance(final String languagesResourceName) {
252
253 final Set<String> ls = new HashSet<>();
254 try (final Scanner lsScanner = new Scanner(Resources.getInputStream(languagesResourceName),
255 ResourceConstants.ENCODING)) {
256 boolean inExtendedComment = false;
257 while (lsScanner.hasNextLine()) {
258 final String line = lsScanner.nextLine().trim();
259 if (inExtendedComment) {
260 if (line.endsWith(ResourceConstants.EXT_CMT_END)) {
261 inExtendedComment = false;
262 }
263 } else if (line.startsWith(ResourceConstants.EXT_CMT_START)) {
264 inExtendedComment = true;
265 } else if (!line.isEmpty()) {
266 ls.add(line);
267 }
268 }
269 return new Languages(Collections.unmodifiableSet(ls));
270 }
271 }
272
273 private static String langResourceName(final NameType nameType) {
274 return String.format("org/apache/commons/codec/language/bm/%s_languages.txt", nameType.getName());
275 }
276
277 private final Set<String> languages;
278
279 private Languages(final Set<String> languages) {
280 this.languages = languages;
281 }
282
283 public Set<String> getLanguages() {
284 return this.languages;
285 }
286 }