Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.i18n.app / org.gvsig.i18n.app.mainplugin / src / main / java / org / gvsig / i18n / impl / TranslationsConsolider.java @ 41318

History | View | Annotate | Download (13.8 KB)

1
/*
2
 * To change this license header, choose License Headers in Project Properties.
3
 * To change this template file, choose Tools | Templates
4
 * and open the template in the editor.
5
 */
6
package org.gvsig.i18n.impl;
7

    
8
import java.io.File;
9
import java.io.FileFilter;
10
import java.io.FileInputStream;
11
import java.io.FileOutputStream;
12
import java.io.IOException;
13
import java.util.ArrayList;
14
import java.util.Collections;
15
import java.util.Enumeration;
16
import java.util.HashMap;
17
import java.util.Iterator;
18
import java.util.List;
19
import java.util.Locale;
20
import java.util.Map;
21
import java.util.Properties;
22
import org.apache.commons.io.FileUtils;
23
import org.apache.commons.io.IOUtils;
24
import org.apache.commons.lang3.StringUtils;
25
import org.gvsig.andami.PluginServices;
26
import org.gvsig.andami.PluginsLocator;
27
import org.gvsig.andami.PluginsManager;
28
import org.gvsig.i18n.I18nManager;
29
import org.gvsig.i18n.Messages;
30
import org.gvsig.tools.ToolsLocator;
31
import org.gvsig.tools.task.SimpleTaskStatus;
32
import org.gvsig.tools.task.TaskStatus;
33
import org.slf4j.Logger;
34
import org.slf4j.LoggerFactory;
35

    
36
/**
37
 *
38
 * @author usuario
39
 */
