//$HeadURL$
/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2008 by:
Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53177 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.igeo.i18n;
import static java.util.Locale.getDefault;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import org.deegree.framework.util.BootLogger;
/**
* Responsible for the access to messages that are visible to the user.
* <p>
* Messages are read from the properties file <code>messages_LANG.properties</code> (LANG is always a lowercased ISO 639
* code), so internationalization is supported. If a certain property (or the property file) for the specific default
* language of the system is not found, the message is taken from <code>messages_en.properties</code>.
*
* @see Locale#getLanguage()
*
* @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
* @author last edited by: $Author$
*
* @version $Revision$, $Date$
*/
public class Messages {
private static Map<String, Properties> propertyMap = new HashMap<String, Properties>();
/**
* Initialization done at class loading time.
*/
static {
try {
Locale[] locales = Locale.getAvailableLocales();
// load all messages from default file ("org/deegree/i18n/message_en.properties")
String fileName = "messages_en.properties";
InputStream is = Messages.class.getResourceAsStream( fileName );
if ( is == null ) {
BootLogger.log( "Error while initializing " + Messages.class.getName() + " : default message file: '"
+ fileName + " not found." );
}
is = Messages.class.getResourceAsStream( fileName );
Properties props = new Properties();
props.load( is );
is.close();
propertyMap.put( "en", props );
if ( !Locale.getDefault().getLanguage().equals( "en" ) ) {
is = Messages.class.getResourceAsStream( "messages_" + Locale.getDefault().getLanguage()
+ ".properties" );
if ( is != null ) {
// override default messages
Properties overrideProps = new Properties();
overrideProps.load( is );
is.close();
props = propertyMap.get( Locale.getDefault().getLanguage() );
if ( props != null ) {
Iterator<?> iter = overrideProps.keySet().iterator();
while ( iter.hasNext() ) {
String key = (String) iter.next();
props.put( key, overrideProps.get( key ) );
}
} else {
propertyMap.put( Locale.getDefault().getLanguage(), overrideProps );
}
}
}
for ( int i = 0; i < locales.length; i++ ) {
Messages.overrideMessages( locales[i].getLanguage() );
}
overrideMessages();
} catch ( IOException e ) {
BootLogger.logError( "Error while initializing " + Messages.class.getName() + " : " + e.getMessage(), e );
}
}
/**
* overrides messages from a properties file read from URl defined in System properties -Dmessages
*/
private static void overrideMessages() {
String m = System.getProperty( "messages" );
if ( m != null ) {
try {
URL url = new URL( m );
InputStream is = url.openStream();
// override default messages
Properties overrideProps = new Properties();
overrideProps.load( is );
is.close();
Collection<Properties> pp = propertyMap.values();
for ( Properties properties : pp ) {
Iterator<?> iter = overrideProps.keySet().iterator();
while ( iter.hasNext() ) {
String key = (String) iter.next();
properties.put( key, overrideProps.get( key ) );
}
}
} catch ( Exception e ) {
BootLogger.logError( e.getMessage(), e );
}
}
}
private static void overrideMessages( String lang )
throws IOException {
InputStream is = Messages.class.getResourceAsStream( "/messages_" + lang + ".properties" );
if ( is != null ) {
// override default messages
Properties overrideProps = new Properties();
overrideProps.load( is );
is.close();
Properties props = propertyMap.get( lang );
if ( props != null ) {
Iterator<?> iter = overrideProps.keySet().iterator();
while ( iter.hasNext() ) {
String key = (String) iter.next();
props.put( key, overrideProps.get( key ) );
}
} else {
propertyMap.put( lang, overrideProps );
}
}
}
/**
* Returns the message assigned to the passed key. If no message is assigned, an error message will be returned that
* indicates the missing key. First the method tries to access messages in the local language if no messages
* available for this language english messages will be used as default
*
* @see MessageFormat for conventions on string formatting and escape characters.
*
* @param key
* @param arguments
* @return the message assigned to the passed key
* @deprecated use
* @see #getMessage(Locale, String, Object[] ) instead
*/
@Deprecated
public static String getMessage( String key, Object... arguments ) {
Properties props = propertyMap.get( Locale.getDefault().getLanguage() );
if ( props == null ) {
props = propertyMap.get( "en" );
}
String s = props.getProperty( key );
if ( s == null ) {
props = propertyMap.get( "en" );
s = props.getProperty( key );
}
if ( s != null ) {
return MessageFormat.format( s, arguments );
}
// to avoid NPEs
return "$Message with key: " + key + " not found$";
}
/**
* same as
*
* @see #getMessage(String, Object[] ) just passing desired language. If no messages are defined for passed language
* 'en' will be used as default.
* @param locale
* @param key
* @param arguments
* @return message assigned to the passed key
*/
public static String getMessage( Locale locale, String key, Object... arguments ) {
Properties props = propertyMap.get( locale.getLanguage() );
if ( props == null ) {
props = propertyMap.get( "en" );
}
String s = props.getProperty( key );
if ( s == null ) {
props = propertyMap.get( "en" );
s = props.getProperty( key );
}
if ( s != null ) {
return MessageFormat.format( s, arguments );
}
// to avoid NPEs
return "$Message with key: " + key + " not found$";
}
/**
* Convenience method with a shorter name. Uses Locale.getDefault as locale.
*
* @param key
* @param arguments
* @return the message
* @see #getMessage(Locale, String, Object[])
*/
public static String get( String key, Object... arguments ) {
return getMessage( getDefault(), key, arguments );
}
}