Revision 38344

View differences:

tags/v2_0_0_Build_2047/libraries/libInternationalization/libInternationalization/config/text_en.properties
1
#Translations for language [en]
2
#Wed Nov 08 12:31:46 CET 2006
3
=\=\=\=\=\=\=
4
<<<<<<<=text_en.properties
5
>>>>>>>=1.6
6
aceptar=Accept
7
Las_traducciones_no_pudieron_ser_cargadas=Translations couldn't be loaded
8
No.hay.lista.de.idiomas.preferidos.quiza.olvido.inicializar.clase=There is no list of favorite languages probably you forgot initialice the class
9
No_hay_lista_de_idiomas_preferidos_quiza_olvido_inicializar_clase=There is not preferred languages list. Maybe the Messages class was not initiated
10
No_se_encontro_la_traduccion_para=Cannot find translation for
0 11

  
tags/v2_0_0_Build_2047/libraries/libInternationalization/libInternationalization/config/text_gl.properties
1
#Translations for language [gl]
2
#Mon Oct 30 09:38:21 CET 2006
3
aceptar=Aceptar
4
Las_traducciones_no_pudieron_ser_cargadas=As traducci\u00f3ns non se puideron cargar
5
No.hay.lista.de.idiomas.preferidos.quiza.olvido.inicializar.clase=
6
No_hay_lista_de_idiomas_preferidos_quiza_olvido_inicializar_clase=Non se atopou a lista de idiomas preferidos.Quiz\u00e1s non se lembrou de inicializar a clase
7
No_se_encontro_la_traduccion_para=Non se atopou a traducci\u00f3n para
0 8

  
tags/v2_0_0_Build_2047/libraries/libInternationalization/libInternationalization/config/text_ca.properties
1
#Translations for language [ca]
2
#Mon Oct 30 09:38:21 CET 2006
3
aceptar=Acceptar
4
Las_traducciones_no_pudieron_ser_cargadas=Les traduccions no s'han pogut carregar
5
No.hay.lista.de.idiomas.preferidos.quiza.olvido.inicializar.clase=
6
No_hay_lista_de_idiomas_preferidos_quiza_olvido_inicializar_clase=No s'ha trobat la llista d'idiomes preferits. Potser ha oblidat inicialitzar la classe
7
No_se_encontro_la_traduccion_para=No s'ha trobat la traducci\u00f3 per a
0 8

  
tags/v2_0_0_Build_2047/libraries/libInternationalization/libInternationalization/config/text_pt.properties
1
#Translations for language [pt]
2
#Mon Oct 30 09:38:21 CET 2006
3
aceptar=Aceitar
4
Las_traducciones_no_pudieron_ser_cargadas=
5
No.hay.lista.de.idiomas.preferidos.quiza.olvido.inicializar.clase=
6
No_hay_lista_de_idiomas_preferidos_quiza_olvido_inicializar_clase=
7
No_se_encontro_la_traduccion_para=N\u00e3o se encontrou a tradu\u00e7\u00e3o de
0 8

  
tags/v2_0_0_Build_2047/libraries/libInternationalization/libInternationalization/config/text_cs.properties
1
#Translations for language [cs]
2
#Mon Oct 30 09:38:21 CET 2006
3
aceptar=Budi\u017e
4
Las_traducciones_no_pudieron_ser_cargadas=
5
No.hay.lista.de.idiomas.preferidos.quiza.olvido.inicializar.clase=
6
No_hay_lista_de_idiomas_preferidos_quiza_olvido_inicializar_clase=
7
No_se_encontro_la_traduccion_para=Nelze nal\u00e9zt p\u0159eklad pro
0 8

  
tags/v2_0_0_Build_2047/libraries/libInternationalization/libInternationalization/config/text_fr.properties
1
#Translations for language [fr]
2
#Mon Oct 30 09:38:21 CET 2006
3
aceptar=Accepter
4
Las_traducciones_no_pudieron_ser_cargadas=Les traductions ne peuvent pas \u00eatre charg\u00e9es.
5
No.hay.lista.de.idiomas.preferidos.quiza.olvido.inicializar.clase=
6
No_hay_lista_de_idiomas_preferidos_quiza_olvido_inicializar_clase=Impossible de trouver la liste des langues pr\u00e9f\u00e9r\u00e9es. Vous avez peut-\u00eatre oubli\u00e9 d'installer la classe.
7
No_se_encontro_la_traduccion_para=Impossible de trouver les traductions pour
0 8

  
tags/v2_0_0_Build_2047/libraries/libInternationalization/libInternationalization/config/text_de.properties
1
#Translations for language [de]
2
#Mon Oct 30 09:38:21 CET 2006
3
aceptar=OK
4
Las_traducciones_no_pudieron_ser_cargadas=
5
No.hay.lista.de.idiomas.preferidos.quiza.olvido.inicializar.clase=
6
No_hay_lista_de_idiomas_preferidos_quiza_olvido_inicializar_clase=
7
No_se_encontro_la_traduccion_para=Konnte \u00dcbersetzung nicht finden f\u00fcr\:
0 8

  
tags/v2_0_0_Build_2047/libraries/libInternationalization/libInternationalization/config/text_eu.properties
1
#Translations for language [eu]
2
#Mon Oct 30 09:38:21 CET 2006
3
aceptar=Ados
4
Las_traducciones_no_pudieron_ser_cargadas=Itzulpenak ezin izan dira kargatu
5
No.hay.lista.de.idiomas.preferidos.quiza.olvido.inicializar.clase=
6
No_hay_lista_de_idiomas_preferidos_quiza_olvido_inicializar_clase=\=Ez da hobetsitako hizkuntzen zerrenda aurkitu. Agian klasea hasieratzea ahaztu zaizu
7
No_se_encontro_la_traduccion_para=Ez da itzulpenik aurkitu honetarako\:
0 8

  
tags/v2_0_0_Build_2047/libraries/libInternationalization/libInternationalization/config/text_it.properties
1
#Translations for language [it]
2
#Tue Nov 07 12:30:01 CET 2006
3
aceptar=Accetta
4
Las_traducciones_no_pudieron_ser_cargadas=
5
No.hay.lista.de.idiomas.preferidos.quiza.olvido.inicializar.clase=
6
No_hay_lista_de_idiomas_preferidos_quiza_olvido_inicializar_clase=
7
No_se_encontro_la_traduccion_para=Non si \u00e9 incontrata la traduzione per
0 8

  
tags/v2_0_0_Build_2047/libraries/libInternationalization/libInternationalization/config/text.properties
1
#Translations for language [es]
2
#Mon Oct 30 09:38:21 CET 2006
3
aceptar=Aceptar
4
Las_traducciones_no_pudieron_ser_cargadas=Las traducciones no pudieron ser cargadas
5
No.hay.lista.de.idiomas.preferidos.quiza.olvido.inicializar.clase=No hay lista de idiomas preferidos. Quiza olvido inicializar la clase
6
No_hay_lista_de_idiomas_preferidos_quiza_olvido_inicializar_clase=No hay lista de idiomas preferidos. Quiz\u00e1 olvid\u00f3 inicializar la clase.
7
No_se_encontro_la_traduccion_para=No se encontr\u00f3 la traducci\u00f3n para
0 8

  
tags/v2_0_0_Build_2047/libraries/libInternationalization/libInternationalization/src-utils/org/gvsig/i18n/utils/ConfigOptions.java
1
package org.gvsig.i18n.utils;
2

  
3
import java.io.File;
4
import java.io.FileInputStream;
5
import java.io.FileNotFoundException;
6
import java.io.IOException;
7
import java.util.ArrayList;
8

  
9
import org.kxml2.io.KXmlParser;
10
import org.xmlpull.v1.XmlPullParserException;
11

  
12
public class ConfigOptions {
13
	// Default values
14
	public String defaultBaseName = "text";
15
	public String defaultBaseDir = ".";
16
	public String databaseDir = "database";
17
	private String configFileName = "config.xml";
18
	public String[] languages;
19
	public ArrayList projects = new ArrayList();
20
	private String defaultLangList="ca;cs;de;en;es;eu;fr;gl;it;pt";
21
	public String sourceKeys = "sources";
22
	private String defaultPropertyDir = "config";
23
	public String[] outputLanguages={"en", "es"};
24
	public String outputDir="output";
25
	public String inputDir="input";
26
	public String[] defaultSrcDirs={"src"};
27
	
28
	
29
	/**
30
	 * The character encoding of the Java source files, used to search keys in the sources.
31
	 */
32
	public String sourcesEncoding = "ISO8859_1";
33
	/**
34
	 * The character encoding of the generated output files for missing keys.
35
	 */
36
	public String outputEncoding = "UTF8";
37
	
38
	/**
39
	 * Creates a new ConfigOptions object.
40
	 */
41
	public ConfigOptions() {
42
		// Now we transform all directories to absolute canonical paths, so
43
		// that the are easier to manage afterwards.
44
		// It's also done at the end of parseVars method, but we must also do
45
		// it here, because parseVars() might not get executed.
46
		try {
47
			this.defaultBaseDir = getAbsolutePath(".", this.defaultBaseDir);
48
			this.databaseDir = getAbsolutePath(this.defaultBaseDir, this.databaseDir);
49
			this.outputDir = getAbsolutePath(this.defaultBaseDir, this.outputDir);
50
			this.inputDir = getAbsolutePath(this.defaultBaseDir, this.inputDir);
51
			
52
			/*
53
			 * 
54
			 File baseDirFile = new File(this.defaultBaseDir);
55
			this.defaultBaseDir = baseDirFile.getCanonicalPath();
56
			File databaseDirFile = new File(this.databaseDir);
57
			if (databaseDirFile.isAbsolute()) {
58
				this.databaseDir = databaseDirFile.getCanonicalPath();
59
			}
60
			else {
61
				this.databaseDir = (new File(this.defaultBaseDir+File.separator+this.databaseDir)).getCanonicalPath();
62
			}
63
			File outputDirFile = new File(this.outputDir);
64
			if (outputDirFile.isAbsolute()) {
65
				this.outputDir = outputDirFile.getCanonicalPath();
66
			}
67
			else {
68
				this.outputDir = (new File(this.defaultBaseDir+File.separator+this.outputDir)).getCanonicalPath();
69
			}
70
			File inputDirFile = new File(this.inputDir);
71
			if (inputDirFile.isAbsolute()) {
72
				this.inputDir = inputDirFile.getCanonicalPath();
73
			}
74
			else {
75
				this.inputDir = (new File(this.defaultBaseDir+File.separator+this.inputDir)).getCanonicalPath();
76
			}
77
			*/
78
		} catch (IOException e) {
79
			System.err.println("Error accediendo a los directorios de las traducciones: "+e.getLocalizedMessage());
80
		}
81
	}
82
	
83
	/**
84
	 *  Creates a new ConfigOptions object, defining the config file to use.
85
	 *  
86
	 * @param configFileName The file name of the config file to use.
87
	 */
88
	public ConfigOptions(String configFileName) {
89
		this.configFileName = configFileName;
90
		
91
		// Now we transform all directories to absolute canonical paths, so
92
		// that the are easier to manage afterwards.
93
		// It's also done at the end of parseVars method, but we must also do
94
		// it here, because parseVars() might not get executed.
95
		try {
96
			this.defaultBaseDir = getAbsolutePath(".", this.defaultBaseDir);
97
			this.databaseDir = getAbsolutePath(this.defaultBaseDir, this.databaseDir);
98
			this.outputDir = getAbsolutePath(this.defaultBaseDir, this.outputDir);
99
			this.inputDir = getAbsolutePath(this.defaultBaseDir, this.inputDir);
100
			
101
			/*File baseDirFile = new File(this.defaultBaseDir);
102
			this.defaultBaseDir = baseDirFile.getCanonicalPath();
103
			File databaseDirFile = new File(this.databaseDir);
104
			if (databaseDirFile.isAbsolute()) {
105
				this.databaseDir = databaseDirFile.getCanonicalPath();
106
			}
107
			else {
108
				this.databaseDir = (new File(this.defaultBaseDir+File.separator+this.databaseDir)).getCanonicalPath();
109
			}
110
			File outputDirFile = new File(this.outputDir);
111
			if (outputDirFile.isAbsolute()) {
112
				this.outputDir = outputDirFile.getCanonicalPath();
113
			}
114
			else {
115
				this.outputDir = (new File(this.defaultBaseDir+File.separator+this.outputDir)).getCanonicalPath();
116
			}
117
			File inputDirFile = new File(this.inputDir);
118
			if (inputDirFile.isAbsolute()) {
119
				this.inputDir = inputDirFile.getCanonicalPath();
120
			}
121
			else {
122
				this.inputDir = (new File(this.defaultBaseDir+File.separator+this.inputDir)).getCanonicalPath();
123
			}*/
124
		} catch (IOException e) {
125
			System.err.println("Error accediendo a los directorios de las traducciones: "+e.getLocalizedMessage());
126
		}
127
	}
128
	
129
	/**
130
	 * Sets the name of the config file to use.
131
	 * 
132
	 * @param configFileName
133
	 */
134
	public void setConfigFile(String configFileName) {
135
		this.configFileName = configFileName;
136
	}
137
	
138
	/**
139
	 * Gets the name of the config file in use.
140
	 * 
141
	 * @return The name of the config file in use.
142
	 */
143
	public String getConfigFile() {
144
		return configFileName;
145
	}
146
	
147
	/**
148
	 *  Loads the config parameters and the projects to consider from the XML
149
	 * config file */
150
	public boolean load() {
151
		KXmlParser parser = new KXmlParser();
152
		
153
		// we use null encoding, in this way kxml2 tries to detect the encoding
154
		try {
155
			parser.setInput(new FileInputStream(configFileName), null);
156
		} catch (FileNotFoundException e1) {
157
			System.err.println(e1.getLocalizedMessage());
158
			return false;
159
		} catch (XmlPullParserException e1) {
160
			// No podemos leer el fichero de configuraci?n. Usamos valores por defecto
161
			System.err.println("Aviso: no se pudo leer correctamente el fichero de configuraci?n. Se usar?n los valores por defecto.");
162
			return false;
163
		}
164
		
165
		try {
166
			for (parser.next(); parser.getEventType()!=KXmlParser.END_DOCUMENT; parser.next()) {
167
				// este bucle externo recorre las etiquetas de primer y segundo nivel
168
				if (parser.getEventType()==KXmlParser.START_TAG) {
169
					if (parser.getName().equals("config")) {
170
						parseVars(parser);
171
					}
172
					else if (parser.getName().equals("projects")) {
173
						parseProjects(parser);
174
					}
175
				}
176
			}	
177
		} catch (XmlPullParserException e1) {
178
			e1.getLocalizedMessage();
179
		} catch (IOException e1) {
180
			e1.getLocalizedMessage();
181
		}
182
		
183
		File outputDirFile = new File(outputDir);
184
		outputDirFile.mkdirs();
185
		File databaseDirFile = new File(databaseDir);
186
		databaseDirFile.mkdirs();
187
		return true;
188
	}
189

  
190
	private void parseVars(KXmlParser parser) throws XmlPullParserException, IOException {
191
		// recorremos todas las etiquetas 'variable' dentro de config
192
		int state;
193
		String name, value;
194
		
195
		for (state = parser.next(); state!=KXmlParser.END_TAG || !parser.getName().equals("config") ; state=parser.next()) {
196
			if (state==KXmlParser.START_TAG) {
197
				if (parser.getName().equals("variable")) {
198
					name = parser.getAttributeValue(null, "name");
199
					value = parser.getAttributeValue(null, "value");
200
					if (name!=null && value!=null) {
201
						value = parser.getAttributeValue(null, "value");
202
						if (parser.getAttributeValue(null, "name").equals("basename")) {
203
							defaultBaseName = parser.getAttributeValue(null, "value");
204
						}
205
						else if (parser.getAttributeValue(null, "name").equals("basedir")) {
206
							defaultBaseDir = parser.getAttributeValue(null, "value");
207
						}
208
						else if (parser.getAttributeValue(null, "name").equals("databaseDir")) {
209
							databaseDir = parser.getAttributeValue(null, "value");
210
						}
211
						else if (parser.getAttributeValue(null, "name").equals("defaultPropertyDir")) {
212
							defaultPropertyDir = parser.getAttributeValue(null, "value");
213
						}
214
						else if (parser.getAttributeValue(null, "name").equals("outputDir")) {
215
							outputDir = parser.getAttributeValue(null, "value");
216
						}
217
						else if (parser.getAttributeValue(null, "name").equals("inputDir")) {
218
							inputDir = parser.getAttributeValue(null, "value");
219
						}
220
						else if (parser.getAttributeValue(null, "name").equals("sourceKeys")) {
221
							sourceKeys = parser.getAttributeValue(null, "value");
222
						}
223
						else if (parser.getAttributeValue(null, "name").equals("srcDirs")) {
224
							String srcDirs = parser.getAttributeValue(null, "value");
225
							this.defaultSrcDirs = srcDirs.split(";");
226
						}
227
						else if (parser.getAttributeValue(null, "name").equals("languages")) {
228
							languages = parser.getAttributeValue(null, "value").split(";");
229
							if (languages.length==0) {
230
								System.err.println("Aviso: No se definieron idiomas a considerar. Se usar? la lista de idiomas\n por defecto: "+defaultLangList);
231
								languages = defaultLangList.split(";");
232
							}
233
						}
234
					}
235
					else {
236
						if (name==null)
237
							System.err.println("Error leyendo el fichero de configuraci?n. No se encontr? el atributo 'name'\nrequerido en la etiqueta <variable>. La etiqueta ser? ignorada.");
238
						if (value==null)
239
							System.err.println("Error leyendo el fichero de configuraci?n. No se encontr? el atributo 'value'\nrequerido en la etiqueta <variable>. La etiqueta ser? ignorada.");
240
					}
241
				}
242
				else {
243
					System.err.println("Aviso: se ignor? una etiqueta desconocida o inesperada: " + parser.getName());
244
				}
245
			}
246
		}
247
		
248
		// Now we transform all directories to absolute canonical paths, so
249
		// that they are easier to manage afterwards.
250
		try {
251
			this.defaultBaseDir = getAbsolutePath(".", this.defaultBaseDir);
252
			this.databaseDir = getAbsolutePath(this.defaultBaseDir, this.databaseDir);
253
			this.outputDir = getAbsolutePath(this.defaultBaseDir, this.outputDir);
254
			this.inputDir = getAbsolutePath(this.defaultBaseDir, this.inputDir);
255
			/**
256
			File baseDirFile = new File(this.defaultBaseDir);
257
			this.defaultBaseDir = baseDirFile.getCanonicalPath();
258
			System.out.println(this.defaultBaseDir);
259
			File databaseDirFile = new File(this.databaseDir);
260
			if (databaseDirFile.isAbsolute()) {
261
				this.databaseDir = databaseDirFile.getCanonicalPath();
262
			}
263
			else {
264
				this.databaseDir = (new File(this.defaultBaseDir+File.separator+this.databaseDir)).getCanonicalPath();
265
			}
266
			File outputDirFile = new File(this.outputDir);
267
			if (outputDirFile.isAbsolute()) {
268
				this.outputDir = outputDirFile.getCanonicalPath();
269
			}
270
			else {
271
				this.outputDir = (new File(this.defaultBaseDir+File.separator+this.outputDir)).getCanonicalPath();
272
			}
273
			File inputDirFile = new File(this.inputDir);
274
			if (inputDirFile.isAbsolute()) {
275
				this.inputDir = inputDirFile.getCanonicalPath();
276
			}
277
			else {
278
				this.inputDir = (new File(this.defaultBaseDir+File.separator+this.inputDir)).getCanonicalPath();
279
			}
280
			*/
281
		} catch (IOException e) {
282
			System.err.println("Error accediendo a los directorios de las traducciones: "+e.getLocalizedMessage());
283
		}
284
	}
285
	
286
	/**
287
	 * Parse the lines containing <project /> tags (between <projects> and </projects>).
288
	 * 
289
	 * @param parser The KXmlParser, pointing to the next <project /> tag (if any)
290
	 * @throws XmlPullParserException
291
	 * @throws IOException
292
	 */
293
	private void parseProjects(KXmlParser parser) throws XmlPullParserException, IOException {
294
		// recorremos todos los proyectos dentro de 'projects'
295
		int state;
296
		String dir;
297
		File dirFile;
298
		Project project;
299
		
300
		for (state = parser.next(); state!=KXmlParser.END_TAG || !parser.getName().equals("projects") ; state=parser.next()) {
301
			if (state==KXmlParser.START_TAG) {
302
				if (parser.getName().equals("project")) {
303
					if (parser.getAttributeValue(null, "dir")!=null) {
304
						dir = parser.getAttributeValue(null,  "dir");
305
						if (dir!=null) {
306
							// we transform it to absolute canonical paths, so
307
							// that it is easier to manage afterwards.
308
							dirFile = new File(dir);
309
							try {
310
								if (dirFile.isAbsolute()) {
311
									dir = dirFile.getCanonicalPath();
312
								}
313
								else {
314
									dir = new File(this.defaultBaseDir+File.separator+dir).getCanonicalPath();
315
								}
316
							} catch (IOException e) {
317
								System.err.println("Error accediendo a los directorios de las traducciones: "+e.getLocalizedMessage());
318
							}
319
							project = new Project();
320
							project.dir = dir;
321
							project.basename = parser.getAttributeValue(null, "basename");
322
							if (project.basename==null)
323
								project.basename = this.defaultBaseName;
324
							
325
							project.propertyDir = parser.getAttributeValue(null, "propertyDir");
326
							if (project.propertyDir==null) {
327
								project.propertyDir = this.defaultPropertyDir;
328
							}
329
							// we transform it to absolute canonical paths, so
330
							// that it is easier to manage afterwards.
331
							File propDirFile = new File(project.propertyDir);
332
							try {
333
								if (propDirFile.isAbsolute()) {
334
									project.propertyDir = propDirFile.getCanonicalPath();
335
								}
336
								else {
337
									project.propertyDir = new File(dir+File.separator+project.propertyDir).getCanonicalPath();
338
								}
339
							} catch (IOException e) {
340
								System.err.println("Error accediendo a los directorios de las traducciones: "+e.getLocalizedMessage());
341
							}
342

  
343
							String srcDirs = parser.getAttributeValue(null, "srcDirs");
344
							if (srcDirs!=null) {
345
								project.srcDirs = srcDirs.split(";");
346
							}
347
							else {
348
								project.srcDirs = this.defaultSrcDirs;
349
							}
350

  
351
							project.sourceKeys = parser.getAttributeValue(null, "sourceKeys");
352
							if (project.sourceKeys==null)
353
								project.sourceKeys = this.sourceKeys;
354
							projects.add(project);
355
						}
356
						else
357
							System.err.println("Error leyendo el fichero de configuraci?n. No se encontr? el atributo 'dir'\nrequerido en la etiqueta <project>. La etiqueta ser? ignorada.");
358
					}
359
				}
360
				else {
361
					System.err.println("Aviso: se ignorar? una etiqueta desconocida o inesperada: " + parser.getName());
362
				}
363
			}
364
		}
365

  
366
	}
367
	
368
	public void setLanguages(String[] languages) {
369
		this.languages = languages; 
370
	}
371
	
372
	public void setProjects(ArrayList projectList) {
373
		this.projects = projectList;
374
	}
375
	
376
	/**
377
	 * Calculates the canonical path for the given path.
378
	 * If the given path is relative, it is calculated from
379
	 * the given baseDir.
380
	 * The 'path' parameter uses the '/' character to as path
381
	 * separator. The returned value uses the default system
382
	 * separator as path separator.  
383
	 * 
384
	 * @param baseDir
385
	 * @param path
386
	 * @return
387
	 * @throws IOException 
388
	 */
389
	public static String getAbsolutePath(String baseDir, String path) throws IOException {
390
		if ('/'!=File.separatorChar)
391
			path = path.replace('/', File.separatorChar);
392
		File pathFile = new File(path);
393
		if (pathFile.isAbsolute())
394
			path = pathFile.getCanonicalPath();
395
		else {
396
			File newFile = new File(baseDir+File.separator+path);
397
			path = newFile.getAbsolutePath();
398
		}
399
		return path;
400
	}
401
}
0 402

  
tags/v2_0_0_Build_2047/libraries/libInternationalization/libInternationalization/src-utils/org/gvsig/i18n/utils/OrderedProperties.java
1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 * 
3
 * This class is based on GNU Classpath's Properties.java
