/*
 * $Id$ 
 *
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:  
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Crimson" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, Sun Microsystems, Inc., 
 * http://www.sun.com.  For more information on the Apache Software 
 * Foundation, please see <http://www.apache.org/>.
 */

package org.apache.xerces.tree;

import java.io.InputStream;
import java.text.FieldPosition;
import java.text.MessageFormat;
import java.util.Hashtable;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;


/**
 * This class provides support for multi-language string lookup, as needed
 * to localize messages from applications supporting multiple languages
 * at the same time.  One class of such applications is network services,
 * such as HTTP servers, which talk to clients who may not be from the
 * same locale as the server.  This class supports a form of negotiation
 * for the language used in presenting a message from some package, where
 * both user (client) preferences and application (server) support are
 * accounted for when choosing locales and formatting messages.
 *
 * <P> Each package should have a singleton package-private message catalog
 * class.  This ensures that the correct class loader will always be used to
 * access message resources, and minimizes use of memory: <PRE>
 *    package <em>some.package</em>;
 *    
 *    // "foo" might be public
 *    class foo {
 *	  ...
 *        // package private
 *        static final Catalog messages = new Catalog ();
 *        static final class Catalog extends MessageCatalog {
 *            Catalog () { super (Catalog.class); }
 *	  }
 *	  ...
 *    }
 * </PRE>
 *
 * <P> Messages for a known client could be generated using code
 * something like this:  <PRE>
 *    String clientLanguages [];
 *    Locale clientLocale;
 *    String clientMessage;
 *
 *    // client languages will probably be provided by client,
 *    // e.g. by an HTTP/1.1 "Accept-Language" header.
 *    clientLanguages = new String [] { "en-ca", "fr-ca", "ja", "zh" };
 *    clientLocale = foo.messages.chooseLocale (clientLanguages);
 *    clientMessage = foo.messages.getMessage (clientLocale,
 *        "fileCount",
 *	  new Object [] { new Integer (numberOfFiles) }
 *        );
 * </PRE>
 *
 * <P> At this time, this class does not include functionality permitting
 * messages to be passed around and localized after-the-fact.  The consequence
 * of this is that the locale for messages must be passed down through layers
 * which have no normal reason to support such passdown, or else the system
 * default locale must be used instead of the one the client needs.
 *
 * <P> <hr> The following guidelines should be used when constructiong
 * multi-language applications:  <OL>
 *
 *	<LI> Always use <a href=#chooseLocale>chooseLocale</a> to select the
 *	locale you pass to your <code>getMessage</code> call.  This lets your
 *	applications use IETF standard locale names, and avoids needless
 *	use of system defaults.
 *
 *	<LI> The localized messages for a given package should always go in
 *	a separate <em>resources</em> sub-package.  There are security
 *	implications; see below.
 *
 *	<LI> Make sure that a language name is included in each bundle name,
 *	so that the developer's locale will not be inadvertently used. That
 *	is, don't create defaults like <em>resources/Messages.properties</em>
 *	or <em>resources/Messages.class</em>, since ResourceBundle will choose
 *	such defaults rather than giving software a chance to choose a more
 *	appropriate language for its messages.  Your message bundles should
 *	have names like <em>Messages_en.properties</em> (for the "en", or
 *	English, language) or <em>Messages_ja.class</em> ("ja" indicates the
 *	Japanese language).
 *
 *	<LI> Only use property files for messages in languages which can
 *	be limited to the ISO Latin/1 (8859-1) characters supported by the
 *	property file format.  (This is mostly Western European languages.)
 *	Otherwise, subclass ResourceBundle to provide your messages; it is
 *	simplest to subclass <code>java.util.ListResourceBundle</code>.
 *
 *	<LI> Never use another package's message catalog or resource bundles.
 *	It should not be possible for a change internal to one package (such
 *	as eliminating or improving messages) to break another package.
 *
 *	</OL>
 *	
 * <P> The "resources" sub-package can be treated separately from the
 * package with which it is associated.  That main package may be sealed
 * and possibly signed, preventing other software from adding classes to
 * the package which would be able to access methods and data which are
 * not designed to be publicly accessible.  On the other hand, resources
 * such as localized messages are often provided after initial product
 * shipment, without a full release cycle for the product.  Such files
 * (text and class files) need to be added to some package.  Since they
 * should not be added to the main package, the "resources" subpackage is
 * used without risking the security or integrity of that main package
 * as distributed in its JAR file.
 *
 * @see java.util.Locale
 * @see java.util.ListResourceBundle
 * @see java.text.MessageFormat
 *
 * @version 1.10
 * @author David Brownell
 */
