/* Created on 19.07.2004 */ package org.jmock.extension; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import org.jmock.core.AbstractDynamicMock; import org.jmock.core.DynamicMockError; import org.jmock.core.Invocation; import org.jmock.core.InvocationDispatcher; /** * @author Martin Kersten */ public class CGLibCoreMock extends AbstractDynamicMock { private Object proxy=null; public CGLibCoreMock( Class mockedClass, String name ) { super( mockedClass, name); } public CGLibCoreMock(Class mockedClass, String name, InvocationDispatcher invocationDispatcher) { super( mockedClass, name, invocationDispatcher ); } private ClassLoader getClassLoader() { return getMockedType().getClassLoader(); } protected Enhancer createEnhancer(Class mockedClass) { Enhancer enhancer=new Enhancer(); enhancer.setClassLoader(getClassLoader()); enhancer.setSuperclass(mockedClass); enhancer.setCallback(createMethodInterceptor()); return enhancer; } protected MethodInterceptor createMethodInterceptor() { return new MyInterceptor(); } public Object createProxy() { return createProxy(new Class[0], new Object[0]); } public Object createProxy(Class [] argumentTypes, Object [] arguments) { checkProxyCreationIsSupported(); proxy=createEnhancer(getMockedType()).create(argumentTypes,arguments); return proxy; } private void checkProxyCreationIsSupported() { if(isProxyConstructed()) throw new UnsupportedOperationException( "A proxy may only be created once."); } private boolean isProxyConstructed() { return proxy!=null; } public Object proxy() { if(!isProxyConstructed()) return createProxy(); else return proxy(); } private class MyInterceptor implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] args, MethodProxy superProxy ) throws Throwable { Invocation invocation = new Invocation(proxy,method,args); try { return mockInvocation(invocation); } catch(DynamicMockError e) { if(!isProxyConstructed()) return superProxy.invokeSuper(obj,args); else throw e; } } } }