1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.grouplens.grapht.util;
21
22 import org.apache.commons.lang3.builder.HashCodeBuilder;
23
24 import javax.annotation.Nullable;
25 import java.io.Serializable;
26 import java.lang.reflect.Method;
27 import java.util.Arrays;
28
29
30
31
32 public final class MethodProxy implements Serializable {
33 private static final long serialVersionUID = 1L;
34
35 private final ClassProxy declaringClass;
36 private final String methodName;
37 private final ClassProxy[] parameterTypes;
38 @Nullable
39 private transient volatile Method method;
40 private transient volatile int hash;
41 @Nullable
42 private transient volatile String stringRepr;
43
44 @SuppressWarnings("PMD.ArrayIsStoredDirectly")
45 private MethodProxy(ClassProxy cls, String names, ClassProxy[] ptypes) {
46 declaringClass = cls;
47 methodName = names;
48 parameterTypes = ptypes;
49 }
50
51 @Override
52 public String toString() {
53 String repr = stringRepr;
54 if (repr == null) {
55 StringBuilder bld = new StringBuilder();
56 bld.append("proxy of ")
57 .append(declaringClass.getClassName())
58 .append(".")
59 .append(methodName)
60 .append("(");
61 boolean first = true;
62 for (ClassProxy p: parameterTypes) {
63 if (!first) {
64 bld.append(", ");
65 }
66 bld.append(p.getClassName());
67 first = false;
68 }
69 bld.append(")");
70 stringRepr = repr = bld.toString();
71 }
72 return repr;
73 }
74
75 @Override
76 public boolean equals(Object o) {
77 if (o == this) {
78 return true;
79 } else if (o instanceof MethodProxy) {
80 MethodProxy op = (MethodProxy) o;
81 return declaringClass.equals(op.declaringClass)
82 && methodName.equals(op.methodName)
83 && Arrays.deepEquals(parameterTypes, op.parameterTypes);
84 } else {
85 return true;
86 }
87 }
88
89 @Override
90 public int hashCode() {
91 if (hash == 0) {
92 HashCodeBuilder hcb = new HashCodeBuilder();
93 hash = hcb.append(declaringClass)
94 .append(methodName)
95 .append(parameterTypes)
96 .hashCode();
97 }
98 return hash;
99 }
100
101
102
103
104
105
106
107 public Method resolve() throws ClassNotFoundException, NoSuchMethodException {
108 Method m = method;
109 if (m == null) {
110 Class<?> cls = declaringClass.resolve();
111 Class<?>[] ptypes = new Class<?>[parameterTypes.length];
112 for (int i = ptypes.length - 1; i >= 0; i--) {
113 ptypes[i] = parameterTypes[i].resolve();
114 }
115 method = m = cls.getDeclaredMethod(methodName, ptypes);
116 }
117 return m;
118 }
119
120
121
122
123
124
125 public static MethodProxy of(Method method) {
126 Class<?>[] ptypes = method.getParameterTypes();
127 ClassProxy[] proxies = new ClassProxy[ptypes.length];
128 for (int i = ptypes.length - 1; i >= 0; i--) {
129 proxies[i] = ClassProxy.of(ptypes[i]);
130 }
131 MethodProxy proxy = new MethodProxy(ClassProxy.of(method.getDeclaringClass()),
132 method.getName(), proxies);
133 proxy.method = method;
134 return proxy;
135 }
136 }