/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id: Messages.java 468654 2006-10-28 07:09:23Z minchau $
 */
package org.apache.xml.serializer.utils;

import java.util.ListResourceBundle;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

/**
 * A utility class for issuing error messages.
 * 
 * A user of this class normally would create a singleton 
 * instance of this class, passing the name
 * of the message class on the constructor. For example:
 * <CODE>
 * static Messages x = new Messages("org.package.MyMessages");
 * </CODE>
 * Later the message is typically generated this way if there are no 
 * substitution arguments:
 * <CODE>
 * String msg = x.createMessage(org.package.MyMessages.KEY_ONE, null); 
 * </CODE>
 * If there are arguments substitutions then something like this:
 * <CODE>
 * String filename = ...;
 * String directory = ...;
 * String msg = x.createMessage(org.package.MyMessages.KEY_TWO, 
 *   new Object[] {filename, directory) ); 
 * </CODE>
 *  
 * The constructor of an instance of this class must be given
 * the class name of a class that extends java.util.ListResourceBundle 
 * ("org.package.MyMessages" in the example above).  
 * The name should not have any language suffix 
 * which will be added automatically by this utility class.
 * 
 * The message class ("org.package.MyMessages")
 * must define the abstract method getContents() that is
 * declared in its base class, for example:
 * <CODE>
 * public Object[][] getContents() {return contents;}
 * </CODE>
 * 
 * It is suggested that the message class expose its
 * message keys like this:
 * <CODE>
 *   public static final String KEY_ONE = "KEY1";
 *   public static final String KEY_TWO = "KEY2";
 *   . . . 
 * </CODE>
 * and used through their names (KEY_ONE ...) rather than
 * their values ("KEY1" ...).
 * 
 * The field contents (returned by getContents()
 * should be initialized something like this:
 * <CODE>
 * public static final Object[][] contents = {
 * { KEY_ONE, "Something has gone wrong!" },
 * { KEY_TWO, "The file ''{0}'' does not exist in directory ''{1}''." },
 * . . .
 * { KEY_N, "Message N" }  }
 * </CODE>
 * 
 * Where that section of code with the KEY to Message mappings
 * (where the message classes 'contents' field is initialized)
 * can have the Message strings translated in an alternate language
 * in a errorResourceClass with a language suffix.
 * 
 * More sophisticated use of this class would be to pass null
 * when contructing it, but then call loadResourceBundle()
 * before creating any messages.
 * 
 * This class is not a public API, it is only public because it is 
 * used in org.apache.xml.serializer.
 *
 *  @xsl.usage internal
 */
public final class Messages
{
    /** The local object to use.  */
    private final Locale m_locale = Locale.getDefault();

    /** The language specific resource object for messages.  */
    private ListResourceBundle m_resourceBundle;

    /** The class name of the error message string table with no language suffix. */
    private String m_resourceBundleName;



    /**
     * Constructor.
     * @param resourceBundle the class name of the ListResourceBundle
     * that the instance of this class is associated with and will use when
     * creating messages.
     * The class name is without a language suffix. If the value passed
     * is null then loadResourceBundle(errorResourceClass) needs to be called
     * explicitly before any messages are created.
     * 
     * @xsl.usage internal
     */
    Messages(String resourceBundle)
    {

        m_resourceBundleName = resourceBundle;
    }
    
    /*
     * Set the Locale object to use. If this method is not called the
     * default locale is used. This method needs to be called before
     * loadResourceBundle().
     * 
     * @param locale non-null reference to Locale object.
     * @xsl.usage internal
     */
//    public void setLocale(Locale locale)
//    {
//        m_locale = locale;
//    }

    /**
     * Get the Locale object that is being used.
     * 
     * @return non-null reference to Locale object.
     * @xsl.usage internal
     */
    private Locale getLocale()
    {
        return m_locale;
    }

    /**
     * Get the ListResourceBundle being used by this Messages instance which was
     * previously set by a call to loadResourceBundle(className)
     * @xsl.usage internal
     */
    private ListResourceBundle getResourceBundle()
    {
        return m_resourceBundle;
    }

    /**
     * Creates a message from the specified key and replacement
     * arguments, localized to the given locale.
     *
     * @param msgKey  The key for the message text.
     * @param args    The arguments to be used as replacement text
     * in the message created.
     *
     * @return The formatted message string.
     * @xsl.usage internal
     */
    public final String createMessage(String msgKey, Object args[])
    {
        if (m_resourceBundle == null)
            m_resourceBundle = loadResourceBundle(m_resourceBundleName);

        if (m_resourceBundle != null)
        {
            return createMsg(m_resourceBundle, msgKey, args);
        }
        else
            return "Could not load the resource bundles: "+ m_resourceBundleName;
    }

