1 /* 2 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package com.sun.beans.finder; 26 27 /** 28 * This class is designed to be a key of a cache 29 * of constructors or methods. 30 * 31 * @since 1.7 32 * 33 * @author Sergey A. Malenkov 34 */ 35 final class Signature { 36 private final Class<?> type; 37 private final String name; 38 private final Class<?>[] args; 39 40 private volatile int code; 41 42 /** 43 * Constructs signature for constructor. 44 * 45 * @param type the class that contains constructor 46 * @param args the types of constructor's parameters 47 */ 48 Signature(Class<?> type, Class<?>[] args) { 49 this(type, null, args); 50 } 51 52 /** 53 * Constructs signature for method. 54 * 55 * @param type the class that contains method 56 * @param name the name of the method 57 * @param args the types of method's parameters 58 */ 59 Signature(Class<?> type, String name, Class<?>[] args) { 60 this.type = type; 61 this.name = name; 62 this.args = args; 63 } 64 65 /** 66 * Indicates whether some other object is "equal to" this one. 67 * 68 * @param object the reference object with which to compare 69 * @return {@code true} if this object is the same as the 70 * {@code object} argument, {@code false} otherwise 71 * @see #hashCode() 72 */ 73 @Override 74 public boolean equals(Object object) { 75 if (this == object) { 76 return true; 77 } 78 if (object instanceof Signature) { 79 Signature signature = (Signature) object; 80 return isEqual(signature.type, this.type) 81 && isEqual(signature.name, this.name) 82 && isEqual(signature.args, this.args); 83 } 84 return false; 85 } 86 87 /** 88 * Indicates whether some object is "equal to" another one. 89 * This method supports {@code null} values. 90 * 91 * @param obj1 the first reference object that will compared 92 * @param obj2 the second reference object that will compared 93 * @return {@code true} if first object is the same as the second object, 94 * {@code false} otherwise 95 */ 96 private static boolean isEqual(Object obj1, Object obj2) { 97 return (obj1 == null) 98 ? obj2 == null 99 : obj1.equals(obj2); 100 } 101 102 /** 103 * Indicates whether some array is "equal to" another one. 104 * This method supports {@code null} values. 105 * 106 * @param args1 the first reference array that will compared 107 * @param args2 the second reference array that will compared 108 * @return {@code true} if first array is the same as the second array, 109 * {@code false} otherwise 110 */ 111 private static boolean isEqual(Class<?>[] args1, Class<?>[] args2) { 112 if ((args1 == null) || (args2 == null)) { 113 return args1 == args2; 114 } 115 if (args1.length != args2.length) { 116 return false; 117 } 118 for (int i = 0; i < args1.length; i++) { 119 if (!isEqual(args1[i], args2[i])) { 120 return false; 121 } 122 } 123 return true; 124 } 125 126 /** 127 * Returns a hash code value for the object. 128 * This method is supported for the benefit of hashtables 129 * such as {@link java.util.HashMap} or {@link java.util.HashSet}. 130 * Hash code computed using algorithm 131 * suggested in Effective Java, Item 8. 132 * 133 * @return a hash code value for this object 134 * @see #equals(Object) 135 */ 136 @Override 137 public int hashCode() { 138 if (this.code == 0) { 139 int code = 17; 140 code = addHashCode(code, this.type); 141 code = addHashCode(code, this.name); 142 143 if (this.args != null) { 144 for (Class<?> arg : this.args) { 145 code = addHashCode(code, arg); 146 } 147 } 148 this.code = code; 149 } 150 return this.code; 151 } 152 153 /** 154 * Adds hash code value if specified object. 155 * This is a part of the algorithm 156 * suggested in Effective Java, Item 8. 157 * 158 * @param code current hash code value 159 * @param object object that updates hash code value 160 * @return updated hash code value 161 * @see #hashCode() 162 */ 163 private static int addHashCode(int code, Object object) { 164 code *= 37; 165 return (object != null) 166 ? code + object.hashCode() 167 : code; 168 } 169 }