/*
 *  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.
 */

/**
* @author Alexey V. Varlamov
* @version $Revision$
*/

package org.apache.harmony.security;

import java.security.Principal;

/**
 * Descriptive implementation of Principal, which holds a name and a classname
 * of unresolved principal. It is used to define an arbitrary Principal which
 * may be not yet instantiated and authenticated.
 * <br>
 * This concept is somewhat similar to UnresolvedPermission. A principal-based
 * policy may grant permissions depending on what Principals own the current
 * execution thread. So the policy refers to this model definition of
 * acceptable principal and compares it with the actual principal.
 *
 * @see org.apache.harmony.security.PolicyEntry
 * @see org.apache.harmony.security.fortress.DefaultPolicy
 */
public final class UnresolvedPrincipal implements Principal {

    /**
     * Wildcard value denotes any class and/or any name.
     */
    public static final String WILDCARD = DefaultPolicyScanner.PrincipalEntry.WILDCARD;

    // Class name
    private final String klass;

    // Principal name
    private final String name;

    /**
     * Constructs a a new definition of a Principal with specified
     * parameters.
     * @param klass fully qualified class name, may be wildcard
     * @param name name of principal, may be wildcard
     * @throws IllegalArgumentException if <code>klass</code> value
     * is <code>null </code> or is empty string
     */
    public UnresolvedPrincipal(String klass, String name) {
        if (klass == null || klass.isEmpty()) {
            throw new IllegalArgumentException();
        }

        this.klass = klass;
        this.name = name;
    }

    /**
     * Returns name of a modeled Principal, or wildcard
     * if any name is acceptable.
     */
    public String getName() {
        return name;
    }

    /**
     * Returns fully qualified class name of a modeled Principal,
     * or wildcard if any class is acceptable.
     */
    public String getClassName() {
        return klass;
    }

    /**
     * Returns <code>true</code> if compared object is a Principal
     * matching this definition, or if it is an UnresolvedPrincipal,
     * which defines the same Principal; <code>false</code> otherwise.
     */
    public boolean equals(Object that) {
        if (that instanceof UnresolvedPrincipal) {
            UnresolvedPrincipal up = (UnresolvedPrincipal) that;
            return klass.equals(up.klass)
                    && (name == null ? up.name == null : name.equals(up.name));
        }
        if (that instanceof Principal) {
            return implies((Principal) that);
        }
        return false;
    }

    /**
     * Returns <code>true</code> if compared object is a Principal
     * exactly matching this definition. Namely, if the fully qualified name
     * of class of passed Principal is equal to the class name value
     * of this definition and the name of passed Principal is equal to
     * the name value of this definition, or if this definition allows
     * any class or name, respectively.
     * Otherwise returns <code>false</code> .
     */
    public boolean implies(Principal another) {
        return (another != null)
                && (WILDCARD.equals(klass)
                    || klass.equals(another.getClass().getName())
                && (WILDCARD.equals(name)
                    || (name == null ? another.getName() == null
                        : name.equals(another.getName()))));
    }

    /**
     * Returns the hash code value for this object.
     */
    public int hashCode() {
        int hash = 0;
        if (name != null) {
            hash ^= name.hashCode();
        }
        if (klass != null) {
            hash ^= klass.hashCode();
        }
        return hash;
    }

    /**
     * Returns a string describing this model of Principal.
     * The format is 'Principal classname &quot;name&quot;'.
     */
    public String toString() {
        return "Principal " + klass + " \"" + name + "\"";
    }
}
