1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 package org.codehaus.groovy.runtime;
36
37 import java.util.ArrayList;
38 import java.util.Collections;
39 import java.util.List;
40
41 /***
42 * An abstract base class for a key used for comparators and Map keys to lookup a method by
43 * name and parameter types
44 *
45 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
46 * @version $Revision: 1.2 $
47 */
48 public abstract class MethodKey {
49
50 private int hash;
51 private String name;
52
53 public MethodKey(String name) {
54 this.name = name;
55 }
56
57 /***
58 * Creates an immutable copy that we can cache.
59 */
60 public MethodKey createCopy() {
61 int size = getParameterCount();
62 Class[] paramTypes = new Class[size];
63 for (int i = 0; i < size; i++) {
64 paramTypes[i] = getParameterType(i);
65 }
66 return new DefaultMethodKey(name, paramTypes);
67 }
68
69 public boolean equals(Object that) {
70 if (this == that) {
71 return true;
72 }
73 else if (hashCode() == that.hashCode() && that instanceof MethodKey) {
74 return equals((MethodKey) that);
75 }
76 return false;
77 }
78
79 public boolean equals(MethodKey that) {
80 int size = getParameterCount();
81 if (name.equals(that.name) && size == that.getParameterCount()) {
82 for (int i = 0; i < size; i++) {
83 if (!getParameterType(i).equals(that.getParameterType(i))) {
84 return false;
85 }
86 }
87 return true;
88 }
89 return false;
90 }
91
92 public int hashCode() {
93 if (hash == 0) {
94 hash = createHashCode();
95 if (hash == 0) {
96 hash = 0xcafebabe;
97 }
98 }
99 return hash;
100 }
101
102 public String toString() {
103 return super.toString() + "[name:" + name + "; params:" + getParamterTypes();
104 }
105
106 public String getName() {
107 return name;
108 }
109
110 public List getParamterTypes() {
111 int size = getParameterCount();
112 if (size <= 0) {
113 return Collections.EMPTY_LIST;
114 }
115 List params = new ArrayList(size);
116 for (int i = 0; i < size; i++) {
117 params.add(getParameterType(i));
118 }
119 return params;
120 }
121
122 public abstract int getParameterCount();
123 public abstract Class getParameterType(int index);
124
125 protected int createHashCode() {
126 int answer = name.hashCode();
127 int size = getParameterCount();
128
129 /*** @todo we should use the real Josh Bloch algorithm here */
130
131
132
133 for (int i = 0; i < size; i++) {
134 answer *= 37;
135 answer = 1 + getParameterType(i).hashCode();
136 }
137 return answer;
138 }
139 }