Search in sources :

Example 1 with CurrentCreationalContext

use of org.apache.openejb.cdi.CurrentCreationalContext in project tomee by apache.

the class BeanContext method newInstance.

@SuppressWarnings("unchecked")
public InstanceContext newInstance() throws Exception {
    final ThreadContext callContext = new ThreadContext(this, null, Operation.INJECTION);
    final ThreadContext oldContext = ThreadContext.enter(callContext);
    final boolean dynamicallyImplemented = isDynamicallyImplemented();
    final WebBeansContext webBeansContext = getWebBeansContext();
    if (dynamicallyImplemented) {
        if (!InvocationHandler.class.isAssignableFrom(getProxyClass())) {
            throw new OpenEJBException("proxy class can only be InvocationHandler");
        }
    }
    try {
        final Context ctx = getJndiEnc();
        final Class beanClass = getBeanClass();
        final CurrentCreationalContext<Object> currentCreationalContext = get(CurrentCreationalContext.class);
        CreationalContext<Object> creationalContext = currentCreationalContext != null ? currentCreationalContext.get() : null;
        final CdiEjbBean cdiEjbBean = get(CdiEjbBean.class);
        if (!CreationalContextImpl.class.isInstance(creationalContext) && webBeansContext != null) {
            if (creationalContext == null) {
                creationalContext = webBeansContext.getCreationalContextFactory().getCreationalContext(cdiEjbBean);
            } else {
                creationalContext = webBeansContext.getCreationalContextFactory().wrappedCreationalContext(creationalContext, cdiEjbBean);
            }
        }
        final Object rootInstance;
        if (cdiEjbBean != null && !dynamicallyImplemented && CdiEjbBean.EjbInjectionTargetImpl.class.isInstance(cdiEjbBean.getInjectionTarget())) {
            rootInstance = CdiEjbBean.EjbInjectionTargetImpl.class.cast(cdiEjbBean.getInjectionTarget()).createNewPojo(creationalContext);
        } else {
            // not a cdi bean
            rootInstance = getManagedClass().newInstance();
        }
        // Create bean instance
        Object beanInstance;
        final InjectionProcessor injectionProcessor;
        if (!dynamicallyImplemented) {
            injectionProcessor = new InjectionProcessor(rootInstance, getInjections(), InjectionProcessor.unwrap(ctx));
            beanInstance = injectionProcessor.createInstance();
            inject(beanInstance, creationalContext);
        } else {
            // update target
            final List<Injection> newInjections = new ArrayList<Injection>();
            for (final Injection injection : getInjections()) {
                if (beanClass.equals(injection.getTarget())) {
                    final Injection updated = new Injection(injection.getJndiName(), injection.getName(), proxyClass);
                    newInjections.add(updated);
                } else {
                    newInjections.add(injection);
                }
            }
            injections.clear();
            injections.addAll(newInjections);
            injectionProcessor = new InjectionProcessor(rootInstance, injections, InjectionProcessor.unwrap(ctx));
            final InvocationHandler handler = (InvocationHandler) injectionProcessor.createInstance();
            beanInstance = DynamicProxyImplFactory.newProxy(this, handler);
            inject(handler, creationalContext);
        }
        // Create interceptors
        final Map<String, Object> interceptorInstances = new LinkedHashMap<String, Object>();
        // Add the stats interceptor instance and other already created interceptor instances
        for (final InterceptorInstance interceptorInstance : this.getUserAndSystemInterceptors()) {
            final Class clazz = interceptorInstance.getData().getInterceptorClass();
            interceptorInstances.put(clazz.getName(), interceptorInstance.getInterceptor());
        }
        for (final InterceptorData interceptorData : this.getInstanceScopedInterceptors()) {
            if (interceptorData.getInterceptorClass().equals(beanClass)) {
                continue;
            }
            final Class clazz = interceptorData.getInterceptorClass();
            final Object iInstance;
            if (webBeansContext != null) {
                ConstructorInjectionBean interceptorConstructor = interceptorData.get(ConstructorInjectionBean.class);
                if (interceptorConstructor == null) {
                    synchronized (this) {
                        interceptorConstructor = interceptorData.get(ConstructorInjectionBean.class);
                        if (interceptorConstructor == null) {
                            interceptorConstructor = new ConstructorInjectionBean(webBeansContext, clazz, webBeansContext.getAnnotatedElementFactory().newAnnotatedType(clazz));
                            interceptorData.set(ConstructorInjectionBean.class, interceptorConstructor);
                        }
                    }
                }
                iInstance = interceptorConstructor.create(creationalContext);
            } else {
                iInstance = clazz.newInstance();
            }
            final InjectionProcessor interceptorInjector = new InjectionProcessor(iInstance, this.getInjections(), InjectionProcessor.unwrap(ctx));
            try {
                final Object interceptorInstance = interceptorInjector.createInstance();
                if (webBeansContext != null) {
                    try {
                        OWBInjector.inject(webBeansContext.getBeanManagerImpl(), interceptorInstance, creationalContext);
                    } catch (final Throwable t) {
                    // TODO handle this differently
                    // this is temporary till the injector can be rewritten
                    }
                }
                interceptorInstances.put(clazz.getName(), interceptorInstance);
            } catch (final ConstructionException e) {
                throw new Exception("Failed to create interceptor: " + clazz.getName(), e);
            }
        }
        interceptorInstances.put(beanClass.getName(), beanInstance);
        // Invoke post construct method
        callContext.setCurrentOperation(Operation.POST_CONSTRUCT);
        final List<InterceptorData> callbackInterceptors = this.getCallbackInterceptors();
        final InterceptorStack postConstruct = new InterceptorStack(beanInstance, null, Operation.POST_CONSTRUCT, callbackInterceptors, interceptorInstances);
        //Transaction Demarcation for Singleton PostConstruct method
        TransactionType transactionType;
        if (componentType == BeanType.SINGLETON || componentType == BeanType.STATEFUL) {
            final Set<Method> callbacks = callbackInterceptors.get(callbackInterceptors.size() - 1).getPostConstruct();
            if (callbacks.isEmpty()) {
                transactionType = TransactionType.RequiresNew;
            } else {
                // TODO: we should take the last one I think
                transactionType = getTransactionType(callbacks.iterator().next());
                if (transactionType == TransactionType.Required) {
                    transactionType = TransactionType.RequiresNew;
                }
            }
        } else {
            transactionType = isBeanManagedTransaction() ? TransactionType.BeanManaged : TransactionType.NotSupported;
        }
        final TransactionPolicy transactionPolicy = EjbTransactionUtil.createTransactionPolicy(transactionType, callContext);
        try {
            //Call the chain
            if (cdiEjbBean != null) {
                // call it, it has no postconstruct but extensions can add stuff here, TODO: see if it should be called before or after effective postconstruct
                cdiEjbBean.getInjectionTarget().postConstruct(beanInstance);
            }
            postConstruct.invoke();
        } catch (final Throwable e) {
            //RollBack Transaction
            EjbTransactionUtil.handleSystemException(transactionPolicy, e, callContext);
        } finally {
            EjbTransactionUtil.afterInvoke(transactionPolicy, callContext);
        }
        // handle cdi decorators
        if (cdiEjbBean != null) {
            final Class<?> proxyClass = Class.class.cast(Reflections.get(cdiEjbBean.getInjectionTarget(), "proxyClass"));
            if (proxyClass != null) {
                // means interception
                final InterceptorResolutionService.BeanInterceptorInfo interceptorInfo = cdiEjbBean.getBeanContext().get(InterceptorResolutionService.BeanInterceptorInfo.class);
                if (interceptorInfo.getDecorators() != null && !interceptorInfo.getDecorators().isEmpty()) {
                    final InterceptorDecoratorProxyFactory pf = webBeansContext.getInterceptorDecoratorProxyFactory();
                    // decorators
                    final Object instance = beanInstance;
                    final List<Decorator<?>> decorators = interceptorInfo.getDecorators();
                    final Map<Decorator<?>, Object> instances = new HashMap<Decorator<?>, Object>();
                    for (int i = decorators.size(); i > 0; i--) {
                        final Decorator<?> decorator = decorators.get(i - 1);
                        CreationalContextImpl.class.cast(creationalContext).putDelegate(beanInstance);
                        final Object decoratorInstance = decorator.create(CreationalContext.class.cast(creationalContext));
                        instances.put(decorator, decoratorInstance);
                        beanInstance = pf.createProxyInstance(proxyClass, instance, new DecoratorHandler(interceptorInfo, decorators, instances, i - 1, instance, cdiEjbBean.getId()));
                    }
                }
            }
        }
        return new InstanceContext(this, beanInstance, interceptorInstances, creationalContext);
    } finally {
        ThreadContext.exit(oldContext);
    }
}
Also used : TransactionType(org.apache.openejb.core.transaction.TransactionType) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) CdiEjbBean(org.apache.openejb.cdi.CdiEjbBean) ArrayList(java.util.ArrayList) CreationalContextImpl(org.apache.webbeans.context.creational.CreationalContextImpl) DecoratorHandler(org.apache.webbeans.intercept.DecoratorHandler) LinkedHashMap(java.util.LinkedHashMap) WebBeansContext(org.apache.webbeans.config.WebBeansContext) InstanceContext(org.apache.openejb.core.InstanceContext) WebBeansContext(org.apache.webbeans.config.WebBeansContext) CurrentCreationalContext(org.apache.openejb.cdi.CurrentCreationalContext) CreationalContext(javax.enterprise.context.spi.CreationalContext) Context(javax.naming.Context) InstanceContext(org.apache.openejb.core.InstanceContext) ThreadContext(org.apache.openejb.core.ThreadContext) InterceptorResolutionService(org.apache.webbeans.intercept.InterceptorResolutionService) ConstructorInjectionBean(org.apache.openejb.cdi.ConstructorInjectionBean) ThreadContext(org.apache.openejb.core.ThreadContext) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy) InterceptorInstance(org.apache.openejb.core.interceptor.InterceptorInstance) Method(java.lang.reflect.Method) AnnotatedMethod(javax.enterprise.inject.spi.AnnotatedMethod) InvocationHandler(java.lang.reflect.InvocationHandler) ApplicationException(javax.ejb.ApplicationException) ConstructionException(org.apache.xbean.recipe.ConstructionException) Decorator(javax.enterprise.inject.spi.Decorator) CurrentCreationalContext(org.apache.openejb.cdi.CurrentCreationalContext) CreationalContext(javax.enterprise.context.spi.CreationalContext) InterceptorData(org.apache.openejb.core.interceptor.InterceptorData) InterceptorStack(org.apache.openejb.core.interceptor.InterceptorStack) TimedObject(javax.ejb.TimedObject) EJBLocalObject(javax.ejb.EJBLocalObject) EJBObject(javax.ejb.EJBObject) ConstructionException(org.apache.xbean.recipe.ConstructionException) InterceptorDecoratorProxyFactory(org.apache.webbeans.proxy.InterceptorDecoratorProxyFactory)

