/** * Copyright 2001-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package be.selckin.swu.pmodel; import net.sf.cglib.core.CollectionUtils; import net.sf.cglib.core.VisibilityPredicate; import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.Factory; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import org.objenesis.Objenesis; import org.objenesis.ObjenesisStd; import java.io.Serializable; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.List; /** * Some code based on and taken from EasyMock */ public class ProxyFactory { private final Objenesis objenesis = new ObjenesisStd(); @SuppressWarnings("unchecked") public <T> T createProxy(Class<T> type, InvocationHandler handler) { MethodInterceptor interceptor = new ProxyMethodInterceptor(handler); Enhancer enhancer = new Enhancer() { @SuppressWarnings("unchecked") @Override protected void filterConstructors(Class sc, List constructors) { CollectionUtils.filter(constructors, new VisibilityPredicate(sc, true)); } }; enhancer.setUseCache(false); enhancer.setSuperclass(type); enhancer.setCallbackType(interceptor.getClass()); Class<?> mockClass = enhancer.createClass(); Enhancer.registerCallbacks(mockClass, null); Enhancer.registerStaticCallbacks(mockClass, new Callback[]{interceptor}); Factory mock = (Factory) objenesis.newInstance(mockClass); // cglib has code that normally gets called in the constructor, but we instantiated the class without calling the constructor, // so call the cglib code this way. mock.getCallback(0); return (T) mock; } public static class ProxyMethodInterceptor implements MethodInterceptor, Serializable { private final InvocationHandler handler; public ProxyMethodInterceptor(InvocationHandler handler) { this.handler = handler; } @SuppressWarnings("ProhibitedExceptionDeclared") @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { return handler.invoke(obj, method, args); } } }