// ============================================================================
// File:               ResourceBundleCollection.java
//
// Project:            I18n
//
// Purpose:            Handle a collection of resource bundles to allow
//                     parts of an applictaion (e.g. beans) to maintain
//                     there own resource bundle but access all these bundles
//                     as an unit.
//
// Author:             Rammi
//-----------------------------------------------------------------------------
// Copyright Notice:   (c) 2002  Rammi (rammi@caff.de)
//                     This code is in the public domain.
//                     Use at own risk.
//                     No guarantees given.
//
// Latest change:      $Date$
//
// History:	       $Log$
//=============================================================================

package de.caff.i18n;

import java.util.*;

/**
 *  Handle a collection of resource bundles. This allows
 *  parts of an application (e.g. beans) to maintain
 *  their own resource bundle but access to all these bundles
 *  is handled as an unit.
 *  @author <a href="mailto:rammi@caff.de">Rammi</a>
 *  @version $Revision$
 */
public class ResourceBundleCollection
        extends ResourceBundle
{
  /** The collected resource bundles. */
  private Collection    resourceBundles = new LinkedList();
  /** The collected resources. */
  private Map resources       = new HashMap();

  /**
   *  Add an resource bundle.
   *  <em>If this bundle defines an already defined resource,
   *  the old resource will be overwritten!</em>
   *  @param  bundle   resource bundle to add
   */
  public void addResourceBundle(ResourceBundle bundle) {
    resourceBundles.add(bundle);
    addEntries(bundle);
  }

  /**
   *  Remove a resource bundle.
   *  @param  bundle   resource bundle to remove
   */
  public void removeResourceBundle(ResourceBundle bundle) {
    if (resourceBundles.remove(bundle)) {
      // really removed
      // --- now we need to create a new Hashtable because we cannot
      // --- easily just remove the key/value pairs due to correct 
      // --- handling of multiple entries
      resources = new HashMap();
      for (Iterator iterator = resourceBundles.iterator(); iterator.hasNext();) {
        addEntries((ResourceBundle)iterator.next());
      }
    }
  }

  /**
   *  Add the key/value pairs from a bundle to the collected list.
   *  @param  bundle   resource bundle for which the entries should be added
   */
  private void addEntries(ResourceBundle bundle) {
    for (Enumeration e = bundle.getKeys();   e.hasMoreElements();  ) {
      Object key = e.nextElement();
      if (I18n.DEBUG) {
	if (resources.get(key) != null) {
	  System.err.println("key '"+key+"'redefined in resource bundle "+bundle);
	}
      }
      resources.put(key, bundle.getObject(key.toString()));
    }
  }

  /**
   *  Must have method for getting the value for a key.
   *  @param  key  see description of java.util.ResourceBundle
   *  @return the value for the given key or <code>null</code>
   */
  protected Object handleGetObject(String key) {
    return resources.get(key);
  }

  /**
   *  Return an iterator of the keys.
   *  @return iterator of all keys from the collected tables.
   */
  public Enumeration getKeys() {
    return Collections.enumeration(resources.keySet());
  }
}
