autofixture.generators.objects.implementationdetails.InterfaceHandler Maven / Gradle / Ivy
package autofixture.generators.objects.implementationdetails;
import autofixture.interfaces.FixtureContract;
import autofixture.interfaces.InstanceType;
import com.google.common.base.Optional;
import com.google.common.reflect.TypeToken;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class InterfaceHandler implements InvocationHandler {
private final FixtureContract fixture;
private final InstanceType instanceType;
private final MethodsInvocationResultCache methodsInvocationResultCache = new MethodsInvocationResultCache();
public InterfaceHandler(final FixtureContract fixture, final InstanceType instanceType) {
this.fixture = fixture;
this.instanceType = instanceType;
}
@Override
public Object invoke(final Object proxy, final Method method, final Object[] arguments) throws Exception {
final TypeToken> returnType = instanceType.resolveActualTypeOf(method);
if (isHashCodeMethod(method)) {
return System.identityHashCode(proxy);
}
if (isEqualsMethod(method, arguments)) {
return proxy == arguments[0];
}
if (wasCalledAtLeastOnceOn(proxy, method)) {
return methodsInvocationResultCache.getResultFor(proxy, method);
}
return generateFreshValueFor(proxy, method, returnType);
}
private boolean isHashCodeMethod(final Method method) {
return "hashCode".equals(method.getName());
}
private boolean wasCalledAtLeastOnceOn(final Object proxy, final Method method) {
return methodsInvocationResultCache.containAResultFor(proxy, method);
}
private boolean isEqualsMethod(final Method mtd, final Object[] arguments) {
return "equals".equals(mtd.getName()) && arguments.length == 1;
}
//TODO check case when new X().GetValue() and new X().GetValue() afterwards - does this work?
private Object generateFreshValueFor(final Object proxy, final Method method, final TypeToken> returnType) {
final Optional