package com.maxifier.guice.events; import gnu.trove.map.hash.THashMap; import net.sf.cglib.reflect.FastClass; import net.sf.cglib.reflect.FastMethod; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.Method; import java.util.Map; import static java.lang.reflect.Modifier.isPublic; /** * Created by IntelliJ IDEA. * User: dalex * Date: 22.06.2009 * Time: 12:33:50 */ public class ClassgenHandlerInvocator<T, L> extends ReflectionHandlerInvocator<T, L> { private static final Logger log = LoggerFactory.getLogger(ClassgenHandlerInvocator.class); private static final Map<Method, FastMethod> METHODS_CACHE = new THashMap<Method, FastMethod>(); private static final Object[] NO_ARGS = {}; private final FastMethod fastMethod; public ClassgenHandlerInvocator(Method method) { super(method); if (!isPublic(method.getDeclaringClass().getModifiers()) || !isPublic(method.getModifiers())) { fastMethod = null; } else { fastMethod = getOrCreateInvocator(method); } } private static synchronized FastMethod getOrCreateInvocator(Method method) { //noinspection unchecked FastMethod inv = METHODS_CACHE.get(method); if (inv == null) { try { inv = FastClass.create(method.getDeclaringClass()).getMethod(method); METHODS_CACHE.put(method, inv); } catch (Throwable e) { log.error("Unable to create FastMethod for " + method, e); } } return inv; } @Override public Object invoke(L instance, T message) throws Exception { if (fastMethod == null) { return super.invoke(instance, message); } else { if (paramType != null) { return fastMethod.invoke(instance, new Object[]{message}); } else { return fastMethod.invoke(instance, NO_ARGS); } } } }