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