Example 2 with CurrentCreationalContext

use of org.apache.openejb.cdi.CurrentCreationalContext in project tomee by apache.

the class SingletonContainer method invoke.

@Override
public Object invoke(final Object deployID, InterfaceType type, final Class callInterface, final Method callMethod, final Object[] args, final Object primKey) throws OpenEJBException {
    final BeanContext beanContext = this.getBeanContext(deployID);
    if (beanContext == null) {
        throw new OpenEJBException("Deployment does not exist in this container. Deployment(id='" + deployID + "'), Container(id='" + containerID + "')");
    }
    // Use the backup way to determine call type if null was supplied.
    if (type == null) {
        type = beanContext.getInterfaceType(callInterface);
    }
    final Method runMethod = beanContext.getMatchingBeanMethod(callMethod);
    final ThreadContext callContext = new ThreadContext(beanContext, primKey);
    final ThreadContext oldCallContext = ThreadContext.enter(callContext);
    final CurrentCreationalContext currentCreationalContext = beanContext.get(CurrentCreationalContext.class);
    Object runAs = null;
    try {
        if (oldCallContext != null) {
            final BeanContext oldBc = oldCallContext.getBeanContext();
            if (oldBc.getRunAsUser() != null || oldBc.getRunAs() != null) {
                runAs = AbstractSecurityService.class.cast(securityService).overrideWithRunAsContext(callContext, beanContext, oldBc);
            }
        }
        final boolean authorized = type == InterfaceType.TIMEOUT || getSecurityService().isCallerAuthorized(callMethod, type);
        if (!authorized) {
            throw new org.apache.openejb.ApplicationException(new EJBAccessException("Unauthorized Access by Principal Denied"));
        }
        final Class declaringClass = callMethod.getDeclaringClass();
        if (EJBHome.class.isAssignableFrom(declaringClass) || EJBLocalHome.class.isAssignableFrom(declaringClass)) {
            if (callMethod.getName().startsWith("create")) {
                return createEJBObject(beanContext, callMethod);
            } else {
                // EJBHome.remove( ) and other EJBHome methods are not process by the container
                return null;
            }
        } else if (EJBObject.class == declaringClass || EJBLocalObject.class == declaringClass) {
            // EJBObject.remove( ) and other EJBObject methods are not process by the container
            return null;
        }
        final Instance instance = instanceManager.getInstance(callContext);
        callContext.setCurrentOperation(type == InterfaceType.TIMEOUT ? Operation.TIMEOUT : Operation.BUSINESS);
        callContext.setCurrentAllowedStates(null);
        callContext.set(Method.class, runMethod);
        callContext.setInvokedInterface(callInterface);
        if (currentCreationalContext != null) {
            //noinspection unchecked
            currentCreationalContext.set(instance.creationalContext);
        }
        return _invoke(callMethod, runMethod, args, instance, callContext, type);
    } finally {
        if (runAs != null) {
            try {
                securityService.associate(runAs);
            } catch (final LoginException e) {
            // no-op
            }
        }
        ThreadContext.exit(oldCallContext);
        if (currentCreationalContext != null) {
            currentCreationalContext.remove();
        }
    }
}
Also used : OpenEJBException(org.apache.openejb.OpenEJBException) EJBHome(javax.ejb.EJBHome) ThreadContext(org.apache.openejb.core.ThreadContext) Method(java.lang.reflect.Method) EJBAccessException(javax.ejb.EJBAccessException) EJBLocalHome(javax.ejb.EJBLocalHome) CurrentCreationalContext(org.apache.openejb.cdi.CurrentCreationalContext) BeanContext(org.apache.openejb.BeanContext) EjbTransactionUtil.handleApplicationException(org.apache.openejb.core.transaction.EjbTransactionUtil.handleApplicationException) LoginException(javax.security.auth.login.LoginException) EJBObject(javax.ejb.EJBObject) EJBLocalObject(javax.ejb.EJBLocalObject)

