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

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
public class DefaultLocaleManager implements LocaleManager {
32

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

    
36
    private static final String LOCALE_CODE_VALENCIANO = "vl";
37

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

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

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

    
74
    public DefaultLocaleManager() {
75
        Locale currentLocale = org.gvsig.i18n.Messages.getCurrentLocale();
76
        this.setCurrentLocale(currentLocale);
77
    }
78

    
79
    public Locale getCurrentLocale() {
80
        return org.gvsig.i18n.Messages.getCurrentLocale();
81
    }
82

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

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

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

    
98
        setCurrentLocaleUI(locale);
99
    }
100

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

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

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

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

    
150
        }
151
        return this.defaultLocales;
152
    }
153

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

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

    
187
            XMLEntity child = getRegisteredLocalesPersistence();
188

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

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

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

    
228
    public String getLanguageDisplayName(Locale locale) {
229

    
230
        String displayName;
231

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

    
244
        return StringUtils.capitalize(displayName);
245
    }
246

    
247
    public Locale[] getLocaleAlternatives(Locale locale) {
248
        Locale alternatives[] = null;
249

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

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

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

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

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

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

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

    
342
        localesEntity.setName(REGISTERED_LOCALES_PERSISTENCE);
343

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

    
353
            localesEntity.addChild(localeEntity);
354
        }
355

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

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

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