// leave this as "abstract" -- each package needs its own subclass,
// else it's not always going to be using the right class loader.
abstract public class MessageCatalog {
    private String			bundleName;

    /**
     * Create a message catalog for use by classes in the same package
     * as the specified class.  This uses <em>Messages</em> resource
     * bundles in the <em>resources</em> sub-package of class passed as
     * a parameter. 
     *
     * @param packageMember Class whose package has localized messages
     */
    protected MessageCatalog (Class packageMember)
    {
	this (packageMember, "Messages");
    }

    /**
     * Create a message catalog for use by classes in the same package
     * as the specified class.  This uses the specified resource
     * bundle name in the <em>resources</em> sub-package of class passed
     * as a parameter; for example, <em>resources.Messages</em>.
     *
     * @param packageMember Class whose package has localized messages
     * @param bundle Name of a group of resource bundles
     */
    private MessageCatalog (Class packageMember, String bundle)
    {
	int	index;

	bundleName = packageMember.getName ();
	index = bundleName.lastIndexOf ('.');
	if (index == -1)	// "ClassName"
	    bundleName = "";
	else			// "some.package.ClassName"
	    bundleName = bundleName.substring (0, index) + ".";
	bundleName = bundleName + "resources." + bundle;
    }


    /**
     * Get a message localized to the specified locale, using the message ID
     * and package name if no message is available.  The locale is normally
     * that of the client of a service, chosen with knowledge that both the
     * client and this server support that locale.  There are two error
     * cases:  first, when the specified locale is unsupported or null, the
     * default locale is used if possible; second, when no bundle supports
     * that locale, the message ID and package name are used.
     *
     * @param locale The locale of the message to use.  If this is null,
     *	the default locale will be used.
     * @param messageId The ID of the message to use.
     * @return The message, localized as described above.
     */
    public String getMessage (
	Locale		locale,
	String		messageId
    ) {
	ResourceBundle	bundle;

	// cope with unsupported locale...
	if (locale == null)
	    locale = Locale.getDefault ();

	try {
	    bundle = ResourceBundle.getBundle (bundleName, locale);
	    return bundle.getString (messageId);
	} catch (MissingResourceException e) {
	    return packagePrefix (messageId);
	} 
    }

    private String packagePrefix (String messageId)
    {
	String	temp = getClass ().getName ();
	int	index = temp.lastIndexOf ('.');

	if (index == -1)	// "ClassName"
	    temp = "";
	else			// "some.package.ClassName"
	    temp = temp.substring (0, index);
	return temp + '/' + messageId;
    }


    /**
     * Format a message localized to the specified locale, using the message
     * ID with its package name if none is available.  The locale is normally
     * the client of a service, chosen with knowledge that both the client
     * server support that locale.  There are two error cases:  first, if the
     * specified locale is unsupported or null, the default locale is used if
     * possible; second, when no bundle supports that locale, the message ID
     * and package name are used.
     *
     * @see java.text.MessageFormat
     *
     * @param locale The locale of the message to use.  If this is null,
     *	the default locale will be used.
     * @param messageId The ID of the message format to use.
     * @param parameters Used when formatting the message.  Objects in
     *	this list are turned to strings if they are not Strings, Numbers,
     *	or Dates (that is, if MessageFormat would treat them as errors).
     * @return The message, localized as described above.
     */
    public String getMessage (
	Locale		locale,
	String		messageId,
	Object		parameters []
    ) {
	if (parameters == null)
	    return getMessage (locale, messageId);

	// since most messages won't be tested (sigh), be friendly to
	// the inevitable developer errors of passing random data types
	// to the message formatting code.
	for (int i = 0; i < parameters.length; i++) {
	    if  (!(parameters[i] instanceof String)
		    && !(parameters[i] instanceof Number)
		    && !(parameters[i] instanceof java.util.Date)) {
		if (parameters [i] == null)
		    parameters [i] = "(null)";
		else
		    parameters[i] = parameters[i].toString();
	    }
	}

	// similarly, cope with unsupported locale...
	if (locale == null)
	    locale = Locale.getDefault ();

	// get the appropriately localized MessageFormat object
	ResourceBundle	bundle;
	MessageFormat	format;

	try {
	    bundle = ResourceBundle.getBundle (bundleName, locale);
	    format = new MessageFormat (bundle.getString (messageId));
	} catch (MissingResourceException e) {
	    String retval;

	    retval = packagePrefix (messageId);
	    for (int i = 0; i < parameters.length; i++) {
		retval += ' ';
		retval += parameters [i];
	    }
	    return retval;
	} 
	format.setLocale (locale);

	// return the formatted message
	StringBuffer	result = new StringBuffer ();

	result = format.format (parameters, result, new FieldPosition (0));
	return result.toString ();
    }


