Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.i18n / src / main / java / org / gvsig / i18n / Messages.java @ 40559

History | View | Annotate | Download (25.4 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
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 3
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
25
*
26
* Copyright (C) 2006-2007 IVER T.I. and Generalitat Valenciana.
27
*
28
* This program is free software; you can redistribute it and/or
29
* modify it under the terms of the GNU General Public License
30
* as published by the Free Software Foundation; either version 2
31
* of the License, or (at your option) any later version.
32
*
33
* This program is distributed in the hope that it will be useful,
34
* but WITHOUT ANY WARRANTY; without even the implied warranty of
35
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
36
* GNU General Public License for more details.
37
*
38
* You should have received a copy of the GNU General Public License
39
* along with this program; if not, write to the Free Software
40
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
41
*
42
* For more information, contact:
43
*
44
*  Generalitat Valenciana
45
*   Conselleria d'Infraestructures i Transport
46
*   Av. Blasco Ib??ez, 50
47
*   46010 VALENCIA
48
*   SPAIN
49
*
50
*      +34 963862235
51
*   gvsig@gva.es
52
*      www.gvsig.gva.es
53
*
54
*    or
55
*
56
*   IVER T.I. S.A
57
*   Salamanca 50
58
*   46005 Valencia
59
*   Spain
60
*
61
*   +34 963163400
62
*   dac@iver.es
63
*/
64

    
65
package org.gvsig.i18n;
66

    
67
import java.io.File;
68
import java.io.IOException;
69
import java.io.InputStream;
70
import java.net.MalformedURLException;
71
import java.net.URL;
72
import java.text.MessageFormat;
73
import java.util.ArrayList;
74
import java.util.Enumeration;
75
import java.util.HashSet;
76
import java.util.IllegalFormatException;
77
import java.util.Iterator;
78
import java.util.Locale;
79
import java.util.Properties;
80
import java.util.Set;
81

    
82
import org.slf4j.Logger;
83
import org.slf4j.LoggerFactory;
84

    
85
/**
86
 * <p>This class offers some methods to provide internationalization services
87
 * to other projects. All the methods are static.</p>
88
 *
89
 * <p>The most useful method is {@link #getText(String) getText(key)} (and family),
90
 * which returns the translation associated
91
 * with the provided key. The class must be initialized before getText can be
92
 * used.</p>
93
 *
94
 * <p>The typical usage sequence would be:</p>
95
 * <ul>
96
 * <li>Add some locale to the prefered locales list: <code>Messages.addLocale(new Locale("es"))</code></li>
97
 * <li>Add some resource file containing translations: <code>Messages.addResourceFamily("text", new File("."))</code></li>
98
 * <li>And finaly getText can be used: <code>Messages.getText("aceptar")</code></li>
99
 * </ul>
100
 *
101
 * <p>The resource files are Java properties files, which contain <code>key=translation</code>
102
 * pairs, one
103
 * pair per line. These files must be encoded using iso-8859-1 encoding, and unicode escaped
104
 * sequences must be used to include characters outside the former encoding.
105
 * There are several ways to specify the property file to load, see the different
106
 * addResourceFamily methods for details.</p>
107
 *
108
 * @author Cesar Martinez Izquierdo (cesar.martinez@iver.es)
109
 *
110
 */
111
public class Messages {
112
    private static Logger logger = LoggerFactory.getLogger("Messages");
113
    private static String _CLASSNAME = "org.gvsig.i18n.Messages";
114

    
115
    /* Each entry will contain a hashmap with translations. Each hasmap
116
     * contains the translations for one language, indexed by the
117
     * translation key. The translations for language (i) in the preferred locales
118
     * list are contained in the position (i) of the localeResources list */
119
    private static ArrayList localeResources = new ArrayList();
120
        private static ArrayList preferredLocales = new ArrayList(); // contains the ordered list of prefered languages/locales (class Locale)
121

    
122

    
123
        /* Set of resource families and classloaders used to load i18n resources. */
124
        private static Set resourceFamilies = new HashSet();
125
        private static Set classLoaders = new HashSet();
126

    
127
        /*
128
         * The language considered the origin of translations, which will
129
         * (possibly) be stored in a property file without language suffix
130
         * (ie: text.properties instead of text_es.properties).
131
         */
132
        private static String baseLanguage = "es";
133
        private static Locale baseLocale = new Locale(baseLanguage);
134

    
135
        /**
136
         * <p>Gets the localized message associated with the provided key.
137
         * If the key is not in the dictionary, return the key and register
138
         * the failure in the log.</p>
139
         *
140
         * <p>The <code>callerName</code> parameter is only
141
         * used as a label when logging, so any String can be used. However, a
142
         * meaningful String should be used, such as the name of the class requiring
143
         * the translation services, in order to identify the source of the failure
144
         * in the log.</p>
145
         *
146
         * @param key         An String which identifies the translation that we want to get.
147
         * @param callerName  A symbolic name given to the caller of this method, to
148
         *                    show it in the log if the key was not found
149
         * @return            an String with the message associated with the provided key.
150
         *                    If the key is not in the dictionary, return the key. If the key
151
         *                    is null, return null.
152
         */
153
        public static String getText(String key, String callerName) {
154
                if (key==null) {
155
                        return null;
156
                }
157
                for (int numLocale=0; numLocale<localeResources.size(); numLocale++) {
158
                        // try to get the translation for any of the languagues in the preferred languages list
159
                        String translation = ((Properties)localeResources.get(numLocale)).getProperty(key);
160
                        if (translation!=null && !translation.equals("")) {
161
                                return translation;
162
                        }
163
                }
164
                logger.warn(callerName+ " -- Cannot find translation for "+key);
165
                return key;
166
        }
167

    
168
        public static String getText(String key,  String[] arguments, String callerName) {
169
                String translation = getText(key, callerName);
170
                if (translation!=null && arguments!=null ) {
171
                        try {
172
                                translation = MessageFormat.format(translation, arguments);
173
                        }
174
                        catch (IllegalFormatException ex) {
175
                                logger.error(callerName+" -- Error formating key: "+key+" -- "+translation);
176
                        }
177
                }
178
                return translation;
179
        }
180
        
181
        public static String translate(String message, String[] args) {
182
                String msg = message;
183
                if (msg == null) {
184
                        return "";
185
                }
186
                msg = getText(msg, args);
187
                if (msg == null) {
188
                        msg = "_" + message.replace("_", " ");
189
                }
190
                return msg;
191
        }
192

    
193
        public static String translate(String message) {
194
                String msg = message;
195
                if (msg == null) {
196
                        return "";
197
                }
198
                msg = getText(msg, (String[]) null);
199
                if (msg == null) {
200
                        msg = "_" + message.replace("_", " ");
201
                }
202
                return msg;
203
        }
204

    
205
        /**
206
         * <p>Gets the localized message associated with the provided key.
207
         * If the key is not in the dictionary or the translation is empty,
208
         * return the key and register the failure in the log.</p>
209
         *
210
         * @param key     An String which identifies the translation that we want to get.
211
         * @return        an String with the message associated with the provided key.
212
         *                If the key is not in the dictionary or the translation is empty,
213
         *                return the key. If the key is null, return null.
214
         */
215
        public static String getText(String key) {
216
                return getText(key, _CLASSNAME);
217
        }
218

    
219
        public static String getText(String key, String[] arguments) {
220
                return getText(key, arguments, _CLASSNAME);
221
        }
222

    
223
        
224
        /**
225
         * <p>Gets the localized message associated with the provided key.
226
         * If the key is not in the dictionary or the translation is empty,
227
         * it returns null and the failure is only registered in the log if
228
         * the param log is true.</p>
229
         *
230
         * @param key        An String which identifies the translation that we want
231
         *                                 to get.
232
         * @param log        Determines whether log a key failure or not
233
         * @return                an String with the message associated with the provided key,
234
         *                                 or null if the key is not in the dictionary or the
235
         *                                 translation is empty.
236
         */
237
        public static String getText(String key, boolean log) {
238
                return getText(key, _CLASSNAME, log);
239
        }
240

    
241
        public static String getText(String key, String[] arguments, boolean log) {
242
                String translation = getText(key, _CLASSNAME, log);
243
                if (translation!=null && arguments!=null ) {
244
                        try {
245
                                translation = MessageFormat.format(translation, arguments);
246
                        } catch (IllegalFormatException ex) {
247
                                if (log) {
248
                                        logger.error(_CLASSNAME+" -- Error formating key: "+key+" -- "+translation);
249
                                }
250
                        }
251
                }
252
                return translation;
253
        }
254

    
255
        /**
256
         * <p>Gets the localized message associated with the provided key.
257
         * If the key is not in the dictionary, it returns null and the failure
258
         * is only registered in the log if the param log is true.</p>
259
         *
260
         * @param key         An String which identifies the translation that we want to get.
261
         * @param callerName  A symbolic name given to the caller of this method, to
262
         *                    show it in the log if the key was not found
263
         * @param log         Determines whether log a key failure or not
264
         * @return            an String with the message associated with the provided key,
265
         *                    or null if the key is not in the dictionary.
266
         */
267
        public static String getText(String key, String callerName, boolean log) {
268
                if (key==null) {
269
                        return null;
270
                }
271
                for (int numLocale=0; numLocale<localeResources.size(); numLocale++) {
272
                        // try to get the translation for any of the languagues in the preferred languages list
273
                        String translation = ((Properties)localeResources.get(numLocale)).getProperty(key);
274
                        if (translation!=null && !translation.equals("")) {
275
                                return translation;
276
                        }
277
                }
278
                if (log) {
279
                        logger.warn(callerName+" -- Cannot find translation for "+key);
280
                }
281
                return null;
282
        }
283

    
284
        public static String getText(String key, String[] arguments, String callerName, boolean log) {
285
                String translation = getText(key, callerName, log);
286
                if (translation!=null) {
287
                        try {
288
                                translation = MessageFormat.format(translation, arguments);
289
                        }
290
                        catch (IllegalFormatException ex) {
291
                                if (log) {
292
                                        logger.error(callerName+" -- Error formating key: "+key+" -- "+translation);
293
                                }
294
                        }
295
                }
296
                return translation;
297
        }
298

    
299
        /**
300
         * <p>Adds an additional family of resource files containing some translations.
301
         * A family is a group of files with a common baseName.
302
         * The file must be an iso-8859-1 encoded file, which can contain any unicode
303
         * character using unicode escaped sequences, and following the syntax:
304
         * <code>key1=value1
305
         * key2=value2</code>
306
         * where 'key1' is the key used to identify the string and must not
307
         * contain the '=' symbol, and 'value1' is the associated translation.</p>
308
         * <p<For example:</p>
309
         * <code>cancel=Cancelar
310
         * accept=Aceptar</code>
311
         * <p>Only one pair key-value is allowed per line.</p>
312
         *
313
         * <p>The actual name of the resource file to load is determined using the rules
314
         * explained in the class java.util.ResourceBundle. Summarizing, for each language
315
         * in the specified preferred locales list it will try to load a file with
316
         *  the following structure: <code>family_locale.properties</code></p>
317
         *
318
         * <p>For example, if the preferred locales list contains {"fr", "es", "en"}, and
319
         * the family name is "text", it will try to load the files "text_fr.properties",
320
         * "text_es.properties" and finally "text_en.properties".</p>
321
         *
322
         * <p>Locales might be more specific, such us "es_AR"  (meaning Spanish from Argentina)
323
         * or "es_AR_linux" (meaning Linux system preferring Spanish from Argentina). In the
324
         * later case, it will try to load "text_es_AR_linux.properties", then
325
         * "text_es_AR.properties" if the former fails, and finally "text_es.properties".</p>
326
         *
327
         * <p>The directory used to locate the resource file is determining by using the
328
         * getResource method from the provided ClassLoader.</p>
329
         *
330
         * @param family    The family name (or base name) which is used to search
331
         *                  actual properties files.
332
         * @param loader    A ClassLoader which is able to find a property file matching
333
         *                                         the specified family name and the preferred locales
334
         * @see             <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/ResourceBundle.html">ResourceBundle</a>
335
         */
336
        public static void addResourceFamily(String family, ClassLoader loader) {
337
                addResourceFamily(family, loader, "");
338
        }
339

    
340
        /**
341
         * <p>Adds an additional family of resource files containing some translations.
342
         * The search path to locate the files is provided by the dirList parameter.</p>
343
         *
344
         * <p>See {@link addResourceFamily(String, ClassLoader)} for a discussion about the
345
         * format of the property files and the way to determine the candidat files
346
         * to load. Note that those methods are different in the way to locate the
347
         * candidat files. This method searches in the provided paths (<code>dirList</code>
348
         * parameter), while the referred method searches using the getResource method
349
         * of the provided ClassLoader.</p>
350
         *
351
         * @param family    The family name (or base name) which is used to search
352
         *                  actual properties files.
353
         * @param dirList   A list of search paths to locate the property files
354
         * @throws MalformedURLException
355
         * @see             <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/ResourceBundle.html">ResourceBundle</a>
356
         */
357
        public static void addResourceFamily(String family, File[] dirList) throws MalformedURLException{
358
                // use our own classloader
359
                URL[] urls = new URL[dirList.length];
360

    
361
                        int i;
362
                        for (i=0; i<urls.length; i++) {
363
                                urls[i] = dirList[i].toURL();
364
                        }
365

    
366
                ClassLoader loader = new MessagesClassLoader(urls);
367
                addResourceFamily(family, loader, "");
368
        }
369

    
370
        /**
371
         * <p>Adds an additional family of resource files containing some translations.
372
         * The search path to locate the files is provided by the dir parameter.</p>
373
         *
374
         * <p>See {@link addResourceFamily(String, ClassLoader)} for a discussion about the
375
         * format of the property files and the way to determine the candidat files
376
         * to load. Note that those methods are different in the way to locate the
377
         * candidat files. This method searches in the provided path (<code>dir</code>
378
         * parameter), while the referred method searches using the getResource method
379
         * of the provided ClassLoader.</p>
380
         *
381
         * @param family    The family name (or base name) which is used to search
382
         *                  actual properties files.
383
         * @param dir       The search path to locate the property files
384
         * @throws MalformedURLException
385
         * @see             <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/ResourceBundle.html">ResourceBundle</a>
386
         */
387
        public static void addResourceFamily(String family, File dir) throws MalformedURLException{
388
                // use our own classloader
389
                URL[] urls = new URL[1];
390
                urls[0] = dir.toURL();
391
                ClassLoader loader = new MessagesClassLoader(urls);
392
                addResourceFamily(family, loader, "");
393
        }
394

    
395

    
396
        /**
397
         * <p>Adds an additional family of resource files containing some translations.
398
         * The search path is determined by the getResource method from the
399
         * provided ClassLoader.</p>
400
         *
401
         * <p>This method is identical to {@link addResourceFamily(String, ClassLoader)},
402
         * except that it adds a <pode>callerName</code> parameter to show in the log.</p>
403
         *
404
         * <p>See {@link addResourceFamily(String, ClassLoader)} for a discussion about the
405
         * format of the property files andthe way to determine the candidat files
406
         * to load.</p>
407
         *
408
         * @param family      The family name (or base name) which is used to search
409
         *                    actual properties files.
410
         * @param loader      A ClassLoader which is able to find a property file matching
411
         *                                           the specified family name and the preferred locales
412
         * @param callerName  A symbolic name given to the caller of this method, to
413
         *                    show it in the log if there is an error
414
         * @see               <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/ResourceBundle.html">ResourceBundle</a>
415
         */
416
        public static void addResourceFamily(String family, ClassLoader loader, String callerName) {
417
                String currentKey;
418
                Enumeration keys;
419
                Locale lang;
420
                Properties properties, translations;
421
                int totalLocales = preferredLocales.size();
422

    
423
                if (totalLocales == 0) {
424
                        // if it's empty, warn about that
425
                        logger.warn("There is not preferred languages list. Maybe the Messages class was not initialized");
426
                }
427

    
428
                resourceFamilies.add(family);
429
                classLoaders.add(loader);
430

    
431
                for (int numLocale=0; numLocale<totalLocales; numLocale++) { // for each language
432
                        properties =  new Properties();
433

    
434
                        lang = (Locale) preferredLocales.get(numLocale);
435
                        translations = (Properties) localeResources.get(numLocale);
436

    
437
                        addResourceFamily(lang, translations, family, loader, callerName);
438
                }
439
        }
440

    
441
        private static void addResourceFamily(Locale lang, Properties translations,
442
                        String family, ClassLoader loader, String callerName) {
443
                Properties properties = new Properties();
444
                String resource = family.replace('.', '/') + "_" + lang.toString()
445
                                + ".properties";
446
                InputStream is = loader.getResourceAsStream(resource);
447
                if (is != null) {
448
                        try {
449
                                properties.load(is);
450
                        } catch (IOException e) {
451
                        }
452
                } else if (lang.equals(baseLocale)) {
453
                        // try also "text.properties" for the base language
454
                        is = loader.getResourceAsStream(family.replace('.', '/')
455
                                        + ".properties");
456

    
457

    
458
                        if (is != null) {
459
                                try {
460
                                        properties.load(is);
461
                                } catch (IOException e) {
462
                                }
463
                        }
464

    
465
                }
466
                Enumeration keys = properties.keys();
467
                while (keys.hasMoreElements()) {
468
                        String currentKey = (String) keys.nextElement();
469
                        if (!translations.containsKey(currentKey)) {
470
                                translations
471
                                                .put(currentKey, properties.getProperty(currentKey));
472
                        }
473
                }
474

    
475
        }
476

    
477
        /**
478
         * <p>Adds an additional family of resource files containing some translations.</p>
479
         *
480
         * <p>This method is identical to {@link addResourceFamily(String, ClassLoader, String)},
481
         * except that it uses the caller's class loader.</p>
482
         *
483
         * <p>See {@link addResourceFamily(String, ClassLoader)} for a discussion about the
484
         * format of the property files and the way to determine the candidat files
485
         * to load.</p>
486
         *
487
         * @param family      The family name (or base name) which is used to search
488
         *                    actual properties files.
489
         * @param callerName  A symbolic name given to the caller of this method, to
490
         *                    show it in the log if there is an error. This is only used
491
         *                    to show
492
         *                    something meaningful in the log, so you can use any string
493
         * @see               <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/ResourceBundle.html">ResourceBundle</a>
494
         */
495
        public static void addResourceFamily(String family, String callerName) {
496
                addResourceFamily(family, Messages.class.getClassLoader(), callerName);
497
        }
498

    
499

    
500
        /**
501
         * Returns an ArrayList containing the ordered list of prefered Locales
502
         * Each element of the ArrayList is a Locale object.
503
         *
504
         * @return an ArrayList containing the ordered list of prefered Locales
505
         * Each element of the ArrayList is a Locale object.
506
         */
507
        public static ArrayList getPreferredLocales() {
508
                return preferredLocales;
509
        }
510

    
511
        /**
512
         * <p>Sets the ordered list of preferred locales.
513
         * Each element of the ArrayList is a Locale object.</p>
514
         *
515
         * <p>Note that calling this method does not load any translation, it just
516
         * adds the language to the preferred locales list, so this method must
517
         * be always called before the translations are loaded using
518
         * the addResourceFamily() methods.</p>
519
         *
520
         * <p>It there was any language in the preferred locale list, the language
521
         * and its associated translations are deleted.</p>
522
         *
523
         *
524
         * @param preferredLocales an ArrayList containing Locale objects.
525
         * The ArrayList represents an ordered list of preferred locales
526
         */
527
        public static void setPreferredLocales(ArrayList preferredLocalesList) {
528
                // delete all existing locales
529
                Iterator oldLocales = preferredLocales.iterator();
530
                while (oldLocales.hasNext()) {
531
                        removeLocale((Locale) oldLocales.next());
532
                }
533

    
534
                // add the new locales now
535
                for (int numLocale=0; numLocale < preferredLocalesList.size(); numLocale++) {
536
                        addLocale((Locale) preferredLocalesList.get(numLocale));
537
                }
538
        }
539

    
540
        /**
541
         * Adds a Locale at the end of the ordered list of preferred locales.
542
         * Note that calling this method does not load any translation, it just
543
         * adds the language to the preferred locales list, so this method must
544
         * be always called before the translations are loaded using
545
         * the addResourceFamily() methods.
546
         *
547
         * @param lang   A Locale object specifying the locale to add
548
         */
549
        public static void addLocale(Locale lang) {
550
                if (!preferredLocales.contains(lang)) { // avoid duplicates
551
                                preferredLocales.add(lang); // add the lang to the ordered list of preferred locales
552
                                Properties dict = new Properties();
553
                                localeResources.add(dict); // add a hashmap which will contain the translation for this language
554
                }
555
        }
556

    
557
        /**
558
         * Removes the specified Locale from the list of preferred locales and the
559
         * translations associated with this locale.
560
         *
561
         * @param lang   A Locale object specifying the locale to remove
562
         * @return       True if the locale was in the preferred locales list, false otherwise
563
         */
564
        public static boolean removeLocale(Locale lang) {
565
                int numLocale = preferredLocales.indexOf(lang);
566
                if (numLocale!=-1) { // we found the locale in the list
567
                        try {
568
                                preferredLocales.remove(numLocale);
569
                                localeResources.remove(numLocale);
570
                        }
571
                        catch (IndexOutOfBoundsException ex) {
572
                                logger.warn(_CLASSNAME + "." + "removeLocale: " + ex.getLocalizedMessage());
573
                        }
574
                        return true;
575
                }
576
                return false;
577
        }
578

    
579
        /**
580
         * Cleans the translation tables (removes all the translations from memory).
581
         */
582
        public static void removeResources() {
583
                for (int numLocale=0; numLocale<localeResources.size(); numLocale++) {
584
                        ((Properties)localeResources.get(numLocale)).clear();
585
                }
586
        }
587

    
588
        /**
589
         * The number of translation keys which have been loaded till now
590
         * (In other words: the number of available translation strings).
591
         *
592
         * @param lang The language for which we want to know the number of translation keys
593
         * return The number of translation keys for the provided language.
594
         */
595
        protected static int size(Locale lang) {
596
                int numLocale = preferredLocales.indexOf(lang);
597
                if (numLocale!=-1) {
598
                        return ((Properties)localeResources.get(numLocale)).size();
599
                };
600
                return 0;
601
        }
602

    
603
        protected static Set keySet(Locale lang) {
604
                int numLocale = preferredLocales.indexOf(lang);
605
                if (numLocale!=-1) {
606
                        return ((Properties)localeResources.get(numLocale)).keySet();
607
                } else {
608
                        return null;
609
                }
610
        }
611

    
612
        /**
613
         * Checks if some locale has been added to the preferred locales
614
         * list, which is necessary before loading any translation because
615
         * only the translations for the preferred locales are loaded.
616
         *
617
         * @return
618
         */
619
        public static boolean hasLocales() {
620
                return preferredLocales.size()>0;
621
        }
622

    
623
        /**
624
         * Gets the base language, the language considered the origin of
625
         * translations, which will be (possibly) stored in a property
626
         * file without language suffix
627
         * (ie: text.properties instead of text_es.properties).
628
         */
629
        public static String getBaseLanguage() {
630
                return baseLanguage;
631
        }
632

    
633
        /**
634
         * Sets the base language, the language considered the origin of
635
         * translations, which will be (possibly)
636
         * stored in a property file without language suffix
637
         * (ie: text.properties instead of text_es.properties).
638
         *
639
         * @param lang The base language to be set
640
         */
641
        public static void setBaseLanguage(String lang) {
642
                baseLanguage = lang;
643
                baseLocale = new Locale(baseLanguage);
644
        }
645

    
646
        /*
647
         * Searches the subdirectories of the provided directory, finding
648
         * all the translation files, and constructing a list of available translations.
649
         * It reports different country codes or variants, if available.
650
         * For example, if there is an en_US translation and an en_GB translation, both
651
         * locales will be present in the Vector.
652
         *
653
         * @return
654
         */
655

    
656
        /**
657
         *
658
         * @return A Vector containing the available locales. Each element is a Locale object
659
         */
660
        /*public static Vector getAvailableLocales() {
661
                return _availableLocales;
662
        }*/
663

    
664
        /**
665
         *
666
         * @return A Vector containing the available languages. Each element is an String object
667
         */
668
        /*public static Vector getAvailableLanguages() {
669
                Vector availableLanguages = new Vector();
670
                Locale lang;
671
                Enumeration locales = _availableLocales.elements();
672
                while (locales.hasMoreElements()) {
673
                        lang = (Locale) locales.nextElement();
674
                        availableLanguages.add(lang.getLanguage());
675
                }
676
                return availableLanguages;
677
        }*/
678

    
679
        public static Properties getAllTexts(Locale lang) {
680
                Properties texts = new Properties();
681
                getAllTexts(lang, null, texts);
682
                for (Iterator iterator = classLoaders.iterator(); iterator.hasNext();) {
683
                        getAllTexts(lang, (ClassLoader) iterator.next(), texts);
684
                }
685
                return texts;
686
        }
687

    
688
        private static void getAllTexts(Locale lang, ClassLoader classLoader,
689
                        Properties texts) {
690
                ClassLoader loader = classLoader == null ? Messages.class
691
                                .getClassLoader() : classLoader;
692

    
693
                for (Iterator iterator = resourceFamilies.iterator(); iterator
694
                                .hasNext();) {
695
                        String family = (String) iterator.next();
696
                        addResourceFamily(lang, texts, family, loader,
697
                                        "Messages.getAllTexts");
698
                }
699
        }
700

    
701
}