Example 3 with CurrentCreationalContext

use of org.apache.openejb.cdi.CurrentCreationalContext in project tomee by apache.

the class StatefulContainer method businessMethod.

protected Object businessMethod(final BeanContext beanContext, final Object primKey, final Class callInterface, final Method callMethod, final Object[] args, final InterfaceType interfaceType) throws OpenEJBException {
    final ThreadContext callContext = new ThreadContext(beanContext, primKey);
    final ThreadContext oldCallContext = ThreadContext.enter(callContext);
    final CurrentCreationalContext currentCreationalContext = beanContext.get(CurrentCreationalContext.class);
    Object runAs = null;
    try {
        if (oldCallContext != null) {
            final BeanContext oldBc = oldCallContext.getBeanContext();
            if (oldBc.getRunAsUser() != null || oldBc.getRunAs() != null) {
                runAs = AbstractSecurityService.class.cast(securityService).overrideWithRunAsContext(callContext, beanContext, oldBc);
            }
        }
        // Security check
        checkAuthorization(callMethod, interfaceType);
        // Start transaction
        final TransactionPolicy txPolicy = EjbTransactionUtil.createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod, interfaceType), callContext);
        Object returnValue = null;
        Instance instance = null;
        try {
            // Obtain instance
            instance = obtainInstance(primKey, callContext, callMethod, true);
            // Resume previous Bean transaction if there was one
            if (txPolicy instanceof BeanTransactionPolicy) {
                final SuspendedTransaction suspendedTransaction = instance.getBeanTransaction();
                if (suspendedTransaction != null) {
                    instance.setBeanTransaction(null);
                    final BeanTransactionPolicy beanTxEnv = (BeanTransactionPolicy) txPolicy;
                    beanTxEnv.resumeUserTransaction(suspendedTransaction);
                }
            }
            // Register the entity managers
            registerEntityManagers(instance, callContext);
            // Register for synchronization callbacks
            registerSessionSynchronization(instance, callContext);
            // Setup for business invocation
            callContext.setCurrentOperation(Operation.BUSINESS);
            callContext.setCurrentAllowedStates(null);
            callContext.setInvokedInterface(callInterface);
            final Method runMethod = beanContext.getMatchingBeanMethod(callMethod);
            callContext.set(Method.class, runMethod);
            if (currentCreationalContext != null) {
                currentCreationalContext.set(instance.creationalContext);
            }
            // Initialize interceptor stack
            final List<InterceptorData> interceptors = beanContext.getMethodInterceptors(runMethod);
            final InterceptorStack interceptorStack = new InterceptorStack(instance.bean, runMethod, Operation.BUSINESS, interceptors, instance.interceptors);
            // Invoke
            returnValue = interceptorStack.invoke(args);
        } catch (final Throwable e) {
            handleException(callContext, txPolicy, e);
        } finally {
            // un register EntityManager
            unregisterEntityManagers(instance, callContext);
            // Commit transaction
            afterInvoke(callContext, txPolicy, instance);
        }
        return returnValue;
    } finally {
        if (runAs != null) {
            try {
                securityService.associate(runAs);
            } catch (final LoginException e) {
            // no-op
            }
        }
        ThreadContext.exit(oldCallContext);
        if (currentCreationalContext != null) {
            currentCreationalContext.remove();
        }
    }
}
Also used : BeanTransactionPolicy(org.apache.openejb.core.transaction.BeanTransactionPolicy) SystemInstance(org.apache.openejb.loader.SystemInstance) ThreadContext(org.apache.openejb.core.ThreadContext) JtaTransactionPolicy(org.apache.openejb.core.transaction.JtaTransactionPolicy) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy) BeanTransactionPolicy(org.apache.openejb.core.transaction.BeanTransactionPolicy) SuspendedTransaction(org.apache.openejb.core.transaction.BeanTransactionPolicy.SuspendedTransaction) Method(java.lang.reflect.Method) CurrentCreationalContext(org.apache.openejb.cdi.CurrentCreationalContext) BeanContext(org.apache.openejb.BeanContext) InterceptorData(org.apache.openejb.core.interceptor.InterceptorData) InterceptorStack(org.apache.openejb.core.interceptor.InterceptorStack) LoginException(javax.security.auth.login.LoginException)

