001
014
015 package com.liferay.portal.kernel.util;
016
017 import com.liferay.portal.kernel.io.Deserializer;
018 import com.liferay.portal.kernel.io.Serializer;
019
020 import java.io.Externalizable;
021 import java.io.IOException;
022 import java.io.ObjectInput;
023 import java.io.ObjectOutput;
024
025 import java.lang.reflect.Method;
026
027 import java.nio.ByteBuffer;
028
029 import java.util.Arrays;
030
031
045 public class MethodKey implements Externalizable {
046
047
051 public MethodKey() {
052 }
053
054 public MethodKey(
055 Class<?> declaringClass, String methodName,
056 Class<?>... parameterTypes) {
057
058 _declaringClass = declaringClass;
059 _methodName = methodName;
060 _parameterTypes = parameterTypes;
061 }
062
063 public MethodKey(Method method) {
064 this(
065 method.getDeclaringClass(), method.getName(),
066 method.getParameterTypes());
067 }
068
069
073 public MethodKey(
074 String declaringClassName, String methodName,
075 Class<?>... parameterTypes) {
076
077 Thread currentThread = Thread.currentThread();
078
079 ClassLoader classLoader = currentThread.getContextClassLoader();
080
081 try {
082 _declaringClass = classLoader.loadClass(declaringClassName);
083 }
084 catch (ClassNotFoundException cnfe) {
085 throw new RuntimeException(cnfe);
086 }
087
088 _methodName = methodName;
089 _parameterTypes = parameterTypes;
090 }
091
092 @Override
093 public boolean equals(Object obj) {
094 if (this == obj) {
095 return true;
096 }
097
098 if (!(obj instanceof MethodKey)) {
099 return false;
100 }
101
102 MethodKey methodKey = (MethodKey)obj;
103
104 if ((_declaringClass == methodKey._declaringClass) &&
105 Validator.equals(_methodName, methodKey._methodName) &&
106 Arrays.equals(_parameterTypes, methodKey._parameterTypes)) {
107
108 return true;
109 }
110
111 return false;
112 }
113
114 public Class<?> getDeclaringClass() {
115 return _declaringClass;
116 }
117
118 public Method getMethod() throws NoSuchMethodException {
119 return MethodCache.get(this);
120 }
121
122 public String getMethodName() {
123 return _methodName;
124 }
125
126 public Class<?>[] getParameterTypes() {
127 return _parameterTypes;
128 }
129
130 @Override
131 public int hashCode() {
132
133
134
135 return _declaringClass.getName().hashCode() ^ _methodName.hashCode();
136 }
137
138 @Override
139 public void readExternal(ObjectInput objectInput)
140 throws ClassNotFoundException, IOException {
141
142 int size = objectInput.readInt();
143
144 byte[] data = new byte[size];
145
146 objectInput.readFully(data);
147
148 Deserializer deserializer = new Deserializer(ByteBuffer.wrap(data));
149
150 _declaringClass = deserializer.readObject();
151 _methodName = deserializer.readString();
152
153 int parameterTypesLength = deserializer.readInt();
154
155 _parameterTypes = new Class<?>[parameterTypesLength];
156
157 for (int i = 0; i < parameterTypesLength; i++) {
158 _parameterTypes[i] = deserializer.readObject();
159 }
160 }
161
162 @Override
163 public String toString() {
164 if (_toString != null) {
165 return _toString;
166 }
167
168 StringBundler sb = new StringBundler(4 + _parameterTypes.length * 2);
169
170 sb.append(_declaringClass.getName());
171 sb.append(StringPool.PERIOD);
172 sb.append(_methodName);
173 sb.append(StringPool.OPEN_PARENTHESIS);
174
175 for (Class<?> parameterType : _parameterTypes) {
176 sb.append(parameterType.getName());
177 sb.append(StringPool.COMMA);
178 }
179
180 sb.setIndex(sb.index() - 1);
181
182 sb.append(StringPool.CLOSE_PARENTHESIS);
183
184 _toString = sb.toString();
185
186 return _toString;
187 }
188
189 public MethodKey transform(ClassLoader classLoader)
190 throws ClassNotFoundException {
191
192 Class<?> declaringClass = classLoader.loadClass(
193 _declaringClass.getName());
194
195 Class<?>[] parameterTypes = new Class<?>[_parameterTypes.length];
196
197 for (int i = 0; i < _parameterTypes.length; i++) {
198 parameterTypes[i] = classLoader.loadClass(
199 _parameterTypes[i].getName());
200 }
201
202 return new MethodKey(declaringClass, _methodName, parameterTypes);
203 }
204
205 @Override
206 public void writeExternal(ObjectOutput objectOutput) throws IOException {
207 Serializer serializer = new Serializer();
208
209 serializer.writeObject(_declaringClass);
210 serializer.writeString(_methodName);
211 serializer.writeInt(_parameterTypes.length);
212
213 for (Class<?> parameterType : _parameterTypes) {
214 serializer.writeObject(parameterType);
215 }
216
217 ByteBuffer byteBuffer = serializer.toByteBuffer();
218
219 objectOutput.writeInt(byteBuffer.remaining());
220 objectOutput.write(
221 byteBuffer.array(), byteBuffer.position(), byteBuffer.remaining());
222 }
223
224 private static final long serialVersionUID = 1L;
225
226 private Class<?> _declaringClass;
227 private String _methodName;
228 private Class<?>[] _parameterTypes;
229
230
231
232 private String _toString;
233
234 }