/* Permissions.java -- a collection of permission collections
   Copyright (C) 1998, 2001, 2002, 2004, 2005  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.security;

import java.io.Serializable;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.NoSuchElementException;

/**
 * This class is a heterogeneous collection of permissions.  It is
 * organized as a collection of <code>PermissionCollection</code>'s stored
 * in a hashtable.  Each individual <code>PermissionCollection</code>
 * contains permissions of a single type.  If a specific type of
 * <code>Permission</code> does not provide a collection type to use
 * via its <code>newPermissionCollection</code> method, then a default
 * collection type which stores its permissions in a hash table will be
 * used.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Eric Blake (ebb9@email.byu.edu)
 * @since 1.1
 */
public final class Permissions extends PermissionCollection
  implements Serializable
{
  /**
   * Compatible with JDK 1.1+.
   */
  private static final long serialVersionUID = 4858622370623524688L;

  /**
   * Holds instances of <code>AllPermission</code>.
   *
   * @serial the permission collection for AllPermission
   */
  private PermissionCollection allPermission;

  // Package-private to avoid a trampoline.
  /**
   * This is the <code>Hashtable</code> that contains our collections.
   *
   * @serial maps Class to PermissionCollection
   */
  final Hashtable perms = new Hashtable();

  /**
   * This method initializes a new instance of <code>Permissions</code>.
   */
  public Permissions()
  {
  }

  /**
   * This method adds a new <code>Permission</code> to this collection.  It
   * will be stored in a <code>PermissionCollection</code> of the appropriate
   * type, as determined by calling <code>newPermissionCollection</code> on
   * the specified permission (if an appropriate collection does not already
   * exist). If this object does not specify a particular type of collection,
   * a default collection, which stores in permissions in a hash table, will
   * be used.
   *
   * @param perm the <code>Permission</code> to add
   * @throws SecurityException if this collection is marked as read only
   */
  public void add(Permission perm)
  {
    if (isReadOnly())
      throw new SecurityException("PermissionCollection is read only");
    if (perm instanceof AllPermission)
      {
        if (allPermission == null)
          {
            allPermission = perm.newPermissionCollection();
            allPermission.add(perm);
            perms.put(perm.getClass(), allPermission);
          }
      }
    else
      {
        PermissionCollection pc
          = (PermissionCollection) perms.get(perm.getClass());
        if (pc == null)
          {
            pc = perm.newPermissionCollection();
            if (pc == null)
              pc = new PermissionsHash();
            perms.put(perm.getClass(), pc);
          }
        pc.add(perm);
      }
  }

  /**
   * This method tests whether or not the specified <code>Permission</code>
   * is implied by this <code>PermissionCollection</code>.
   *
   * @param perm the <code>Permission</code> to test
   * @return true if the specified permission is implied by this
   */
  public boolean implies(Permission perm)
  {
    if (allPermission != null)
      return true;
    PermissionCollection pc
      = (PermissionCollection) perms.get(perm.getClass());
    return pc == null ? false : pc.implies(perm);
  }

  /**
   * This method returns an <code>Enumeration</code> which contains a
   * list of all <code>Permission</code> objects contained in this
   * collection.
   *
   * @return an <code>Enumeration</code> of this collection's elements
   */
  public Enumeration elements()
  {
    return new Enumeration()
    {
      Enumeration main_enum = perms.elements();
      Enumeration sub_enum;

      public boolean hasMoreElements()
      {
        if (sub_enum == null)
          {
            if (main_enum == null)
              return false;
            if (! main_enum.hasMoreElements())
              {
                main_enum = null;
                return false;
              }
            PermissionCollection pc =
              (PermissionCollection) main_enum.nextElement();
            sub_enum = pc.elements();
          }
        if (! sub_enum.hasMoreElements())
          {
            sub_enum = null;
            return hasMoreElements();
          }
        return true;
      }

      public Object nextElement()
      {
        if (! hasMoreElements())
          throw new NoSuchElementException();
        return sub_enum.nextElement();
      }
    };
  }

  /**
   * Implements the permission collection for all permissions without one of
   * their own, and obeys serialization of JDK.
   *
   * @author Eric Blake (ebb9@email.byu.edu)
   */
  private static final class PermissionsHash extends PermissionCollection
  {
    /**
     * Compatible with JDK 1.1+.
     */
    private static final long serialVersionUID = -8491988220802933440L;

    /**
     * Hashtable where we store permissions.
     *
     * @serial the stored permissions, both as key and value
     */
    private final Hashtable perms = new Hashtable();

    /**
     * Add a permission. We don't need to check for read-only, as this
     * collection is never exposed outside of Permissions, which has already
     * done that check.
     *
     * @param perm the permission to add
     */
    public void add(Permission perm)
    {
      perms.put(perm, perm);
    }

    /**
     * Returns true if perm is in the collection.
     *
     * @param perm the permission to check
     * @return true if it is implied
     */
    // FIXME: Should this method be synchronized?
    public boolean implies(Permission perm)
    {
      Enumeration elements = elements();
      
      while (elements.hasMoreElements())
	{
	  Permission p = (Permission)elements.nextElement();
	  if (p.implies(perm))
	    return true;
	}
      return false;
    }

    /**
     * Return the elements.
     *
     * @return the elements
     */
    public Enumeration elements()
    {
      return perms.elements();
    }
  } // class PermissionsHash
} // class Permissions