4
 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
5
 * Copyright (C) 2006 IVER T.I. and Generalitat Valenciana.
6
 *
7
 * This program is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU General Public License
9
 * as published by the Free Software Foundation; either version 2
10
 * of the License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
20
 *
21
 * For more information, contact:
22
 *
23
 *  Generalitat Valenciana
24
 *   Conselleria d'Infraestructures i Transport
25
 *   Av. Blasco Ib??ez, 50
26
 *   46010 VALENCIA
27
 *   SPAIN
28
 *
29
 *      +34 963862235
30
 *   gvsig@gva.es
31
 *      www.gvsig.gva.es
32
 *
33
 *    or
34
 *
35
 *   IVER T.I. S.A
36
 *   Salamanca 50
37
 *   46005 Valencia
38
 *   Spain
39
 *
40
 *   +34 963163400
41
 *   dac@iver.es
42
 */
43

  
44

  
45
package org.gvsig.i18n.utils;
46

  
47
import java.io.BufferedReader;
48
import java.io.IOException;
49
import java.io.InputStream;
50
import java.io.InputStreamReader;
51
import java.io.OutputStream;
52
import java.io.OutputStreamWriter;
53
import java.io.PrintStream;
54
import java.io.PrintWriter;
55
import java.util.Calendar;
56
import java.util.Collections;
57
import java.util.Comparator;
58
import java.util.Enumeration;
59
import java.util.HashSet;
60
import java.util.Iterator;
61
import java.util.PropertyResourceBundle;
62
import java.util.Set;
63
import java.util.TreeMap;
64
import java.util.Map.Entry;
65

  
66
/**
67
* A set of persistent properties, which can be saved or loaded from a stream.
68
* A property list may also contain defaults, searched if the main list
69
* does not contain a property for a given key.
70
*
71
* An example of a properties file for the german language is given
72
* here.  This extends the example given in ListResourceBundle.
73
* Create a file MyResource_de.properties with the following contents
74
* and put it in the CLASSPATH.  (The character
75
* <code>\</code><code>u00e4</code> is the german umlaut)
76
*
77
* 
78
<pre>s1=3
79
s2=MeineDisk
80
s3=3. M\<code></code>u00e4rz 96
81
s4=Die Diskette ''{1}'' enth\<code></code>u00e4lt {0} in {2}.
82
s5=0
83
s6=keine Dateien
84
s7=1
85
s8=eine Datei
86
s9=2
87
s10={0,number} Dateien
88
s11=Das Formatieren schlug fehl mit folgender Exception: {0}
89
s12=FEHLER
90
s13=Ergebnis
91
s14=Dialog
92
s15=Auswahlkriterium
93
s16=1,3</pre>
94
*
95
* <p>Although this is a sub class of a hash table, you should never
96
* insert anything other than strings to this property, or several
97
* methods, that need string keys and values, will fail.  To ensure
98
* this, you should use the <code>get/setProperty</code> method instead
99
* of <code>get/put</code>.
100
*
101
* Properties are saved in the specified encoding. If no encoding is
102
* specified, then the ISO 8859-1 encoding is used, with Unicode escapes with
103
* a single <code>u</code> for any character which cannot be represented.
104
*
105
* @author Jochen Hoenicke
106
* @author Eric Blake (ebb9@email.byu.edu)
107
* @author Cesar Martinez Izquierdo (cesar.martinez@iver.es)
108
* @see PropertyResourceBundle
109
* @status updated to 1.4
110
*/
111
public class OrderedProperties extends TreeMap
112
{
113
	
114
/**
115
* The property list that contains default values for any keys not
116
* in this property list.
117
*
118
* @serial the default properties
119
*/
120
protected OrderedProperties defaults;
121

  
122
/**
123
* Compatible with JDK 1.0+.
124
*/
125
private static final long serialVersionUID = -5087876565919950510L;
126

  
127
/**
128
* Creates a new empty property list with no default values.
129
*/
130
public OrderedProperties()
131
{
132
	super(new StringComparator());
133
}
134

  
135
/**
136
* Create a new empty property list with the specified default values.
137
*
138
* @param defaults a Properties object containing the default values
139
*/
140
public OrderedProperties(OrderedProperties defaults)
141
{
142
	super(new StringComparator());
143
	this.defaults = defaults;
144
}
145

  
146
/**
147
* Adds the given key/value pair to this properties.  This calls
148
* the hashtable method put.
149
*
150
* @param key the key for this property
151
* @param value the value for this property
152
* @return The old value for the given key
153
* @see #getProperty(String)
154
* @since 1.2
155
*/
156
public Object setProperty(String key, String value)
157
{
158
 return put(key, value);
159
}
160

  
161
/**
162
* Reads a property list from an input stream.  The stream should
163
* have the following format: <br>
164
*
165
* An empty line or a line starting with <code>#</code> or
166
* <code>!</code> is ignored.  An backslash (<code>\</code>) at the
167
* end of the line makes the line continueing on the next line
168
* (but make sure there is no whitespace after the backslash).
169
* Otherwise, each line describes a key/value pair. <br>
170
*
171
* The chars up to the first whitespace, = or : are the key.  You
172
* can include these caracters in the key, if you precede them with
173
* a backslash (<code>\</code>). The key is followed by optional
174
* whitespaces, optionally one <code>=</code> or <code>:</code>,
175
* and optionally some more whitespaces.  The rest of the line is
176
* the resource belonging to the key. <br>
177
*
178
* Escape sequences <code>\t, \n, \r, \\, \", \', \!, \#, \ </code>(a
179
* space), and unicode characters with the
180
* <code>\\u</code><em>xxxx</em> notation are detected, and
181
* converted to the corresponding single character. <br>
182
*
183
* 
184
<pre># This is a comment
185
key     = value
186
k\:5      \ a string starting with space and ending with newline\n
187
# This is a multiline specification; note that the value contains
188
# no white space.
189
weekdays: Sunday,Monday,Tuesday,Wednesday,\\
190
       Thursday,Friday,Saturday
191
# The safest way to include a space at the end of a value:
192
label   = Name:\\u0020</pre>
193
*
194
* @param inStream the input stream
195
* @throws IOException if an error occurred when reading the input
196
* @throws NullPointerException if in is null
197
*/
198
public void load(InputStream inStream) throws IOException
199
{
200
 // The spec says that the file must be encoded using ISO-8859-1.
201
 BufferedReader reader =
202
   new BufferedReader(new InputStreamReader(inStream, "ISO-8859-1"));
203
 String line;
204

  
205
 while ((line = reader.readLine()) != null)
206
   {
207
     char c = 0;
208
     int pos = 0;
209
	// Leading whitespaces must be deleted first.
210
     while (pos < line.length()
211
            && Character.isWhitespace(c = line.charAt(pos)))
212
       pos++;
213

  
214
     // If empty line or begins with a comment character, skip this line.
215
     if ((line.length() - pos) == 0
216
	    || line.charAt(pos) == '#' || line.charAt(pos) == '!')
217
       continue;
218

  
219
     // The characters up to the next Whitespace, ':', or '='
220
     // describe the key.  But look for escape sequences.
221
	// Try to short-circuit when there is no escape char.
222
	int start = pos;
223
	boolean needsEscape = line.indexOf('\\', pos) != -1;
224
     StringBuffer key = needsEscape ? new StringBuffer() : null;
225
     while (pos < line.length()
226
            && ! Character.isWhitespace(c = line.charAt(pos++))
227
            && c != '=' && c != ':')
228
       {
229
         if (needsEscape && c == '\\')
230
           {
231
             if (pos == line.length())
232
               {
233
                 // The line continues on the next line.  If there
234
                 // is no next line, just treat it as a key with an
235
                 // empty value.
236
                 line = reader.readLine();
237
		    if (line == null)
238
		      line = "";
239
                 pos = 0;
240
                 while (pos < line.length()
241
                        && Character.isWhitespace(c = line.charAt(pos)))
242
                   pos++;
243
               }
244
             else
245
               {
246
                 c = line.charAt(pos++);
247
                 switch (c)
248
                   {
249
                   case 'n':
250
                     key.append('\n');
251
                     break;
252
                   case 't':
253
                     key.append('\t');
254
                     break;
255
                   case 'r':
256
                     key.append('\r');
257
                     break;
258
                   case 'u':
259
                     if (pos + 4 <= line.length())
260
                       {
261
                         char uni = (char) Integer.parseInt
262
                           (line.substring(pos, pos + 4), 16);
263
                         key.append(uni);
264
                         pos += 4;
265
                       }        // else throw exception?
266
                     break;
267
                   default:
268
                     key.append(c);
269
                     break;
270
                   }
271
               }
272
           }
273
         else if (needsEscape)
274
           key.append(c);
275
       }
276

  
277
     boolean isDelim = (c == ':' || c == '=');
278

  
279
	String keyString;
280
	if (needsEscape)
281
	  keyString = key.toString();
282
	else if (isDelim || Character.isWhitespace(c))
283
	  keyString = line.substring(start, pos - 1);
284
	else
285
	  keyString = line.substring(start, pos);
286

  
287
     while (pos < line.length()
288
            && Character.isWhitespace(c = line.charAt(pos)))
289
       pos++;
290

  
291
     if (! isDelim && (c == ':' || c == '='))
292
       {
293
         pos++;
294
         while (pos < line.length()
295
                && Character.isWhitespace(c = line.charAt(pos)))
296
           pos++;
297
       }
298

  
299
	// Short-circuit if no escape chars found.
300
	if (!needsEscape)
301
	  {
302
	    put(keyString, line.substring(pos));
303
	    continue;
304
	  }
305

  
306
	// Escape char found so iterate through the rest of the line.
307
     StringBuffer element = new StringBuffer(line.length() - pos);
308
     while (pos < line.length())
309
       {
310
         c = line.charAt(pos++);
311
         if (c == '\\')
312
           {
313
             if (pos == line.length())
314
               {
315
                 // The line continues on the next line.
316
                 line = reader.readLine();
317

  
318
		    // We might have seen a backslash at the end of
319
		    // the file.  The JDK ignores the backslash in
320
		    // this case, so we follow for compatibility.
321
		    if (line == null)
322
		      break;
323

  
324
                 pos = 0;
325
                 while (pos < line.length()
326
                        && Character.isWhitespace(c = line.charAt(pos)))
327
                   pos++;
328
                 element.ensureCapacity(line.length() - pos +
329
                                        element.length());
330
               }
331
             else
332
               {
333
                 c = line.charAt(pos++);
334
                 switch (c)
335
                   {
336
                   case 'n':
337
                     element.append('\n');
338
                     break;
339
                   case 't':
340
                     element.append('\t');
341
                     break;
342
                   case 'r':
343
                     element.append('\r');
344
                     break;
345
                   case 'u':
346
                     if (pos + 4 <= line.length())
347
                       {
348
                         char uni = (char) Integer.parseInt
349
                           (line.substring(pos, pos + 4), 16);
350
                         element.append(uni);
351
                         pos += 4;
352
                       }        // else throw exception?
353
                     break;
354
                   default:
355
                     element.append(c);
356
                     break;
357
                   }
358
               }
359
           }
360
         else
361
           element.append(c);
362
       }
363
     put(keyString, element.toString());
364
   }
365
}
366

  
367
/**
368
* Reads a property list from an input stream, using the
369
* provided encoding. The provided stream should be
370
* correctly encoded as specified, otherwise an IOException
371
* error will be thrown. No escape sequences are accepted
372
* to represent any character, and thus this method has some
373
* limitations and the
374
* format of the accepted property files is slightly
375
* different from
376
* the standard Java property files.
377
* 
378
* The main differences are:
379
* <ul><li>whitespaces, = or : cannot be present in
380
* the key.</li>
381
* <li>each pair key/value must be contained in a single line</li>
382
* </ul>
383
* 
384
* The stream should have the following format: <br>
385
*
386
* An empty line or a line starting with <code>#</code> or
387
* <code>!</code> is ignored.
388
* Otherwise, each line describes a key/value pair. <br>
389
*
390
* The chars up to the first whitespace, = or : are the key.  You
391
* cannot include these caracters in the key. The key is followed by optional
392
* whitespaces, optionally one <code>=</code> or <code>:</code>,
393
* and optionally some more whitespaces.  The rest of the line is
394
* the resource belonging to the key. <br>
395
*
396
* @param inStream the input stream
397
* @throws IOException if an error occurred when reading the input
398
* @throws NullPointerException if in is null
399
*/
400
public void load(InputStream inStream, String encoding) throws IOException {
401
	BufferedReader reader = new BufferedReader(new InputStreamReader(inStream, encoding));
402

  
403
	String line;
404
	while ((line = reader.readLine()) != null) {
405
		int pos = 0;
406
		// Leading whitespaces must be deleted first.
407
		while (pos < line.length()
408
			 && Character.isWhitespace(line.charAt(pos)))
409
			pos++;
410

  
411
     	// If empty line or begins with a comment character, skip this line.
412
     	if ((line.length() - pos) == 0
413
     			|| line.charAt(pos) == '#' || line.charAt(pos) == '!')
414
     		continue;
415

  
416

  
417
     	// do something
418
     	String[] entry = line.substring(pos).split(" *[=: ] *", 2);
419
     	if (entry.length==2) {
420
     		put(entry[0], entry[1]);
421
     	}
422
     	else {
423
     		put(entry[0], "");
424
     	}
425
	}
426
}
427

  
428

  
429
/**
430
* Writes the key/value pairs to the given output stream, in a format
431
* suitable for
432
* {@link #load(InputStream, String) load(InputStream is, String encoding)}.
433
* Note that this method does not use escape sequences to represent
434
* characters outside the encoding range, charset-dependent
435
* substitution sequence will
436
* be generated if such character is present in the stream.
437
* Moreover, because there is no escape sequences, the newline (\n)
438
* and carriage return (\r) characters must not be used (the 
439
* resulting property file will be incorrect). Because of the
440
* same reason, whitespaces, :, =, ! and # must not be used in the
441
* key<br>
442
*
443
* If header is not null, this method writes a comment containing
444
* the header as first line to the stream.  The next line (or first
445
* line if header is null) contains a comment with the current date.
446
* Afterwards the key/value pairs are written to the stream in the
447
* following format.<br>
448
*
449
* Each line has the form <code>key = value</code>.
450
*
451
* Following the listing, the output stream is flushed but left open.
452
*
453
* @param out the output stream
454
* @param header the header written in the first line, may be null
455
* @throws ClassCastException if this property contains any key or
456
*         value that isn't a string
457
* @throws IOException if writing to the stream fails
458
* @throws NullPointerException if out is null
459
* @since 1.2
460
*/
461
public void store(OutputStream out, String header, String encoding) throws IOException {
462
	PrintWriter writer
463
	   = new PrintWriter(new OutputStreamWriter(out, encoding));
464
	if (header != null)
465
		writer.println("#" + header);
466
	writer.println ("#" + Calendar.getInstance ().getTime ());
467

  
468
	Iterator iter = entrySet ().iterator ();
469
	int i = size ();
470
	while (--i >= 0) {
471
		Entry entry = (Entry) iter.next ();
472
	    writer.println (entry.getKey()+"="+entry.getValue());
473
	}
474

  
475
	writer.flush ();
476
}
477

  
478

  
479

  
480
/**
481
* Writes the key/value pairs to the given output stream, in a format
482
* suitable for {@link #load(InputStream) load(InputStream)}.<br>
483
*
484
* If header is not null, this method writes a comment containing
485
* the header as first line to the stream.  The next line (or first
486
* line if header is null) contains a comment with the current date.
487
* Afterwards the key/value pairs are written to the stream in the
488
* following format.<br>
489
*
490
* Each line has the form <code>key = value</code>.  Newlines,
491
* Returns and tabs are written as <code>\n,\t,\r</code> resp.
492
* The characters <code>\, !, #, =</code> and <code>:</code> are
493
* preceeded by a backslash.  Spaces are preceded with a backslash,
494
* if and only if they are at the beginning of the key.  Characters
495
* that are not in the ascii range 33 to 127 are written in the
496
* <code>\</code><code>u</code>xxxx Form.<br>
497
*
498
* Following the listing, the output stream is flushed but left open.
499
*
500
* @param out the output stream
501
* @param header the header written in the first line, may be null
502
* @throws ClassCastException if this property contains any key or
503
*         value that isn't a string
504
* @throws IOException if writing to the stream fails
505
* @throws NullPointerException if out is null
506
* @since 1.2
507
*/
508
public void store(OutputStream out, String header) throws IOException
509
{
510
 // The spec says that the file must be encoded using ISO-8859-1.
511
 PrintWriter writer
512
   = new PrintWriter(new OutputStreamWriter(out, "ISO-8859-1"));
513
 if (header != null)
514
   writer.println("#" + header);
515
 writer.println ("#" + Calendar.getInstance ().getTime ());
516
 
517
 Iterator iter = entrySet ().iterator ();
518
 int i = size ();
519
 StringBuffer s = new StringBuffer (); // Reuse the same buffer.
520
 while (--i >= 0)
521
   {
522
     Entry entry = (Entry) iter.next ();
523
     formatForOutput ((String) entry.getKey (), s, true);
524
     s.append ('=');
525
     formatForOutput ((String) entry.getValue (), s, false);
526
     writer.println (s);
527
   }
528

  
529
 writer.flush ();
530
}
531

  
532
/**
533
* Gets the property with the specified key in this property list.
534
* If the key is not found, the default property list is searched.
535
* If the property is not found in the default, null is returned.
536
*
537
* @param key The key for this property
538
* @return the value for the given key, or null if not found
539
* @throws ClassCastException if this property contains any key or
540
*         value that isn't a string
541
* @see #defaults
542
* @see #setProperty(String, String)
543
* @see #getProperty(String, String)
544
*/
545
public String getProperty(String key)
546
{
547
 OrderedProperties prop = this;
548
 // Eliminate tail recursion.
549
 do
550
   {
551
     String value = (String) prop.get(key);
552
     if (value != null)
553
       return value;
554
     prop = prop.defaults;
555
   }
556
 while (prop != null);
557
 return null;
558
}
559

  
560
/**
561
* Gets the property with the specified key in this property list.  If
562
* the key is not found, the default property list is searched.  If the
563
* property is not found in the default, the specified defaultValue is
564
* returned.
565
*
566
* @param key The key for this property
567
* @param defaultValue A default value
568
* @return The value for the given key
569
* @throws ClassCastException if this property contains any key or
570
*         value that isn't a string
571
* @see #defaults
572
* @see #setProperty(String, String)
573
*/
574
public String getProperty(String key, String defaultValue)
575
{
576
 String prop = getProperty(key);
577
 if (prop == null)
578
   prop = defaultValue;
579
 return prop;
580
}
581

  
582
/**
583
* Returns an enumeration of all keys in this property list, including
584
* the keys in the default property list.
585
*
586
* @return an Enumeration of all defined keys
587
*/
588
public Enumeration propertyNames()
589
{
590
 // We make a new Set that holds all the keys, then return an enumeration
591
 // for that. This prevents modifications from ruining the enumeration,
592
 // as well as ignoring duplicates.
593
 OrderedProperties prop = this;
594
 Set s = new HashSet();
595
 // Eliminate tail recursion.
596
 do
597
   {
598
     s.addAll(prop.keySet());
599
     prop = prop.defaults;
600
   }
601
 while (prop != null);
602
 return Collections.enumeration(s);
603
}
604

  
605
/**
606
* Prints the key/value pairs to the given print stream.  This is 
607
* mainly useful for debugging purposes.
608
*
609
* @param out the print stream, where the key/value pairs are written to
610
* @throws ClassCastException if this property contains a key or a
611
*         value that isn't a string
612
* @see #list(PrintWriter)
613
*/
614
public void list(PrintStream out)
615
{
616
 PrintWriter writer = new PrintWriter (out);
617
 list (writer);
618
}
619

  
620
/**
621
* Prints the key/value pairs to the given print writer.  This is
622
* mainly useful for debugging purposes.
623
*
624
* @param out the print writer where the key/value pairs are written to
625
* @throws ClassCastException if this property contains a key or a
626
*         value that isn't a string
627
* @see #list(PrintStream)
628
* @since 1.1
629
*/
630
public void list(PrintWriter out)
631
{
632
 out.println ("-- listing properties --");
633

  
634
 Iterator iter = entrySet ().iterator ();
635
 int i = size ();
636
 while (--i >= 0)
637
   {
638
     Entry entry = (Entry) iter.next ();
639
     out.print ((String) entry.getKey () + "=");
640

  
641
     // JDK 1.3/1.4 restrict the printed value, but not the key,
642
     // to 40 characters, including the truncating ellipsis.
643
     String s = (String ) entry.getValue ();
644
     if (s != null && s.length () > 40)
645
       out.println (s.substring (0, 37) + "...");
646
     else
647
       out.println (s);
648
   }
649
 out.flush ();
650
}
651

  
652
/**
653
* Formats a key or value for output in a properties file.
654
* See store for a description of the format.
655
*
656
* @param str the string to format
657
* @param buffer the buffer to add it to
658
* @param key true if all ' ' must be escaped for the key, false if only
659
*        leading spaces must be escaped for the value
660
* @see #store(OutputStream, String)
661
*/
662
private void formatForOutput(String str, StringBuffer buffer, boolean key)
663
{
664
 if (key)
665
   {
666
     buffer.setLength(0);
667
     buffer.ensureCapacity(str.length());
668
   }
669
 else
670
   buffer.ensureCapacity(buffer.length() + str.length());
671
 boolean head = true;
672
 int size = str.length();
673
 for (int i = 0; i < size; i++)
674
   {
675
     char c = str.charAt(i);
676
     switch (c)
677
       {
678
       case '\n':
679
         buffer.append("\\n");
680
         break;
681
       case '\r':
682
         buffer.append("\\r");
683
         break;
684
       case '\t':
685
         buffer.append("\\t");
686
         break;
687
       case ' ':
688
         buffer.append(head ? "\\ " : " ");
689
         break;
690
       case '\\':
691
       case '!':
692
       case '#':
693
       case '=':
694
       case ':':
695
         buffer.append('\\').append(c);
696
         break;
697
       default:
698
         if (c < ' ' || c > '~')
699
           {
700
             String hex = Integer.toHexString(c);
701
             buffer.append("\\u0000".substring(0, 6 - hex.length()));
702
             buffer.append(hex);
703
           }
704
         else
705
           buffer.append(c);
706
       }
707
     if (c != ' ')
708
       head = key;
709
   }
710
}
711

  
712
} // class OrderedProperties
713

  
714

  
715
class StringComparator implements Comparator {
716
	 public int compare(Object o1, Object o2) {
717
		 String s1 = o1.toString();
718
		 String s2 = o2.toString();
719

  
720
		 if (s1.compareToIgnoreCase(s2)!=0) // we want case insensitive ordenation, but we still need to differenciate 'OK' from 'Ok'
721
			 return s1.compareToIgnoreCase(s2);
722
		 else
723
			 return -s1.compareTo(s2); // we want lower case before upper case
724
	 }
725
}
0 726

  
tags/v2_0_0_Build_2047/libraries/libInternationalization/libInternationalization/src-utils/org/gvsig/i18n/utils/TranslationDatabase.java
1
/**
2
 * 
3
 */
