/* ResourceBundle -- aids in loading resource bundles
   Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006
   Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.util;

import gnu.classpath.VMStackWalker;

import gnu.java.lang.CPStringBuilder;

import java.io.IOException;
import java.io.InputStream;

/**
 * A resource bundle contains locale-specific data. If you need localized
 * data, you can load a resource bundle that matches the locale with
 * <code>getBundle</code>. Now you can get your object by calling
 * <code>getObject</code> or <code>getString</code> on that bundle.
 *
 * <p>When a bundle is demanded for a specific locale, the ResourceBundle
 * is searched in following order (<i>def. language</i> stands for the
 * two letter ISO language code of the default locale (see
 * <code>Locale.getDefault()</code>).
 *
<pre>baseName_<i>language code</i>_<i>country code</i>_<i>variant</i>
baseName_<i>language code</i>_<i>country code</i>
baseName_<i>language code</i>
baseName_<i>def. language</i>_<i>def. country</i>_<i>def. variant</i>
baseName_<i>def. language</i>_<i>def. country</i>
baseName_<i>def. language</i>
baseName</pre>
 *
 * <p>A bundle is backed up by less specific bundles (omitting variant, country
 * or language). But it is not backed up by the default language locale.
 *
 * <p>If you provide a bundle for a given locale, say
 * <code>Bundle_en_UK_POSIX</code>, you must also provide a bundle for
 * all sub locales, ie. <code>Bundle_en_UK</code>, <code>Bundle_en</code>, and
 * <code>Bundle</code>.
 *
 * <p>When a bundle is searched, we look first for a class with the given
 * name, then for a file with <code>.properties</code> extension in the
 * classpath. The name must be a fully qualified classname (with dots as
 * path separators).
 *
 * <p>(Note: This implementation always backs up the class with a properties
 * file if that is existing, but you shouldn't rely on this, if you want to
 * be compatible to the standard JDK.)
 *
 * @author Jochen Hoenicke
 * @author Eric Blake (ebb9@email.byu.edu)
 * @see Locale
 * @see ListResourceBundle
 * @see PropertyResourceBundle
 * @since 1.1
 * @status updated to 1.4
 */
public abstract class ResourceBundle
{
  /**
   * Maximum size of our cache of <code>ResourceBundle</code>s keyed by
   * {@link BundleKey} instances.
   *
   * @see BundleKey
   */
  private static final int CACHE_SIZE = 100;

  /**
   * The parent bundle. This is consulted when you call getObject and there
   * is no such resource in the current bundle. This field may be null.
   */
  protected ResourceBundle parent;

  /**
   * The locale of this resource bundle. You can read this with
   * <code>getLocale</code> and it is automatically set in
   * <code>getBundle</code>.
   */
  private Locale locale;

  /**
   * A VM-wide cache of resource bundles already fetched.
   * <p>
   * This {@link Map} is a Least Recently Used (LRU) cache, of the last
   * {@link #CACHE_SIZE} accessed <code>ResourceBundle</code>s keyed by the
   * tuple: default locale, resource-bundle name, resource-bundle locale, and
   * classloader.
   *
   * @see BundleKey
   */
  private static Map<BundleKey,Object> bundleCache =
    new LinkedHashMap<BundleKey,Object>(CACHE_SIZE + 1, 0.75F, true)
  {
    public boolean removeEldestEntry(Map.Entry<BundleKey,Object> entry)
    {
      return size() > CACHE_SIZE;
    }
  };

  /**
   * The constructor. It does nothing special.
   */
  public ResourceBundle()
  {
  }

  /**
   * Get a String from this resource bundle. Since most localized Objects
   * are Strings, this method provides a convenient way to get them without
   * casting.
   *
   * @param key the name of the resource
   * @throws MissingResourceException if the resource can't be found
   * @throws NullPointerException if key is null
   * @throws ClassCastException if resource is not a string
   */
  public final String getString(String key)
  {
    return (String) getObject(key);
  }

  /**
   * Get an array of Strings from this resource bundle. This method
   * provides a convenient way to get it without casting.
   *
   * @param key the name of the resource
   * @throws MissingResourceException if the resource can't be found
   * @throws NullPointerException if key is null
   * @throws ClassCastException if resource is not a string
   */
  public final String[] getStringArray(String key)
  {
    return (String[]) getObject(key);
  }

  /**
   * Get an object from this resource bundle. This will call
   * <code>handleGetObject</code> for this resource and all of its parents,
   * until it finds a non-null resource.
   *
   * @param key the name of the resource
   * @throws MissingResourceException if the resource can't be found
   * @throws NullPointerException if key is null
   */
  public final Object getObject(String key)
  {
    for (ResourceBundle bundle = this; bundle != null; bundle = bundle.parent)
      {
        Object o = bundle.handleGetObject(key);
        if (o != null)
          return o;
      }

    String className = getClass().getName();
    throw new MissingResourceException("Key '" + key
                                       + "'not found in Bundle: "
                                       + className, className, key);
  }

