/* MBeanPermission.java -- Permissions controlling server access.
   Copyright (C) 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 javax.management;

import gnu.java.lang.CPStringBuilder;

import java.security.Permission;

import java.io.IOException;
import java.io.ObjectInputStream;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

/**
 * <p>
 * Represents the permissions required to perform
 * operations using the {@link MBeanServer}.  As with
 * all {@link java.security.Permission} objects, an
 * instance of this class either represents a permission
 * already held or one that is required to access a
 * particular service.  In the case of {@link MBeanPermission}s,
 * implication checks are made using an instance of this class
 * when a user requests an operation from the server, and a
 * {@link SecurityManager} is in place.
 * </p>
 * <p>
 * An {@link MBeanPermission} consists of four elements,
 * which all have to match for the permission to be implied.
 * These are as follows:
 * </p>
 * <ol>
 * <li><strong>The action</strong>.  For a required permission,
 * this is a single value.  For a permission held by the user,
 * this is a list of comma-separated actions (with spaces allowed),
 * or <code>*</code> (representing all actions).  {@link #getActions()}
 * returns this value.</li>
 * <li><strong>The class name</strong>.  For a required permission,
 * this is the class name of the bean being accessed, if any.  If
 * a bean isn't involved in this action, the value is <code>null</code>.
 * For a permission held by the user, it has one of three values:
 * <ol>
 * <li>The empty string, implying any class.</li>
 * <li><code>*</code>, also implying any class.</li>
 * <li>A class name pattern, which may specify a single class
 * (e.g. <code>java.lang.Object</code>) or a series of classes
 * using the wildcard character <code>*</code> (e.g.
 * <code>javax.swing.*</code>.)</li>
 * </ol></li>
 * <li><strong>The member</strong>.  For a required permission,
 * this is the member of the bean being accessed (an attribute
 * or operation), if any.  If a member of the bean isn't involved
 * in this action, the value is <code>null</code>.
 * For a permission held by the user, it has one of three values:
 * <ol>
 * <li>The empty string, implying any member.</li>
 * <li><code>*</code>, also implying any member.</li>
 * <li>The name of a member.</li>
 * </ol></li>
 * <li>The object name</strong>.  For a required permission,
 * this is the {@link ObjectName} of the bean being accessed, if
 * any.  If a bean isn't involved in this action, the value is
 * <code>null</code>.  The name may not be a pattern.
 * For a permission held by the user, it may be the empty
 * string (allowing everything) or an {@link ObjectName}
 * pattern.
 * </li></ol>
 * {@link #getName()} returns the latter three of these as a
 * single string:
 * </p>
 * <p><code>className#member[objectName]</code></p>
 * <p>
 * where <code>""</code> is disallowed, as, although any of
 * the elements may be omitted, not all of them should be
 * left out simultaneously.  <code>"-"</code> is used to
 * represent <code>null</code>.  When this occurs in a
 * required permission, anything may match it.  When this
 * forms part of a permission held by the user, it only
 * matches another <code>null</code> value.
 * </p>
 * <p>The list of valid actions is as follows:</p>
 * <ul>
 * <li>addNotificationListener</li>
 * <li>getAttribute</li>
 * <li>getClassLoader</li>
 * <li>getClassLoaderFor</li>
 * <li>getClassLoaderRepository</li>
 * <li>getDomains</li>
 * <li>getMBeanInfo</li>
 * <li>getObjectInstance</li>
 * <li>instantiate</li>
 * <li>invoke</li>
 * <li>isInstanceOf</li>
 * <li>queryMBeans</li>
 * <li>queryNames</li>
 * <li>registerMBean</li>
 * <li>removeNotificationListener</li>
 * <li>setAttribute</li>
 * <li>unregisterMBean</li>
 * </ul>
 *
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 * @since 1.5
 */
