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 | 41284 | jjdelcerro | /*
|
---|---|---|---|
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 | 41318 | jjdelcerro | import org.gvsig.i18n.Messages; |
30 | 41284 | jjdelcerro | 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 | 41318 | jjdelcerro | 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 | 41284 | jjdelcerro | 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 | 41318 | jjdelcerro | n = mergeWithTranslationsFromMessages(task,n); |
207 | 41284 | jjdelcerro | 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 | 41318 | jjdelcerro | task.setRangeOfValues(0, plugins.size() + subfolders.length + locales.length*2 + 1); |
228 | 41284 | jjdelcerro | |
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 | 41318 | jjdelcerro | } |
355 | 41284 | jjdelcerro | 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 | } |