Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.framework / org.gvsig.andami / src / main / java / org / gvsig / andami / impl / DefaultLocaleManager.java @ 41715

History | View | Annotate | Download (15.6 KB)

1
package org.gvsig.andami.impl;
2

    
3
import java.io.File;
4
import java.net.URL;
5
import java.security.AccessController;
6
import java.security.PrivilegedAction;
7
import java.util.Collections;
8
import java.util.Comparator;
9
import java.util.HashSet;
10
import java.util.Iterator;
11
import java.util.List;
12
import java.util.Locale;
13
import java.util.Set;
14
import java.util.TreeSet;
15
import javax.swing.JComponent;
16
import javax.swing.SwingUtilities;
17
import org.apache.commons.configuration.PropertiesConfiguration;
18
import org.apache.commons.lang3.LocaleUtils;
19
import org.apache.commons.lang3.StringUtils;
20
import org.gvsig.andami.Launcher;
21
import org.gvsig.andami.LocaleManager;
22
import org.gvsig.andami.PluginServices;
23
import org.gvsig.andami.PluginsLocator;
24
import org.gvsig.andami.PluginsManager;
25
import org.gvsig.andami.config.generate.AndamiConfig;
26
import org.gvsig.andami.installer.translations.TranslationsInstallerFactory;
27
import org.gvsig.andami.ui.mdiFrame.MDIFrame;
28
import org.gvsig.installer.lib.api.InstallerLocator;
29
import org.gvsig.installer.lib.api.InstallerManager;
30
import org.gvsig.utils.XMLEntity;
31
import org.slf4j.Logger;
32
import org.slf4j.LoggerFactory;
33

    
34
public class DefaultLocaleManager implements LocaleManager {
35

    
36
    private static final Logger logger
37
            = LoggerFactory.getLogger(DefaultLocaleManager.class);
38

    
39
    private static final String LOCALE_CODE_VALENCIANO = "vl";
40

    
41
    private static final String I18N_EXTENSION = "org.gvsig.i18n.extension";
42
    private static final String INSTALLED_TRANSLATIONS_HOME_FOLDER = "i18n";
43
    private static final String VARIANT = "variant";
44
    private static final String COUNTRY = "country";
45
    private static final String LANGUAGE = "language";
46
    private static final String REGISTERED_LOCALES_PERSISTENCE = "RegisteredLocales";
47
    
48
    private static final String LOCALE_CONFIG_FILENAME = "locale.config";
49

    
50
    private final Locale[] hardcoredLocales = new Locale[]{
51
        // Default supported locales
52
        SPANISH, // Spanish
53
        ENGLISH, // English
54
        new Locale("en", "US"), // English US
55
        new Locale("ca"), // Catalan
56
        new Locale("gl"), // Galician
57
        new Locale("eu"), // Basque
58
        new Locale("de"), // German
59
        new Locale("cs"), // Czech
60
        new Locale("fr"), // French
61
        new Locale("it"), // Italian
62
        new Locale("pl"), // Polish
63
        new Locale("pt"), // Portuguese
64
        new Locale("pt", "BR"), // Portuguese Brazil
65
        new Locale("ro"), // Romanian
66
        new Locale("zh"), // Chinese
67
        new Locale("ru"), // Russian
68
        new Locale("el"), // Greek
69
        new Locale("ro"), // Romanian
70
        new Locale("pl"), // Polish
71
        new Locale("tr"), // Turkish
72
        new Locale("sr"), // Serbio
73
        new Locale("sw") // Swahili
74
    };
75

    
76
    private Set installedLocales = null;
77
    private Set defaultLocales = null;
78

    
79
    public DefaultLocaleManager() {
80
        Locale currentLocale = org.gvsig.i18n.Messages.getCurrentLocale();
81
        this.setCurrentLocale(currentLocale);
82
    }
83

    
84
    public Locale getCurrentLocale() {
85
        return org.gvsig.i18n.Messages.getCurrentLocale();
86
    }
87

    
88
    public void setCurrentLocale(final Locale locale) {
89
        org.gvsig.i18n.Messages.setCurrentLocale(locale, this.getLocaleAlternatives(locale));
90

    
91
        String localeStr = locale.getLanguage();
92
        if (localeStr.equalsIgnoreCase(LOCALE_CODE_VALENCIANO)) {
93
            Locale.setDefault(new Locale("ca"));
94
        } else {
95
            Locale.setDefault(locale);
96
        }
97

    
98
        AndamiConfig config = Launcher.getAndamiConfig();
99
        config.setLocaleLanguage(locale.getLanguage());
100
        config.setLocaleCountry(locale.getCountry());
101
        config.setLocaleVariant(locale.getVariant());
102

    
103
        setCurrentLocaleUI(locale);
104
    }
105

    
106
    public Locale getDefaultSystemLocale() {
107
        String language, region, country, variant;
108
        language = getSystemProperty("user.language", "en");
109
        // for compatibility, check for old user.region property
110
        region = getSystemProperty("user.region", null);
111

    
112
        if (region != null) {
113
            // region can be of form country, country_variant, or _variant
114
            int i = region.indexOf('_');
115
            if (i >= 0) {
116
                country = region.substring(0, i);
117
                variant = region.substring(i + 1);
118
            } else {
119
                country = region;
120
                variant = "";
121
            }
122
        } else {
123
            country = getSystemProperty("user.country", "");
124
            variant = getSystemProperty("user.variant", "");
125
        }
126
        return new Locale(language, country, variant);
127
    }
128

    
129
    private Set<Locale> loadLocalesFromConfing(File localesFile)  { 
130
        PropertiesConfiguration config = null;
131
        if (!localesFile.canRead()) {
132
            return null;
133
        }
134
        try {
135
            config = new PropertiesConfiguration(localesFile);
136
        } catch (Exception ex) {
137
            logger.warn("Can't open locale configuration '" + localesFile + "'.", ex);
138
            return null;
139
        }
140
        
141
        Set<Locale> locales = new HashSet<Locale>();
142
        List localeCodes = config.getList("locale");
143
        for (Object localeCode : localeCodes) {
144
            try {
145
                Locale locale = LocaleUtils.toLocale((String) localeCode);
146
                locales.add(locale);
147
            } catch(IllegalArgumentException ex) {
148
                logger.warn("Can't load locale '"+localeCode+"' from config '"+localesFile.getAbsolutePath()+"'.",ex);
149
            }
150
        }
151
        return locales;
152
    }
153
    
154
    public Set<Locale> getDefaultLocales() {
155
        if (this.defaultLocales == null) {
156
            PluginsManager pluginsManager = PluginsLocator.getManager();
157
            File localesFile = new File(pluginsManager.getApplicationI18nFolder(), LOCALE_CONFIG_FILENAME);
158
            
159
            Set<Locale> locales = loadLocalesFromConfing(localesFile);
160
            defaultLocales = new HashSet<Locale>();
161
            if( locales == null ) {
162
                for (int i = 0; i < hardcoredLocales.length; i++) {
163
                    defaultLocales.add(hardcoredLocales[i]);
164
                }
165
            } else {
166
                defaultLocales.addAll(locales);
167
            }
168
        }
169
        return this.defaultLocales;
170
    }
171

    
172
    public boolean installLocales(URL localesFile) {
173
        PluginsManager pluginsManager = PluginsLocator.getManager();
174
        PropertiesConfiguration config = null;
175
        try {
176
            config = new PropertiesConfiguration(localesFile);
177
        } catch (Exception ex) {
178
            logger.warn("Can't open configuration '" + localesFile + "'.", ex);
179
        }
180
        if (config == null) {
181
            return false;
182
        }
183
        List localeCodes = config.getList("locale");
184
        for (Object localeCode : localeCodes) {
185
            Locale locale = LocaleUtils.toLocale((String) localeCode);
186
            if (!getInstalledLocales().contains(locale)) {
187
                this.installedLocales.add(locale);
188
            }
189
        }
190
        storeInstalledLocales();
191
        return true;
192
    }
193

    
194
    public Set<Locale> getInstalledLocales() {
195
        if (installedLocales == null) {
196
            installedLocales = new TreeSet<Locale>(new Comparator<Locale>() {
197
                public int compare(Locale t0, Locale t1) {
198
                    if (t1 == null || t0 == null) {
199
                        return 0;
200
                    }
201
                    // return getLanguageDisplayName(t0).compareToIgnoreCase(getLanguageDisplayName(t1));
202
                    return t0.toString().compareToIgnoreCase(t1.toString());
203
                }
204
            });
205

    
206
            XMLEntity child = getRegisteredLocalesPersistence();
207

    
208
            // If the list of registered locales is not already persisted,
209
            // this should be the first time gvSIG is run with the I18nPlugin
210
            // so we will take the list of default locales
211
            if (child == null) {
212
                installedLocales.addAll(getDefaultLocales());
213
                storeInstalledLocales();
214
            } else {
215
                XMLEntity localesEntity = getRegisteredLocalesPersistence();
216
                for (int i = 0; i < localesEntity.getChildrenCount(); i++) {
217
                    Locale locale = null;
218
                    XMLEntity localeEntity = localesEntity.getChild(i);
219
                    String language = localeEntity.getStringProperty(LANGUAGE);
220
                    String country = localeEntity.getStringProperty(COUNTRY);
221
                    String variant = localeEntity.getStringProperty(VARIANT);
222
                    locale = new Locale(language, country, variant);
223
                    installedLocales.add(locale);
224
                }
225
            }
226
            Set<Locale> lfp = getAllLocalesFromPackages();
227
            installedLocales.addAll(lfp);
228
        }
229
        return Collections.unmodifiableSet(installedLocales);
230
    }
231

    
232
    public boolean installLocale(Locale locale) {
233
        // Add the locale to the list of installed ones, if it
234
        // is new, otherwise, update the texts.
235
        if (!getInstalledLocales().contains(locale)) {
236
            getInstalledLocales().add(locale);
237
            storeInstalledLocales();
238
        }
239
        return true;
240
    }
241

    
242
    public boolean uninstallLocale(Locale locale) {
243
        if (!getInstalledLocales().remove(locale)) {
244
            return false;
245
        }
246
        storeInstalledLocales();
247
        return true;
248
    }
249

    
250
    public String getLanguageDisplayName(Locale locale) {
251

    
252
        String displayName;
253

    
254
        if ("eu".equals(locale.getLanguage())
255
                && "vascuence".equals(locale.getDisplayLanguage())) {
256
            // Correction for the Basque language display name,
257
            // show it in Basque, not in Spanish
258
            displayName = "Euskera";
259
        } else if (LOCALE_CODE_VALENCIANO.equals(locale.getLanguage())) {
260
            // Patch for Valencian/Catalan
261
            displayName = "Valenci?";
262
        } else {
263
            displayName = locale.getDisplayLanguage(locale);
264
        }
265

    
266
        return StringUtils.capitalize(displayName);
267
    }
268
    
269
    public String getLocaleDisplayName(Locale locale) {
270
        String displayName = this.getLanguageDisplayName(locale);
271
        
272
        if( !StringUtils.isBlank(locale.getCountry()) ) {
273
            if( !StringUtils.isBlank(locale.getVariant()) ) {
274
                displayName = displayName + " (" + 
275
                        StringUtils.capitalize(locale.getDisplayCountry(locale)) + "/" + 
276
                        locale.getDisplayVariant(locale) + ")";
277
            } else {
278
                displayName = displayName + " ("+locale.getDisplayCountry(locale)+")";
279
            }
280
        }
281
        
282
        return displayName;
283
    }
284

    
285
    public Locale[] getLocaleAlternatives(Locale locale) {
286
        Locale alternatives[] = null;
287

    
288
        String localeStr = locale.getLanguage();
289
        if (localeStr.equals("es")
290
                || localeStr.equals("ca")
291
                || localeStr.equals("gl")
292
                || localeStr.equals("eu")
293
                || localeStr.equals(LOCALE_CODE_VALENCIANO)) {
294
            alternatives = new Locale[2];
295
            alternatives[0] = new Locale("es");
296
            alternatives[1] = new Locale("en");
297
        } else {
298
            // prefer English for the rest
299
            alternatives = new Locale[2];
300
            alternatives[0] = new Locale("en");
301
            alternatives[1] = new Locale("es");
302
        }
303
        return alternatives;
304
    }
305

    
306
    private void setCurrentLocaleUI(final Locale locale) {
307
        if (!SwingUtilities.isEventDispatchThread()) {
308
            try {
309
                SwingUtilities.invokeAndWait(new Runnable() {
310
                    public void run() {
311
                        setCurrentLocaleUI(locale);
312
                    }
313
                });
314
            } catch (Exception ex) {
315
                // Ignore
316
            }
317
        }
318
        try {
319
            JComponent.setDefaultLocale(locale);
320
        } catch (Exception ex) {
321
            logger.warn("Problems setting locale to JComponent.", ex);
322
        }
323
        if (MDIFrame.isInitialized()) {
324
            try {
325
                MDIFrame.getInstance().setLocale(locale);
326
            } catch (Exception ex) {
327
                logger.warn("Problems settings locale to MDIFrame.", ex);
328
            }
329
        }
330
    }
331

    
332
    public File getResourcesFolder() {
333
        File i18nFolder = new File(
334
                PluginsLocator.getManager().getApplicationHomeFolder(),
335
                INSTALLED_TRANSLATIONS_HOME_FOLDER
336
        );
337
        if (!i18nFolder.exists()) {
338
            i18nFolder.mkdirs();
339
        }
340
        return i18nFolder;
341
    }
342

    
343
    /**
344
     * Returns the child XMLEntity with the RegisteredLocales.
345
     */
346
    private XMLEntity getRegisteredLocalesPersistence() {
347
        XMLEntity entity = getI18nPersistence();
348
        XMLEntity child = null;
349
        for (int i = entity.getChildrenCount() - 1; i >= 0; i--) {
350
            XMLEntity tmpchild = entity.getChild(i);
351
            if (tmpchild.getName().equals(REGISTERED_LOCALES_PERSISTENCE)) {
352
                child = tmpchild;
353
                break;
354
            }
355
        }
356
        return child;
357
    }
358

    
359
    /**
360
     * Stores the list of installed locales into the plugin persistence.
361
     */
362
    private void storeInstalledLocales() {
363
        XMLEntity localesEntity = getRegisteredLocalesPersistence();
364

    
365
        // Remove the previous list of registered languages
366
        if (localesEntity != null) {
367
            XMLEntity i18nPersistence = getI18nPersistence();
368
            for (int i = i18nPersistence.getChildrenCount() - 1; i >= 0; i--) {
369
                XMLEntity child = i18nPersistence.getChild(i);
370
                if (child.getName().equals(REGISTERED_LOCALES_PERSISTENCE)) {
371
                    i18nPersistence.removeChild(i);
372
                    break;
373
                }
374
            }
375
        }
376

    
377
        // Create the new persistence for the registered languages
378
        localesEntity = new XMLEntity();
379

    
380
        localesEntity.setName(REGISTERED_LOCALES_PERSISTENCE);
381

    
382
        Set<Locale> locales = getInstalledLocales();
383
        for (Iterator iterator = locales.iterator(); iterator.hasNext();) {
384
            Locale locale = (Locale) iterator.next();
385
            XMLEntity localeEntity = new XMLEntity();
386
            localeEntity.setName(locale.getDisplayName());
387
            localeEntity.putProperty(LANGUAGE, locale.getLanguage());
388
            localeEntity.putProperty(COUNTRY, locale.getCountry());
389
            localeEntity.putProperty(VARIANT, locale.getVariant());
390

    
391
            localesEntity.addChild(localeEntity);
392
        }
393

    
394
        getI18nPersistence().addChild(localesEntity);
395
    }
396

    
397
    /**
398
     * Returns the I18n Plugin persistence.
399
     */
400
    private XMLEntity getI18nPersistence() {
401
        XMLEntity entity
402
                = PluginServices.getPluginServices(I18N_EXTENSION).getPersistentXML();
403
        return entity;
404
    }
405

    
406
    @SuppressWarnings("unchecked")
407
    private String getSystemProperty(final String property, String defaultValue) {
408
        String value
409
                = (String) AccessController.doPrivileged(new PrivilegedAction() {
410
                    public Object run() {
411
                        return System.getProperty(property);
412
                    }
413
                });
414
        return value == null ? defaultValue : value;
415
    }
416
    
417
    private Set<Locale> getAllLocalesFromPackages() {
418
        Set<Locale> locales = new HashSet<Locale>();
419
        InstallerManager installerManager = InstallerLocator.getInstallerManager();
420
        List<File> folders = installerManager.getAddonFolders(TranslationsInstallerFactory.PROVIDER_NAME);
421
        for( File folder : folders ) {
422
            File file = new File(folder,LOCALE_CONFIG_FILENAME);
423
            Set<Locale> l = this.loadLocalesFromConfing(file);
424
            locales.addAll(l);
425
        }
426
        return locales;
427
    }
428
}