1/* 2 * Copyright 2001-2009 OFFIS, Tammo Freese 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package org.easymock.internal; 17 18import java.io.IOException; 19import java.io.Serializable; 20import java.lang.reflect.InvocationHandler; 21import java.lang.reflect.Method; 22import java.lang.reflect.Proxy; 23 24public class ObjectMethodsFilter implements InvocationHandler, Serializable { 25 26 private static final long serialVersionUID = -2120581954279966998L; 27 28 private transient Method equalsMethod; 29 30 private transient Method hashCodeMethod; 31 32 private transient Method toStringMethod; 33 34 private final MockInvocationHandler delegate; 35 36 private final String name; 37 38 public ObjectMethodsFilter(Class<?> toMock, MockInvocationHandler delegate, 39 String name) { 40 if (name != null && !Invocation.isJavaIdentifier(name)) { 41 throw new IllegalArgumentException(String.format("'%s' is not a valid Java identifier.", name)); 42 43 } 44 try { 45 if (toMock.isInterface()) { 46 toMock = Object.class; 47 } 48 equalsMethod = toMock.getMethod("equals", 49 new Class[] { Object.class }); 50 hashCodeMethod = toMock.getMethod("hashCode", (Class[]) null); 51 toStringMethod = toMock.getMethod("toString", (Class[]) null); 52 } catch (NoSuchMethodException e) { 53 // ///CLOVER:OFF 54 throw new RuntimeException("An Object method could not be found!"); 55 // ///CLOVER:ON 56 } 57 this.delegate = delegate; 58 this.name = name; 59 } 60 61 public final Object invoke(Object proxy, Method method, Object[] args) 62 throws Throwable { 63 if (equalsMethod.equals(method)) { 64 return Boolean.valueOf(proxy == args[0]); 65 } 66 if (hashCodeMethod.equals(method)) { 67 return Integer.valueOf(System.identityHashCode(proxy)); 68 } 69 if (toStringMethod.equals(method)) { 70 return mockToString(proxy); 71 } 72 return delegate.invoke(proxy, method, args); 73 } 74 75 private String mockToString(Object proxy) { 76 return (name != null) ? name : "EasyMock for " + mockType(proxy); 77 } 78 79 private String mockType(Object proxy) { 80 if (Proxy.isProxyClass(proxy.getClass())) 81 return proxy.getClass().getInterfaces()[0].toString(); 82 else 83 return proxy.getClass().getSuperclass().toString(); 84 } 85 86 public MockInvocationHandler getDelegate() { 87 return delegate; 88 } 89 90 private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException { 91 stream.defaultReadObject(); 92 try { 93 toStringMethod = ((MethodSerializationWrapper) stream.readObject()).getMethod(); 94 equalsMethod = ((MethodSerializationWrapper) stream.readObject()).getMethod(); 95 hashCodeMethod = ((MethodSerializationWrapper) stream.readObject()).getMethod(); 96 } catch (NoSuchMethodException e) { 97 // ///CLOVER:OFF 98 throw new IOException(e.toString()); 99 // ///CLOVER:ON 100 } 101 } 102 103 private void writeObject(java.io.ObjectOutputStream stream) throws IOException { 104 stream.defaultWriteObject(); 105 stream.writeObject(new MethodSerializationWrapper(toStringMethod)); 106 stream.writeObject(new MethodSerializationWrapper(equalsMethod)); 107 stream.writeObject(new MethodSerializationWrapper(hashCodeMethod)); 108 } 109}