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