001    package groovy.mock.interceptor;
002    
003    import groovy.lang.ProxyMetaClass;
004    import groovy.lang.MetaClassRegistry;
005    import groovy.lang.MetaClass;
006    
007    import java.beans.IntrospectionException;
008    
009    import org.codehaus.groovy.runtime.InvokerHelper;
010    
011    /**
012     * The ProxyMetaClass for the MockInterceptor.
013     * Instance and class methods are intercepted, but constructors are not to allow mocking of aggregated objects.
014     * @author Dierk Koenig
015     */
016    
017    public class MockProxyMetaClass extends ProxyMetaClass {
018    
019        /**
020         * @param adaptee the MetaClass to decorate with interceptability
021         */
022        public MockProxyMetaClass(MetaClassRegistry registry, Class theClass, MetaClass adaptee) throws IntrospectionException {
023            super(registry, theClass, adaptee);
024        }
025    
026        /**
027         * convenience factory method for the most usual case.
028         */
029        public static MockProxyMetaClass make(Class theClass) throws IntrospectionException {
030            MetaClassRegistry metaRegistry = InvokerHelper.getInstance().getMetaRegistry();
031            MetaClass meta = metaRegistry.getMetaClass(theClass);
032            return new MockProxyMetaClass(metaRegistry, theClass, meta);
033        }
034    
035    
036        public Object invokeMethod(final Object object, final String methodName, final Object[] arguments) {
037            if (null == interceptor) {
038                throw new RuntimeException("cannot invoke without interceptor");
039            }
040            return interceptor.beforeInvoke(object, methodName, arguments);
041        }
042    
043        public Object invokeStaticMethod(final Object object, final String methodName, final Object[] arguments) {
044            if (null == interceptor) {
045                throw new RuntimeException("cannot invoke without interceptor");
046            }
047            return interceptor.beforeInvoke(object, methodName, arguments);
048        }
049    
050        /**
051         * Unlike general impl in superclass, ctors are not intercepted but relayed
052         */
053        public Object invokeConstructor(final Object[] arguments) {
054            return adaptee.invokeConstructor(arguments);
055        }
056        
057    }