Example 4 with CurrentCreationalContext

use of org.apache.openejb.cdi.CurrentCreationalContext in project tomee by apache.

the class StatelessContainer method invoke.

@SuppressWarnings("unchecked")
@Override
public Object invoke(final Object deployID, InterfaceType type, final Class callInterface, final Method callMethod, final Object[] args, final Object primKey) throws OpenEJBException {
    final BeanContext beanContext = this.getBeanContext(deployID);
    if (beanContext == null) {
        final String msg = "Deployment does not exist in this container. Deployment(id='" + deployID + "'), Container(id='" + containerID + "')";
        throw new OpenEJBException(msg);
    }
    // Use the backup way to determine call type if null was supplied.
    if (type == null) {
        type = beanContext.getInterfaceType(callInterface);
    }
    final Method runMethod = beanContext.getMatchingBeanMethod(callMethod);
    final ThreadContext callContext = new ThreadContext(beanContext, primKey);
    final ThreadContext oldCallContext = ThreadContext.enter(callContext);
    Instance bean = null;
    final CurrentCreationalContext currentCreationalContext = beanContext.get(CurrentCreationalContext.class);
    Object runAs = null;
    try {
        if (oldCallContext != null) {
            final BeanContext oldBc = oldCallContext.getBeanContext();
            if (oldBc.getRunAsUser() != null || oldBc.getRunAs() != null) {
                runAs = AbstractSecurityService.class.cast(securityService).overrideWithRunAsContext(callContext, beanContext, oldBc);
            }
        }
        //Check auth before overriding context
        final boolean authorized = type == InterfaceType.TIMEOUT || this.securityService.isCallerAuthorized(callMethod, type);
        if (!authorized) {
            throw new org.apache.openejb.ApplicationException(new javax.ejb.EJBAccessException("Unauthorized Access by Principal Denied"));
        }
        final Class declaringClass = callMethod.getDeclaringClass();
        if (javax.ejb.EJBHome.class.isAssignableFrom(declaringClass) || javax.ejb.EJBLocalHome.class.isAssignableFrom(declaringClass)) {
            if (callMethod.getName().startsWith("create")) {
                return new ProxyInfo(beanContext, null);
            } else {
                // EJBHome.remove( ) and other EJBHome methods are not process by the container
                return null;
            }
        } else if (javax.ejb.EJBObject.class == declaringClass || javax.ejb.EJBLocalObject.class == declaringClass) {
            // EJBObject.remove( ) and other EJBObject methods are not process by the container
            return null;
        }
        bean = this.instanceManager.getInstance(callContext);
        callContext.setCurrentOperation(type == InterfaceType.TIMEOUT ? Operation.TIMEOUT : Operation.BUSINESS);
        callContext.set(Method.class, runMethod);
        callContext.setInvokedInterface(callInterface);
        if (currentCreationalContext != null) {
            currentCreationalContext.set(bean.creationalContext);
        }
        return _invoke(callMethod, runMethod, args, bean, callContext, type);
    } finally {
        if (runAs != null) {
            try {
                securityService.associate(runAs);
            } catch (final LoginException e) {
            // no-op
            }
        }
        if (bean != null) {
            if (callContext.isDiscardInstance()) {
                this.instanceManager.discardInstance(callContext, bean);
            } else {
                this.instanceManager.poolInstance(callContext, bean);
            }
        }
        ThreadContext.exit(oldCallContext);
        if (currentCreationalContext != null) {
            currentCreationalContext.remove();
        }
    }
}
Also used : OpenEJBException(org.apache.openejb.OpenEJBException) ThreadContext(org.apache.openejb.core.ThreadContext) Method(java.lang.reflect.Method) CurrentCreationalContext(org.apache.openejb.cdi.CurrentCreationalContext) BeanContext(org.apache.openejb.BeanContext) ProxyInfo(org.apache.openejb.ProxyInfo) EjbTransactionUtil.handleApplicationException(org.apache.openejb.core.transaction.EjbTransactionUtil.handleApplicationException) LoginException(javax.security.auth.login.LoginException)

Aggregations

Method (java.lang.reflect.Method)4 CurrentCreationalContext (org.apache.openejb.cdi.CurrentCreationalContext)4 ThreadContext (org.apache.openejb.core.ThreadContext)4 LoginException (javax.security.auth.login.LoginException)3 BeanContext (org.apache.openejb.BeanContext)3 EJBLocalObject (javax.ejb.EJBLocalObject)2 EJBObject (javax.ejb.EJBObject)2 OpenEJBException (org.apache.openejb.OpenEJBException)2 InterceptorData (org.apache.openejb.core.interceptor.InterceptorData)2 InterceptorStack (org.apache.openejb.core.interceptor.InterceptorStack)2 EjbTransactionUtil.handleApplicationException (org.apache.openejb.core.transaction.EjbTransactionUtil.handleApplicationException)2 TransactionPolicy (org.apache.openejb.core.transaction.TransactionPolicy)2 InvocationHandler (java.lang.reflect.InvocationHandler)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ApplicationException (javax.ejb.ApplicationException)1 EJBAccessException (javax.ejb.EJBAccessException)1 EJBHome (javax.ejb.EJBHome)1