001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/i18n/Messages.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 package org.deegree.i18n; 037 038 import java.io.IOException; 039 import java.io.InputStream; 040 import java.text.MessageFormat; 041 import java.util.Enumeration; 042 import java.util.HashMap; 043 import java.util.Iterator; 044 import java.util.Locale; 045 import java.util.Map; 046 import java.util.Properties; 047 048 import org.deegree.framework.log.ILogger; 049 import org.deegree.framework.log.LoggerFactory; 050 import org.deegree.framework.util.BootLogger; 051 052 /** 053 * Responsible for the access to messages that are visible to the user. 054 * <p> 055 * Messages are read from the properties file <code>messages_LANG.properties</code> (LANG is always a lowercased ISO 639 056 * code), so internationalization is supported. If a certain property (or the property file) for the specific default 057 * language of the system is not found, the message is taken from <code>messages_en.properties</code>. 058 * 059 * @see Locale#getLanguage() 060 * 061 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 062 * @author <a href="mailto:taddei@lat-lon.de">Ugo Taddei</a> 063 * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a> 064 * @author last edited by: $Author: apoth $ 065 * 066 * @version $Revision: 26673 $, $Date: 2010-09-10 12:58:10 +0200 (Fr, 10 Sep 2010) $ 067 */ 068 public class Messages { 069 070 private static final ILogger LOG = LoggerFactory.getLogger( Messages.class ); 071 072 /* This definition allows Eclipse to display the content of referenced message keys. */ 073 @SuppressWarnings("unused") 074 private static final String BUNDLE_NAME = "org.deegree.i18n.messages_en"; 075 076 private static Properties defaultProps = new Properties(); 077 078 private static Map<Locale, Properties> props = new HashMap<Locale, Properties>(); 079 080 private static String lang; 081 082 /** 083 * Initialization done at class loading time. 084 */ 085 static { 086 try { 087 // load all messages from default file ("org/deegree/i18n/message_en.properties") 088 String fileName = "messages_en.properties"; 089 InputStream is = Messages.class.getResourceAsStream( fileName ); 090 if ( is == null ) { 091 BootLogger.log( "Error while initializing " + Messages.class.getName() + " : " 092 + " default message file: '" + fileName + " not found." ); 093 } 094 is = Messages.class.getResourceAsStream( fileName ); 095 defaultProps.load( is ); 096 is.close(); 097 098 // override messages using file "/message_en.properties" 099 fileName = "/messages_en.properties"; 100 overrideMessages( fileName, defaultProps ); 101 102 lang = Locale.getDefault().getLanguage(); 103 if ( !"".equals( lang ) && !"en".equals( lang ) ) { 104 // override messages using file "org/deegree/i18n/message_LANG.properties" 105 fileName = "messages_" + lang + ".properties"; 106 overrideMessages( fileName, defaultProps ); 107 // override messages using file "/message_LANG.properties" 108 fileName = "/messages_" + lang + ".properties"; 109 overrideMessages( fileName, defaultProps ); 110 } 111 } catch ( IOException e ) { 112 BootLogger.logError( "Error while initializing " + Messages.class.getName() + " : " + e.getMessage(), e ); 113 } 114 } 115 116 private static void overrideMessages( String propertiesFile, Properties props ) 117 throws IOException { 118 InputStream is = Messages.class.getResourceAsStream( propertiesFile ); 119 if ( is != null ) { 120 // override default messages 121 Properties overrideProps = new Properties(); 122 overrideProps.load( is ); 123 is.close(); 124 Iterator<?> iter = overrideProps.keySet().iterator(); 125 while ( iter.hasNext() ) { 126 String key = (String) iter.next(); 127 props.put( key, overrideProps.get( key ) ); 128 } 129 } 130 } 131 132 private static String get( Properties props, String key, Object... args ) { 133 String s = (String) props.get( key ); 134 if ( s != null ) { 135 return MessageFormat.format( s, args ); 136 } 137 138 return "$Message with key: " + key + " not found$"; 139 } 140 141 /** 142 * @param loc 143 * the locale to be used 144 * @param key 145 * to get 146 * @param arguments 147 * to fill in the message 148 * @return the localized message 149 */ 150 public static synchronized String get( Locale loc, String key, Object... arguments ) { 151 if ( loc.getLanguage().equals( lang ) ) { 152 return get( key, arguments ); 153 } 154 155 if ( !props.containsKey( loc ) ) { 156 Properties p = new Properties(); 157 158 String l = loc.getLanguage(); 159 160 if ( !"".equals( l ) ) { 161 try { 162 // override messages in this order: 163 // messages_en.properties 164 // /messages_en.properties 165 // messages_lang.properties 166 // /messages_lang.properties 167 String fileName = "messages_en.properties"; 168 overrideMessages( fileName, p ); 169 fileName = "/messages_en.properties"; 170 overrideMessages( fileName, p ); 171 fileName = "messages_" + l + ".properties"; 172 overrideMessages( fileName, p ); 173 fileName = "/messages_" + l + ".properties"; 174 overrideMessages( fileName, p ); 175 } catch ( IOException e ) { 176 LOG.logError( "Error loading language file for language '" + l + "': ", e ); 177 } 178 } 179 180 props.put( loc, p ); 181 } 182 183 return get( props.get( loc ), key, arguments ); 184 } 185 186 /** 187 * 188 * @param locale 189 * @return copy of complete list of properties 190 */ 191 public static synchronized Properties getProperties( Locale locale ) { 192 if ( locale == null ) { 193 locale = Locale.getDefault(); 194 } 195 if ( !props.containsKey( locale ) ) { 196 Properties p = new Properties(); 197 198 String l = locale.getLanguage(); 199 200 if ( !"".equals( l ) ) { 201 try { 202 // override messages in this order: 203 // messages_en.properties 204 // /messages_en.properties 205 // messages_lang.properties 206 // /messages_lang.properties 207 String fileName = "messages_en.properties"; 208 overrideMessages( fileName, p ); 209 fileName = "/messages_en.properties"; 210 overrideMessages( fileName, p ); 211 fileName = "messages_" + l + ".properties"; 212 overrideMessages( fileName, p ); 213 fileName = "/messages_" + l + ".properties"; 214 overrideMessages( fileName, p ); 215 } catch ( IOException e ) { 216 LOG.logError( "Error loading language file for language '" + l + "': ", e ); 217 } 218 } 219 220 props.put( locale, p ); 221 } 222 Properties p1 = props.get( locale ); 223 Properties p2 = new Properties( ); 224 Enumeration<Object> keys = p1.keys(); 225 while ( keys.hasMoreElements() ) { 226 String key = (String) keys.nextElement(); 227 String value = p1.getProperty( key ); 228 p2.put( key, value ); 229 230 } 231 return p2; 232 } 233 234 /** 235 * Alias for #getMessage. 236 * 237 * @param key 238 * @param arguments 239 * @return the message 240 */ 241 public static String get( String key, Object... arguments ) { 242 return getMessage( key, arguments ); 243 } 244 245 /** 246 * Returns the message assigned to the passed key. If no message is assigned, an error message will be returned that 247 * indicates the missing key. 248 * 249 * @see MessageFormat for conventions on string formatting and escape characters. 250 * 251 * @param key 252 * @param arguments 253 * @return the message assigned to the passed key 254 */ 255 public static String getMessage( String key, Object... arguments ) { 256 return get( defaultProps, key, arguments ); 257 } 258 }