root / branches / v10 / extensions / extI18n / src / org / gvsig / i18n / impl / I18nManagerImpl.java @ 26065
History | View | Annotate | Download (19.9 KB)
1 |
/* gvSIG. Geographic Information System of the Valencian Government
|
---|---|
2 |
*
|
3 |
* Copyright (C) 2007-2008 Infrastructures and Transports Department
|
4 |
* of the Valencian Gobernment (CIT)
|
5 |
*
|
6 |
* This program is free software; you can redistribute it and/or
|
7 |
* modify it under the terms of the GNU General Public License
|
8 |
* as published by the Free Software Foundation; either version 2
|
9 |
* of the License, or (at your option) any later version.
|
10 |
*
|
11 |
* This program is distributed in the hope that it will be useful,
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14 |
* GNU General Public License for more details.
|
15 |
*
|
16 |
* You should have received a copy of the GNU General Public License
|
17 |
* along with this program; if not, write to the Free Software
|
18 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
19 |
* MA 02110-1301, USA.
|
20 |
*
|
21 |
*/
|
22 |
|
23 |
/*
|
24 |
* AUTHORS (In addition to CIT):
|
25 |
* 2008 {DiSiD Technologies} {New extension for installation and update of text translations}
|
26 |
*/
|
27 |
package org.gvsig.i18n.impl; |
28 |
|
29 |
import java.io.*; |
30 |
import java.util.*; |
31 |
import java.util.Map.Entry; |
32 |
import java.util.jar.*; |
33 |
import java.util.zip.ZipEntry; |
34 |
|
35 |
import org.gvsig.i18n.*; |
36 |
|
37 |
import com.iver.andami.Launcher; |
38 |
import com.iver.andami.PluginServices; |
39 |
import com.iver.andami.config.generate.AndamiConfig; |
40 |
import com.iver.utiles.StringUtilities; |
41 |
import com.iver.utiles.XMLEntity; |
42 |
|
43 |
/**
|
44 |
* Implementation of the I18nManager interface.
|
45 |
*
|
46 |
* @author <a href="mailto:dcervera@disid.com">David Cervera</a>
|
47 |
* @author <a href="mailto:cordin@disid.com">C?sar Ordi?ana</a>
|
48 |
*/
|
49 |
public class I18nManagerImpl implements I18nManager { |
50 |
|
51 |
private static final String MF_LOCALE_VARIANT = "locale-variant"; |
52 |
|
53 |
private static final String MF_LOCALE_COUNTRY = "locale-country"; |
54 |
|
55 |
private static final String MF_LOCALE_LANGUAGE = "locale-language"; |
56 |
|
57 |
private static final String MF_REFLOCALE_VARIANT = "reference-locale-variant"; |
58 |
|
59 |
private static final String MF_REFLOCALE_COUNTRY = "reference-locale-country"; |
60 |
|
61 |
private static final String MF_REFLOCALE_LANGUAGE = "reference-locale-language"; |
62 |
|
63 |
private static final String I18N_EXTENSION = "org.gvsig.i18n"; |
64 |
|
65 |
private static final String VARIANT = "variant"; |
66 |
|
67 |
private static final String COUNTRY = "country"; |
68 |
|
69 |
private static final String LANGUAGE = "language"; |
70 |
|
71 |
private static final String REGISTERED_LOCALES_PERSISTENCE = "RegisteredLocales"; |
72 |
|
73 |
private static final I18nManager DEFAULT = new I18nManagerImpl(); |
74 |
|
75 |
private Set registeredLocales; |
76 |
|
77 |
/**
|
78 |
* The list of default reference locales. The last one will be used to get
|
79 |
* all the keys when translating to a new locale.
|
80 |
*/
|
81 |
private Locale[] referenceLocales = new Locale[] { ENGLISH, SPANISH }; |
82 |
|
83 |
private Locale[] defaultLocales = new Locale[] { |
84 |
// Default supported locales
|
85 |
new Locale("ca"), // Catalan |
86 |
new Locale("cs"), // Czech |
87 |
new Locale("de"), // German |
88 |
ENGLISH, // English
|
89 |
SPANISH, // Spanish
|
90 |
new Locale("eu"), // Basque |
91 |
new Locale("fr"), // French |
92 |
new Locale("gl"), // Galician |
93 |
new Locale("it"), // Italian |
94 |
new Locale("pl"), // Polish |
95 |
new Locale("pt"), // Portuguese |
96 |
new Locale("ro"), // Romanian |
97 |
new Locale("zh"), // Chinese |
98 |
}; |
99 |
|
100 |
/**
|
101 |
* Returns the unique instance of the I18nManager.
|
102 |
*
|
103 |
* @return the unique instance
|
104 |
*/
|
105 |
public static I18nManager getInstance() { |
106 |
return DEFAULT;
|
107 |
} |
108 |
|
109 |
public static String capitalize(String text) { |
110 |
// Convert the first letter to uppercase
|
111 |
String capitalLetter = new String(new char[] { Character |
112 |
.toUpperCase(text.charAt(0)) });
|
113 |
return capitalLetter.concat(text.substring(1)); |
114 |
} |
115 |
|
116 |
/**
|
117 |
* Empty constructor.
|
118 |
*/
|
119 |
I18nManagerImpl() { |
120 |
} |
121 |
|
122 |
public Locale[] getInstalledLocales() { |
123 |
if (registeredLocales == null) { |
124 |
|
125 |
XMLEntity child = getRegisteredLocalesPersistence(); |
126 |
|
127 |
// If the list of registered locales is not already persisted,
|
128 |
// this should be the first time gvSIG is run with the I18nPlugin
|
129 |
// so we will take the list of default locales
|
130 |
if (child == null) { |
131 |
Locale[] defaultLocales = getDefaultLocales(); |
132 |
registeredLocales = new HashSet(defaultLocales.length); |
133 |
for (int i = 0; i < defaultLocales.length; i++) { |
134 |
registeredLocales.add(defaultLocales[i]); |
135 |
} |
136 |
storeInstalledLocales(); |
137 |
} |
138 |
else {
|
139 |
XMLEntity localesEntity = getRegisteredLocalesPersistence(); |
140 |
registeredLocales = new HashSet(localesEntity |
141 |
.getChildrenCount()); |
142 |
for (int i = 0; i < localesEntity.getChildrenCount(); i++) { |
143 |
XMLEntity localeEntity = localesEntity.getChild(i); |
144 |
String language = localeEntity.getStringProperty(LANGUAGE);
|
145 |
String country = localeEntity.getStringProperty(COUNTRY);
|
146 |
String variant = localeEntity.getStringProperty(VARIANT);
|
147 |
Locale locale = new Locale(language, country, variant); |
148 |
registeredLocales.add(locale); |
149 |
} |
150 |
} |
151 |
} |
152 |
|
153 |
return (Locale[]) registeredLocales |
154 |
.toArray(new Locale[registeredLocales.size()]); |
155 |
} |
156 |
|
157 |
public void uninstallLocale(Locale locale) throws I18nException { |
158 |
if (getCurrentLocale().equals(locale) || isReferenceLocale(locale)) {
|
159 |
throw new UninstallLocaleException(locale); |
160 |
} |
161 |
|
162 |
if (registeredLocales.remove(locale)) {
|
163 |
// Remove from the configured locale list
|
164 |
storeInstalledLocales(); |
165 |
|
166 |
// Remove the resource bundle file
|
167 |
File bundleFile = new File(getResourcesFolder(), |
168 |
getResourceFileName(locale)); |
169 |
|
170 |
if (bundleFile.exists()) {
|
171 |
bundleFile.delete(); |
172 |
} |
173 |
} |
174 |
} |
175 |
|
176 |
public String getDisplayName(Locale locale) { |
177 |
return getDisplayName(locale, locale);
|
178 |
} |
179 |
|
180 |
public String getDisplayName(Locale locale, Locale displayLocale) { |
181 |
StringBuffer name = new StringBuffer(getLanguageDisplayName(locale, |
182 |
displayLocale)); |
183 |
|
184 |
boolean close = false; |
185 |
|
186 |
if (!isEmpty(locale.getCountry())) {
|
187 |
name.append(" (");
|
188 |
name.append(locale.getDisplayCountry(displayLocale)); |
189 |
close = true;
|
190 |
} |
191 |
|
192 |
if (!isEmpty(locale.getVariant())) {
|
193 |
if (close) {
|
194 |
name.append(" - ");
|
195 |
} |
196 |
else {
|
197 |
name.append(" (");
|
198 |
close = true;
|
199 |
} |
200 |
name.append(locale.getDisplayVariant(displayLocale)); |
201 |
} |
202 |
|
203 |
if (close) {
|
204 |
name.append(')');
|
205 |
} |
206 |
|
207 |
return name.toString();
|
208 |
} |
209 |
|
210 |
private boolean isEmpty(String text) { |
211 |
return text == null || text.trim().length() == 0; |
212 |
} |
213 |
|
214 |
public String getLanguageDisplayName(Locale locale) { |
215 |
return getLanguageDisplayName(locale, locale);
|
216 |
} |
217 |
|
218 |
public String getLanguageDisplayName(Locale locale, Locale displayLocale) { |
219 |
|
220 |
String displayName;
|
221 |
|
222 |
// Correction for the Basque language display name,
|
223 |
// show it in Basque, not in Spanish
|
224 |
if ("eu".equals(locale.getLanguage()) |
225 |
&& "vascuence".equals(locale.getDisplayLanguage())) {
|
226 |
displayName = "Euskera";
|
227 |
} |
228 |
// Patch for Valencian/Catalan
|
229 |
else if ("ca".equals(locale.getLanguage())) { |
230 |
displayName = Messages.getText("__catalan");
|
231 |
} |
232 |
else {
|
233 |
displayName = locale.getDisplayLanguage(displayLocale); |
234 |
} |
235 |
|
236 |
return capitalize(displayName);
|
237 |
} |
238 |
|
239 |
public Locale getCurrentLocale() { |
240 |
return Locale.getDefault(); |
241 |
} |
242 |
|
243 |
public void setCurrentLocale(Locale locale) { |
244 |
AndamiConfig config = Launcher.getAndamiConfig(); |
245 |
config.setLocaleLanguage(locale.getLanguage()); |
246 |
config.setLocaleCountry(locale.getCountry()); |
247 |
config.setLocaleVariant(locale.getVariant()); |
248 |
} |
249 |
|
250 |
public Locale[] installLocales(File importFile) throws I18nException { |
251 |
List importLocales = new ArrayList(); |
252 |
|
253 |
try {
|
254 |
FileInputStream fis = new FileInputStream(importFile); |
255 |
JarInputStream jaris = new JarInputStream(fis); |
256 |
|
257 |
JarEntry entry;
|
258 |
while ((entry = jaris.getNextJarEntry()) != null) { |
259 |
|
260 |
Attributes attributes = entry.getAttributes();
|
261 |
|
262 |
if (attributes != null) { |
263 |
// Extract the language only if it is not a reference
|
264 |
// language
|
265 |
String language = attributes.getValue(MF_LOCALE_LANGUAGE);
|
266 |
if (language != null) { |
267 |
String country = attributes.getValue(MF_LOCALE_COUNTRY);
|
268 |
country = country == null ? "" : country; |
269 |
String variant = attributes.getValue(MF_LOCALE_VARIANT);
|
270 |
variant = variant == null ? "" : variant; |
271 |
Locale locale = new Locale(language, country, variant); |
272 |
importLocales.add(locale); |
273 |
|
274 |
// Add the locale to the list of installed ones, if it
|
275 |
// is
|
276 |
// new, otherwise, update the texts.
|
277 |
if (!registeredLocales.contains(locale)) {
|
278 |
registeredLocales.add(locale); |
279 |
storeInstalledLocales(); |
280 |
} |
281 |
|
282 |
// Replace the old bundle with the new one
|
283 |
File bundleFile = getResourceFile(locale);
|
284 |
FileOutputStream fos = new FileOutputStream(bundleFile); |
285 |
BufferedOutputStream bos = new BufferedOutputStream(fos); |
286 |
int len = 0; |
287 |
byte[] buffer = new byte[2048]; |
288 |
while ((len = jaris.read(buffer)) > 0) { |
289 |
bos.write(buffer, 0, len);
|
290 |
} |
291 |
bos.flush(); |
292 |
bos.close(); |
293 |
fos.close(); |
294 |
} |
295 |
} |
296 |
} |
297 |
|
298 |
} catch (Exception ex) { |
299 |
throw new InstallLocalesException(importFile, ex); |
300 |
} |
301 |
|
302 |
return (Locale[]) importLocales |
303 |
.toArray(new Locale[importLocales.size()]); |
304 |
} |
305 |
|
306 |
public void exportLocaleForUpdate(Locale locale, Locale referenceLocale, |
307 |
File exportFile) throws I18nException { |
308 |
Manifest manifest = new Manifest(); |
309 |
|
310 |
// First, add an entry for the locale to update
|
311 |
addLocaleToManifest(locale, manifest, false);
|
312 |
// Next, another entry for the reference locale, if not a default one
|
313 |
if (!isReferenceLocale(referenceLocale)) {
|
314 |
addLocaleToManifest(referenceLocale, manifest, true);
|
315 |
} |
316 |
// Finally, an entry per default reference locale, if not the locale to
|
317 |
// update
|
318 |
for (int i = 0; i < referenceLocales.length; i++) { |
319 |
if (!locale.equals(referenceLocales[i])) {
|
320 |
addLocaleToManifest(referenceLocales[i], manifest, true);
|
321 |
} |
322 |
} |
323 |
|
324 |
try {
|
325 |
FileOutputStream fos = new FileOutputStream(exportFile); |
326 |
JarOutputStream jaros = new JarOutputStream(fos, manifest); |
327 |
|
328 |
// BufferedOutputStream bos = new BufferedOutputStream(jaros);
|
329 |
// PrintStream ps = new PrintStream(bos);
|
330 |
PrintStream ps = new PrintStream(jaros); |
331 |
Map texts = null; |
332 |
|
333 |
// First, export the locale to update
|
334 |
texts = getAllTexts(locale); |
335 |
putResourceInJar(jaros, ps, texts, getResourceFileName(locale)); |
336 |
// Next, export the locale selected as reference (if not in the
|
337 |
// default reference locales list)
|
338 |
if (!isReferenceLocale(referenceLocale)) {
|
339 |
texts = getAllTexts(referenceLocale); |
340 |
putResourceInJar(jaros, ps, texts, |
341 |
getResourceFileName(referenceLocale)); |
342 |
} |
343 |
// Finally, export the default reference locales
|
344 |
for (int i = 0; i < referenceLocales.length; i++) { |
345 |
if (!locale.equals(referenceLocales[i])) {
|
346 |
texts = getAllTexts(referenceLocales[i]); |
347 |
putResourceInJar(jaros, ps, texts, |
348 |
getResourceFileName(referenceLocales[i])); |
349 |
} |
350 |
} |
351 |
|
352 |
ps.flush(); |
353 |
ps.close(); |
354 |
jaros.close(); |
355 |
fos.close(); |
356 |
} catch (IOException ex) { |
357 |
throw new ExportLocaleException(locale, ex); |
358 |
} |
359 |
} |
360 |
|
361 |
public void exportLocaleForTranslation(Locale locale, |
362 |
Locale referenceLocale, File exportFile) throws I18nException { |
363 |
Manifest manifest = new Manifest(); |
364 |
|
365 |
// First, add an entry for the locale to update
|
366 |
addLocaleToManifest(locale, manifest, false);
|
367 |
// Next, another entry for the reference locale, if not a default one
|
368 |
if (!isReferenceLocale(referenceLocale)) {
|
369 |
addLocaleToManifest(referenceLocale, manifest, true);
|
370 |
} |
371 |
// Finally, an entry per default reference locale
|
372 |
for (int i = 0; i < referenceLocales.length; i++) { |
373 |
addLocaleToManifest(referenceLocales[i], manifest, true);
|
374 |
} |
375 |
|
376 |
try {
|
377 |
FileOutputStream fos = new FileOutputStream(exportFile); |
378 |
JarOutputStream jaros = new JarOutputStream(fos, manifest); |
379 |
|
380 |
// BufferedOutputStream bos = new BufferedOutputStream(jaros);
|
381 |
// PrintStream ps = new PrintStream(bos);
|
382 |
PrintStream ps = new PrintStream(jaros); |
383 |
Map texts = null; |
384 |
|
385 |
// First, export the reference locale translations
|
386 |
for (int i = 0; i < referenceLocales.length; i++) { |
387 |
texts = getAllTexts(referenceLocales[i]); |
388 |
putResourceInJar(jaros, ps, texts, |
389 |
getResourceFileName(referenceLocales[i])); |
390 |
} |
391 |
// Next, export the locale selected as reference (if not in the
|
392 |
// default reference locales list)
|
393 |
if (!isReferenceLocale(referenceLocale)) {
|
394 |
texts = getAllTexts(referenceLocale); |
395 |
putResourceInJar(jaros, ps, texts, |
396 |
getResourceFileName(referenceLocale)); |
397 |
} |
398 |
|
399 |
// Finally, the new locale translations, taking the keys from
|
400 |
// the reference locale, but without values
|
401 |
// We will use the keys of the last reference locale
|
402 |
putResourceInJar(jaros, ps, texts, getResourceFileName(locale), |
403 |
false);
|
404 |
|
405 |
ps.close(); |
406 |
// bos.close();
|
407 |
jaros.close(); |
408 |
fos.close(); |
409 |
} catch (IOException ex) { |
410 |
throw new ExportLocaleException(locale, ex); |
411 |
} |
412 |
} |
413 |
|
414 |
public Locale[] getReferenceLocales() { |
415 |
return referenceLocales;
|
416 |
} |
417 |
|
418 |
public void setReferenceLocales(Locale[] referenceLocales) { |
419 |
this.referenceLocales = referenceLocales;
|
420 |
} |
421 |
|
422 |
public void setDefaultLocales(Locale[] defaultLocales) { |
423 |
this.defaultLocales = defaultLocales;
|
424 |
} |
425 |
|
426 |
/**
|
427 |
* Returns all the localized texts and its keys for a locale.
|
428 |
*/
|
429 |
private Map getAllTexts(Locale locale) { |
430 |
return Messages.getAllTexts(locale);
|
431 |
} |
432 |
|
433 |
/**
|
434 |
* Returns if a locale is one of the default reference ones.
|
435 |
*/
|
436 |
private boolean isReferenceLocale(Locale locale) { |
437 |
for (int i = 0; i < referenceLocales.length; i++) { |
438 |
if (referenceLocales[i].equals(locale)) {
|
439 |
return true; |
440 |
} |
441 |
} |
442 |
return false; |
443 |
} |
444 |
|
445 |
/**
|
446 |
* Puts a new resource file into a Jar file.
|
447 |
*/
|
448 |
private void putResourceInJar(JarOutputStream jaros, PrintStream ps, |
449 |
Map texts, String resourceFileName) throws IOException { |
450 |
|
451 |
putResourceInJar(jaros, ps, texts, resourceFileName, true);
|
452 |
} |
453 |
|
454 |
/**
|
455 |
* Puts a new resource file into a Jar file.
|
456 |
*/
|
457 |
private void putResourceInJar(JarOutputStream jaros, PrintStream ps, |
458 |
Map texts, String resourceFileName, boolean withValue) |
459 |
throws IOException { |
460 |
// Add ZIP entry for the resource bundle file
|
461 |
jaros.putNextEntry(new ZipEntry(resourceFileName)); |
462 |
|
463 |
for (Iterator iterator = texts.entrySet().iterator(); iterator |
464 |
.hasNext();) { |
465 |
Entry entry = (Entry) iterator.next(); |
466 |
String keyEncoded = escape((String) entry.getKey(), true); |
467 |
ps.print(keyEncoded); |
468 |
ps.print("=");
|
469 |
if (withValue) {
|
470 |
String valueEncoded = escape((String) entry.getValue(), false); |
471 |
ps.println(valueEncoded); |
472 |
} |
473 |
else {
|
474 |
ps.println(); |
475 |
} |
476 |
} |
477 |
|
478 |
ps.flush(); |
479 |
|
480 |
// Close the ZIP entry, the file is complete
|
481 |
jaros.closeEntry(); |
482 |
} |
483 |
|
484 |
/**
|
485 |
* Adds an entry to a MANIFEST.MF file with the name of a locale resource
|
486 |
* bundle properties file, adding labels with the id of the locale, and if
|
487 |
* it is a reference or the locale to translate or update.
|
488 |
*/
|
489 |
private String addLocaleToManifest(Locale locale, Manifest manifest, |
490 |
boolean isReference) {
|
491 |
final String languageKey = isReference ? MF_REFLOCALE_LANGUAGE |
492 |
: MF_LOCALE_LANGUAGE; |
493 |
final String countryKey = isReference ? MF_REFLOCALE_COUNTRY |
494 |
: MF_LOCALE_COUNTRY; |
495 |
final String variantKey = isReference ? MF_REFLOCALE_VARIANT |
496 |
: MF_LOCALE_VARIANT; |
497 |
|
498 |
String resourceFileName = getResourceFileName(locale);
|
499 |
|
500 |
Attributes localeAttributes = new Attributes(4); |
501 |
localeAttributes.putValue(languageKey, locale.getLanguage()); |
502 |
String country = locale.getCountry();
|
503 |
if (country != null && country.length() > 0) { |
504 |
localeAttributes.putValue(countryKey, country); |
505 |
} |
506 |
String variant = locale.getVariant();
|
507 |
if (variant != null && variant.length() > 0) { |
508 |
localeAttributes.putValue(variantKey, variant); |
509 |
} |
510 |
manifest.getEntries().put(resourceFileName, localeAttributes); |
511 |
|
512 |
return resourceFileName;
|
513 |
} |
514 |
|
515 |
/**
|
516 |
* Returns the file which contains the translations for a locale.
|
517 |
*/
|
518 |
private File getResourceFile(Locale locale) { |
519 |
return new File(getResourcesFolder(), getResourceFileName(locale)); |
520 |
} |
521 |
|
522 |
/**
|
523 |
* Returns the name of the file which contains the translations for a
|
524 |
* locale.
|
525 |
*/
|
526 |
private String getResourceFileName(Locale locale) { |
527 |
StringBuffer fileName = new StringBuffer("text"); |
528 |
|
529 |
// Spanish without country is the default locale
|
530 |
if (!(isEmpty(locale.getCountry()) && "es".equals(locale.getLanguage()))) { |
531 |
fileName.append('_').append(locale.getLanguage());
|
532 |
} |
533 |
|
534 |
// Add the locale country
|
535 |
if (!isEmpty(locale.getCountry())) {
|
536 |
fileName.append('_').append(locale.getCountry());
|
537 |
} |
538 |
|
539 |
// Add the locale variant
|
540 |
if (!isEmpty(locale.getVariant())) {
|
541 |
fileName.append('_').append(locale.getVariant());
|
542 |
} |
543 |
|
544 |
fileName.append(".properties");
|
545 |
return fileName.toString();
|
546 |
} |
547 |
|
548 |
/**
|
549 |
* Returns the folder where to store the resource bundle files.
|
550 |
*/
|
551 |
private File getResourcesFolder() { |
552 |
return PluginServices.getPluginServices("com.iver.cit.gvsig") |
553 |
.getPluginDirectory(); |
554 |
} |
555 |
|
556 |
/**
|
557 |
* Returns the child XMLEntity with the RegisteredLocales.
|
558 |
*/
|
559 |
private XMLEntity getRegisteredLocalesPersistence() {
|
560 |
XMLEntity entity = getI18nPersistence(); |
561 |
XMLEntity child = null;
|
562 |
for (int i = entity.getChildrenCount() - 1; i >= 0; i--) { |
563 |
XMLEntity tmpchild = entity.getChild(i); |
564 |
if (tmpchild.getName().equals(REGISTERED_LOCALES_PERSISTENCE)) {
|
565 |
child = tmpchild; |
566 |
break;
|
567 |
} |
568 |
} |
569 |
return child;
|
570 |
} |
571 |
|
572 |
/**
|
573 |
* Returns the I18n Plugin persistence.
|
574 |
*/
|
575 |
private XMLEntity getI18nPersistence() {
|
576 |
XMLEntity entity = PluginServices.getPluginServices(I18N_EXTENSION) |
577 |
.getPersistentXML(); |
578 |
return entity;
|
579 |
} |
580 |
|
581 |
/**
|
582 |
* Returns the list of default locales bundled with gvSIG.
|
583 |
*/
|
584 |
private Locale[] getDefaultLocales() { |
585 |
return defaultLocales;
|
586 |
} |
587 |
|
588 |
/**
|
589 |
* Stores the list of installed locales into the plugin persistence.
|
590 |
*/
|
591 |
private void storeInstalledLocales() { |
592 |
XMLEntity localesEntity = getRegisteredLocalesPersistence(); |
593 |
|
594 |
// Remove the previous list of registered languages
|
595 |
if (localesEntity != null) { |
596 |
XMLEntity i18nPersistence = getI18nPersistence(); |
597 |
for (int i = i18nPersistence.getChildrenCount() - 1; i >= 0; i--) { |
598 |
XMLEntity child = i18nPersistence.getChild(i); |
599 |
if (child.getName().equals(REGISTERED_LOCALES_PERSISTENCE)) {
|
600 |
i18nPersistence.removeChild(i); |
601 |
break;
|
602 |
} |
603 |
} |
604 |
} |
605 |
|
606 |
// Create the new persistence for the registered languages
|
607 |
localesEntity = new XMLEntity();
|
608 |
|
609 |
localesEntity.setName(REGISTERED_LOCALES_PERSISTENCE); |
610 |
|
611 |
for (Iterator iterator = registeredLocales.iterator(); iterator |
612 |
.hasNext();) { |
613 |
Locale locale = (Locale) iterator.next(); |
614 |
XMLEntity localeEntity = new XMLEntity();
|
615 |
localeEntity.setName(locale.getDisplayName()); |
616 |
localeEntity.putProperty(LANGUAGE, locale.getLanguage()); |
617 |
localeEntity.putProperty(COUNTRY, locale.getCountry()); |
618 |
localeEntity.putProperty(VARIANT, locale.getVariant()); |
619 |
|
620 |
localesEntity.addChild(localeEntity); |
621 |
} |
622 |
|
623 |
getI18nPersistence().addChild(localesEntity); |
624 |
} |
625 |
|
626 |
private String escape(String value, boolean replaceBlanks) { |
627 |
// First replace non printable characters
|
628 |
if (replaceBlanks) {
|
629 |
value = StringUtilities.replace(value, " ", "\\ "); |
630 |
} |
631 |
value = StringUtilities.replace(value, ":", "\\:"); |
632 |
value = StringUtilities.replace(value, "\n", "\\n"); |
633 |
value = StringUtilities.replace(value, "\t", "\\t"); |
634 |
value = StringUtilities.replace(value, "\b", "\\b"); |
635 |
value = StringUtilities.replace(value, "\f", "\\f"); |
636 |
value = StringUtilities.replace(value, "\r", "\\r"); |
637 |
// value = StringUtilities.replace(value, "\\", "\\\\");
|
638 |
// value = StringUtilities.replace(value, "\'", "\\\'");
|
639 |
// value = StringUtilities.replace(value, "\"", "\\\"");
|
640 |
|
641 |
// Next, encode in raw-unicode-escape
|
642 |
return toRawUnicodeEncoded(value);
|
643 |
} |
644 |
|
645 |
private String toRawUnicodeEncoded(String value) { |
646 |
StringBuffer sb = new StringBuffer(); |
647 |
for (int i = 0; i < value.length(); i++) { |
648 |
char c = value.charAt(i);
|
649 |
if (c <= 0x80) { |
650 |
sb.append(c); |
651 |
} |
652 |
else {
|
653 |
sb.append("\\u");
|
654 |
String hexValue = Integer.toHexString((int) c); |
655 |
// Append 0 if the hex value has less than 4 digits
|
656 |
for (int j = hexValue.length(); j < 4; j++) { |
657 |
sb.append('0');
|
658 |
} |
659 |
sb.append(hexValue); |
660 |
} |
661 |
} |
662 |
return sb.toString();
|
663 |
} |
664 |
} |