Revision 4460

View differences:

trunk/libraries/libInternationalization/src/org/gvsig/i18n/Messages.java
1
package org.gvsig.i18n;
2

  
3
import java.io.*;
4
import java.util.*;
5
import org.apache.log4j.Logger;
6

  
7
/**
8
 * @author Generalitat Valenciana and Iver
9
 *
10
 */
11
public class Messages {
12
	//private static final String ENCODING="UTF-8";
13
    private static Logger logger = Logger.getLogger("Messages");
14
    
15
	private static Hashtable localeResources = new Hashtable(100, 2);; // contains the translations, indexed by key
16
	private static Properties _localeProperties = new Properties(); 
17
	private static Vector _preferredLocales; // contains the ordered list of prefered languages/locales (class Locale)
18
	private static Vector _availableLocales;
19
	
20
	/**
21
	 * @param key
22
	 * @return an String with the message associated with the provided key.
23
	 * If the key is not in the dictionary, return the key.
24
	 * 
25
	 * Gets the localized message associated with the provided key.
26
	 * If the key is not in the dictionary, return the key and register
27
	 * the failure in the log.
28
	 */
29
	public static String getText(String key) {
30
		String translation = (String) localeResources.get(key);
31
		if (translation!=null)
32
			return translation;
33
		logger.warn("");
34
		return key;
35
	}
36
	
37
	/**
38
	 * @param key
39
	 * @return an String with the message associated with the provided key,
40
	 * or null if the key is not in the dictionary.
41
	 * If the key is not found, the failure IS NOT registered in the log.
42
	 * 
43
	 * Gets the localized message associated with the provided key.
44
	 * Returns null if the key is not in the dictionary.
45
	 */
46
	public static String getTextNoLog(String key) {
47
		return (String) localeResources.get(key);
48
	}	
49
	
50
	/**
51
	 * Adds an additional family of resource files containing some translations.
52
	 * A family is a group of files with a common baseName.
53
	 * The file must be an UTF-8 encoded file, with the format:
54
	 * key1=value1
55
	 * key2=value2
56
	 * where 'key1' is the key used to identify the string and must not
57
	 * contain the '=' symbol, and 'value1' is the associated translation.
58
	 * For example:
59
	 * cancel=Cancelar
60
	 * accept=Aceptar
61
	 * Only one pair key-value is allowed per line.
62
	 * 
63
	 * @param basedir The directory in which the properties file is stored 
64
	 * @param family  The family name (or base name) which is used to search
65
	 * actual properties files.
66
	 */
67
	public static void addResourceFamily(String basedir, String family) {
68
		FileInputStream inputStream=null;
69
		BufferedReader reader=null;
70
		//String line;
71
		String fileName="";
72
		
73
		String currentKey;
74
		Enumeration properties;
75
		
76
		Enumeration languages = _preferredLocales.elements();
77
		Locale lang;
78
		//String[] entry;
79
		while (languages.hasMoreElements()) { // for each language
80
			lang = (Locale) languages.nextElement();
81
			// get all the possible langcode candidates
82
			Enumeration langcodes = getLangcodeList(lang);
83
			while (inputStream==null && (langcodes.hasMoreElements() || lang.getLanguage().equals("es"))) {
84
				
85
				if (langcodes.hasMoreElements())
86
					fileName = basedir+File.separator+family+"_"+(String)langcodes.nextElement()+".properties";
87
				else // we need this for Spanish, as it is the default language for the moment
88
					fileName = basedir+File.separator+family+".properties";
89
				try {
90
					inputStream = new FileInputStream(fileName);
91
				}
92
				catch (FileNotFoundException fnfex) {
93
					/* No harm if the file was not found. We don't know which files are present in advance.
94
					 * We just keep trying to open a valid file for this locale.
95
					 * First we tried to open "lang_country_variant", now "lang_contry"
96
					 * and finally we'll try just "lang" and "".
97
					 */
98
				}
99
			}
100

  
101
			if (inputStream!=null) {
102
				/* If we got a valid inputStream, we read it. Otherwise, we'll continue with the
103
				 * next language
104
				 */
105
				try {
106
					/** Tendremos que usar el objeto properties mientras nuestras traducciones
107
					 * est?n codificadas usando Unicape escaped sequences (ya que no hay forma sencilla
108
					 * de cargar estos ficheros correctamente si no es usando esta clase) **/
109
					_localeProperties.load(inputStream);
110
					properties = _localeProperties.propertyNames();
111
					while (properties.hasMoreElements()) {
112
						currentKey = (String) properties.nextElement();
113
						if (!localeResources.containsKey(currentKey)) {
114
							localeResources.put(currentKey, _localeProperties.getProperty(currentKey));
115
						}
116
					}
117
					inputStream.close();
118
				}
119
				catch (IOException iox){
120
					// if there was some error while reading, log it and close the stream
121
					logger.error(Messages.getText("Messages -- error.intentado.leer:"+fileName));
122
					try {
123
						inputStream.close();
124
					}
125
					catch (IOException iox2) {}
126
				}
127
					
128
					/*reader = new BufferedReader(new InputStreamReader(inputStream, ENCODING));
129
				
130
					// each line from the file is added to the Hashtable				
131
					for (line=reader.readLine(); line!=null; line=reader.readLine()) {
132
						// the line contains a pair "key=value"
133
						entry = line.split("=", 2);
134
						if (entry.length == 2) {
135
							// if the key is already present, we don't overwrite its contents
136
							if (!localeResources.containsKey(entry[0])) {
137
								localeResources.put(entry[0], entry[1]);
138
							}
139
						}
140
						else {
141
							logger.warn(Messages.getText("error.de.sintaxis.en.archivo:"+fileName));
142
						}
143
					}
144
					reader.close();
145
					*/
146
			/*	}
147
				catch (UnsupportedEncodingException ueex) {
148
					logger.error(Messages.getText("codificacion.caracteres.no.permitida"));
149
					try {
150
						inputStream.close();
151
					}
152
					catch (IOException ex) {}
153
				}
154
				catch (IOException ioex) {
155
					logger.error(Messages.getText("codificacion.caracteres.no.permitida"));
156
					try {
157
						reader.close();
158
					} catch (IOException ex) {}
159
				}*/
160
			}
161
		}
162
	}
163
	
164
	/**
165
	 * Returns a vector containing the ordered list of prefered Locales
166
	 * Each element of the vector is a Locale object.
167
	 * 
168
	 * @return a vector containing the ordered list of prefered Locales
169
	 * Each element of the vector is a Locale object.
170
	 */
171
	public static Vector getPreferredLocales() {
172
		return _preferredLocales;
173
	}
174
	
175
	/**
176
	 * Set the ordered list of preferred locales.
177
	 * Each element of the vector is a Locale object.
178
	 * 
179
	 * @param preferredLocales a vector containing Locale objects.
180
	 * The Vector represents an ordered list of preferred locales
181
	 */
182
	public static void setPreferredLocales(Vector preferredLocales) {
183
		_preferredLocales = preferredLocales;
184
	}
185
	
186
	/**
187
	 * Searches the subdirectories of the provided directory, finding
188
	 * all the translation files, and constructing a list of available translations.
189
	 * It reports different country codes or variants, if available.
190
	 * For example, if there is an en_US translation and an en_GB translation, both
191
	 * locales will be present in the Vector.
192
	 * 
193
	 * @return
194
	 */
195
	
196
	/**
197
	 * 
198
	 * @return A Vector containing the available locales. Each element is a Locale object
199
	 */
200
	public static Vector getAvailableLocales() {
201
		return _availableLocales;
202
	}
203
	
204
	/**
205
	 * 
206
	 * @return A Vector containing the available languages. Each element is an String object
207
	 */
208
	public static Vector getAvailableLanguages() {
209
		Vector availableLanguages = new Vector();
210
		Locale lang;
211
		Enumeration locales = _availableLocales.elements();
212
		while (locales.hasMoreElements()) {
213
			lang = (Locale) locales.nextElement();
214
			availableLanguages.add(lang.getLanguage());
215
		}
216
		return availableLanguages;
217
	}
218

  
219
	public static Hashtable getLocaleResources() {
220
		return localeResources;
221
	}
222
	
223
	
224
	/**
225
	 * This method returns all the possible valid localecodes for a given
226
	 * Locale object, starting with the most specifical localecode candidat.
227
	 * For example, given a Locale object containing "es_ES_linux_cs",
228
	 * it would return an Enumeration containing: {"es_ES_linux_cs", "es_ES", "es"}
229
	 * 
230
	 * @param localecode
231
	 * @return Enumeration of String objects, containing all the possible locales for
232
	 * a given localocode
233
	 */
234
	private static Enumeration getLangcodeList(Locale localecode) {
235
		Vector list = new Vector();
236
		if (!localecode.getVariant().equals("")) {
237
			list.add(localecode.toString());
238
		}
239
		if (!localecode.getCountry().equals("")) {
240
			list.add(localecode.getLanguage()+"_"+localecode.getCountry());
241
		}
242
		if (!localecode.getLanguage().equals("")) {
243
			list.add(localecode.getLanguage());
244
		}
245
		
246
		return list.elements();
247
	}
248
	
249
	/**
250
	 *  File filter that includes the files starting with "text_" and ending with ".gvslocales"
251
	 */
252
	/*private class LocaleFileFilter implements FileFilter {
253
		public boolean accept(File pathname) {
254
			if (!pathname.getName().startsWith("text_"))
255
				return false;
256
			if (!pathname.getName().endsWith(".gvslocales"))
257
				return false;
258
			return true;
259
		}
260
	}*/
261
	/*	public static Vector checkAvailableLocales(File directory) {
262
	Vector availableLocales = new Vector();
263
	if (directory.isDirectory()) {
264
		int contador;
265
		File[] localeFiles;
266
		File currentFile;
267
		String[] nameParts;
268
		String lang;
269
		// get files containing translations
270
		localeFiles = directory.listFiles(new LocaleFileFilter());
271
		for (contador=0; contador<localeFiles.length; contador++) {
272
			lang = null;
273
			currentFile = localeFiles[contador];
274
			// get the language code of the file
275
			nameParts = currentFile.getName().split("_");
276
			if (nameParts.length >= 2) {
277
				// ie. "text_es.gvslocales", "text_es_ES.gvslocales", "text_es_ES_linux-cs.gvslocales"
278
				nameParts = nameParts[1].split("\\.");
279
				if (nameParts.length == 2) {
280
					lang=nameParts[1];
281
				}
282
			}
283
			else if (nameParts.length > 2){
284
				//ie. "text_es_ES.gvslocales", "text_es_ES_linux_cs.gvslocales"
285
				lang=nameParts[1];
286
			}
287
			if (lang!=null) {
288
				availableLocales.add(lang);
289
			}
290
		}
291
	}
292
	else {
293
		logger.warn(Messages.getText("provided.name.is.not.directory"));
294
	}
295
	_availableLocales = availableLocales;
296
	return availableLocales;
297
}*/
298

  
299
	/**
300
	 * @param fileName
301
	 * 
302
	 * Adds an additional resource file containing some translations.
303
	 * The file must be an UTF-8 encoded file, with the format:
304
	 * key1=value1
305
	 * key2=value2
306
	 * where 'key1' is the key used to identify the string and must not
307
	 * contain the '=' symbol, and 'value1' is the associated translation.
308
	 * For example:
309
	 * cancel=Cancelar
310
	 * accept=Aceptar
311
	 * Only one pair key-value is allowed per line.
312
	 * 
313
	 */
314
	/*public static void addLocalizedFile(String baseName, Locale localeCode) {
315
		FileInputStream inputStream;
316
		BufferedReader reader=null;
317
		String line;
318
		Hashtable localizedResource;
319
		
320
		String[] entry;
321
		if (localeResources.containsKey(localeCode)) {
322
			localizedResource = (Hashtable) localeResources.get(localeCode);
323
		}
324
		else {
325
			// si todav?a no existe una Hashtable para este langcode, la creamos
326
			localizedResource = new Hashtable(100, 2);
327
			localeResources.put(localeCode, localizedResource);			
328
		}
329
		try {
330
			inputStream = new FileInputStream(baseName+"_"+localeCode+".properties");
331
			try {
332
				reader = new BufferedReader(new InputStreamReader(inputStream, ENCODING));
333
			}
334
			catch (UnsupportedEncodingException uee) {
335
				
336
			}
337
			// each line from the file is added to the Hashtable
338
			try {
339
				for (line=reader.readLine(); line!=null; line=reader.readLine()) {
340
					// the line contains a pair "key=value"
341
					entry = line.split("=");
342
					if (entry.length == 2) {
343
						// if the key is already present, we don't overwrite its contents
344
						if (!localizedResource.containsKey(entry[0])) {
345
							localizedResource.put(entry[0], entry[1]);
346
						}
347
					}
348
					else {
349
						// FIXME!! decidir qu? hacer exactamente en caso de error (y por supuesto, localizar el mensaje de error usando esta clase!!!)
350
						//throw new org.omg.CORBA.UnknownUserException();
351
					}
352
				}
353
				reader.close();				
354
			}
355
			catch (IOException ioex) {
356
				
357
			}
358
		}
359
		catch (FileNotFoundException ex) {
360
			System.err.println("error");		
361
		}		
362
	}*/
363
}
0 364

  
trunk/libraries/libInternationalization/build.xml
1
<project name="i18n (Internationalization)" default="dist" basedir=".">
2
	<description>
