//$Id: RemoveInterceptor.java 8626 2008-08-07 19:50:09Z pete.muir@jboss.org $ package org.jboss.seam.ejb; import static org.jboss.seam.ComponentType.STATEFUL_SESSION_BEAN; import java.lang.reflect.Method; import java.rmi.RemoteException; import javax.ejb.ApplicationException; import javax.ejb.Remove; import org.jboss.seam.log.LogProvider; import org.jboss.seam.log.Logging; 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.intercept.AbstractInterceptor; import org.jboss.seam.intercept.InvocationContext; /** * Removes SFSB components from the Seam context after invocation * of an EJB @Remove method, or when a system exception is thrown * from the bean. * * @author Gavin King */ @Interceptor(stateless=true, type=InterceptorType.CLIENT) public class RemoveInterceptor extends AbstractInterceptor { private static final long serialVersionUID = -6693606158918954699L; private static final LogProvider log = Logging.getLogProvider(RemoveInterceptor.class); @AroundInvoke public Object aroundInvoke(InvocationContext invocation) throws Exception { //we have the method from the local interface, get the corresponding one //for the actual bean class (it has the @Remove annotation) Method removeMethod = getComponent().getRemoveMethod( invocation.getMethod().getName() ); Object result; try { result = invocation.proceed(); } catch (Exception exception) { removeIfNecessary(removeMethod, exception); throw exception; } removeIfNecessary(removeMethod); return result; } private void removeIfNecessary(Method removeMethod, Exception exception) { if ( exception instanceof RuntimeException || exception instanceof RemoteException ) { if ( !exception.getClass().isAnnotationPresent(ApplicationException.class) ) { //it is a "system exception" remove(); } } else if ( removeMethod!=null ) { if ( !removeMethod.getAnnotation(Remove.class).retainIfException() ) { remove(); } } } private void removeIfNecessary(Method removeMethod) { if ( removeMethod!=null ) { remove(); } } private void remove() { getComponent().getScope().getContext().remove( getComponent().getName() ); if ( log.isDebugEnabled() ) { log.debug( "Stateful component was removed: " + getComponent().getName() ); } } public boolean isInterceptorEnabled() { return getComponent().getType() == STATEFUL_SESSION_BEAN; } }