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 @Override
070 public boolean equals(Object obj) {
071 if (this == obj) {
072 return true;
073 }
074
075 if (!(obj instanceof MethodKey)) {
076 return false;
077 }
078
079 MethodKey methodKey = (MethodKey)obj;
080
081 if ((_declaringClass == methodKey._declaringClass) &&
082 Validator.equals(_methodName, methodKey._methodName) &&
083 Arrays.equals(_parameterTypes, methodKey._parameterTypes)) {
084
085 return true;
086 }
087
088 return false;
089 }
090
091 public Class<?> getDeclaringClass() {
092 return _declaringClass;
093 }
094
095 public Method getMethod() throws NoSuchMethodException {
096 return MethodCache.get(this);
097 }
098
099 public String getMethodName() {
100 return _methodName;
101 }
102
103 public Class<?>[] getParameterTypes() {
104 return _parameterTypes;
105 }
106
107 @Override
108 public int hashCode() {
109
110
111
112 return _declaringClass.getName().hashCode() ^ _methodName.hashCode();
113 }
114
115 public void readExternal(ObjectInput objectInput)
116 throws ClassNotFoundException, IOException {
117
118 int size = objectInput.readInt();
119
120 byte[] data = new byte[size];
121
122 objectInput.readFully(data);
123
124 Deserializer deserializer = new Deserializer(ByteBuffer.wrap(data));
125
126 _declaringClass = deserializer.readObject();
127 _methodName = deserializer.readString();
128
129 int parameterTypesLength = deserializer.readInt();
130
131 _parameterTypes = new Class<?>[parameterTypesLength];
132
133 for (int i = 0; i < parameterTypesLength; i++) {
134 _parameterTypes[i] = deserializer.readObject();
135 }
136 }
137
138 @Override
139 public String toString() {
140 if (_toString != null) {
141 return _toString;
142 }
143
144 StringBundler sb = new StringBundler(4 + _parameterTypes.length * 2);
145
146 sb.append(_declaringClass.getName());
147 sb.append(StringPool.PERIOD);
148 sb.append(_methodName);
149 sb.append(StringPool.OPEN_PARENTHESIS);
150
151 for (Class<?> parameterType : _parameterTypes) {
152 sb.append(parameterType.getName());
153 sb.append(StringPool.COMMA);
154 }
155
156 sb.setIndex(sb.index() - 1);
157
158 sb.append(StringPool.CLOSE_PARENTHESIS);
159
160 _toString = sb.toString();
161
162 return _toString;
163 }
164
165 public MethodKey transform(ClassLoader classLoader)
166 throws ClassNotFoundException {
167
168 Class<?> declaringClass = classLoader.loadClass(
169 _declaringClass.getName());
170
171 Class<?>[] parameterTypes = new Class<?>[_parameterTypes.length];
172
173 for (int i = 0; i < _parameterTypes.length; i++) {
174 parameterTypes[i] = classLoader.loadClass(
175 _parameterTypes[i].getName());
176 }
177
178 return new MethodKey(declaringClass, _methodName, parameterTypes);
179 }
180
181 public void writeExternal(ObjectOutput objectOutput) throws IOException {
182 Serializer serializer = new Serializer();
183
184 serializer.writeObject(_declaringClass);
185 serializer.writeString(_methodName);
186 serializer.writeInt(_parameterTypes.length);
187
188 for (Class<?> parameterType : _parameterTypes) {
189 serializer.writeObject(parameterType);
190 }
191
192 ByteBuffer byteBuffer = serializer.toByteBuffer();
193
194 objectOutput.writeInt(byteBuffer.remaining());
195 objectOutput.write(
196 byteBuffer.array(), byteBuffer.position(), byteBuffer.remaining());
197 }
198
199 private static final long serialVersionUID = 1L;
200
201 private Class<?> _declaringClass;
202
203 private String _methodName;
204 private Class<?>[] _parameterTypes;
205
206
207
208 private String _toString;
209
210 }