    /**
     * Creates a message from the specified key and replacement
     * arguments, localized to the given locale.
     *
     * @param errorCode The key for the message text.
     *
     * @param fResourceBundle The resource bundle to use.
     * @param msgKey  The message key to use.
     * @param args      The arguments to be used as replacement text
     *                  in the message created.
     *
     * @return The formatted message string.
     * @xsl.usage internal
     */
    private final String createMsg(
        ListResourceBundle fResourceBundle,
        String msgKey,
        Object args[]) //throws Exception
    {

        String fmsg = null;
        boolean throwex = false;
        String msg = null;

        if (msgKey != null)
            msg = fResourceBundle.getString(msgKey);
        else
            msgKey = "";

        if (msg == null)
        {
            throwex = true;
            /* The message is not in the bundle . . . this is bad,
             * so try to get the message that the message is not in the bundle
             */
            try
            {

                msg =
                    java.text.MessageFormat.format(
                        MsgKey.BAD_MSGKEY,
                        new Object[] { msgKey, m_resourceBundleName });
            }
            catch (Exception e)
            {
                /* even the message that the message is not in the bundle is
                 * not there ... this is really bad
                 */
                msg =
                    "The message key '"
                        + msgKey
                        + "' is not in the message class '"
                        + m_resourceBundleName+"'";
            }
        }
        else if (args != null)
        {
            try
            {
                // Do this to keep format from crying.
                // This is better than making a bunch of conditional
                // code all over the place.
                int n = args.length;

                for (int i = 0; i < n; i++)
                {
                    if (null == args[i])
                        args[i] = "";
                }

                fmsg = java.text.MessageFormat.format(msg, args);
                // if we get past the line above we have create the message ... hurray!
            }
            catch (Exception e)
            {
                throwex = true;
                try
                {
                    // Get the message that the format failed.
                    fmsg =
                        java.text.MessageFormat.format(
                            MsgKey.BAD_MSGFORMAT,
                            new Object[] { msgKey, m_resourceBundleName });
                    fmsg += " " + msg;
                }
                catch (Exception formatfailed)
                {
                    // We couldn't even get the message that the format of
                    // the message failed ... so fall back to English.
                    fmsg =
                        "The format of message '"
                            + msgKey
                            + "' in message class '"
                            + m_resourceBundleName
                            + "' failed.";
                }
            }
        }
        else
            fmsg = msg;

        if (throwex)
        {
            throw new RuntimeException(fmsg);
        }

        return fmsg;
    }

    /**
     * Return a named ResourceBundle for a particular locale.  This method mimics the behavior
     * of ResourceBundle.getBundle().
     * 
     * @param className the name of the class that implements ListResourceBundle,
     * without language suffix.
     * @return the ResourceBundle
     * @throws MissingResourceException
     * @xsl.usage internal
     */
    private ListResourceBundle loadResourceBundle(String resourceBundle)
        throws MissingResourceException
    {
        m_resourceBundleName = resourceBundle;
        Locale locale = getLocale();

        ListResourceBundle lrb;

        try
        {

            ResourceBundle rb =
                ResourceBundle.getBundle(m_resourceBundleName, locale);
            lrb = (ListResourceBundle) rb;
        }
        catch (MissingResourceException e)
        {
            try // try to fall back to en_US if we can't load
                {

                // Since we can't find the localized property file,
                // fall back to en_US.
                lrb =
                    (ListResourceBundle) ResourceBundle.getBundle(
                        m_resourceBundleName,
                        new Locale("en", "US"));
            }
            catch (MissingResourceException e2)
            {

                // Now we are really in trouble.
                // very bad, definitely very bad...not going to get very far
                throw new MissingResourceException(
                    "Could not load any resource bundles." + m_resourceBundleName,
                    m_resourceBundleName,
                    "");
            }
        }
        m_resourceBundle = lrb;
        return lrb;
    }

    /**
     * Return the resource file suffic for the indicated locale
     * For most locales, this will be based the language code.  However
     * for Chinese, we do distinguish between Taiwan and PRC
     *
     * @param locale the locale
     * @return an String suffix which can be appended to a resource name
     * @xsl.usage internal
     */
    private static String getResourceSuffix(Locale locale)
    {

        String suffix = "_" + locale.getLanguage();
        String country = locale.getCountry();

        if (country.equals("TW"))
            suffix += "_" + country;

        return suffix;
    }
}
