package org.apache.webbeans.ejb.common.interceptor;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.PostActivate;
import javax.ejb.PrePassivate;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.spi.Context;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.Decorator;
import javax.interceptor.AroundInvoke;
import javax.interceptor.AroundTimeout;
import javax.interceptor.InvocationContext;
import org.apache.webbeans.config.OWBLogConst;
import org.apache.webbeans.config.WebBeansContext;
import org.apache.webbeans.context.ContextFactory;
import org.apache.webbeans.context.creational.CreationalContextImpl;
import org.apache.webbeans.decorator.DelegateHandler;
import org.apache.webbeans.decorator.WebBeansDecoratorConfig;
import org.apache.webbeans.decorator.WebBeansDecoratorInterceptor;
import org.apache.webbeans.ejb.common.component.BaseEjbBean;
import org.apache.webbeans.inject.OWBInjector;
import org.apache.webbeans.intercept.InterceptorData;
import org.apache.webbeans.intercept.InterceptorDataImpl;
import javax.enterprise.inject.spi.InterceptionType;
import org.apache.webbeans.intercept.InvocationContextImpl;
import org.apache.webbeans.logger.WebBeansLoggerFacade;
import org.apache.webbeans.spi.ContextsService;
import org.apache.webbeans.util.WebBeansUtil;
{
private static final long serialVersionUID = -4317127341083031217L;
private static final Logger logger = WebBeansLoggerFacade.getLogger(OpenWebBeansEjbInterceptor.class);
private static transient ThreadLocal<BaseEjbBean<?>> threadLocal = new ThreadLocal<BaseEjbBean<?>>();
private static transient ThreadLocal<CreationalContext<?>> threadLocalCreationalContext = new ThreadLocal<CreationalContext<?>>();
protected transient Map<Method, List<InterceptorData>> interceptedMethodMap = new WeakHashMap<Method, List<InterceptorData>>();
protected transient Map<Method, List<InterceptorData>> nonCtxInterceptedMethodMap = new WeakHashMap<Method, List<InterceptorData>>();
private transient Map<Class<?>, BaseEjbBean<?>> resolvedBeans = new HashMap<Class<?>, BaseEjbBean<?>>();
private CreationalContext<?> cc;
private transient BaseEjbBean<?> contextual;
private transient WebBeansContext webBeansContext;
private CreationalKey ccKey;
{
}
public static void setThreadLocal(BaseEjbBean<?> ejbBean, CreationalContext<?> creationalContext)
{
threadLocal.set(ejbBean);
threadLocalCreationalContext.set(creationalContext);
}
{
threadLocal.set(null);
threadLocalCreationalContext.set(null);
threadLocal.remove();
threadLocalCreationalContext.remove();
}
@AroundInvoke
{
boolean requestCreated = false;
boolean applicationCreated = false;
boolean requestAlreadyActive = false;
boolean applicationAlreadyActive = false;
if (logger.isLoggable(Level.FINE))
{
logger.log(Level.FINE, "Intercepting EJB method {0} ", ejbContext.getMethod());
}
try
{
if (webBeansContext.getOpenWebBeansConfiguration().isUseEJBInterceptorActivation())
{
int result = activateContexts(RequestScoped.class);
if(result == 1)
{
requestCreated = true;
}
else if(result == -1)
{
requestAlreadyActive = true;
}
result = activateContexts(ApplicationScoped.class);
if(result == 1)
{
applicationCreated = true;
}
else if(result == -1)
{
applicationAlreadyActive = true;
}
}
if (this.contextual == null)
{
return ejbContext.proceed();
}
return callInterceptorsAndDecorators(ejbContext.getMethod(), ejbContext.getTarget(), ejbContext.getParameters(), ejbContext);
}
finally
{
if (webBeansContext.getOpenWebBeansConfiguration().isUseEJBInterceptorActivation())
{
if(!requestAlreadyActive)
{
deActivateContexts(requestCreated, RequestScoped.class);
}
if(!applicationAlreadyActive)
{
deActivateContexts(applicationCreated, ApplicationScoped.class);
}
}
}
}
public void lifecycleCommon(InvocationContext context, InterceptionType interceptionType)
{
try
{
if ((this.contextual != null) && WebBeansUtil.isContainsInterceptorMethod(this.contextual.getInterceptorStack(), interceptionType))
{
InvocationContextImpl impl = new InvocationContextImpl(webBeansContext, this.contextual, context.getTarget(), null, null,
webBeansContext.getInterceptorUtil().getInterceptorMethods(this.contextual.getInterceptorStack(), interceptionType), interceptionType);
impl.setCreationalContext(this.cc);
impl.setEJBInvocationContext(context);
impl.setCcKey(this.ccKey);
impl.proceed();
}
else
{
context.proceed();
}
}
catch (Exception e)
{
logger.log(Level.SEVERE, WebBeansLoggerFacade.constructMessage(OWBLogConst.ERROR_0008, interceptionType), e);
throw new RuntimeException(e);
}
}
@PostConstruct
{
if (logger.isLoggable(Level.FINE))
{
logger.fine("entry");
}
if (this.webBeansContext == null)
{
this.webBeansContext = WebBeansContext.currentInstance();
}
BaseEjbBean<?> injectionTarget = threadLocal.get();
this.ccKey = new CreationalKey();
if (injectionTarget == null)
{
this.contextual = findTargetBean(context.getTarget());
if (this.contextual == null)
{
try
{
context.proceed();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
return;
}
}
else
{
this.contextual = injectionTarget;
unsetThreadLocal();
}
this.cc = webBeansContext.getBeanManagerImpl().createCreationalContext(this.contextual);
if (logger.isLoggable(Level.FINE))
{
logger.log(Level.FINE, "manager = {0} interceptor_instance = {1} contextual = {2} ",
new Object[] { this.webBeansContext.getBeanManagerImpl(), this, this.contextual});
}
lifecycleCommon(context, InterceptionType.POST_CONSTRUCT);
if (webBeansContext.getOpenWebBeansConfiguration().isUseEJBInterceptorInjection())
{
Object instance = context.getTarget();
try
{
OWBInjector.inject(webBeansContext.getBeanManagerImpl(), instance, this.cc);
}
catch (Exception e)
{
logger.log(Level.SEVERE, WebBeansLoggerFacade.constructMessage(OWBLogConst.ERROR_0026, contextual), e);
}
}
}
@PreDestroy
{
lifecycleCommon(context, InterceptionType.PRE_DESTROY);
this.interceptedMethodMap.clear();
this.resolvedBeans.clear();
this.nonCtxInterceptedMethodMap.clear();
if(this.cc != null)
{
this.cc.release();
}
}
{
ContextsService service = webBeansContext.getService(ContextsService.class);
Context ctx = service.getCurrentContext(scopeType);
ContextFactory contextFactory = webBeansContext.getContextFactory();
if(scopeType == RequestScoped.class)
{
if(ctx != null && !ctx.isActive())
{
contextFactory.activateContext(scopeType);
return 0;
}
else if(ctx == null)
{
contextFactory.initRequestContext(null);
return 1;
}
}
ctx = service.getCurrentContext(scopeType);
if(ctx != null && !ctx.isActive())
{
contextFactory.activateContext(scopeType);
return 0;
}
else if(ctx == null)
{
contextFactory.initApplicationContext(null);
return 1;
}
return -1;
}
{
ContextFactory contextFactory = webBeansContext.getContextFactory();
if(scopeType == ApplicationScoped.class)
{
if(destroy)
{
contextFactory.destroyApplicationContext(null);
}
else
{
contextFactory.deActivateContext(ApplicationScoped.class);
}
}
else
{
if(destroy)
{
contextFactory.destroyRequestContext(null);
}
else
{
contextFactory.deActivateContext(RequestScoped.class);
}
}
}
{
if (instance == null)
{
return null;
}
BaseEjbBean<?> ejbBean = this.resolvedBeans.get(instance.getClass());
if(ejbBean == null)
{
Set<Bean<?>> beans = webBeansContext.getBeanManagerImpl().getComponents();
for(Bean<?> bean : beans)
{
if(bean instanceof BaseEjbBean)
{
if(bean.getBeanClass() == instance.getClass())
{
ejbBean = (BaseEjbBean<?>)bean;
if (logger.isLoggable(Level.FINE))
{
logger.log(Level.FINE, "Found managed bean for [{0}] [{1}]", WebBeansLoggerFacade.args(instance.getClass(), ejbBean));
}
this.resolvedBeans.put(instance.getClass(), ejbBean);
break;
}
}
}
}
else
{
if (logger.isLoggable(Level.FINE))
{
logger.log(Level.FINE, "Managed bean for [{0}] found in cache: [{1}]", WebBeansLoggerFacade.args(instance.getClass(), ejbBean));
}
}
return ejbBean;
}
{
Object rv = null;
BaseEjbBean<?> injectionTarget = this.contextual;
InterceptorDataImpl decoratorInterceptorDataImpl = null;
List<Object> decorators = null;
DelegateHandler delegateHandler = null;
List<Decorator<?>> decoratorStack = injectionTarget.getDecoratorStack();
List<InterceptorData> interceptorStack = injectionTarget.getInterceptorStack();
if (logger.isLoggable(Level.FINE))
{
logger.log(Level.FINE, "Decorator stack for target {0}", decoratorStack);
logger.log(Level.FINE, "Interceptor stack {0}", interceptorStack);
}
if (decoratorStack.size() > 0 )
{
if (logger.isLoggable(Level.FINE))
{
logger.fine("Obtaining a delegate");
}
delegateHandler = new DelegateHandler(this.contextual, ejbContext);
final Object delegate =
webBeansContext.getProxyFactory().createDecoratorDelegate(injectionTarget, delegateHandler);
decorators = WebBeansDecoratorConfig.getDecoratorStack(injectionTarget, instance, delegate,
(CreationalContextImpl<?>)this.cc);
delegateHandler.setDecorators(decorators);
}
if (interceptorStack.size() == 0)
{
if (decoratorStack.size() == 0)
{
rv = ejbContext.proceed();
}
else
{
rv = delegateHandler.invoke(instance, method, null, arguments);
}
}
else
{
if (this.interceptedMethodMap.get(method) == null)
{
List<InterceptorData> filteredInterceptorStack = new ArrayList<InterceptorData>(interceptorStack);
webBeansContext.getInterceptorUtil().filterCommonInterceptorStackList(filteredInterceptorStack, method);
webBeansContext.getInterceptorUtil().filterOverridenAroundInvokeInterceptor(injectionTarget.getBeanClass(), filteredInterceptorStack);
this.interceptedMethodMap.put(method, filteredInterceptorStack);
}
List<InterceptorData> filteredInterceptorStack = new ArrayList<InterceptorData>(this.interceptedMethodMap.get(method));
if (delegateHandler != null)
{
WebBeansDecoratorInterceptor lastInterceptor = new WebBeansDecoratorInterceptor(delegateHandler, instance);
decoratorInterceptorDataImpl = new InterceptorDataImpl(true, lastInterceptor, webBeansContext);
decoratorInterceptorDataImpl.setDefinedInInterceptorClass(true);
decoratorInterceptorDataImpl.setAroundInvoke(
webBeansContext.getSecurityService().doPrivilegedGetDeclaredMethod(lastInterceptor.getClass(),
"invokeDecorators",
new Class[] {InvocationContext.class}));
filteredInterceptorStack.add(decoratorInterceptorDataImpl);
}
rv = webBeansContext.getInterceptorUtil().callAroundInvokes(webBeansContext, this.contextual, instance, (CreationalContextImpl<?>) this.cc, method,
arguments, webBeansContext.getInterceptorUtil().getInterceptorMethods(filteredInterceptorStack, InterceptionType.AROUND_INVOKE),
ejbContext, this.ccKey);
}
return rv;
}
@AroundTimeout
{
Object rv = null;
if (logger.isLoggable(Level.FINE))
{
logger.fine("OWBEI:: @AroundTimeout entry. Trying to run Interceptors.");
}
if ((this.contextual != null) && WebBeansUtil.isContainsInterceptorMethod(this.contextual.getInterceptorStack(), InterceptionType.AROUND_TIMEOUT))
{
try
{
InvocationContextImpl impl = new InvocationContextImpl(webBeansContext, null, context.getTarget(), null, null,
webBeansContext.getInterceptorUtil().getInterceptorMethods(this.contextual.getInterceptorStack(),
InterceptionType.AROUND_TIMEOUT),
InterceptionType.AROUND_TIMEOUT);
impl.setCreationalContext(this.cc);
impl.setEJBInvocationContext(context);
impl.setCcKey((Object)this.ccKey);
rv = impl.proceed();
}
catch (Exception e)
{
logger.log(Level.SEVERE, WebBeansLoggerFacade.constructMessage(OWBLogConst.ERROR_0008, "@AroundTimeout."), e);
throw new RuntimeException(e);
}
}
else
{
rv = context.proceed();
}
return rv;
}
@PrePassivate
{
if (logger.isLoggable(Level.FINE))
{
logger.log(Level.FINE, "manager = {0} interceptor_instance = {1} contextual = {2} ",
WebBeansLoggerFacade.args(this.webBeansContext.getBeanManagerImpl(), this, this.contextual));
}
lifecycleCommon(context, InterceptionType.PRE_PASSIVATE);
}
@PostActivate
{
this.contextual = findTargetBean(context.getTarget());
if (logger.isLoggable(Level.FINE))
{
logger.log(Level.FINE, "manager = {0} interceptor_instance = {1} contextual = {2} ",
WebBeansLoggerFacade.args(this.webBeansContext.getBeanManagerImpl(), this, this.contextual));
}
lifecycleCommon(context, InterceptionType.POST_ACTIVATE);
}
{
return threadLocalCreationalContext.get();
}
{
return threadLocal.get();
}
private void writeObject(ObjectOutputStream out)
throws IOException
{
if (logger.isLoggable(Level.FINE))
{
logger.log(Level.FINE, "manager = {0} interceptor_instance = {1} contextual = {2} ",
WebBeansLoggerFacade.args(this.webBeansContext.getBeanManagerImpl(), this, this.contextual));
}
out.defaultWriteObject();
}
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException
{
if (logger.isLoggable(Level.FINE))
{
logger.log(Level.FINE, "interceptor instance = " + this.hashCode());
}
interceptedMethodMap = new WeakHashMap<Method, List<InterceptorData>>();
nonCtxInterceptedMethodMap = new WeakHashMap<Method, List<InterceptorData>>();
resolvedBeans = new HashMap<Class<?>, BaseEjbBean<?>>();
s.defaultReadObject();
this.webBeansContext = WebBeansContext.currentInstance();
if (logger.isLoggable(Level.FINE))
{
logger.log(Level.FINE, "manager = {0} interceptor_instance = {1} contextual = {2} ",
WebBeansLoggerFacade.args(this.webBeansContext.getBeanManagerImpl(), this, this.contextual));
}
}
{
}
}