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 @ 41390

History | View | Annotate | Download (13.5 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.ui.mdiFrame.MDIFrame;
27
import org.gvsig.utils.XMLEntity;
28
import org.slf4j.Logger;
29
import org.slf4j.LoggerFactory;
30

    
31

    
32
public class DefaultLocaleManager implements LocaleManager {
33

    
34
    private static final Logger logger
35
            = LoggerFactory.getLogger(DefaultLocaleManager.class);
36

    
37
    private static final String LOCALE_CODE_VALENCIANO = "vl";
38
    
39
    private static final String I18N_EXTENSION = "org.gvsig.i18n.extension";
40
    private static final String INSTALLED_TRANSLATIONS_HOME_FOLDER = "i18n";
41
    private static final String VARIANT = "variant";
42
    private static final String COUNTRY = "country";
43
    private static final String LANGUAGE = "language";
44
    private static final String REGISTERED_LOCALES_PERSISTENCE = "RegisteredLocales";
45

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

    
72
    private Set installedLocales = null;
73
    private Set defaultLocales = null;
74

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

    
84
    public void setCurrentLocale(final Locale locale) {
85
        org.gvsig.i18n.Messages.setCurrentLocale(locale, this.getLocaleAlternatives(locale));
86

    
87
        String localeStr = locale.getLanguage();
88
        if ( localeStr.equalsIgnoreCase(LOCALE_CODE_VALENCIANO) ) {
89
            Locale.setDefault(new Locale("ca"));
90
        } else {
91
            Locale.setDefault(locale);
92
        }
93

    
94
        AndamiConfig config = Launcher.getAndamiConfig();
95
        config.setLocaleLanguage(locale.getLanguage());
96
        config.setLocaleCountry(locale.getCountry());
97
        config.setLocaleVariant(locale.getVariant());
98

    
99
        setCurrentLocaleUI(locale);
100
    }
101

    
102
    public Locale getDefaultSystemLocale() {
103
        String language, region, country, variant;
104
        language = getSystemProperty("user.language", "en");
105
        // for compatibility, check for old user.region property
106
        region = getSystemProperty("user.region", null);
107

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

    
125
    public Set<Locale> getDefaultLocales() {
126
        if ( this.defaultLocales == null ) {
127
            PluginsManager pluginsManager = PluginsLocator.getManager();
128
            File localesFile = new File(pluginsManager.getApplicationI18nFolder(), "locale.config");
129

    
130
            PropertiesConfiguration config = null;
131
            if ( localesFile.canRead() ) {
132
                try {
133
                    config = new PropertiesConfiguration(localesFile);
134
                } catch (Exception ex) {
135
                    logger.warn("Can't open configuration '" + localesFile + "'.", ex);
136
                }
137
            }
138
            defaultLocales = new HashSet<Locale>();
139
            if ( config == null ) {
140
                for ( int i = 0; i < hardcoredLocales.length; i++ ) {
141
                    defaultLocales.add(hardcoredLocales[i]);
142
                }
143
            } else {
144
                List localeCodes = config.getList("locale");
145
                for ( Object localeCode : localeCodes ) {
146
                    Locale locale = LocaleUtils.toLocale((String) localeCode);
147
                    defaultLocales.add(locale);
148
                }
149
            }
150

    
151
        }
152
        return this.defaultLocales;
153
    }
154

    
155
    public boolean installLocales(URL localesFile) {
156
        PluginsManager pluginsManager = PluginsLocator.getManager();
157
        PropertiesConfiguration config = null;
158
        try {
159
            config = new PropertiesConfiguration(localesFile);
160
        } catch (Exception ex) {
161
            logger.warn("Can't open configuration '" + localesFile + "'.", ex);
162
        }
163
        if ( config == null ) {
164
            return false;
165
        }
166
        List localeCodes = config.getList("locale");
167
        for ( Object localeCode : localeCodes ) {
168
            Locale locale = LocaleUtils.toLocale((String) localeCode);
169
            if ( !getInstalledLocales().contains(locale) ) {
170
                this.installedLocales.add(locale);
171
            }
172
        }
173
        storeInstalledLocales();
174
        return true;
175
    }
176

    
177
    public Set<Locale> getInstalledLocales() {
178
        if ( installedLocales == null ) {
179
            installedLocales = new TreeSet<Locale>(new Comparator<Locale>() {
180
                public int compare(Locale t0, Locale t1) {
181
                    if( t1 == null || t0 == null ) {
182
                        return 0;
183
                    }
184
                    return getLanguageDisplayName(t0).compareToIgnoreCase(getLanguageDisplayName(t1));
185
                }
186
            });
187

    
188
            XMLEntity child = getRegisteredLocalesPersistence();
189

    
190
            // If the list of registered locales is not already persisted,
191
            // this should be the first time gvSIG is run with the I18nPlugin
192
            // so we will take the list of default locales
193
            if ( child == null ) {
194
                installedLocales.addAll(getDefaultLocales());
195
                storeInstalledLocales();
196
            } else {
197
                XMLEntity localesEntity = getRegisteredLocalesPersistence();
198
                for ( int i = 0; i < localesEntity.getChildrenCount(); i++ ) {
199
                    XMLEntity localeEntity = localesEntity.getChild(i);
200
                    String language = localeEntity.getStringProperty(LANGUAGE);
201
                    String country = localeEntity.getStringProperty(COUNTRY);
202
                    String variant = localeEntity.getStringProperty(VARIANT);
203
                    Locale locale = new Locale(language, country, variant);
204
                    installedLocales.add(locale);
205
                }
206
            }
207
        }
208
        return Collections.unmodifiableSet(installedLocales);
209
    }
210

    
211
    public boolean installLocale(Locale locale) {
212
        // Add the locale to the list of installed ones, if it
213
        // is new, otherwise, update the texts.
214
        if ( !getInstalledLocales().contains(locale) ) {
215
            getInstalledLocales().add(locale);
216
            storeInstalledLocales();
217
        }
218
        return true;
219
    }
220

    
221
    public boolean uninstallLocale(Locale locale) {
222
        if ( !getInstalledLocales().remove(locale) ) {
223
            return false;
224
        }
225
        storeInstalledLocales();
226
        return true;
227
    }
228

    
229
    public String getLanguageDisplayName(Locale locale) {
230

    
231
        String displayName;
232

    
233
        if ( "eu".equals(locale.getLanguage())
234
                && "vascuence".equals(locale.getDisplayLanguage()) ) {
235
            // Correction for the Basque language display name,
236
            // show it in Basque, not in Spanish
237
            displayName = "Euskera";
238
        } else if ( LOCALE_CODE_VALENCIANO.equals(locale.getLanguage()) ) {
239
            // Patch for Valencian/Catalan
240
            displayName = "Valenci?";
241
        } else {
242
            displayName = locale.getDisplayLanguage(locale);
243
        }
244

    
245
        return StringUtils.capitalize(displayName);
246
    }
247
    
248
    public Locale[] getLocaleAlternatives(Locale locale) {
249
        Locale alternatives[] = null;
250

    
251
        String localeStr = locale.getLanguage();
252
        if ( localeStr.equals("es") || 
253
             localeStr.equals("ca") ||
254
             localeStr.equals("gl") || 
255
             localeStr.equals("eu") ||
256
             localeStr.equals(LOCALE_CODE_VALENCIANO) ) {
257
            alternatives = new Locale[2];
258
            alternatives[0] = new Locale("es");
259
            alternatives[1] = new Locale("en");
260
        } else {
261
            // prefer English for the rest
262
            alternatives = new Locale[2];
263
            alternatives[0] = new Locale("en");
264
            alternatives[1] = new Locale("es");
265
        }
266
        return alternatives;
267
    }
268

    
269
    private void setCurrentLocaleUI(final Locale locale) {
270
        if ( !SwingUtilities.isEventDispatchThread() ) {
271
            try {
272
                SwingUtilities.invokeAndWait(new Runnable() {
273
                    public void run() {
274
                        setCurrentLocaleUI(locale);
275
                    }
276
                });
277
            } catch (Exception ex) {
278
                // Ignore
279
            }
280
        }
281
        try {
282
            JComponent.setDefaultLocale(locale);
283
        } catch (Exception ex) {
284
            logger.warn("Problems setting locale to JComponent.", ex);
285
        }
286
        try {
287
            MDIFrame.getInstance().setLocale(locale);
288
        } catch (Exception ex) {
289
            logger.warn("Problems settings locale to MDIFrame.", ex);
290
        }
291
    }
292

    
293
    public File getResourcesFolder() {
294
        File i18nFolder = new File(
295
                PluginsLocator.getManager().getApplicationHomeFolder(),
296
                INSTALLED_TRANSLATIONS_HOME_FOLDER
297
        );
298
        if ( !i18nFolder.exists() ) {
299
            i18nFolder.mkdirs();
300
        }
301
        return i18nFolder;
302
    }
303

    
304
    /**
305
     * Returns the child XMLEntity with the RegisteredLocales.
306
     */
307
    private XMLEntity getRegisteredLocalesPersistence() {
308
        XMLEntity entity = getI18nPersistence();
309
        XMLEntity child = null;
310
        for ( int i = entity.getChildrenCount() - 1; i >= 0; i-- ) {
311
            XMLEntity tmpchild = entity.getChild(i);
312
            if ( tmpchild.getName().equals(REGISTERED_LOCALES_PERSISTENCE) ) {
313
                child = tmpchild;
314
                break;
315
            }
316
        }
317
        return child;
318
    }
319

    
320
    /**
321
     * Stores the list of installed locales into the plugin persistence.
322
     */
323
    private void storeInstalledLocales() {
324
        XMLEntity localesEntity = getRegisteredLocalesPersistence();
325

    
326
        // Remove the previous list of registered languages
327
        if ( localesEntity != null ) {
328
            XMLEntity i18nPersistence = getI18nPersistence();
329
            for ( int i = i18nPersistence.getChildrenCount() - 1; i >= 0; i-- ) {
330
                XMLEntity child = i18nPersistence.getChild(i);
331
                if ( child.getName().equals(REGISTERED_LOCALES_PERSISTENCE) ) {
332
                    i18nPersistence.removeChild(i);
333
                    break;
334
                }
335
            }
336
        }
337

    
338
        // Create the new persistence for the registered languages
339
        localesEntity = new XMLEntity();
340

    
341
        localesEntity.setName(REGISTERED_LOCALES_PERSISTENCE);
342

    
343
        Set<Locale> locales = getInstalledLocales();
344
        for ( Iterator iterator = locales.iterator(); iterator.hasNext(); ) {
345
            Locale locale = (Locale) iterator.next();
346
            XMLEntity localeEntity = new XMLEntity();
347
            localeEntity.setName(locale.getDisplayName());
348
            localeEntity.putProperty(LANGUAGE, locale.getLanguage());
349
            localeEntity.putProperty(COUNTRY, locale.getCountry());
350
            localeEntity.putProperty(VARIANT, locale.getVariant());
351

    
352
            localesEntity.addChild(localeEntity);
353
        }
354

    
355
        getI18nPersistence().addChild(localesEntity);
356
    }
357

    
358
    /**
359
     * Returns the I18n Plugin persistence.
360
     */
361
    private XMLEntity getI18nPersistence() {
362
        XMLEntity entity
363
                = PluginServices.getPluginServices(I18N_EXTENSION).getPersistentXML();
364
        return entity;
365
    }
366

    
367
    @SuppressWarnings("unchecked")
368
    private String getSystemProperty(final String property, String defaultValue) {
369
        String value
370
                = (String) AccessController.doPrivileged(new PrivilegedAction() {
371
                    public Object run() {
372
                        return System.getProperty(property);
373
                    }
374
                });
375
        return value == null ? defaultValue : value;
376
    }
377
}