3
        Instala el plugin
4
    </description>
5
	<!-- set global properties for this build -->
6
	<property name="src" location="src"/>
7
	<property name="build" location="bin"/>
8
	<property name="dist"  location="dist"/>
9
	<property name="plugin" value="org.gvsig.i18n"/>
10
	<property name="extensionDir" location="../_fwAndami/gvSIG/extensiones"/>
11
	<property name="build-doc" value="build-doc"/>
12

  
13
	<target name="init">
14
		<!-- Create the time stamp -->
15
		<tstamp />
16
	</target>
17

  
18
	<target name="build-doc" depends="" description="Genera la documentación">
19
		<javadoc
20
			packagenames="org.gvsig.i18n.*"
21
			sourcepath="src"
22
			defaultexcludes="yes"
23
			destdir="${build-doc}/org.gvsig.i18n"
24
			windowtitle="libInternationalization API">
25
		</javadoc>
26
	</target>
27

  
28
	<target name="compile" depends="init"
29
		description="compile the source " >
30
	    <!-- Compile the java code from ${src} into ${build}
31
	    <javac srcdir="${src}" destdir="${build}"/> -->
32
	</target>
33

  
34
	<target name="dist" depends="compile"
35
		description="generate the distribution" >
36
		<!-- Create the distribution directory -->
37
		<mkdir dir="${dist}"/>
38
		
39
	    <jar jarfile="${dist}/i18n.jar" basedir="${build}"/>
40
	</target>
41

  
42
	<target name="clean"
43
		description="clean up" >
44
		<!-- Delete the ${build} and ${dist} directory trees -->
45
		<delete dir="${build}"/>
46
		<delete dir="${dist}"/>
47
	</target>
48
</project>
0 49

  

Also available in: Unified diff