/* BasicPermission.java -- implements a simple named permission
   Copyright (C) 1998, 1999, 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.security;

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

/**
 * This class implements a simple model for named permissions without an
 * associated action list.  That is, either the named permission is granted
 * or it is not.
 *
 * <p>It also supports trailing wildcards to allow the easy granting of
 * permissions in a hierarchical fashion.  (For example, the name "org.gnu.*"
 * might grant all permissions under the "org.gnu" permissions hierarchy).
 * The only valid wildcard character is a '*' which matches anything. It
 * must be the rightmost element in the permission name and must follow a
 * '.' or else the Permission name must consist of only a '*'. Any other
 * occurrence of a '*' is not valid.
 *
 * <p>This class ignores the action list.  Subclasses can choose to implement
 * actions on top of this class if desired.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Eric Blake (ebb9@email.byu.edu)
 * @see Permission
 * @see Permissions
 * @see PermissionCollection
 * @see RuntimePermission
 * @see SecurityPermission
 * @see PropertyPermission
 * @see AWTPermission
 * @see NetPermission
 * @see SecurityManager
 * @since 1.1
 * @status updated to 1.4
 */
public abstract class BasicPermission extends Permission
  implements Serializable
{
  /**
   * Compatible with JDK 1.1+.
   */
  private static final long serialVersionUID = 6279438298436773498L;

  /**
   * Create a new instance with the specified permission name. If the
   * name is empty an exception is thrown.
   *
   * @param name the name of this permission
   * @throws NullPointerException if name is null
   * @throws IllegalArgumentException if name is invalid
   */
  public BasicPermission(String name)
  {
    super(name);

    // This routine used to check for illegal wildcards, but no such
    // requirement exists in the specification and Sun's runtime
    // doesn't appear to do it.

    if (name.equals(""))
      throw new IllegalArgumentException("Empty name");
  }

  /**
   * Create a new instance with the specified permission name. If the name
   * is empty, or contains an illegal wildcard character, an exception is
   * thrown. The actions parameter is ignored.
   *
   * @param name the name of this permission
   * @param actions ignored
   * @throws NullPointerException if name is null
   * @throws IllegalArgumentException if name is invalid
   */
  public BasicPermission(String name, String actions)
  {
    this(name);
  }

  /**
   * This method tests to see if the specified permission is implied by this
   * permission.  This will be true if the following conditions are met:<ul>
   * <li>The specified object is an instance of the same class as this
   * object.</li>
   * <li>The name of the specified permission is implied by this permission's
   * name based on wildcard matching. For example, "a.*" implies "a.b".</li>
   * </ul>
   *
   * @param perm the <code>Permission</code> object to test against
   * @return true if the specified permission is implied
   */
  public boolean implies(Permission perm)
  {
    if (! getClass().isInstance(perm))
      return false;

    String otherName = perm.getName();
    String name = getName();

    if (name.equals(otherName))
      return true;

    int last = name.length() - 1;
    return name.charAt(last) == '*'
      && otherName.startsWith(name.substring(0, last));
  }

  /**
   * This method tests to see if this object is equal to the specified
   * <code>Object</code>.  This will be true if and only if the specified
   * object meets the following conditions:<ul>
   * <li>It is an instance of the same class as this.</li>
   * <li>It has the same name as this permission.</li>
   * </ul>
   *
   * @param obj the <code>Object</code> to test for equality
   * @return true if obj is semantically equal to this
   */
  public boolean equals(Object obj)
  {
    return getClass().isInstance(obj)
      && getName().equals(((BasicPermission) obj).getName());
  }

  /**
   * This method returns a hash code for this permission object.  The hash
   * code returned is the value returned by calling the <code>hashCode</code>
   * method on the <code>String</code> that is the name of this permission.
   *
   * @return a hash value for this object
   */
  public int hashCode()
  {
    return getName().hashCode();
  }

  /**
   * This method returns a list of the actions associated with this
   * permission.  This method always returns the empty string ("") since
   * this class ignores actions.
   *
   * @return the action list
   */
  public String getActions()
  {
    return "";
  }

  /**
   * This method returns an instance of <code>PermissionCollection</code>
   * suitable for storing <code>BasicPermission</code> objects.  The
   * collection returned can only store objects of the same type as this.
   * Subclasses which use actions must override this method; but a class with
   * no actions will work fine with this.
   *
   * @return a new empty <code>PermissionCollection</code> object
   */
  public PermissionCollection newPermissionCollection()
  {
    return new BasicPermissionCollection(getClass());
  }

  /**
   * Implements AllPermission.newPermissionCollection, and obeys serialization
   * of JDK.
   *
   * @author Eric Blake (ebb9@email.byu.edu)
   */
  private static final class BasicPermissionCollection extends PermissionCollection
  {
    /**
     * Compatible with JDK 1.1+.
     */
    private static final long serialVersionUID = 739301742472979399L;

    /**
     * The permissions in the collection.
     *
     * @serial a hash mapping name to permissions, all of type permClass
     */
    private final Hashtable permissions = new Hashtable();

    /**
     * If "*" is in the collection.
     *
     * @serial true if a permission named "*" is in the collection
     */
    private boolean all_allowed;

    /**
     * The runtime class which all entries in the table must belong to.
     *
     * @serial the limiting subclass of this collection
     */
    private final Class permClass;

    /**
     * Construct a collection over the given runtime class.
     *
     * @param c the class
     */
    BasicPermissionCollection(Class c)
    {
      permClass = c;
    }

    /**
     * Add a Permission. It must be of the same type as the permission which
     * created this collection.
     *
     * @param perm the permission to add
     * @throws IllegalArgumentException if perm is not the correct type
     * @throws SecurityException if the collection is read-only
     */
    public void add(Permission perm)
    {
      if (isReadOnly())
        throw new SecurityException("readonly");
      if (! permClass.isInstance(perm))
        throw new IllegalArgumentException("Expecting instance of " + permClass);
      BasicPermission bp = (BasicPermission) perm;
      String name = bp.getName();
      if (name.equals("*"))
        all_allowed = true;
      permissions.put(name, bp);
    }

    /**
     * Returns true if this collection implies the given permission.
     *
     * @param permission the permission to check
     * @return true if it is implied by this
     */
    public boolean implies(Permission permission)
    {
      if (! permClass.isInstance(permission))
        return false;
      if (all_allowed)
        return true;
      BasicPermission toImply = (BasicPermission) permission;
      String name = toImply.getName();
      if (name.equals("*"))
        return false;
      int prefixLength = name.length();
      if (name.endsWith("*"))
        prefixLength -= 2;

      while (true)
        {
          if (permissions.get(name) != null)
            return true;
          prefixLength = name.lastIndexOf('.', prefixLength);
          if (prefixLength < 0)
            return false;
          name = name.substring(0, prefixLength + 1) + '*';
        }
    }

    /**
     * Enumerate over the collection.
     *
     * @return an enumeration of the collection contents
     */
    public Enumeration elements()
    {
      return permissions.elements();
    }
  } // class BasicPermissionCollection
} // class BasicPermission
