1 package net.sf.openrocket.l10n;
3 import java.util.Collections;
4 import java.util.HashMap;
5 import java.util.Locale;
7 import java.util.regex.Pattern;
9 import net.sf.openrocket.util.Chars;
12 * Helper methods for localization needs.
14 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
16 public final class L10N {
19 * Unicode character normalization map. This is used because Android does
20 * not support the java.text.Normalize class.
22 private static final Map<Character, String> NORMALIZATION_MAP;
25 // Prevent instantiation
30 * Replace a text token by a replacement value.
32 * A text token is a string portion that should be surrounded by
35 * @param original the original string.
36 * @param token the text token to replace.
37 * @param replacement the replacement text.
38 * @return the modified string.
40 public static String replace(String original, String token, String replacement) {
41 return Pattern.compile(token, Pattern.LITERAL).matcher(original).replaceAll(replacement);
46 * Convert a language code into a Locale.
48 * @param langcode the language code (<code>null</code> ok).
49 * @return the corresponding locale (or <code>null</code> if the input was <code>null</code>)
51 public static Locale toLocale(String langcode) {
52 if (langcode == null) {
57 String[] split = langcode.split("[_-]", 3);
58 if (split.length == 1) {
59 l = new Locale(split[0]);
60 } else if (split.length == 2) {
61 l = new Locale(split[0], split[1]);
63 l = new Locale(split[0], split[1], split[2]);
69 public static String normalize(String text) {
70 text = unicodeNormalize(text);
71 text = text.toLowerCase();
72 text = text.replaceAll("\\s+", " ");
75 StringBuilder sb = new StringBuilder(text.length());
76 for (char c : text.toCharArray()) {
77 if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) {
79 } else if (c == ' ' || c == '/' || c == Chars.FRACTION) {
85 text = text.replaceAll("^_+", "");
86 text = text.replaceAll("_+$", "");
91 private static String unicodeNormalize(String text) {
92 StringBuilder sb = new StringBuilder(text.length());
93 for (char c : text.toCharArray()) {
94 String s = NORMALIZATION_MAP.get(c);
101 return sb.toString();
107 * This list is generated using the L10NGenerator utility.
109 Map<Character, String> m = new HashMap<Character, String>();
110 m.put('\u00aa', "a");
111 m.put('\u00b2', "2");
112 m.put('\u00b3', "3");
113 m.put('\u00b9', "1");
114 m.put('\u00ba', "o");
115 m.put('\u00bc', "1/4");
116 m.put('\u00bd', "1/2");
117 m.put('\u00be', "3/4");
118 m.put('\u00c0', "A");
119 m.put('\u00c1', "A");
120 m.put('\u00c2', "A");
121 m.put('\u00c3', "A");
122 m.put('\u00c4', "A");
123 m.put('\u00c5', "A");
124 m.put('\u00c7', "C");
125 m.put('\u00c8', "E");
126 m.put('\u00c9', "E");
127 m.put('\u00ca', "E");
128 m.put('\u00cb', "E");
129 m.put('\u00cc', "I");
130 m.put('\u00cd', "I");
131 m.put('\u00ce', "I");
132 m.put('\u00cf', "I");
133 m.put('\u00d1', "N");
134 m.put('\u00d2', "O");
135 m.put('\u00d3', "O");
136 m.put('\u00d4', "O");
137 m.put('\u00d5', "O");
138 m.put('\u00d6', "O");
139 m.put('\u00d9', "U");
140 m.put('\u00da', "U");
141 m.put('\u00db', "U");
142 m.put('\u00dc', "U");
143 m.put('\u00dd', "Y");
144 m.put('\u00e0', "a");
145 m.put('\u00e1', "a");
146 m.put('\u00e2', "a");
147 m.put('\u00e3', "a");
148 m.put('\u00e4', "a");
149 m.put('\u00e5', "a");
150 m.put('\u00e7', "c");
151 m.put('\u00e8', "e");
152 m.put('\u00e9', "e");
153 m.put('\u00ea', "e");
154 m.put('\u00eb', "e");
155 m.put('\u00ec', "i");
156 m.put('\u00ed', "i");
157 m.put('\u00ee', "i");
158 m.put('\u00ef', "i");
159 m.put('\u00f1', "n");
160 m.put('\u00f2', "o");
161 m.put('\u00f3', "o");
162 m.put('\u00f4', "o");
163 m.put('\u00f5', "o");
164 m.put('\u00f6', "o");
165 m.put('\u00f9', "u");
166 m.put('\u00fa', "u");
167 m.put('\u00fb', "u");
168 m.put('\u00fc', "u");
169 m.put('\u00fd', "y");
170 m.put('\u00ff', "y");
171 m.put('\u0100', "A");
172 m.put('\u0101', "a");
173 m.put('\u0102', "A");
174 m.put('\u0103', "a");
175 m.put('\u0104', "A");
176 m.put('\u0105', "a");
177 m.put('\u0106', "C");
178 m.put('\u0107', "c");
179 m.put('\u0108', "C");
180 m.put('\u0109', "c");
181 m.put('\u010a', "C");
182 m.put('\u010b', "c");
183 m.put('\u010c', "C");
184 m.put('\u010d', "c");
185 m.put('\u010e', "D");
186 m.put('\u010f', "d");
187 m.put('\u0112', "E");
188 m.put('\u0113', "e");
189 m.put('\u0114', "E");
190 m.put('\u0115', "e");
191 m.put('\u0116', "E");
192 m.put('\u0117', "e");
193 m.put('\u0118', "E");
194 m.put('\u0119', "e");
195 m.put('\u011a', "E");
196 m.put('\u011b', "e");
197 m.put('\u011c', "G");
198 m.put('\u011d', "g");
199 m.put('\u011e', "G");
200 m.put('\u011f', "g");
201 m.put('\u0120', "G");
202 m.put('\u0121', "g");
203 m.put('\u0122', "G");
204 m.put('\u0123', "g");
205 m.put('\u0124', "H");
206 m.put('\u0125', "h");
207 m.put('\u0128', "I");
208 m.put('\u0129', "i");
209 m.put('\u012a', "I");
210 m.put('\u012b', "i");
211 m.put('\u012c', "I");
212 m.put('\u012d', "i");
213 m.put('\u012e', "I");
214 m.put('\u012f', "i");
215 m.put('\u0130', "I");
216 m.put('\u0132', "IJ");
217 m.put('\u0133', "ij");
218 m.put('\u0134', "J");
219 m.put('\u0135', "j");
220 m.put('\u0136', "K");
221 m.put('\u0137', "k");
222 m.put('\u0139', "L");
223 m.put('\u013a', "l");
224 m.put('\u013b', "L");
225 m.put('\u013c', "l");
226 m.put('\u013d', "L");
227 m.put('\u013e', "l");
228 m.put('\u013f', "L");
229 m.put('\u0140', "l");
230 m.put('\u0143', "N");
231 m.put('\u0144', "n");
232 m.put('\u0145', "N");
233 m.put('\u0146', "n");
234 m.put('\u0147', "N");
235 m.put('\u0148', "n");
236 m.put('\u0149', "n");
237 m.put('\u014c', "O");
238 m.put('\u014d', "o");
239 m.put('\u014e', "O");
240 m.put('\u014f', "o");
241 m.put('\u0150', "O");
242 m.put('\u0151', "o");
243 m.put('\u0154', "R");
244 m.put('\u0155', "r");
245 m.put('\u0156', "R");
246 m.put('\u0157', "r");
247 m.put('\u0158', "R");
248 m.put('\u0159', "r");
249 m.put('\u015a', "S");
250 m.put('\u015b', "s");
251 m.put('\u015c', "S");
252 m.put('\u015d', "s");
253 m.put('\u015e', "S");
254 m.put('\u015f', "s");
255 m.put('\u0160', "S");
256 m.put('\u0161', "s");
257 m.put('\u0162', "T");
258 m.put('\u0163', "t");
259 m.put('\u0164', "T");
260 m.put('\u0165', "t");
261 m.put('\u0168', "U");
262 m.put('\u0169', "u");
263 m.put('\u016a', "U");
264 m.put('\u016b', "u");
265 m.put('\u016c', "U");
266 m.put('\u016d', "u");
267 m.put('\u016e', "U");
268 m.put('\u016f', "u");
269 m.put('\u0170', "U");
270 m.put('\u0171', "u");
271 m.put('\u0172', "U");
272 m.put('\u0173', "u");
273 m.put('\u0174', "W");
274 m.put('\u0175', "w");
275 m.put('\u0176', "Y");
276 m.put('\u0177', "y");
277 m.put('\u0178', "Y");
278 m.put('\u0179', "Z");
279 m.put('\u017a', "z");
280 m.put('\u017b', "Z");
281 m.put('\u017c', "z");
282 m.put('\u017d', "Z");
283 m.put('\u017e', "z");
284 m.put('\u017f', "s");
285 m.put('\u01a0', "O");
286 m.put('\u01a1', "o");
287 m.put('\u01af', "U");
288 m.put('\u01b0', "u");
289 m.put('\u01c4', "DZ");
290 m.put('\u01c5', "Dz");
291 m.put('\u01c6', "dz");
292 m.put('\u01c7', "LJ");
293 m.put('\u01c8', "Lj");
294 m.put('\u01c9', "lj");
295 m.put('\u01ca', "NJ");
296 m.put('\u01cb', "Nj");
297 m.put('\u01cc', "nj");
298 m.put('\u01cd', "A");
299 m.put('\u01ce', "a");
300 m.put('\u01cf', "I");
301 m.put('\u01d0', "i");
302 m.put('\u01d1', "O");
303 m.put('\u01d2', "o");
304 m.put('\u01d3', "U");
305 m.put('\u01d4', "u");
306 m.put('\u01d5', "U");
307 m.put('\u01d6', "u");
308 m.put('\u01d7', "U");
309 m.put('\u01d8', "u");
310 m.put('\u01d9', "U");
311 m.put('\u01da', "u");
312 m.put('\u01db', "U");
313 m.put('\u01dc', "u");
314 m.put('\u01de', "A");
315 m.put('\u01df', "a");
316 m.put('\u01e0', "A");
317 m.put('\u01e1', "a");
318 m.put('\u01e6', "G");
319 m.put('\u01e7', "g");
320 m.put('\u01e8', "K");
321 m.put('\u01e9', "k");
322 m.put('\u01ea', "O");
323 m.put('\u01eb', "o");
324 m.put('\u01ec', "O");
325 m.put('\u01ed', "o");
326 m.put('\u01f0', "j");
327 m.put('\u01f1', "DZ");
328 m.put('\u01f2', "Dz");
329 m.put('\u01f3', "dz");
330 m.put('\u01f4', "G");
331 m.put('\u01f5', "g");
332 m.put('\u01f8', "N");
333 m.put('\u01f9', "n");
334 m.put('\u01fa', "A");
335 m.put('\u01fb', "a");
336 m.put('\u0200', "A");
337 m.put('\u0201', "a");
338 m.put('\u0202', "A");
339 m.put('\u0203', "a");
340 m.put('\u0204', "E");
341 m.put('\u0205', "e");
342 m.put('\u0206', "E");
343 m.put('\u0207', "e");
344 m.put('\u0208', "I");
345 m.put('\u0209', "i");
346 m.put('\u020a', "I");
347 m.put('\u020b', "i");
348 m.put('\u020c', "O");
349 m.put('\u020d', "o");
350 m.put('\u020e', "O");
351 m.put('\u020f', "o");
352 m.put('\u0210', "R");
353 m.put('\u0211', "r");
354 m.put('\u0212', "R");
355 m.put('\u0213', "r");
356 m.put('\u0214', "U");
357 m.put('\u0215', "u");
358 m.put('\u0216', "U");
359 m.put('\u0217', "u");
360 m.put('\u0218', "S");
361 m.put('\u0219', "s");
362 m.put('\u021a', "T");
363 m.put('\u021b', "t");
364 m.put('\u021e', "H");
365 m.put('\u021f', "h");
366 m.put('\u0226', "A");
367 m.put('\u0227', "a");
368 m.put('\u0228', "E");
369 m.put('\u0229', "e");
370 m.put('\u022a', "O");
371 m.put('\u022b', "o");
372 m.put('\u022c', "O");
373 m.put('\u022d', "o");
374 m.put('\u022e', "O");
375 m.put('\u022f', "o");
376 m.put('\u0230', "O");
377 m.put('\u0231', "o");
378 m.put('\u0232', "Y");
379 m.put('\u0233', "y");
380 m.put('\u2070', "0");
381 m.put('\u2071', "i");
382 m.put('\u2074', "4");
383 m.put('\u2075', "5");
384 m.put('\u2076', "6");
385 m.put('\u2077', "7");
386 m.put('\u2078', "8");
387 m.put('\u2079', "9");
388 m.put('\u2080', "0");
389 m.put('\u2081', "1");
390 m.put('\u2082', "2");
391 m.put('\u2083', "3");
392 m.put('\u2084', "4");
393 m.put('\u2085', "5");
394 m.put('\u2086', "6");
395 m.put('\u2087', "7");
396 m.put('\u2088', "8");
397 m.put('\u2089', "9");
398 m.put('\u2044', "/");
399 m.put('\u200b', " ");
400 m.put('\u00a0', " ");
401 NORMALIZATION_MAP = Collections.unmodifiableMap(m);