package org.jboss.seam.async;
import static org.jboss.seam.ComponentType.JAVA_BEAN;
import org.jboss.seam.annotations.async.Asynchronous;
import org.jboss.seam.annotations.intercept.AroundInvoke;
import org.jboss.seam.annotations.intercept.Interceptor;
import org.jboss.seam.annotations.intercept.InterceptorType;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.intercept.AbstractInterceptor;
import org.jboss.seam.intercept.InvocationContext;
/**
* Dispatches method calls to @Asynchronous methods
* asynchronously, and returns the "timer" object
* if necessary.
*
* @author Gavin King
*
*/
@Interceptor(stateless=true, type=InterceptorType.CLIENT)
public class AsynchronousInterceptor extends AbstractInterceptor
{
private static final long serialVersionUID = 9194177339867853303L;
private static final String REENTRANT = "org.jboss.seam.async.AsynchronousIntercepter.REENTRANT";
@AroundInvoke
public Object aroundInvoke(InvocationContext invocation) throws Exception
{
boolean scheduleAsync = invocation.getMethod().isAnnotationPresent(Asynchronous.class) &&
(!isExecutingAsynchronousCall() || Contexts.getEventContext().isSet(REENTRANT));
if (scheduleAsync)
{
Dispatcher dispatcher = AbstractDispatcher.instance();
if (dispatcher==null)
{
throw new IllegalStateException("org.jboss.seam.async.dispatcher is not installed in components.xml");
}
Object timer = dispatcher.scheduleInvocation( invocation, getComponent() );
//if the method returns a Timer, return it to the client
return timer!=null && invocation.getMethod().getReturnType().isAssignableFrom( timer.getClass() ) ? timer : null;
} else {
boolean setFlag = false;
if (isExecutingAsynchronousCall()) {
Contexts.getEventContext().set(REENTRANT, true);
setFlag = true;
}
try {
return invocation.proceed();
} finally {
if (setFlag) {
Contexts.getEventContext().remove(REENTRANT);
}
}
}
}
private boolean isExecutingAsynchronousCall()
{
return Contexts.getEventContext().isSet(AbstractDispatcher.EXECUTING_ASYNCHRONOUS_CALL);
}
public boolean isInterceptorEnabled()
{
return ( getComponent().getType().isEjb() && getComponent().businessInterfaceHasAnnotation(Asynchronous.class) ) ||
( getComponent().getType() == JAVA_BEAN && getComponent().beanClassHasAnnotation(Asynchronous.class) );
}
}