001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_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.HashMap;
042    import java.util.Iterator;
043    import java.util.Locale;
044    import java.util.Map;
045    import java.util.Properties;
046    
047    import org.deegree.framework.log.ILogger;
048    import org.deegree.framework.log.LoggerFactory;
049    import org.deegree.framework.util.BootLogger;
050    
051    /**
052     * Responsible for the access to messages that are visible to the user.
053     * <p>
054     * Messages are read from the properties file <code>messages_LANG.properties</code> (LANG is
055     * always a lowercased ISO 639 code), so internationalization is supported. If a certain property
056     * (or the property file) for the specific default language of the system is not found, the message
057     * 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: mschneider $
065     *
066     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
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            String s = get( props.get( loc ), key, arguments );
184            return s;
185        }
186    
187        /**
188         * Alias for #getMessage.
189         *
190         * @param key
191         * @param arguments
192         * @return the message
193         */
194        public static String get( String key, Object... arguments ) {
195            return getMessage( key, arguments );
196        }
197    
198        /**
199         * Returns the message assigned to the passed key. If no message is assigned, an error message
200         * will be returned that indicates the missing key.
201         *
202         * @see MessageFormat for conventions on string formatting and escape characters.
203         *
204         * @param key
205         * @param arguments
206         * @return the message assigned to the passed key
207         */
208        public static String getMessage( String key, Object... arguments ) {
209            return get( defaultProps, key, arguments );
210        }
211    }