  /**
   * Return the actual locale of this bundle. You can use it after calling
   * getBundle, to know if the bundle for the desired locale was loaded or
   * if the fall back was used.
   *
   * @return the bundle's locale
   */
  public Locale getLocale()
  {
    return locale;
  }

  /**
   * Set the parent of this bundle. The parent is consulted when you call
   * getObject and there is no such resource in the current bundle.
   *
   * @param parent the parent of this bundle
   */
  protected void setParent(ResourceBundle parent)
  {
    this.parent = parent;
  }

  /**
   * Get the appropriate ResourceBundle for the default locale. This is like
   * calling <code>getBundle(baseName, Locale.getDefault(),
   * getClass().getClassLoader()</code>, except that any security check of
   * getClassLoader won't fail.
   *
   * @param baseName the name of the ResourceBundle
   * @return the desired resource bundle
   * @throws MissingResourceException if the resource bundle can't be found
   * @throws NullPointerException if baseName is null
   */
  public static ResourceBundle getBundle(String baseName)
  {
    ClassLoader cl = VMStackWalker.getCallingClassLoader();
    if (cl == null)
      cl = ClassLoader.getSystemClassLoader();
    return getBundle(baseName, Locale.getDefault(), cl);
  }

  /**
   * Get the appropriate ResourceBundle for the given locale. This is like
   * calling <code>getBundle(baseName, locale,
   * getClass().getClassLoader()</code>, except that any security check of
   * getClassLoader won't fail.
   *
   * @param baseName the name of the ResourceBundle
   * @param locale A locale
   * @return the desired resource bundle
   * @throws MissingResourceException if the resource bundle can't be found
   * @throws NullPointerException if baseName or locale is null
   */
  public static ResourceBundle getBundle(String baseName, Locale locale)
  {
    ClassLoader cl = VMStackWalker.getCallingClassLoader();
    if (cl == null)
      cl = ClassLoader.getSystemClassLoader();
    return getBundle(baseName, locale, cl);
  }

  /** Cache key for the ResourceBundle cache.  Resource bundles are keyed
      by the combination of bundle name, locale, and class loader. */
  private static class BundleKey
  {
    Locale defaultLocale;
    String baseName;
    Locale locale;
    ClassLoader classLoader;
    int hashcode;

    BundleKey() {}

    BundleKey(Locale dl, String s, Locale l, ClassLoader cl)
    {
      set(dl, s, l, cl);
    }

    void set(Locale dl, String s, Locale l, ClassLoader cl)
    {
      defaultLocale = dl;
      baseName = s;
      locale = l;
      classLoader = cl;
      hashcode = defaultLocale.hashCode() ^ baseName.hashCode()
          ^ locale.hashCode() ^ classLoader.hashCode();
    }

    public int hashCode()
    {
      return hashcode;
    }

    public boolean equals(Object o)
    {
      if (! (o instanceof BundleKey))
        return false;
      BundleKey key = (BundleKey) o;
      return hashcode == key.hashcode
          && defaultLocale.equals(key.defaultLocale)
          && baseName.equals(key.baseName)
          && locale.equals(key.locale)
          && classLoader.equals(key.classLoader);
    }

    public String toString()
    {
      CPStringBuilder builder = new CPStringBuilder(getClass().getName());
      builder.append("[defaultLocale=");
      builder.append(defaultLocale);
      builder.append(",baseName=");
      builder.append(baseName);
      builder.append(",locale=");
      builder.append(locale);
      builder.append(",classLoader=");
      builder.append(classLoader);
      builder.append("]");
      return builder.toString();
    }
  }

  /** A cache lookup key. This avoids having to a new one for every
   *  getBundle() call. */
  private static final BundleKey lookupKey = new BundleKey();

  /** Singleton cache entry to represent previous failed lookups. */
  private static final Object nullEntry = new Object();

  /**
   * Get the appropriate ResourceBundle for the given locale. The following
   * strategy is used:
   *
   * <p>A sequence of candidate bundle names are generated, and tested in
   * this order, where the suffix 1 means the string from the specified
   * locale, and the suffix 2 means the string from the default locale:</p>
   *
   * <ul>
   * <li>baseName + "_" + language1 + "_" + country1 + "_" + variant1</li>
   * <li>baseName + "_" + language1 + "_" + country1</li>
   * <li>baseName + "_" + language1</li>
   * <li>baseName + "_" + language2 + "_" + country2 + "_" + variant2</li>
   * <li>baseName + "_" + language2 + "_" + country2</li>
   * <li>baseName + "_" + language2</li>
   * <li>baseName</li>
   * </ul>
   *
   * <p>In the sequence, entries with an empty string are ignored. Next,
   * <code>getBundle</code> tries to instantiate the resource bundle:</p>
   *
   * <ul>
   * <li>First, an attempt is made to load a class in the specified classloader
   * which is a subclass of ResourceBundle, and which has a public constructor
   * with no arguments, via reflection.</li>
   * <li>Next, a search is made for a property resource file, by replacing
   * '.' with '/' and appending ".properties", and using
   * ClassLoader.getResource(). If a file is found, then a
   * PropertyResourceBundle is created from the file's contents.</li>
   * </ul>
   * If no resource bundle was found, a MissingResourceException is thrown.
   *
   * <p>Next, the parent chain is implemented. The remaining candidate names
   * in the above sequence are tested in a similar manner, and if any results
   * in a resource bundle, it is assigned as the parent of the first bundle
   * using the <code>setParent</code> method (unless the first bundle already
   * has a parent).</p>
   *
   * <p>For example, suppose the following class and property files are
   * provided: MyResources.class, MyResources_fr_CH.properties,
   * MyResources_fr_CH.class, MyResources_fr.properties,
   * MyResources_en.properties, and MyResources_es_ES.class. The contents of
   * all files are valid (that is, public non-abstract subclasses of
   * ResourceBundle with public nullary constructors for the ".class" files,
   * syntactically correct ".properties" files). The default locale is
   * Locale("en", "UK").</p>
   *
   * <p>Calling getBundle with the shown locale argument values instantiates
   * resource bundles from the following sources:</p>
   *
   * <ul>
   * <li>Locale("fr", "CH"): result MyResources_fr_CH.class, parent
   *   MyResources_fr.properties, parent MyResources.class</li>
   * <li>Locale("fr", "FR"): result MyResources_fr.properties, parent
   *   MyResources.class</li>
   * <li>Locale("de", "DE"): result MyResources_en.properties, parent
   *   MyResources.class</li>
   * <li>Locale("en", "US"): result MyResources_en.properties, parent
   *   MyResources.class</li>
   * <li>Locale("es", "ES"): result MyResources_es_ES.class, parent
   *   MyResources.class</li>
   * </ul>
   *
   * <p>The file MyResources_fr_CH.properties is never used because it is hidden
   * by MyResources_fr_CH.class.</p>
   *
   * @param baseName the name of the ResourceBundle
   * @param locale A locale
   * @param classLoader a ClassLoader
   * @return the desired resource bundle
   * @throws MissingResourceException if the resource bundle can't be found
   * @throws NullPointerException if any argument is null
   * @since 1.2
   */
  // This method is synchronized so that the cache is properly
  // handled.
  public static synchronized ResourceBundle getBundle
    (String baseName, Locale locale, ClassLoader classLoader)
  {
    Locale defaultLocale = Locale.getDefault();
    // This will throw NullPointerException if any arguments are null.
    lookupKey.set(defaultLocale, baseName, locale, classLoader);
    Object obj = bundleCache.get(lookupKey);
    if (obj instanceof ResourceBundle)
      return (ResourceBundle) obj;

    if (obj == nullEntry)
      throw new MissingResourceException("Bundle " + baseName
                                         + " not found for locale " + locale
                                         + " by classloader " + classLoader,
                                         baseName, "");
    // First, look for a bundle for the specified locale. We don't want
    // the base bundle this time.
    boolean wantBase = locale.equals(defaultLocale);
    ResourceBundle bundle = tryBundle(baseName, locale, classLoader, wantBase);
    // Try the default locale if neccessary.
    if (bundle == null && ! wantBase)
      bundle = tryBundle(baseName, defaultLocale, classLoader, true);

    BundleKey key = new BundleKey(defaultLocale, baseName, locale, classLoader);
    if (bundle == null)
      {
        // Cache the fact that this lookup has previously failed.
        bundleCache.put(key, nullEntry);
        throw new MissingResourceException("Bundle " + baseName
                                           + " not found for locale " + locale
                                           + " by classloader " + classLoader,
                                           baseName, "");
      }
    // Cache the result and return it.
    bundleCache.put(key, bundle);
    return bundle;
  }

  /**
   * Override this method to provide the resource for a keys. This gets
   * called by <code>getObject</code>. If you don't have a resource
   * for the given key, you should return null instead throwing a
   * MissingResourceException. You don't have to ask the parent, getObject()
   * already does this; nor should you throw a MissingResourceException.
   *
   * @param key the key of the resource
   * @return the resource for the key, or null if not in bundle
   * @throws NullPointerException if key is null
   */
  protected abstract Object handleGetObject(String key);

  /**
   * This method should return all keys for which a resource exists; you
   * should include the enumeration of any parent's keys, after filtering out
   * duplicates.
   *
   * @return an enumeration of the keys
   */
  public abstract Enumeration<String> getKeys();

  /**
   * Tries to load a class or a property file with the specified name.
   *
   * @param localizedName the name
   * @param classloader the classloader
   * @return the resource bundle if it was loaded, otherwise the backup
   */
  private static ResourceBundle tryBundle(String localizedName,
                                          ClassLoader classloader)
  {
    ResourceBundle bundle = null;
    try
      {
        Class<?> rbClass;
        if (classloader == null)
          rbClass = Class.forName(localizedName);
        else
          rbClass = classloader.loadClass(localizedName);
        // Note that we do the check up front instead of catching
        // ClassCastException.  The reason for this is that some crazy
        // programs (Eclipse) have classes that do not extend
        // ResourceBundle but that have the same name as a property
        // bundle; in fact Eclipse relies on ResourceBundle not
        // instantiating these classes.
        if (ResourceBundle.class.isAssignableFrom(rbClass))
          bundle = (ResourceBundle) rbClass.newInstance();
      }
    catch (Exception ex) {}

    if (bundle == null)
      {
        try
          {
            InputStream is;
            String resourceName
              = localizedName.replace('.', '/') + ".properties";
            if (classloader == null)
              is = ClassLoader.getSystemResourceAsStream(resourceName);
            else
              is = classloader.getResourceAsStream(resourceName);
            if (is != null)
              bundle = new PropertyResourceBundle(is);
          }
        catch (IOException ex)
          {
            MissingResourceException mre = new MissingResourceException
              ("Failed to load bundle: " + localizedName, localizedName, "");
            mre.initCause(ex);
            throw mre;
          }
      }

    return bundle;
  }

  /**
   * Tries to load the bundle for a given locale, also loads the backup
   * locales with the same language.
   *
   * @param baseName the raw bundle name, without locale qualifiers
   * @param locale the locale
   * @param classLoader the classloader
   * @param wantBase whether a resource bundle made only from the base name
   *        (with no locale information attached) should be returned.
   * @return the resource bundle if it was loaded, otherwise the backup
   */
  private static ResourceBundle tryBundle(String baseName, Locale locale,
                                          ClassLoader classLoader,
                                          boolean wantBase)
  {
    String language = locale.getLanguage();
    String country = locale.getCountry();
    String variant = locale.getVariant();

    int baseLen = baseName.length();

    // Build up a CPStringBuilder containing the complete bundle name, fully
    // qualified by locale.
    CPStringBuilder sb = new CPStringBuilder(baseLen + variant.length() + 7);

    sb.append(baseName);

    if (language.length() > 0)
      {
        sb.append('_');
        sb.append(language);

        if (country.length() > 0)
          {
            sb.append('_');
            sb.append(country);

            if (variant.length() > 0)
              {
                sb.append('_');
                sb.append(variant);
              }
          }
      }

    // Now try to load bundles, starting with the most specialized name.
    // Build up the parent chain as we go.
    String bundleName = sb.toString();
    ResourceBundle first = null; // The most specialized bundle.
    ResourceBundle last = null; // The least specialized bundle.

    while (true)
      {
        ResourceBundle foundBundle = tryBundle(bundleName, classLoader);
        if (foundBundle != null)
          {
            if (first == null)
              first = foundBundle;
            if (last != null)
              last.parent = foundBundle;
            foundBundle.locale = locale;
            last = foundBundle;
          }
        int idx = bundleName.lastIndexOf('_');
        // Try the non-localized base name only if we already have a
        // localized child bundle, or wantBase is true.
        if (idx > baseLen || (idx == baseLen && (first != null || wantBase)))
          bundleName = bundleName.substring(0, idx);
        else
          break;
      }

    return first;
  }

  /**
   * Remove all resources from the cache that were loaded
   * using the class loader of the calling class.
   *
   * @since 1.6
   */
  public static final void clearCache()
  {
    clearCache(VMStackWalker.getCallingClassLoader());
  }

  /**
   * Remove all resources from the cache that were loaded
   * using the specified class loader.
   *
   * @param loader the loader used for the bundles that will be removed.
   * @throws NullPointerException if {@code loader} is {@code null}.
   * @since 1.6
   */
  public static final void clearCache(ClassLoader loader)
  {
    if (loader == null)
      throw new NullPointerException("The loader can not be null.");
    synchronized (ResourceBundle.class)
      {
        Iterator<BundleKey> iter = bundleCache.keySet().iterator();
        while (iter.hasNext())
          {
            BundleKey key = iter.next();
            if (key.classLoader == loader)
              iter.remove();
          }
      }
  }

}
