//$Id: ConversationalInterceptor.java 8626 2008-08-07 19:50:09Z pete.muir@jboss.org $
package org.jboss.seam.core;
import java.lang.reflect.Method;
import org.jboss.seam.NoConversationException;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.Conversational;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.bpm.BeginTask;
import org.jboss.seam.annotations.bpm.StartTask;
import org.jboss.seam.annotations.intercept.AroundInvoke;
import org.jboss.seam.annotations.intercept.Interceptor;
import org.jboss.seam.bpm.BusinessProcessInterceptor;
import org.jboss.seam.intercept.AbstractInterceptor;
import org.jboss.seam.intercept.InvocationContext;
/**
* Check that a conversational bean is not being invoked
* outside the scope of a long-running conversation. If
* it is, throw an exception.
*
* @author Gavin King
*/
@Interceptor(stateless=true,
around={BijectionInterceptor.class, BusinessProcessInterceptor.class})
public class ConversationalInterceptor extends AbstractInterceptor
{
private static final long serialVersionUID = 1127583515811479385L;
@AroundInvoke
public Object aroundInvoke(InvocationContext invocation) throws Exception
{
Method method = invocation.getMethod();
if ( isNoConversationForConversationalBean(method) )
{
Events.instance().raiseEvent("org.jboss.seam.noConversation");
throw new NoConversationException( "no long-running conversation for @Conversational bean: " + getComponent().getName() );
}
return invocation.proceed();
}
private boolean isNoConversationForConversationalBean(Method method)
{
boolean classlevelViolation = componentIsConversational() &&
!Manager.instance().isLongRunningOrNestedConversation() &&
!method.isAnnotationPresent(Begin.class) &&
!method.isAnnotationPresent(StartTask.class) &&
!method.isAnnotationPresent(BeginTask.class) &&
!method.isAnnotationPresent(Destroy.class) &&
!method.isAnnotationPresent(Create.class); //probably superfluous
if (classlevelViolation) return true;
boolean methodlevelViolation = methodIsConversational(method) &&
!Manager.instance().isLongRunningOrNestedConversation();
return methodlevelViolation;
}
private boolean methodIsConversational(Method method)
{
return method.isAnnotationPresent(Conversational.class);
}
private boolean componentIsConversational()
{
return getComponent().getBeanClass().isAnnotationPresent(Conversational.class);
}
public boolean isInterceptorEnabled()
{
return getComponent().beanClassHasAnnotation(Conversational.class);
}
}