40
public class TranslationsConsolider {
41

    
42
    private static final Logger logger = LoggerFactory.getLogger(TranslationsConsolider.class);
43

    
44
    private I18nManager i18nManager = null;
45
    private PluginsManager pluginsManager = null;
46
    private Map<String, Map<String, String>> allTranslations = null;
47
    private Locale currentLocale = null;
48
    private Map<String, List<String>> keysInPlugins = null;
49

    
50
    public TranslationsConsolider() {
51
        this.pluginsManager = PluginsLocator.getManager();
52
        this.allTranslations = new HashMap<String, Map<String, String>>();
53
        this.currentLocale = this.getI18nManager().getCurrentLocale();
54
        this.keysInPlugins = new HashMap<String, List<String>>();
55
    }
56

    
57
    public void setCurrentLocale(Locale locale) {
58
        this.currentLocale = locale;
59
    }
60

    
61
    public Locale getCurrentLocale() {
62
        return this.currentLocale;
63
    }
64

    
65
    public I18nManager getI18nManager() {
66
        if ( this.i18nManager == null ) {
67
            this.i18nManager = I18nManagerImpl.getInstance();
68
        }
69
        return this.i18nManager;
70
    }
71

    
72
    public void addKey(String key, String pluginCode) {
73
        List<String> pluginCodes = this.keysInPlugins.get(key);
74
        if ( pluginCodes == null ) {
75
            pluginCodes = new ArrayList<String>();
76
            this.keysInPlugins.put(key, pluginCodes);
77
        }
78
        if ( !StringUtils.isBlank(pluginCode) ) {
79
            if ( !pluginCodes.contains(pluginCode) ) {
80
                pluginCodes.add(pluginCode);
81
            }
82
        }
83
    }
84

    
85
    public void addLocale(Locale locale) {
86
        if ( this.allTranslations.get(locale.toString()) == null ) {
87
            this.allTranslations.put(locale.toString().toLowerCase(), new HashMap<String, String>());
88
        }
89
    }
90

    
91
    public List<String> getPluginCodesOfKey(String key) {
92
        List<String> pluginCodes = this.keysInPlugins.get(key);
93
        return pluginCodes;
94
    }
95

    
96
    public Map<String, String> getTranslations(String locale) {
97
        Map<String, String> translations = this.allTranslations.get(locale.toString().toLowerCase());
98
        return translations;
99
    }
100

    
101
    public Map<String, String> getTranslations(Locale locale) {
102
        return this.getTranslations(locale.toString());
103
    }
104

    
105
    public void add(Locale locale, String key, String value, String pluginCode) {
106
        Map<String, String> translations = this.getTranslations(locale);
107
        if ( !translations.containsKey(key) ) {
108
            translations.put(key, value);
109
            this.addKey(key, pluginCode);
110
        }
111
    }
112

    
113
    public void add(Locale locale, Properties properties, String pluginCode) {
114
        this.addLocale(locale);
115
        Enumeration enumKeys = properties.keys();
116
        while ( enumKeys.hasMoreElements() ) {
117
            String key = (String) enumKeys.nextElement();
118
            String value = properties.getProperty(key);
119
            this.add(locale, key, value, pluginCode);
120
        }
121
    }
122

    
123
    public List<Locale> getLocales() {
124
        List<Locale> locales = new ArrayList<Locale>(this.allTranslations.size());
125
        Iterator<String> itLocales = this.allTranslations.keySet().iterator();
126
        while ( itLocales.hasNext() ) {
127
            Locale locale = new Locale(itLocales.next().toString());
128
            locales.add(locale);
129
        }
130
        return locales;
131
    }
132

    
133
    public List<String> getKeys() {
134
        List<String> keys = new ArrayList<String>(this.keysInPlugins.size());
135
        keys.addAll(this.keysInPlugins.keySet());
136
        Collections.sort(keys);
137
        return keys;
138
    }
139

    
140
    private String getResourceFileName(Locale locale) {
141
        StringBuilder fileName = new StringBuilder();
142
        fileName.append("text");
143
        if ( !StringUtils.isBlank(locale.getLanguage()) ) {
144
            fileName.append("_");
145
            fileName.append(locale.getLanguage());
146
        }
147
        if ( !StringUtils.isBlank(locale.getCountry()) ) {
148
            fileName.append("_");
149
            fileName.append(locale.getCountry());
150
        }
151
        if ( !StringUtils.isBlank(locale.getVariant()) ) {
152
            fileName.append("_");
153
            fileName.append(locale.getVariant());
154
        }
155
        fileName.append(".properties");
156
        return fileName.toString();
157
    }
158

    
159
    public String getTranslation(String locale, String key) {
160
        Map<String, String> translations = this.getTranslations(locale);
161
        if ( translations == null ) {
162
            logger.warn("Can't locate the translations for locale '" + locale + "'.");
163
            return null;
164
        }
165
        return translations.get(key);
166
    }
167

    
168
    public String getTranslation(Locale locale, String key) {
169
        return this.getTranslation(locale.toString(), key);
170
    }
171

    
172
    public String get(String key) {
173
        return this.getTranslation(currentLocale, key);
174
    }
175

    
176
    public void put(String key, String value) {
177
        this.add(currentLocale, key, value, null);
178
    }
179

    
180
    private int mergeWithTranslationsFromMessages(SimpleTaskStatus task, int n) {
181
        List<Locale> locales = this.getLocales();
182
        
183
        for(int i=0; i<locales.size(); i++) {
184
            Locale locale = locales.get(i);
185
            task.message("merge "+locale.toString());
186
            task.setCurValue(n++);
187
            Properties translations = Messages.getTranslations(locale);
188
            Enumeration<Object> keys = translations.keys();
189
            while( keys.hasMoreElements() ) {
190
                String key = (String) keys.nextElement();
191
                String value = translations.getProperty(key);
192
                this.add(locale, key, value, null);
193
            }
194
        }
195
        return n;
196
        
197
    }
198
    
199
    public void consolide() throws IOException {
200
        SimpleTaskStatus task = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("Consolide translations");
201
        task.setAutoremove(true);
202
        task.add();
203
        try {
204
            task.setTitle("Consolide translations");
205
            int n = this.loadAllTranslations(task);
206
            n = mergeWithTranslationsFromMessages(task,n);
207
            if( !task.isCancellationRequested() ) {
208
                this.storeAsProperties(task, n);
209
            }
210
        } finally {
211
            task.terminate();
212
        }
213
    }
214
    
215
    private int loadAllTranslations(SimpleTaskStatus task) {
216
        task.message("searching locales");
217
        Locale[] locales = this.getI18nManager().getInstalledLocales();
218

    
219
        List<PluginServices> plugins = this.pluginsManager.getPlugins();
220
        File appI18nFolder = pluginsManager.getApplicationI18nFolder();
221
        File[] subfolders = appI18nFolder.listFiles(new FileFilter() {
222
            public boolean accept(File file) {
223
                return file.isDirectory();
224
            }
225
        });
226
        int n = 1;
227
        task.setRangeOfValues(0, plugins.size() + subfolders.length + locales.length*2 + 1);
228

    
229
        task.message("loading from andami.");
230
        task.setCurValue(n++);
231
        loadTranslation(locales, appI18nFolder, null);
232

    
233
        for ( File subfolder : subfolders ) {
234
            if( task.isCancellationRequested() ) {
235
                return n;
236
            }
237
            task.setCurValue(n++);
238
            if ( subfolder.isDirectory() ) {
239
                task.message("loading " + subfolder.getName());
240
                if ( "andami".equals(subfolder.getName()) ) {
241
                    loadTranslation(locales, appI18nFolder, "org.gvsig.andami");
242
                } else {
243
                    loadTranslation(locales, appI18nFolder, null);
244
                }
245
            }
246
        }
247

    
248
        for ( PluginServices plugin : plugins ) {
249
            if( task.isCancellationRequested() ) {
250
                return n;
251
            }
252
            if ( plugin != null ) {
253
                task.message("loading " + plugin.getPluginName());
254
                task.setCurValue(n++);
255
                loadTranslation(locales, plugin.getPluginDirectory(), plugin.getPluginName());
256
            }
257
        }
258
        return n;
259
    }
260

    
261
    private void loadTranslation(Locale[] locales, File folder, String pluginCode) {
262
        for ( Locale locale : locales ) {
263
            File f1 = new File(folder, getResourceFileName(locale));
264
            File f2 = new File(folder, "i18n/" + getResourceFileName(locale));
265
            if ( !f1.exists() && !f2.exists() ) {
266
                if ( "es".equals(locale.getLanguage()) ) {
267
                    f1 = new File(folder, "text.properties");
268
                    f2 = new File(folder, "i18n/text.properties");
269
                }
270
            }
271
            if ( f1.exists() ) {
272
                loadTranslation(locale, f1, pluginCode);
273
            }
274
            if ( f2.exists() ) {
275
                loadTranslation(locale, f2, pluginCode);
276
            }
277
        }
278
    }
279

    
280
    private void loadTranslation(Locale locale, File f, String pluginCode) {
281
        FileInputStream fins = null;
282
        try {
283
            Properties properties = new Properties();
284
            fins = new FileInputStream(f);
285
            properties.load(fins);
286
            this.add(locale, properties, pluginCode);
287
        } catch (IOException ex) {
288
            logger.warn("Error processing property file '" + f.getAbsolutePath() + "'.", ex);
289
        } finally {
290
            IOUtils.closeQuietly(fins);
291
        }
292
    }
293

    
294
    private void storeAsProperties(SimpleTaskStatus task, int pos) throws IOException {
295
        task.message("Prepraring to store");
296
        File folder = new File(this.pluginsManager.getApplicationI18nFolder(), "translations.all");
297
        if( !folder.exists() ) {
298
            FileUtils.forceMkdir(folder);
299
        }
300
        List<String> keys = this.getKeys();
301
        List<Locale> locales = this.getLocales();
302
        for ( Locale locale : locales ) {
303
            task.setCurValue(pos++);
304
            task.message("Storing "+locale.toString());
305
            Map<String, String> translations = this.getTranslations(locale);
306
            Properties properties = new Properties();
307
            for ( String key : keys ) {
308
                String value = this.getTranslation(locale, key);
309
                if( value == null ) {
310
                    value = "";
311
                }
312
                properties.setProperty(key, value);
313
            }
314
            File f = new File(folder, this.getResourceFileName(locale));
315
            FileOutputStream fos = null;
316
            try {
317
                fos = new FileOutputStream(f);
318
                properties.store(fos, null);
319
            } catch (Exception ex) {
320
                logger.warn("Can't write properties '" + f.getAbsolutePath() + "'.", ex);
321
            } finally {
322
                IOUtils.closeQuietly(fos);
323
            }
324

    
325
        }
326
        task.message("Storing plugin information");
327
        Properties properties = new Properties();
328
        for ( String key : keys ) {
329
            List<String> pluginCodes = this.keysInPlugins.get(key);
330
            StringBuilder ss = null;
331
            for ( String pluginCode : pluginCodes ) {
332
                if ( ss == null ) {
333
                    ss = new StringBuilder();
334
                } else {
335
                    ss.append(", ");
336
                }
337
                ss.append(pluginCode);
338
            }
339
            if ( ss == null ) {
340
                properties.setProperty(key, "");
341
            } else {
342
                properties.setProperty(key, ss.toString());
343
            }
344
        }
345
        FileOutputStream fos = null;
346
        File f = new File(folder, "keysbyplugin.properties");
347
        try {
348
            fos = new FileOutputStream(f);
349
            properties.store(fos, null);
350
        } catch (Exception ex) {
351
            logger.warn("Can't write properties '" + f.getAbsolutePath() + "'.", ex);
352
        } finally {
353
            IOUtils.closeQuietly(fos);
354
        }             
355
        task.message("");
356
    }
357

    
358
    /*
359
     def storeAsDBF(self):
360
     maxl = 100
361
     for k in self.keys():
362
     if len(k) > maxl:
363
     maxl = len(k)
364
     #print "max key len: ", maxl
365
        
366
     folder = File(self.__pluginsManager.getApplicationFolder(),"i18n")
367
     f = File(folder,"translations.dbf")
368
     try:
369
     f.delete()
370
     except:
371
     print "Can't delete file "+f.getAbsolutePath()
372
     schema = createSchema() 
373
     schema.append( "ID" , "Integer" , 7)
374
     schema.append( "key" , "String" , maxl)
375
     schema.append( "locale" , "String" , 30)
376
     schema.append( "translation" , "String" , 200)
377
     schema.append( "plugins" , "String" , 200)
378

379
     table = createDBF( schema, File(folder,"translations.dbf"))
380

381
     locales = self.getI18nManager().getInstalledLocales()
382
     idCounter = 1
383
     for key in self.keys():
384
     for locale in locales:
385
     pluginCodes = ""
386
     for pluginCode in self.getPluginCodesOfKey(key):
387
     pluginCodes += pluginCode + " "
388
     pluginCodes = str(pluginCodes).strip()
389
        
390
     table.append(ID=idCounter, 
391
     key=key, 
392
     locale=locale.toString(), 
393
     translation=self.getTranslation(locale, key),
394
     plugins=pluginCodes
395
     )
396
     idCounter +=1
397
     table.commit()
398
  
399
     */
400
}