    /**
     * Chooses a client locale to use, using the first language specified in
     * the list that is supported by this catalog.  If none of the specified
     * languages is supported, a null value is returned.  Such a list of
     * languages might be provided in an HTTP/1.1 "Accept-Language" header
     * field, or through some other content negotiation mechanism.
     *
     * <P> The language specifiers recognized are RFC 1766 style ("fr" for
     * all French, "fr-ca" for Canadian French), although only the strict
     * ISO subset (two letter language and country specifiers) is currently
     * supported.  Java-style locale strings ("fr_CA") are also supported.
     *
     * @see java.util.Locale
     *
     * @param languages Array of language specifiers, ordered with the most
     *	preferable one at the front.  For example, "en-ca" then "fr-ca",
     *  followed by "zh_CN".
     * @return The most preferable supported locale, or null.
     */
    public Locale chooseLocale (String languages [])
    {
	if ((languages = canonicalize (languages)) != null) {
	    for (int i = 0; i < languages.length; i++)
		if (isLocaleSupported (languages [i]))
		    return getLocale (languages [i]);
	}
	return null;
    }


    //
    // Canonicalizes the RFC 1766 style language strings ("en-in") to
    // match standard Java usage ("en_IN"), removing strings that don't
    // use two character ISO language and country codes.   Avoids all
    // memory allocations possible, so that if the strings passed in are
    // just lowercase ISO codes (a common case) the input is returned.
    //
    private String [] canonicalize (String languages [])
    {
	boolean		didClone = false;
	int		trimCount = 0;

	if (languages == null)
	    return languages;

	for (int i = 0; i < languages.length; i++) {
	    String	lang = languages [i];
	    int		len = lang.length ();

	    // no RFC1766 extensions allowed; "zh" and "zh-tw" (etc) are OK
	    // as are regular locale names with no variant ("de_CH").
	    if (!(len == 2 || len == 5)) {
		if (!didClone) {
		    languages = (String []) languages.clone ();
		    didClone = true;
		}
		languages [i] = null;
		trimCount++;
		continue;
	    }

	    // language code ... if already lowercase, we change nothing
	    if (len == 2) {
		lang = lang.toLowerCase ();
		if (lang != languages [i]) {
		    if (!didClone) {
			languages = (String []) languages.clone ();
			didClone = true;
		    }
		    languages [i] = lang;
		}
		continue;
	    }

	    // language_country ... fixup case, force "_"
	    char	buf [] = new char [5];

	    buf [0] = Character.toLowerCase (lang.charAt (0));
	    buf [1] = Character.toLowerCase (lang.charAt (1));
	    buf [2] = '_';
	    buf [3] = Character.toUpperCase (lang.charAt (3));
	    buf [4] = Character.toUpperCase (lang.charAt (4));
	    if (!didClone) {
		languages = (String []) languages.clone ();
		didClone = true;
	    }
	    languages [i] = new String (buf);
	}

	// purge any shadows of deleted RFC1766 extended language codes
	if (trimCount != 0) {
	    String	temp [] = new String [languages.length - trimCount];
	    int		i;

	    for (i = 0, trimCount = 0; i < temp.length; i++) {
		while (languages [i + trimCount] == null)
		    trimCount++;
		temp [i] = languages [i + trimCount];
	    }
	    languages = temp;
	}
	return languages;
    }


