package java.security;

import ej.annotation.Nullable;

/**
 * Abstract class for representing access to a system resource. All permissions have a name (whose
 * interpretation depends on the subclass), as well as abstract functions for defining the semantics
 * of the particular Permission subclass.
 *
 * <p>
 * Most Permission objects also include an "actions" list that tells the actions that are permitted
 * for the object. For example, for a <code>java.io.FilePermission</code> object, the permission
 * name is the pathname of a file (or directory), and the actions list (such as "read, write")
 * specifies which actions are granted for the specified file (or for files in the specified
 * directory). The actions list is optional for Permission objects, such as
 * <code>java.lang.RuntimePermission</code>, that don't need such a list; you either have the named
 * permission (such as "system.exit") or you don't.
 *
 * <p>
 * An important method that must be implemented by each subclass is the <code>implies</code> method
 * to compare Permissions. Basically, "permission p1 implies permission p2" means that if one is
 * granted permission p1, one is naturally granted permission p2. Thus, this is not an equality
 * test, but rather more of a subset test.
 *
 * <P>
 * Permission objects are similar to String objects in that they are immutable once they have been
 * created. Subclasses should not provide methods that can change the state of a permission once it
 * has been created.
 *
 */

public abstract class Permission implements Guard, java.io.Serializable {

	/**
	 * Constructs a permission with the specified name.
	 *
	 * @param name
	 *        name of the Permission object being created.
	 *
	 */
	public Permission(String name) {
		throw new RuntimeException();
	}

	/**
	 * Checks two Permission objects for equality.
	 * <P>
	 * Do not use the <code>equals</code> method for making access control decisions; use the
	 * <code>implies</code> method.
	 *
	 * @param obj
	 *        the object we are testing for equality with this object.
	 *
	 * @return true if both Permission objects are equivalent.
	 */

	@Override
	public abstract boolean equals(@Nullable Object obj);

	/**
	 * Returns the actions as a String. This is abstract so subclasses can defer creating a String
	 * representation until one is needed. Subclasses should always return actions in what they consider
	 * to be their canonical form. For example, two FilePermission objects created via the following:
	 *
	 * <pre>
	 * perm1 = new FilePermission(p1, &quot;read,write&quot;);
	 * perm2 = new FilePermission(p2, &quot;write,read&quot;);
	 * </pre>
	 *
	 * both return "read,write" when the <code>getActions</code> method is invoked.
	 *
	 * @return the actions of this Permission.
	 *
	 */
	public abstract String getActions();

	/**
	 * Returns the name of this Permission. For example, in the case of a
	 * <code>java.io.FilePermission</code>, the name will be a pathname.
	 *
	 * @return the name of this Permission.
	 *
	 */
	public final String getName() {
		throw new RuntimeException();
	}

	/**
	 * Returns the hash code value for this Permission object.
	 * <P>
	 * The required <code>hashCode</code> behavior for Permission Objects is the following:
	 * <ul>
	 * <li>Whenever it is invoked on the same Permission object more than once during an execution of a
	 * Java application, the <code>hashCode</code> method must consistently return the same integer.
	 * This integer need not remain consistent from one execution of an application to another execution
	 * of the same application.
	 * <li>If two Permission objects are equal according to the <code>equals</code> method, then calling
	 * the <code>hashCode</code> method on each of the two Permission objects must produce the same
	 * integer result.
	 * </ul>
	 *
	 * @return a hash code value for this object.
	 */

	@Override
	public abstract int hashCode();

	/**
	 * Checks if the specified permission's actions are "implied by" this object's actions.
	 * <P>
	 * This must be implemented by subclasses of Permission, as they are the only ones that can impose
	 * semantics on a Permission object.
	 *
	 * @param permission
	 *        the permission to check against.
	 *
	 * @return true if the specified permission is implied by this object, false if not.
	 */

	public abstract boolean implies(Permission permission);

	/**
	 * Returns a string describing this Permission. The convention is to specify the class name, the
	 * permission name, and the actions in the following format: '("ClassName" "name" "actions")', or
	 * '("ClassName" "name")' if actions list is null or empty.
	 *
	 * @return information about this Permission.
	 */
	@Override
	public String toString() {
		throw new RuntimeException();
	}
}
