svn-gvsig-desktop / tags / v1_0_RELEASE / libraries / libInternationalization / src-utils / org / gvsig / i18n / utils / Keys.java @ 9167
History | View | Annotate | Download (13.6 KB)
1 | 6129 | cesar | /**
|
---|---|---|---|
2 | *
|
||
3 | */
|
||
4 | package org.gvsig.i18n.utils; |
||
5 | |||
6 | import java.io.BufferedReader; |
||
7 | import java.io.File; |
||
8 | import java.io.FileInputStream; |
||
9 | import java.io.FileNotFoundException; |
||
10 | 6240 | cesar | import java.io.FileOutputStream; |
11 | 6129 | cesar | import java.io.IOException; |
12 | import java.io.InputStreamReader; |
||
13 | import java.io.UnsupportedEncodingException; |
||
14 | 7039 | cesar | import java.util.ArrayList; |
15 | 6129 | cesar | import java.util.HashMap; |
16 | import java.util.HashSet; |
||
17 | import java.util.Iterator; |
||
18 | import java.util.regex.Matcher; |
||
19 | import java.util.regex.Pattern; |
||
20 | |||
21 | import org.kxml2.io.KXmlParser; |
||
22 | import org.xmlpull.v1.XmlPullParserException; |
||
23 | |||
24 | /**
|
||
25 | * @author cesar
|
||
26 | *
|
||
27 | */
|
||
28 | public class Keys { |
||
29 | private ConfigOptions config;
|
||
30 | |||
31 | public Keys(ConfigOptions config) {
|
||
32 | this.config = config;
|
||
33 | } |
||
34 | |||
35 | public void load() { |
||
36 | Project project; |
||
37 | for (int currentProject=0; currentProject<config.projects.size(); currentProject++) { |
||
38 | project = ((Project)config.projects.get(currentProject)); |
||
39 | /**
|
||
40 | * There is two options, "properties" and "sources". "sources" is the default, so
|
||
41 | * if there was something different to "properties", we assume "sources".
|
||
42 | */
|
||
43 | if (!project.sourceKeys.equals("properties")) { |
||
44 | project.dictionaries = loadProjectFromSources(project); |
||
45 | } |
||
46 | else {
|
||
47 | 6547 | cesar | // load the keys for each language from the property file
|
48 | 6129 | cesar | project.dictionaries = loadProjectFromProperties(project); |
49 | 6547 | cesar | // add missing keys tp each language
|
50 | completeKeys(project); |
||
51 | 6129 | cesar | } |
52 | } |
||
53 | } |
||
54 | |||
55 | 6240 | cesar | public void save() { |
56 | Project project; |
||
57 | 6351 | cesar | OrderedProperties dict; |
58 | 6240 | cesar | FileOutputStream stream=null; |
59 | String lang;
|
||
60 | |||
61 | for (int currentProject=0; currentProject<config.projects.size(); currentProject++) { |
||
62 | project = ((Project)config.projects.get(currentProject)); |
||
63 | |||
64 | for (int currentLang=0; currentLang<config.languages.length; currentLang++) { |
||
65 | lang = (String) config.languages[currentLang];
|
||
66 | 6351 | cesar | dict = (OrderedProperties) project.dictionaries.get(lang); |
67 | 6240 | cesar | |
68 | if (dict.size()>0) { |
||
69 | // ensure the directory exists
|
||
70 | File propertyDir = new File(project.propertyDir); |
||
71 | if (propertyDir.mkdirs())
|
||
72 | System.out.println("Aviso -- directorio creado: "+project.propertyDir); |
||
73 | |||
74 | try {
|
||
75 | // different for spanish...
|
||
76 | if (lang.equals("es")) { |
||
77 | stream = new FileOutputStream(project.propertyDir+File.separator+project.basename+".properties"); |
||
78 | } |
||
79 | else {
|
||
80 | stream = new FileOutputStream(project.propertyDir+File.separator+project.basename+"_"+lang+".properties"); |
||
81 | } |
||
82 | } catch (FileNotFoundException e) { |
||
83 | // TODO Auto-generated catch block
|
||
84 | e.printStackTrace(); |
||
85 | } |
||
86 | |||
87 | try {
|
||
88 | dict.store(stream, "Translations for language ["+lang+"]"); |
||
89 | } catch (IOException e) { |
||
90 | // TODO Auto-generated catch block
|
||
91 | e.printStackTrace(); |
||
92 | } |
||
93 | } |
||
94 | } |
||
95 | } |
||
96 | } |
||
97 | |||
98 | 6129 | cesar | private HashMap loadProjectFromSources(Project project) { |
99 | // always start with an empty HashMap when loading
|
||
100 | HashMap dictionaries = new HashMap(); |
||
101 | String lang;
|
||
102 | |||
103 | /**
|
||
104 | * The keys obtained from the sources and the config.xml files of the
|
||
105 | * plugins.
|
||
106 | */
|
||
107 | HashSet keys = new HashSet(); |
||
108 | /**
|
||
109 | * The translations loaded from the property files of the project.
|
||
110 | */
|
||
111 | |||
112 | 6205 | cesar | dictionaries = loadProjectFromProperties(project); |
113 | 6129 | cesar | |
114 | 7040 | cesar | for (int i=0; i<project.srcDirs.length; i++) { |
115 | try {
|
||
116 | keys = loadKeysFromSources(ConfigOptions.getAbsolutePath(File.separator, project.dir+File.separator+project.srcDirs[i]), keys); |
||
117 | } |
||
118 | catch (IOException ex) { |
||
119 | // It there was an error reading the directory, just warn and skip the dir
|
||
120 | System.err.println(project.dir +" -- Aviso: no se pudo leer el directorio "+project.dir+File.separator+project.srcDirs[i]); |
||
121 | } |
||
122 | } |
||
123 | |||
124 | 6129 | cesar | for (int currentLang=0; currentLang<config.languages.length; currentLang++) { |
125 | lang = config.languages[currentLang]; |
||
126 | 7040 | cesar | |
127 | 6351 | cesar | OrderedProperties currentDict = (OrderedProperties) dictionaries.get(lang); |
128 | 6129 | cesar | Iterator keysIterator = keys.iterator();
|
129 | String key;
|
||
130 | // add missing keys
|
||
131 | while (keysIterator.hasNext()) {
|
||
132 | key = (String) keysIterator.next();
|
||
133 | if (!currentDict.containsKey(key)) {
|
||
134 | currentDict.put(key, "");
|
||
135 | 6240 | cesar | System.out.println(project.dir+" -- Aviso -- clave a?adida: "+key); |
136 | 6129 | cesar | } |
137 | } |
||
138 | 6352 | cesar | |
139 | 6129 | cesar | // remove extra keys
|
140 | 6352 | cesar | // first make a list of keys to remove, because it's not possible to access the iterator and the TreeMap at the same time
|
141 | 7090 | cesar | /* HashSet removedKeys = new HashSet();
|
142 | 6351 | cesar | Iterator dictKey = currentDict.keySet().iterator();
|
143 | while (dictKey.hasNext()) {
|
||
144 | key = (String) dictKey.next();
|
||
145 | 6129 | cesar | if (!keys.contains(key)) {
|
146 | 6352 | cesar | removedKeys.add(key);
|
147 | 6240 | cesar | System.out.println(project.dir+" -- Aviso -- clave eliminada: "+key);
|
148 | 6129 | cesar | }
|
149 | }
|
||
150 | 6352 | cesar | // now we really remove the keys
|
151 | Iterator removedKeysIt = removedKeys.iterator();
|
||
152 | while (removedKeysIt.hasNext()) {
|
||
153 | key = (String) removedKeysIt.next();
|
||
154 | currentDict.remove(key);
|
||
155 | 7090 | cesar | }*/
|
156 | 6129 | cesar | } |
157 | |||
158 | return dictionaries;
|
||
159 | } |
||
160 | |||
161 | 6547 | cesar | /**
|
162 | * Reads the keys from all the languages, to make a unique list containing
|
||
163 | * all the keys.
|
||
164 | */
|
||
165 | public void completeKeys(Project project) { |
||
166 | /* The list of all the keys */
|
||
167 | HashSet keys = new HashSet(); |
||
168 | // always start with an empty HashMap when loading
|
||
169 | //HashMap dictionaries = new HashMap();
|
||
170 | String lang;
|
||
171 | |||
172 | // calculate all the keys
|
||
173 | for (int currentLang=0; currentLang<config.languages.length; currentLang++) { |
||
174 | lang = config.languages[currentLang]; |
||
175 | |||
176 | OrderedProperties currentDict = (OrderedProperties) project.dictionaries.get(lang); |
||
177 | if (currentDict==null) { |
||
178 | currentDict = new OrderedProperties();
|
||
179 | project.dictionaries.put(lang, currentDict); |
||
180 | } |
||
181 | else {
|
||
182 | Iterator keysIterator = currentDict.keySet().iterator();
|
||
183 | String key;
|
||
184 | // add missing keys
|
||
185 | while (keysIterator.hasNext()) {
|
||
186 | key = (String) keysIterator.next();
|
||
187 | keys.add(key); |
||
188 | } |
||
189 | } |
||
190 | } |
||
191 | |||
192 | // add missing keys to each language
|
||
193 | for (int currentLang=0; currentLang<config.languages.length; currentLang++) { |
||
194 | lang = config.languages[currentLang]; |
||
195 | |||
196 | OrderedProperties currentDict = (OrderedProperties) project.dictionaries.get(lang); |
||
197 | Iterator keysIterator = keys.iterator();
|
||
198 | String key;
|
||
199 | // add missing keys
|
||
200 | while (keysIterator.hasNext()) {
|
||
201 | key = (String) keysIterator.next();
|
||
202 | if (!currentDict.containsKey(key)) {
|
||
203 | currentDict.put(key, "");
|
||
204 | System.out.println(project.dir+" -- Aviso -- clave a?adida: "+key); |
||
205 | } |
||
206 | } |
||
207 | } |
||
208 | } |
||
209 | 6129 | cesar | |
210 | 6547 | cesar | |
211 | 6129 | cesar | private HashSet loadKeysFromSources(String directory, HashSet keys) { |
212 | 6232 | cesar | String key;
|
213 | 6129 | cesar | File dir = new File(directory); |
214 | File files[] = dir.listFiles(); |
||
215 | 7039 | cesar | final int BLOCKSIZE = 8192; |
216 | char[] partialBuffer = new char[BLOCKSIZE+1]; |
||
217 | String text;
|
||
218 | StringBuffer buffer;
|
||
219 | |||
220 | // stores the position of the newlines
|
||
221 | //ArrayList newLines = new ArrayList();
|
||
222 | // int lineNumber;
|
||
223 | |||
224 | 6129 | cesar | if (files!=null) { |
225 | 7039 | cesar | //Pattern keyPattern = Pattern.compile("(PluginServices|Messages)\\.(getText|getString|get)\\([^\"\\)]*\"([^\"]*)\"[^\\)]*\\)");
|
226 | Pattern keyPattern = Pattern.compile( |
||
227 | 8765 | jjdelcerro | "(PluginServices|Messages)\\p{Space}*\\.\\p{Space}*(getText|getString|get)\\p{Space}*\\([^\"\\)]*\"([^\"]*)\"[^\\+\\)]*(\\+[^\\)]*)*\\)");
|
228 | 7039 | cesar | Matcher keyMatcher = keyPattern.matcher(""); |
229 | //"(PluginServices|Messages)\\.(getText|getString|get)\\p{Space}*\\([^\"\\)]*\"([^\"]*)\"[^\\+\\)]*(\\+[^\"]*\"([^\"]*)\"[^\\+\\)]*)*\\)");
|
||
230 | //Pattern newLinePattern = Pattern.compile("\n");
|
||
231 | //Matcher newLineMatcher = newLinePattern.matcher("");
|
||
232 | 6129 | cesar | |
233 | for (int i=0; i<files.length; i++) { |
||
234 | if (files[i].isDirectory()) {
|
||
235 | 7039 | cesar | keys = loadKeysFromSources(files[i].toString(), keys); |
236 | continue;
|
||
237 | 6129 | cesar | } |
238 | 7039 | cesar | else if (files[i].getName().toLowerCase().equals("PluginServices.java")) { |
239 | |||
240 | 6129 | cesar | //[Messages.]getText(...)
|
241 | 6235 | cesar | Pattern PsPattern = Pattern.compile("(Messages\\.)*getText\\([^\"\\)]*\"([^\"]*)\"[^\\)]*\\)"); |
242 | 6129 | cesar | Matcher PsMatcher = PsPattern.matcher(""); |
243 | |||
244 | FileInputStream fis=null; |
||
245 | try {
|
||
246 | fis = new FileInputStream(files[i]); |
||
247 | |||
248 | 7039 | cesar | buffer = new StringBuffer(); |
249 | 6129 | cesar | BufferedReader currentFile=null; |
250 | 7039 | cesar | |
251 | currentFile = new BufferedReader(new InputStreamReader(fis, config.sourcesEncoding)); |
||
252 | while (currentFile.read(partialBuffer, 0, BLOCKSIZE)!=-1) { |
||
253 | buffer.append(partialBuffer); |
||
254 | 6129 | cesar | } |
255 | 7039 | cesar | text = buffer.toString(); |
256 | 6129 | cesar | |
257 | 7039 | cesar | |
258 | PsMatcher.reset(text); |
||
259 | |||
260 | while (PsMatcher.find()) {
|
||
261 | key = PsMatcher.group(2);
|
||
262 | if (!key.equals("")) |
||
263 | keys.add(key); |
||
264 | 6129 | cesar | } |
265 | 7039 | cesar | currentFile.close(); |
266 | } catch (UnsupportedEncodingException e1) { |
||
267 | System.err.println(e1.getLocalizedMessage());
|
||
268 | continue;
|
||
269 | 6129 | cesar | } |
270 | 7039 | cesar | catch (IOException e1) { |
271 | System.err.println(e1.getLocalizedMessage());
|
||
272 | continue;
|
||
273 | } |
||
274 | 6129 | cesar | } |
275 | else if (files[i].getName().toLowerCase().endsWith(".java")) { |
||
276 | FileInputStream fis=null; |
||
277 | try {
|
||
278 | fis = new FileInputStream(files[i]); |
||
279 | 7039 | cesar | BufferedReader currentFile=null; |
280 | 6129 | cesar | |
281 | 7039 | cesar | currentFile = new BufferedReader(new InputStreamReader(fis, config.sourcesEncoding)); |
282 | buffer = new StringBuffer(); |
||
283 | |||
284 | int readChars; // number of characters which were read |
||
285 | while ( (readChars = currentFile.read(partialBuffer, 0, BLOCKSIZE)) != -1) { |
||
286 | buffer.append(partialBuffer, 0, readChars);
|
||
287 | 6129 | cesar | } |
288 | 7039 | cesar | text = buffer.toString(); |
289 | 6129 | cesar | |
290 | 7039 | cesar | /*newLineMatcher.reset(text);
|
291 | while (newLineMatcher.find()) {
|
||
292 | newLines.add(new Integer(newLineMatcher.end()-1));
|
||
293 | }*/
|
||
294 | // lineNumber=1;
|
||
295 | |||
296 | keyMatcher.reset(text); |
||
297 | |||
298 | while (keyMatcher.find()) {
|
||
299 | |||
300 | // find out in which line number we are
|
||
301 | /*while (keyMatcher.start() > ((Integer)newLines.get(lineNumber)).intValue() ) lineNumber++;
|
||
302 | System.out.println("FileName: "+files[i].getCanonicalPath()+"; lineNumber: "+lineNumber);*/
|
||
303 | |||
304 | StringBuffer keyBuffer = new StringBuffer(); |
||
305 | |||
306 | // for (int ii=0; ii<=keyMatcher.groupCount(); ii++) {
|
||
307 | // System.out.println("group: "+ ii+ "; " + keyMatcher.group(ii));
|
||
308 | // }
|
||
309 | // for (int groupNumb=3; groupNumb<=keyMatcher.groupCount(); groupNumb+=2) {
|
||
310 | // if (keyMatcher.group(groupNumb)!=null)
|
||
311 | // keyBuffer.append(keyMatcher.group(groupNumb));
|
||
312 | // }
|
||
313 | |||
314 | if (keyMatcher.group(4)!=null) { |
||
315 | System.err.println("\nError: clave repartida en varias l?neas"); |
||
316 | System.err.println("Fichero: "+files[i].getCanonicalPath()); |
||
317 | System.err.println("C?digo: "); |
||
318 | System.err.println(keyMatcher.group());
|
||
319 | 6129 | cesar | } |
320 | 7039 | cesar | else {
|
321 | key = keyMatcher.group(3);
|
||
322 | if (!key.equals("")) |
||
323 | keys.add(key); |
||
324 | } |
||
325 | 6129 | cesar | } |
326 | 7039 | cesar | currentFile.close(); |
327 | } catch (UnsupportedEncodingException e1) { |
||
328 | System.err.println(e1.getLocalizedMessage());
|
||
329 | continue;
|
||
330 | 6129 | cesar | } |
331 | 7039 | cesar | catch (IOException e1) { |
332 | System.err.println(e1.getLocalizedMessage());
|
||
333 | continue;
|
||
334 | } |
||
335 | 6129 | cesar | } |
336 | else if (files[i].getName().equalsIgnoreCase("config.xml")) { |
||
337 | keys = loadKeysFromXml(files[i], keys); |
||
338 | } |
||
339 | } |
||
340 | } |
||
341 | |||
342 | return keys;
|
||
343 | } |
||
344 | |||
345 | |||
346 | private HashSet loadKeysFromXml(File fileName, HashSet keys) { |
||
347 | KXmlParser parser = new KXmlParser();
|
||
348 | String tagname, attribute;
|
||
349 | |||
350 | // we use null encoding, in this way kxml2 tries to detect the encoding
|
||
351 | try {
|
||
352 | parser.setInput(new FileInputStream(fileName), null); |
||
353 | } catch (FileNotFoundException e1) { |
||
354 | System.err.println(e1.getLocalizedMessage());
|
||
355 | return keys;
|
||
356 | } catch (XmlPullParserException e1) {
|
||
357 | // No podemos leer el fichero de configuraci?n. Usamos valores por defecto
|
||
358 | System.err.println("Aviso: error al cargar el fichero "+fileName); |
||
359 | return keys;
|
||
360 | } |
||
361 | |||
362 | try {
|
||
363 | for (parser.next(); parser.getEventType()!=KXmlParser.END_DOCUMENT; parser.next()) {
|
||
364 | // este bucle externo recorre las etiquetas de primer y segundo nivel
|
||
365 | if (parser.getEventType()==KXmlParser.START_TAG) {
|
||
366 | tagname = parser.getName(); |
||
367 | if (tagname.equals("menu") || tagname.equals("action-tool") || tagname.equals("selectable-tool") || tagname.equals("entry")) { |
||
368 | attribute = parser.getAttributeValue(null, "text"); |
||
369 | if (attribute!=null) { |
||
370 | String menuParts[] = attribute.split("/"); |
||
371 | for (int i=0; i<menuParts.length; i++) { |
||
372 | 6232 | cesar | if (!menuParts[i].equals("")) |
373 | keys.add(menuParts[i]); |
||
374 | 6129 | cesar | } |
375 | } |
||
376 | |||
377 | attribute = parser.getAttributeValue(null, "tooltip"); |
||
378 | 6232 | cesar | if (attribute!=null && !attribute.equals("")) { |
379 | 6129 | cesar | keys.add(attribute); |
380 | } |
||
381 | |||
382 | |||
383 | } |
||
384 | 6984 | cesar | else if (tagname.equals("combo-scale")) { |
385 | attribute = parser.getAttributeValue(null, "label"); |
||
386 | if (attribute!=null && !attribute.equals("")) { |
||
387 | 6129 | cesar | keys.add(attribute); |
388 | } |
||
389 | 6984 | cesar | } |
390 | |||
391 | 6129 | cesar | } |
392 | } |
||
393 | } catch (XmlPullParserException e1) {
|
||
394 | e1.getLocalizedMessage(); |
||
395 | } catch (IOException e1) { |
||
396 | e1.getLocalizedMessage(); |
||
397 | } |
||
398 | return keys;
|
||
399 | } |
||
400 | |||
401 | private HashMap loadProjectFromProperties(Project project) { |
||
402 | // always start with an empty HashMap when loading
|
||
403 | HashMap dictionaries = new HashMap(); |
||
404 | String lang;
|
||
405 | 6351 | cesar | OrderedProperties dictionary; |
406 | 6129 | cesar | |
407 | FileInputStream stream=null; |
||
408 | |||
409 | for (int currentLang=0; currentLang<config.languages.length; currentLang++) { |
||
410 | lang = config.languages[currentLang]; |
||
411 | 6351 | cesar | dictionary = new OrderedProperties();
|
412 | 6129 | cesar | try {
|
413 | // different for spanish...
|
||
414 | if (lang.equals("es")) { |
||
415 | stream = new FileInputStream(project.propertyDir+File.separator+project.basename+".properties"); |
||
416 | } |
||
417 | else {
|
||
418 | stream = new FileInputStream(project.propertyDir+File.separator+project.basename+"_"+lang+".properties"); |
||
419 | } |
||
420 | try {
|
||
421 | dictionary.load(stream); |
||
422 | } catch (IOException e) { |
||
423 | System.err.println("Error cargando la base de datos para el idioma: ["+lang+"]. "+e.getLocalizedMessage()); |
||
424 | } |
||
425 | } catch (FileNotFoundException e) { |
||
426 | 6205 | cesar | System.err.println(project.dir + " -- Error cargando la base de datos para el idioma: ["+lang+"]. "+e.getLocalizedMessage()); |
427 | 6129 | cesar | } |
428 | dictionaries.put(lang, dictionary); |
||
429 | } |
||
430 | return dictionaries;
|
||
431 | } |
||
432 | } |