/*
 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package com.sun.beans.finder;

/**
 * This class is designed to be a key of a cache
 * of constructors or methods.
 *
 * @since 1.7
 *
 * @author Sergey A. Malenkov
 */
final class Signature {
    private final Class<?> type;
    private final String name;
    private final Class<?>[] args;

    private volatile int code;

    /**
     * Constructs signature for constructor.
     *
     * @param type  the class that contains constructor
     * @param args  the types of constructor's parameters
     */
    Signature(Class<?> type, Class<?>[] args) {
        this(type, null, args);
    }

    /**
     * Constructs signature for method.
     *
     * @param type  the class that contains method
     * @param name  the name of the method
     * @param args  the types of method's parameters
     */
    Signature(Class<?> type, String name, Class<?>[] args) {
        this.type = type;
        this.name = name;
        this.args = args;
    }

    /**
     * Indicates whether some other object is "equal to" this one.
     *
     * @param object  the reference object with which to compare
     * @return {@code true} if this object is the same as the
     *         {@code object} argument, {@code false} otherwise
     * @see #hashCode()
     */
    @Override
    public boolean equals(Object object) {
        if (this == object) {
            return true;
        }
        if (object instanceof Signature) {
            Signature signature = (Signature) object;
            return isEqual(signature.type, this.type)
                && isEqual(signature.name, this.name)
                && isEqual(signature.args, this.args);
        }
        return false;
    }

    /**
     * Indicates whether some object is "equal to" another one.
     * This method supports {@code null} values.
     *
     * @param obj1  the first reference object that will compared
     * @param obj2  the second reference object that will compared
     * @return {@code true} if first object is the same as the second object,
     *         {@code false} otherwise
     */
    private static boolean isEqual(Object obj1, Object obj2) {
        return (obj1 == null)
                ? obj2 == null
                : obj1.equals(obj2);
    }

    /**
     * Indicates whether some array is "equal to" another one.
     * This method supports {@code null} values.
     *
     * @param args1 the first reference array that will compared
     * @param args2 the second reference array that will compared
     * @return {@code true} if first array is the same as the second array,
     *         {@code false} otherwise
     */
    private static boolean isEqual(Class<?>[] args1, Class<?>[] args2) {
        if ((args1 == null) || (args2 == null)) {
            return args1 == args2;
        }
        if (args1.length != args2.length) {
            return false;
        }
        for (int i = 0; i < args1.length; i++) {
            if (!isEqual(args1[i], args2[i])) {
                return false;
            }
        }
        return true;
    }

    /**
     * Returns a hash code value for the object.
     * This method is supported for the benefit of hashtables
     * such as {@link java.util.HashMap} or {@link java.util.HashSet}.
     * Hash code computed using algorithm
     * suggested in Effective Java, Item 8.
     *
     * @return a hash code value for this object
     * @see #equals(Object)
     */
    @Override
    public int hashCode() {
        if (this.code == 0) {
            int code = 17;
            code = addHashCode(code, this.type);
            code = addHashCode(code, this.name);

            if (this.args != null) {
                for (Class<?> arg : this.args) {
                    code = addHashCode(code, arg);
                }
            }
            this.code = code;
        }
        return this.code;
    }

    /**
     * Adds hash code value if specified object.
     * This is a part of the algorithm
     * suggested in Effective Java, Item 8.
     *
     * @param code    current hash code value
     * @param object  object that updates hash code value
     * @return updated hash code value
     * @see #hashCode()
     */
    private static int addHashCode(int code, Object object) {
        code *= 37;
        return (object != null)
                ? code + object.hashCode()
                : code;
    }
}
