/* | 
|
 * Copyright (c) 2008, 2013, 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;  | 
|
}  | 
|
Class<?> getType() {  | 
|
return this.type;  | 
|
}  | 
|
String getName() {  | 
|
return this.name;  | 
|
}  | 
|
Class<?>[] getArgs() {  | 
|
return this.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;  | 
|
}  | 
|
}  |