    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_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: 26674 $, $Date: 2010-09-10 12:58:42 +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    }