private void invoke( final T t, final Class<?> c, final Class<? extends Annotation> annotation, final InterceptionType interceptionType ) { final Set<Method> candidates = stream(c.getDeclaredMethods()) .filter(it -> it.getAnnotation(annotation) != null) .collect(toSet()); if (candidates.isEmpty()) { return; } if (candidates.size() > 1) { throw new TestEEfiException("Only one @" + annotation.getSimpleName() + " method is allowed per class"); } // TODO check for correct modifiers etc. final Method method = candidates.iterator().next(); method.setAccessible(true); try { invokeIntercepted(new Object[]{}, t, method, interceptionType); } catch (final Throwable e) { throw new TestEEfiException("Failed to invoke @" + annotation.getSimpleName() + " method " + method, e); } }
private InterceptorData createInterceptorData(final Interceptor<?> i) { final InterceptorData data; if (CdiInterceptorBean.class.isInstance(i)) { final CdiInterceptorBean cdiInterceptorBean = CdiInterceptorBean.class.cast(i); data = new InterceptorData(i.getBeanClass()); data.getAroundInvoke().addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.AROUND_INVOKE)); data.getPostConstruct().addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.POST_CONSTRUCT)); data.getPreDestroy().addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.PRE_DESTROY)); data.getPostActivate().addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.POST_ACTIVATE)); data.getPrePassivate().addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.PRE_PASSIVATE)); data.getAroundTimeout().addAll(getInterceptionMethodAsListOrEmpty(cdiInterceptorBean, InterceptionType.AROUND_TIMEOUT)); /* AfterBegin, BeforeCompletion and AfterCompletion are ignored since not handled by CDI */ } else { // TODO: here we are not as good as in previous since we loose inheritance for instance data = InterceptorData.scan(i.getBeanClass()); } return data; }
public InterceptorChain getInterceptorChain( final ContextFactory contextFactory ) { return new InterceptorChain() { @Override public <T> Object invoke( final Object target, final Method method, final Object[] args, final ChainEnd<T> next, final InterceptionType interceptionType ) throws Throwable { if (interceptorBindings == null) { return next.invoke(); } return processInterceptorChain( new ArrayList<>(interceptorBindings.getAllInterceptors()), target, method, args, contextFactory, next, interceptionType ); } }; }
@SuppressWarnings("unchecked") private <T> Object processInterceptorChain( final List<Interceptor<?>> chain, final Object target, final Method method, final Object[] args, final ContextFactory contextFactory, final InterceptorChain.ChainEnd<T> next, final InterceptionType interceptionType ) throws Throwable { if (chain.isEmpty()) { return next.invoke(); } final Interceptor<Object> it = (Interceptor<Object>) chain.remove(0); final Releaser releaser = new Releaser(); try { return intercept( it, it.create(contextFactory.create(it, releaser)), target, method, args, () -> processInterceptorChain(chain, target, method, args, contextFactory, next, interceptionType), interceptionType ); } finally { releaser.release(); } }
private <T> Object intercept( final Interceptor<T> it, final T instance, final Object target, final Method method, final Object[] args, final Proceed proceed, final InterceptionType interceptionType ) throws Exception { return it.intercept( interceptionType, instance, context(target, interceptionType == InterceptionType.AROUND_INVOKE ? method : null, args, proceed) ); }
<T> Object invoke( Object target, Method method, Object[] args, ChainEnd<T> next, InterceptionType interceptionType ) throws Throwable;
private Object invokeIntercepted( final Object[] args, final T target, final Method method, final InterceptionType interceptionType ) throws Throwable { return chain.invoke(target, method, args, () -> { try { return method.invoke(target, args); } catch (final InvocationTargetException e) { throw e.getTargetException(); } }, interceptionType); }
private void invoke(final T t, final Class<? extends Annotation> annotation, final InterceptionType type) { Class<?> c = t.getClass(); while (c != null && c != Object.class) { invoke(t, c, annotation, type); c = c.getSuperclass(); } }
@Override public List<Interceptor<?>> resolveInterceptors(final InterceptionType type, final Annotation... interceptorBindings) { final List<Interceptor<?>> interceptors = super.resolveInterceptors(type, interceptorBindings); final List<Interceptor<?>> parentInterceptors = getParentBm().resolveInterceptors(type, interceptorBindings); for (final Interceptor<?> i : parentInterceptors) { if (!interceptors.contains(i)) { interceptors.add(i); } } return interceptors; }
private List<Interceptor<?>> resolveInterceptors(Object instance, Method method) { BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager(); Annotation[] interceptorBindings = extractInterceptorBindings(beanManager, instance, method); if (interceptorBindings.length > 0) { return beanManager.resolveInterceptors(InterceptionType.AROUND_INVOKE, interceptorBindings); } return new ArrayList<Interceptor<?>>(); }
@Test public void testDisabledInterceptor() { List<Interceptor<?>> interceptors = weld.getBeanManager().resolveInterceptors(InterceptionType.AROUND_INVOKE, FooBinding.Literal.INSTANCE); assertEquals(1, interceptors.size()); assertEquals(MockInterceptor.class, interceptors.get(0).getBeanClass()); }
@Override public boolean intercepts(InterceptionType type) { return this.type.equals(type); }
@Override public Object intercept(InterceptionType type, MockInterceptorInstance instance, InvocationContext ctx) throws Exception { return callback.invoke(ctx, instance.getInterceptedBean()); }
public MockInterceptor aroundInvoke(InterceptionCallback callback) { return type(InterceptionType.AROUND_INVOKE).callback(callback).build(); }
public MockInterceptor aroundConstruct(InterceptionCallback callback) { return type(InterceptionType.AROUND_CONSTRUCT).callback(callback).build(); }
public MockInterceptor postConstruct(InterceptionCallback callback) { return type(InterceptionType.POST_CONSTRUCT).callback(callback).build(); }
public MockInterceptor preDestroy(InterceptionCallback callback) { return type(InterceptionType.PRE_DESTROY).callback(callback).build(); }
@Override public List<Interceptor<?>> resolveInterceptors(InterceptionType type, Annotation... interceptorBindings) { // TODO Auto-generated method stub return null; }
@Override public List<Interceptor<?>> resolveInterceptors( final InterceptionType arg0, final Annotation... arg1) { return this.beanManager.resolveInterceptors(arg0, arg1); }
private List<Method> getInterceptionMethodAsListOrEmpty(final CdiInterceptorBean cdiInterceptorBean, final InterceptionType aroundInvoke) { final Method[] methods = cdiInterceptorBean.getInterceptorMethods(aroundInvoke); return methods == null ? Collections.<Method>emptyList() : asList(methods); }
/** * * @param beanClass * @param type * @param callback * @param interceptorBindings */ private MockInterceptor(Class<?> beanClass, InterceptionType type, InterceptionCallback callback, Set<Annotation> interceptorBindings) { this.beanClass = beanClass; this.type = type; this.callback = callback; this.interceptorBindings = interceptorBindings; }