/* * JBoss, Home of Professional Open Source * * Distributable under LGPL license. * See terms of license at gnu.org. */ package org.jboss.seam.intercept; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.ejb.PostActivate; import javax.ejb.PrePassivate; import javax.interceptor.AroundInvoke; import javax.interceptor.InvocationContext; import org.jboss.seam.log.LogProvider; import org.jboss.seam.log.Logging; import org.jboss.seam.Component; import org.jboss.seam.Seam; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.intercept.InterceptorType; /** * Controller interceptor for server-side interceptors of * EJB3 session bean components. * * @author Gavin King */ public class SessionBeanInterceptor extends RootInterceptor { private static final long serialVersionUID = -7474586917199426345L; private static final LogProvider log = Logging.getLogProvider(SessionBeanInterceptor.class); public static ThreadLocal<Component> COMPONENT = new ThreadLocal<Component>(); /** * Called when instantiated by EJB container. * (In this case it might be a Seam component, * but we won't know until postConstruct() is * called.) */ public SessionBeanInterceptor() { super(InterceptorType.SERVER); } @AroundInvoke public Object aroundInvoke(InvocationContext invocation) throws Exception { return invoke( new EJBInvocationContext(invocation), EventType.AROUND_INVOKE); } @PrePassivate public void prePassivate(InvocationContext invocation) { invokeAndHandle( new EJBInvocationContext(invocation), EventType.PRE_PASSIVATE); } @PostActivate public void postActivate(InvocationContext invocation) { invokeAndHandle( new EJBInvocationContext(invocation), EventType.POST_ACTIVATE); } @PreDestroy public void preDestroy(InvocationContext invocation) { invokeAndHandle( new EJBInvocationContext(invocation), EventType.PRE_DESTORY); } @PostConstruct public void postConstruct(InvocationContext invocation) { Component invokingComponent = SessionBeanInterceptor.COMPONENT.get(); Object bean = invocation.getTarget(); if ( invokingComponent!=null && invokingComponent.getBeanClass().isInstance(bean) ) { //the session bean was obtained by the application by //calling Component.getInstance(), could be a role //other than the default role //note: minor bug here, since if we got another instance of the same // bean from JNDI or @EJB while constructing a component, // or in an interceptor while calling a component, // this will cause that bean to think it is an instance of the // component role (rather than the default role) if ( log.isTraceEnabled() ) { log.trace("post construct phase for instance of component: " + invokingComponent.getName()); } init(invokingComponent); } else if ( bean.getClass().isAnnotationPresent(Name.class) ) { //the session bean was obtained by the application from //JNDI, or @EJB (or it was an MDB), so assume the default role //TODO: look at more than just @Name, consider components.xml String defaultComponentName = bean.getClass().getAnnotation(Name.class).value(); if ( log.isTraceEnabled() ) { log.trace("post construct phase for component instantiated outside Seam, assuming default role: " + defaultComponentName); } init( Seam.componentForName(defaultComponentName) ); } else { if ( log.isTraceEnabled() ) { log.trace("post construct phase for non-component bean"); } initNonSeamComponent(); } postConstruct(bean); invokeAndHandle( new EJBInvocationContext(invocation), EventType.POST_CONSTRUCT ); } }