/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package java.security;

import java.io.IOException;
import java.io.Serializable;

/**
 * {@code BasicPermission} is the common base class of all permissions which
 * have a name but no action lists. A {@code BasicPermission} is granted or it
 * is not.
 * <p>
 * Names of a BasicPermission follow the dot separated, hierarchical property
 * naming convention. Asterisk '*' can be used as wildcards. Either by itself,
 * matching anything, or at the end of the name, immediately preceded by a '.'.
 * For example:
 *
 * <pre>
 * java.io.*  grants all permissions under the java.io permission hierarchy
 * *          grants all permissions
 * </pre>
 * <p>
 * While this class ignores the action list in the
 * {@link #BasicPermission(String, String)} constructor, subclasses may
 * implement actions on top of this class.
 */
public abstract class BasicPermission extends Permission implements
    Serializable {

    private static final long serialVersionUID = 6279438298436773498L;

    /**
     * Constructs a new instance of {@code BasicPermission} with the specified
     * name.
     *
     * @param name
     *            the name of the permission.
     * @throws NullPointerException if {@code name} is {@code null}.
     * @throws IllegalArgumentException if {@code name.length() == 0}.
     */
    public BasicPermission(String name) {
        super(name);
        checkName(name);
    }

    /**
     * Constructs a new instance of {@code BasicPermission} with the specified
     * name. The {@code action} parameter is ignored.
     *
     * @param name
     *            the name of the permission.
     * @param action
     *            is ignored.
     * @throws NullPointerException
     *             if {@code name} is {@code null}.
     * @throws IllegalArgumentException
     *             if {@code name.length() == 0}.
     */
    public BasicPermission(String name, String action) {
        super(name);
        checkName(name);
    }

    /**
     * Checks name parameter
     */
    private final void checkName(String name) {
        if (name == null) {
            throw new NullPointerException("name == null");
        }
        if (name.isEmpty()) {
            throw new IllegalArgumentException("name.isEmpty()");
        }
    }

    /**
     * Compares the specified object with this {@code BasicPermission} for
     * equality. Returns {@code true} if the specified object has the same class
     * and the two {@code Permissions}s have the same name.
     * <p>
     * The {@link #implies(Permission)} method should be used for making access
     * control checks.
     *
     * @param obj
     *            object to be compared for equality with this {@code
     *            BasicPermission}.
     * @return {@code true} if the specified object is equal to this {@code
     *         BasicPermission}, otherwise {@code false}.
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }

        if (obj != null && obj.getClass() == this.getClass()) {
            return this.getName().equals(((Permission)obj).getName());
        }
        return false;
    }

    /**
     * Returns the hash code value for this {@code BasicPermission}. Returns the
     * same hash code for {@code BasicPermission}s that are equal to each other
     * as required by the general contract of {@link Object#hashCode}.
     *
     * @return the hash code value for this {@code BasicPermission}.
     * @see Object#equals(Object)
     * @see BasicPermission#equals(Object)
     */
    @Override
    public int hashCode() {
        return getName().hashCode();
    }

    /**
     * Returns the actions associated with this permission. Since {@code
     * BasicPermission} instances have no actions, an empty string is returned.
     *
     * @return an empty string.
     */
    @Override
    public String getActions() {
        return "";
    }

    /**
     * Indicates whether the specified permission is implied by this permission.
     *
     * @param permission
     *            the permission to check against this permission.
     * @return {@code true} if the specified permission is implied by this
     *         permission, {@code false} otherwise.
     */
    @Override
    public boolean implies(Permission permission) {
        if (permission != null && permission.getClass() == this.getClass()) {
            return nameImplies(getName(), permission.getName());
        }
        return false;
    }

    /**
     * Checks if {@code thisName} implies {@code thatName},
     * accordingly to hierarchical property naming convention.
     * It is assumed that names cannot be {@code null} or empty.
     */
    static boolean nameImplies(String thisName, String thatName) {
        if (thisName == thatName) {
            return true;
        }
        int end = thisName.length();
        if (end > thatName.length()) {
            return false;
        }
        if (thisName.charAt(--end) == '*'
            && (end == 0 || thisName.charAt(end - 1) == '.')) {
            //wildcard found
            end--;
        } else if (end != (thatName.length()-1)) {
            //names are not equal
            return false;
        }
        for (int i = end; i >= 0; i--) {
            if (thisName.charAt(i) != thatName.charAt(i)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Returns an empty {@link PermissionCollection} for holding permissions.
     * <p>
     * For {@code PermissionCollection} (and subclasses which do not override
     * this method), the collection which is returned does <em>not</em> invoke
     * the {@link #implies(Permission)} method of the permissions which are
     * stored in it when checking if the collection implies a permission.
     * Instead, it assumes that if the type of the permission is correct, and
     * the name of the permission is correct, there is a match.
     *
     * @return an empty {@link PermissionCollection} for holding permissions.
     * @see BasicPermissionCollection
     */
    @Override
    public PermissionCollection newPermissionCollection() {
        return new BasicPermissionCollection();
    }

    /**
     * Checks name after default deserialization.
     */
    private void readObject(java.io.ObjectInputStream in) throws IOException,
        ClassNotFoundException {
        in.defaultReadObject();
        checkName(this.getName());
    }
}