    //
    // Returns a locale object supporting the specified locale, using
    // a small cache to speed up some common languages and reduce the
    // needless allocation of memory.
    //
    private Locale getLocale (String localeName)
    {
	String		language, country;
	int		index;

	index = localeName.indexOf ('_');
	if (index == -1) {
	    //
	    // Special case the builtin JDK languages
	    //
	    if (localeName.equals ("de"))
		return Locale.GERMAN;
	    if (localeName.equals ("en"))
		return Locale.ENGLISH;
	    if (localeName.equals ("fr"))
		return Locale.FRENCH;
	    if (localeName.equals ("it"))
		return Locale.ITALIAN;
	    if (localeName.equals ("ja"))
		return Locale.JAPANESE;
	    if (localeName.equals ("ko"))
		return Locale.KOREAN;
	    if (localeName.equals ("zh"))
		return Locale.CHINESE;

	    language = localeName;
	    country = "";
	} else {
	    if (localeName.equals ("zh_CN"))
		return Locale.SIMPLIFIED_CHINESE;
	    if (localeName.equals ("zh_TW"))
		return Locale.TRADITIONAL_CHINESE;

	    //
	    // JDK also has constants for countries:  en_GB, en_US, en_CA,
	    // fr_FR, fr_CA, de_DE, ja_JP, ko_KR.  We don't use those.
	    //
	    language = localeName.substring (0, index);
	    country = localeName.substring (index + 1);
	}

	return new Locale (language, country);
    }


    //
    // cache for isLanguageSupported(), below ... key is a language
    // or locale name, value is a Boolean
    //
    private Hashtable		cache = new Hashtable (5);


    /**
     * Returns true iff the specified locale has explicit language support.
     * For example, the traditional Chinese locale "zh_TW" has such support
     * if there are message bundles suffixed with either "zh_TW" or "zh".
     *
     * <P> This method is used to bypass part of the search path mechanism
     * of the <code>ResourceBundle</code> class, specifically the parts which
     * force use of default locales and bundles.  Such bypassing is required
     * in order to enable use of a client's preferred languages.  Following
     * the above example, if a client prefers "zh_TW" but can also accept
     * "ja", this method would be used to detect that there are no "zh_TW"
     * resource bundles and hence that "ja" messages should be used.  This
     * bypasses the ResourceBundle mechanism which will return messages in
     * some other locale (picking some hard-to-anticipate default) instead
     * of reporting an error and letting the client choose another locale.
     *
     * @see java.util.Locale
     *
     * @param localeName A standard Java locale name, using two character
     *	language codes optionally suffixed by country codes.
     * @return True iff the language of that locale is supported.
     */
    public boolean isLocaleSupported (String localeName)
    {
	//
	// Use previous results if possible.  We expect that the codebase
	// is immutable, so we never worry about changing the cache.
	// 
	Boolean		value = (Boolean) cache.get (localeName);

	if (value != null)
	    return value.booleanValue ();

	//
	// Try "language_country_variant", then "language_country",
	// then finally "language" ... assuming the longest locale name
	// is passed.  If not, we'll try fewer options.
	//
	ClassLoader		loader = null;

	for (;;) {
	    String		name = bundleName + "_" + localeName;

	    // look up classes ...
	    try {
		Class.forName (name);
		cache.put (localeName, Boolean.TRUE);
		return true;
	    } catch (Exception e) {}

	    // ... then property files (only for ISO Latin/1 messages)
	    InputStream		in;

	    if (loader == null)
		loader = getClass ().getClassLoader ();

	    name = name.replace ('.', '/');
	    name = name + ".properties";
	    if (loader == null)
		in = ClassLoader.getSystemResourceAsStream (name);
	    else
		in = loader.getResourceAsStream (name);
	    if (in != null) {
		cache.put (localeName, Boolean.TRUE);
		return true;
	    }

	    int index = localeName.indexOf ('_');

	    if (index > 0)
		localeName = localeName.substring (0, index);
	    else
		break;
	}

	//
	// If we got this far, we failed.  Remember for later.
	//
	cache.put (localeName, Boolean.FALSE);
	return false;
    }
}