4
package org.gvsig.i18n.utils;
5

  
6
import java.io.File;
7
import java.io.FileInputStream;
8
import java.io.FileNotFoundException;
9
import java.io.FileOutputStream;
10
import java.io.IOException;
11
import java.util.ArrayList;
12
import java.util.HashMap;
13
import java.util.Iterator;
14
import java.util.Set;
15

  
16
/**
17
 * @author cesar
18
 *
19
 */
20
public class TranslationDatabase {
21
	
22
	public TranslationDatabase(ConfigOptions config){
23
		this.config = config; 
24
	}
25
	
26
	private ConfigOptions config;
27
	private HashMap dictionaries;
28
	
29
	public void load() {
30
		// always start with an empty HashMap when loading
31
		dictionaries = new HashMap();
32
		String lang;
33
		DoubleProperties dictionary;
34
		
35
		FileInputStream stream=null;
36
		
37
		for (int currentLang=0; currentLang<config.languages.length; currentLang++) {
38
			lang = config.languages[currentLang];
39
			dictionary = new DoubleProperties();
40
			try {
41
				stream = new FileInputStream(config.databaseDir+File.separator+config.defaultBaseName+"_"+lang+".properties");
42
				try {
43
					dictionary.load(stream);
44
				} catch (IOException e) {
45
					System.err.println("Error cargando la base de datos para el idioma: ["+lang+"]. "+e.getLocalizedMessage());
46
				}
47
			} catch (FileNotFoundException e) {
48
				System.err.println("Error cargando la base de datos para el idioma: ["+lang+"]. "+e.getLocalizedMessage());
49
			}
50
			dictionaries.put(lang, dictionary);
51
		}
52
	}
53
	
54
	public void save() {
55
		String lang;
56
		DoubleProperties dictionary;
57
		
58
		FileOutputStream stream=null;
59

  
60
		for (int currentLang=0; currentLang<config.languages.length; currentLang++) {
61
			lang = config.languages[currentLang];
62
			
63
			dictionary = ((DoubleProperties)dictionaries.get(lang));
64
			
65
			try {
66
				stream = new FileOutputStream(config.databaseDir+File.separator+config.defaultBaseName+"_"+lang+".properties");
67
				try {
68
					dictionary.store(stream, "Translations for language: " + lang);
69
				} catch (IOException e) {
70
					System.err.println("Error guardando la base de datos para el idioma: ["+lang+"]. "+e.getLocalizedMessage());
71
				}
72
			} catch (FileNotFoundException e) {
73
				System.err.println("Error guardando la base de datos para el idioma: ["+lang+"]. "+e.getLocalizedMessage());
74
			}
75
		}
76
	}
77
	
78
	public String getTranslation(String lang, String key) {
79
		if (lang==null || key==null) return null;
80
		
81
		DoubleProperties dictionary = (DoubleProperties) dictionaries.get(lang);
82
		if (dictionary==null) return null;
83
		return (String) dictionary.get(key);
84
	}
85
	
86
	public String setTranslation(String lang, String key, String translation) {
87
		if (lang==null || key==null) return null;
88

  
89
		DoubleProperties dictionary = (DoubleProperties) dictionaries.get(lang);
90
		if (dictionary==null) return null;
91
		String oldvalue = (String) dictionary.get(key);
92
		dictionary.put(key, translation);
93
		return oldvalue;
94
	}
95
	
96
	/**
97
	 * Removes the key from the specified dictionary, and its associated translation.
98
	 * It has no effect if the key was not present in the dictionary.
99
	 * 
100
	 * @param lang The language from which the key should be removed.
101
	 * @param key  The key to be removed.
102
	 * @return The translation associated with the key, or null if the
103
	 * key was not present in the dictionary. It also returns null if any of the parameters is
104
	 * null, or if there was no dictionary for the specified language.
105
	 */
106
	public String removeTranslation(String lang, String key) {
107
		if (lang==null || key==null) return null;
108

  
109
		DoubleProperties dictionary = (DoubleProperties) dictionaries.get(lang);
110
		if (dictionary==null) return null;
111
		String oldvalue = (String) dictionary.get(key);
112
		dictionary.remove(key);
113
		return oldvalue;
114
	}
115
	
116
	/**
117
	 * Removes the key and its associated translation from all the dictionaries.
118
	 * The key will be deleted from the dictionaries in which it is present (if any).
119
	 * 
120
	 * @param key  The key to be removed.
121
	 * @return True if the key was removed from any dictionary, or false if the key
122
	 * was not present in any dictionary.
123
	 * @throws NullPointerException if the key is null.
124
	 */
125
	public boolean removeTranslation(String key) throws NullPointerException {
126
		DoubleProperties dictionary;
127
		String lang;
128
		boolean present=false;
129
		
130
		Set keys = dictionaries.keySet();
131
		Iterator langIterator = keys.iterator();
132
		while (langIterator.hasNext()) {
133
			lang = (String) langIterator.next();
134
			dictionary = (DoubleProperties) dictionaries.get(lang);
135
			if (dictionary.containsKey(key)) {
136
				present=true;
137
				dictionary.remove(key);
138
			}
139
		}
140
		return present;
141
	}
142
	
143
	public boolean containsLanguage(String lang) {
144
		return dictionaries.containsKey(lang);
145
	}
146

  
147
	public boolean containsKey(String lang, String key) {
148
		if (lang==null || key==null) return false;
149

  
150
		DoubleProperties dictionary = (DoubleProperties) dictionaries.get(lang);
151
		return dictionary.containsKey(key);
152
	}
153
	
154
	public String getAssociatedKey(String lang, String value) {
155
		if (lang==null || value==null) return null;
156

  
157
		DoubleProperties dictionary = (DoubleProperties) dictionaries.get(lang);
158
		return dictionary.getAssociatedKey(value);
159
	}
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff