/**
 * $Id: MultipleResourceBundleFactory.java 80125 2009-01-15 01:18:00Z aguther $
 *
 * Unpublished Work Copyright 2007 MarketTools, Inc. All Rights Reserved.
 *
 * Last changed by $Author: aguther $
 * Last changed at $Date: 2009-01-14 17:18:00 -0800 (Wed, 14 Jan 2009) $
 */
package com.markettools.platform.webutil;

import java.util.Hashtable;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.List;
import java.util.ArrayList;
import java.util.Enumeration;


/**
 * Responsible for loading and caching MultipleResourceBundle object for given list
 * of property names based on locale.
 *
 * @author  Leonard Gestrin (lgestrin)
 * @since   1.0, (Mar 27, 2008)
 */
public class MultipleResourceBundleFactory {



    /** Static hash table containing loaded bundles. */
    private Hashtable<Locale, MultipleResourceBundle> loadedBundles =
        new Hashtable<Locale, MultipleResourceBundle>();


    /**
     * Method setBaseNames sets the baseNames of this MultipleResourceBundleFactory
     * object.
     *
     * @param  baseNames  the baseNames of this MultipleResourceBundleFactory object.
     */
    public void setBaseNames(String[] baseNames) {
        this.baseNames = baseNames;
    }

    /** base names for the bundles. */
    private String[] baseNames;

    /**
     * @return  returns bundle for default locale.
     */
    public MultipleResourceBundle getBundle() {
        return getBundle(Locale.getDefault());
    }

    /**
     * @param   locale  .
     *
     * @return  MultipleResourceBundle mapped to locale, or nulll if not found.
     *
     * @throws  MissingResourceException  if bundle is not found.
     */
    synchronized public MultipleResourceBundle getBundle(Locale locale)
        throws MissingResourceException {

        if (loadedBundles.get(locale) == null) {

            MultipleResourceBundle bundle = new MultipleResourceBundle(baseNames,
                    locale);
            loadedBundles.put(locale, bundle);
        }

        return loadedBundles.get(locale);

    }


    /**
     * @return  string representation of bundle base names.
     */
    public String getBaseNamesAsString() {

        if (baseNames == null) {
            return "";
        }

        StringBuilder sb = new StringBuilder();

        for (String baseName : baseNames) {
            sb.append(baseName).append(".properties, ");
        }

        return sb.toString();
    }

    /**
 * Class represents ResourceBundle that encapsulates multiple resource bundles as
     * one.
     *
     * @author  Leonard Gestrin (lgestrin)
     * @since   1.0, (Mar 26, 2008)
     */
   class MultipleResourceBundle extends ResourceBundle {

        /** list of known bundles. */
        private List<ResourceBundle> bundles = new ArrayList<ResourceBundle>();


        /**
         * Initialize resource bundles.  Use the MultipleResourceBundleFactory.getBundle method to retrieve an instance.
         *
         * @param   bundleBaseNames  - list of bundle names.
         * @param   locale           - locale for which to load bundles.
         *
         * @throws  java.util.MissingResourceException  .
         */
         MultipleResourceBundle(String[] bundleBaseNames, Locale locale)
            throws MissingResourceException {

            for (String bundleBaseName : bundleBaseNames) {
                bundles.add(ResourceBundle.getBundle(bundleBaseName, locale));
            }

        }

        /**
         * Gets an object for the given key from this resource bundle. Returns null if
         * this resource bundle does not contain an object for the given key. if object
         * is found in multiple bundles, returns the first found one.
         *
         * @param   key  the key for the desired object
         *
         * @return  the object for the given key, or null
         *
         * @throws  NullPointerException  if <code>key</code> is <code>null</code>
         */
        protected Object handleGetObject(String key) {

            for (ResourceBundle resBundle : bundles) {

                try {

                    if (resBundle.getObject(key) != null) {
                        return resBundle.getObject(key);
                    }
                } catch (MissingResourceException mre) {
                    // suppress since need to iterrate through all bundles.
                }
            }

            // did not find.
            throw new MissingResourceException("failed to find resource for the key:"
                + key,
                this.getClass().toString(), key);
        }

        /**
         * @return  keys. in reality, throws exception.
         */
        public Enumeration<String> getKeys() {
            throw new UnsupportedOperationException(
                "not implemented - do we really need it?");

            // To change body of implemented methods use File | Settings | File
            // Templates.//return null;
        }
    }
}