public class MBeanPermission
  extends Permission
{

  /**
   * Compatible with JDK 1.5
   */
  private static final long serialVersionUID = -2416928705275160661L;

  /**
   * The list of actions associated with this permission.
   */
  private String actions;

  /**
   * The list of actions as an ordered set.
   */
  private transient Set<String> actionSet;

  /**
   * The set of valid actions.
   */
  private static final Set<String> validSet;

  /**
   * Initialise the set of valid actions.
   */
  static
  {
    validSet = new HashSet<String>();
    validSet.add("addNotificationListener");
    validSet.add("getAttribute");
    validSet.add("getClassLoader");
    validSet.add("getClassLoaderFor");
    validSet.add("getClassLoaderRepository");
    validSet.add("getDomains");
    validSet.add("getMBeanInfo");
    validSet.add("getObjectInstance");
    validSet.add("instantiate");
    validSet.add("invoke");
    validSet.add("isInstanceOf");
    validSet.add("queryMBeans");
    validSet.add("queryNames");
    validSet.add("registerMBean");
    validSet.add("removeNotificationListener");
    validSet.add("setAttribute");
    validSet.add("unregisterMBean");
  }

  /**
   * Constructs a new {@link MBeanPermission} with the specified name
   * and actions.  The name is of the form <code>className#member[objectName]</code>,
   * where each element is optional, but a completely empty or <code>null</code>
   * name is disallowed.  Actions are specified as a comma-separated list
   * and may also not be empty or <code>null</code>.
   *
   * @param name the name of the permission.
   * @param actions the actions associated with this permission.
   * @throws IllegalArgumentException if the name or actions are invalid.
   */
  public MBeanPermission(String name, String actions)
  {
    super(name);
    if (name == null || name.length() == 0)
      throw new IllegalArgumentException("The supplied name was null or empty.");
    if (actions == null || actions.length() == 0)
      throw new IllegalArgumentException("The supplied action list was null or empty.");
    this.actions = actions;
    updateActionSet();
  }

  /**
   * Constructs a new {@link MBeanPermission} with the specified class name,
   * member, object name and actions.  The name of the permission is created
   * using the form <code>className#member[objectName]</code>,
   * where each element is optional, but an empty or <code>null</code>
   * name is disallowed.  Actions are specified as a comma-separated list
   * and may also not be empty or <code>null</code>.
   *
   * @param className the name of the class to which this permission applies,
   *                  or either <code>null</code> or <code>"-"</code> for a
   *                  value which may be implied by any class name, but not
   *                  imply any class name itself.
   * @param member the member of the class to which this permission applies,
   *               or either <code>null</code> or <code>"-"</code> for a
   *               value which may be implied by any member, but not
   *               imply any member itself.
   * @param name the {@link ObjectName} to which this permission applies,
   *                  or <code>null</code> for a value which may be implied by
   *                  any object name, but not imply any object name itself.
   * @param actions the actions associated with this permission.
   */
  public MBeanPermission(String className, String member,
                         ObjectName name, String actions)
  {
    this((className == null ? "-" : className) + "#"
         + (member == null ? "-" : member) + "["
         + (name == null ? "-" : name.toString()) + "]", actions);
  }

  /**
   * Returns true if the given object is also an {@link MBeanPermission}
   * with the same name and actions.
   *
   * @param obj the object to test.
   * @return true if the object is an {@link MBeanPermission} with
   *         the same name and actions.
   */
  public boolean equals(Object obj)
  {
    if (obj instanceof MBeanPermission)
      {
        MBeanPermission p = (MBeanPermission) obj;
        return (p.getName().equals(getName()) &&
                p.getActions().equals(actions));
      }
    return false;
  }

  /**
   * Returns the list of actions in alphabetical order.
   *
   * @return the list of actions.
   */
  public String getActions()
  {
    Iterator<String> it = actionSet.iterator();
    CPStringBuilder builder = new CPStringBuilder();
    while (it.hasNext())
      {
        builder.append(it.next());
        if (it.hasNext())
          builder.append(",");
      }
    return builder.toString();
  }

  /**
   * Returns the hashcode of the permission as the sum
   * of the hashcodes of the name and actions.
   *
   * @return the hashcode of the permission.
   */
  public int hashCode()
  {
    return getName().hashCode() + actions.hashCode();
  }

  /**
   * <p>
   * Returns true if this permission implies the supplied permission.
   * This happens if the following holds:
   * </p>
   * <ul>
   * <li>The supplied permission is an {@link MBeanPermission}</li>
   * <li>The supplied permission has either a <code>null</code> classname
   * or its classname matches the classname of this permission.  A
   * classname of <code>"*"</code> for this permission always matches
   * the classname of the supplied permission.  Generally, <code>'*'</code>
   * acts as a wildcard, so <code>".*"</code> matches <code>'.'</code>
   * followed by anything.</li>
   * <li>The supplied permission has either a <code>null</code> member
   * or its member matches the member of this permission.  A member of
   * <code>"*"</code> for this permission always matches the member
   * of the supplied permission.</li>
   * <li>The supplied permission has either a <code>null</code> object name
   * or its object name matches the object name of this permission.  If the
   * object name of this permission is a pattern, {@link ObjectName#apply(ObjectName)}
   * may be used as well.</li>
   * <li>The supplied permission's actions are a subset of the actions
   * of this permission.  If the <code>queryMBeans</code> action is presented,
   * the <code>queryNames</code> action is implied.</li>
   * </ul>
   *
   * @param p the permission to check that this permission implies.
   * @return true if this permission implies <code>p</code>.
   */
  public boolean implies(Permission p)
  {
    if (p instanceof MBeanPermission)
      {
        MBeanPermission mp = (MBeanPermission) p;
        NameHolder pName = new NameHolder(mp.getName());
        NameHolder name = new NameHolder(getName());
        if (!(name.equals(pName)))
          return false;
        for (String nextAction : mp.actionSet)
          {
            boolean found = actions.contains(nextAction);
            if (!found)
              if (nextAction.equals("queryNames"))
                found = actions.contains("queryMBeans");
            if (!found)
              return false;
          }
        return true;
      }
    return false;
  }

  /**
   * Small helper class to handle deconstruction of the name.
   *
   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
   */
  private class NameHolder
  {

    /**
     * The class name.
     */
    private String className;

    /**
     * The member.
     */
    private String member;

    /**
     * The object name.
     */
    private ObjectName objectName;

    /**
     * Constructs a broken-down name from a given name.
     *
     * @param name the name to break down.
     */
    public NameHolder(String name)
    {
      String objectName = null;
      int memberIndex = name.indexOf("#");
      int onIndex = name.indexOf("[");
      if (onIndex == -1)
        {
          if (memberIndex == -1)
            className = name;
          else
            {
              className = name.substring(0, memberIndex);
              member = name.substring(memberIndex + 1);
            }
        }
      else
        {
          if (memberIndex == -1)
            {
              className = name.substring(0, onIndex);
              objectName = name.substring(onIndex + 1,
                                          name.length() - 1);
            }
          else
            {
              className = name.substring(0, memberIndex);
              member = name.substring(memberIndex + 1, onIndex);
              objectName = name.substring(onIndex + 1,
                                          name.length() - 1);
            }
        }
      if (className.equals("-"))
        className = null;
      if (member.equals("-"))
        member = null;
      if (objectName == null || objectName.equals("-"))
        this.objectName = null;
      else
        try
          {
            this.objectName = new ObjectName(objectName);
          }
        catch (MalformedObjectNameException e)
          {
            throw (Error)
              (new InternalError("Invalid object name.").initCause(e));
          }
    }

    /**
     * <p>
     * Returns true if the supplied object is also a
     * {@link NameHolder} and the following holds:
     * </p>
     * <ul>
     * <li>The supplied classname is <code>null</code> or the two match.  A
     * classname of <code>"*"</code> for this holder always matches
     * the classname of the supplied holder.  Generally, <code>'*'</code>
     * acts as a wildcard, so <code>".*"</code> matches <code>'.'</code>
     * followed by anything.</li>
     * <li>The supplied name holder has either a <code>null</code> member
     * or its member matches the member of this name holder.  A member of
     * <code>"*"</code> for this name holder always matches the member
     * of the supplied name holder.</li>
     * <li>The supplied name holder has either a <code>null</code> object name
     * or its object name matches the object name of this name holder.  If the
     * object name of this name holder is a pattern,
     * {@link ObjectName#apply(ObjectName)} may be used as well.</li>
     * </ul>
     *
     * @param obj the object to compare with this.
     * @return true if the above holds.
     */
    public boolean equals(Object obj)
    {
      if (obj instanceof NameHolder)
        {
          NameHolder nh = (NameHolder) obj;
          boolean cn = false;
          String ocn = nh.getClassName();
          if (ocn == null || className.equals("*"))
            cn = true;
          else
            {
              int wcIndex = className.indexOf("*");
              if (wcIndex != -1)
                cn = ocn.startsWith(className.substring(0, wcIndex));
              else
                cn = ocn.equals(className);
            }
          boolean m = false;
          String om = nh.getMember();
          if (om == null || member.equals("*"))
            m = true;
          else
            m = om.equals(member);
          boolean on = false;
          ObjectName oon = nh.getObjectName();
          if (oon == null)
            on = true;
          else if (objectName.isPattern())
            on = objectName.apply(oon);
          else
            on = oon.equals(objectName);
          return (cn && m && on);
        }
      return false;
    }

    /**
     * Returns the class name.
     */
    public String getClassName()
    {
      return className;
    }

    /**
     * Returns the member.
     */
    public String getMember()
    {
      return member;
    }

    /**
     * Returns the object name.
     */
    public ObjectName getObjectName()
    {
      return objectName;
    }
  }

  /**
   * Updates the action set from the current value of
   * the actions string.
   */
  private void updateActionSet()
  {
    String[] actionsArray = actions.split(",");
    actionSet = new TreeSet<String>();
    for (int a = 0; a < actionsArray.length; ++a)
      actionSet.add(actionsArray[a].trim());
  }

  /**
   * Reads the object from a stream and ensures the incoming
   * data is valid.
   *
   * @param in the input stream.
   * @throws IOException if an I/O error occurs.
   * @throws ClassNotFoundException if a class used by the object
   *                                can not be found.
   */
  private void readObject(ObjectInputStream in)
    throws IOException, ClassNotFoundException
  {
    in.defaultReadObject();
    updateActionSet();
    checkActions();
  }

  /**
   * Checks that the actions used in this permission
   * are from the valid set.
   *
   * @throws IllegalArgumentException if the name or actions are invalid.
   */
  private void checkActions()
  {
    for (String action : actionSet)
      {
        if (!(validSet.contains(action)))
          throw new IllegalArgumentException("Invalid action "
                                             + action + " found.");
      }
  }

}
