use of org.apache.openejb.core.transaction.TransactionType in project tomee by apache.
the class BeanContext method newInstance.
@SuppressWarnings("unchecked")
public InstanceContext newInstance() throws Exception {
final boolean dynamicallyImplemented = isDynamicallyImplemented();
final WebBeansContext webBeansContext = getWebBeansContext();
if (dynamicallyImplemented) {
if (!InvocationHandler.class.isAssignableFrom(getProxyClass())) {
throw new OpenEJBException("proxy class can only be InvocationHandler");
}
}
final ThreadContext callContext = new ThreadContext(this, null, Operation.INJECTION);
final ThreadContext oldContext = ThreadContext.enter(callContext);
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<>();
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<>();
// 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());
}
final Collection<DependentCreationalContext<?>> createdDependents = getDependents(creationalContext);
for (final InterceptorData interceptorData : this.getInstanceScopedInterceptors()) {
if (interceptorData.getInterceptorClass().equals(beanClass)) {
continue;
}
final Class clazz = interceptorData.getInterceptorClass();
final Object iInstance;
if (webBeansContext != null) {
Object preInstantiated = null;
if (createdDependents != null) {
for (final DependentCreationalContext<?> dcc : createdDependents) {
if (clazz.isInstance(dcc.getInstance())) {
// is that enough? do we have more to match?
preInstantiated = dcc.getInstance();
break;
}
}
}
if (preInstantiated != null) {
iInstance = preInstantiated;
} else {
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);
}
}
}
CreationalContextImpl cc = (CreationalContextImpl) creationalContext;
Object oldDelegate = cc.putDelegate(beanInstance);
Bean<?> oldBean = cc.putBean(cdiEjbBean);
Contextual<?> oldContextual = cc.putContextual(interceptorData.getCdiInterceptorBean() != null ? interceptorData.getCdiInterceptorBean() : // otherwise BeanMetaData is broken
interceptorConstructor);
try {
iInstance = interceptorConstructor.create(creationalContext);
} finally {
cc.putBean(oldBean);
cc.putContextual(oldContextual);
cc.putDelegate(oldDelegate);
}
}
} 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<>();
for (int i = decorators.size(); i > 0; i--) {
final Decorator<?> decorator = decorators.get(i - 1);
CreationalContextImpl cc = (CreationalContextImpl) creationalContext;
Object oldDelegate = cc.putDelegate(beanInstance);
Bean<?> oldBean = cc.putBean(cdiEjbBean);
// otherwise BeanMetaData is broken
Contextual<?> oldContextual = cc.putContextual(decorator);
Object decoratorInstance = null;
try {
decoratorInstance = decorator.create(CreationalContext.class.cast(creationalContext));
} finally {
cc.putBean(oldBean);
cc.putContextual(oldContextual);
cc.putDelegate(oldDelegate);
}
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);
}
}
use of org.apache.openejb.core.transaction.TransactionType in project tomee by apache.
the class SingletonInstanceManager method freeInstance.
public void freeInstance(final ThreadContext callContext) {
final BeanContext beanContext = callContext.getBeanContext();
final Data data = (Data) beanContext.getContainerData();
final Future<Instance> instanceFuture = data.singleton.get();
// Possible the instance was never created
if (instanceFuture == null) {
return;
}
final Instance instance;
try {
instance = instanceFuture.get();
} catch (final InterruptedException e) {
Thread.interrupted();
logger.error("Singleton shutdown failed because the thread was interrupted: " + beanContext.getDeploymentID(), e);
return;
} catch (final ExecutionException e) {
// Instance was never initialized
return;
}
try {
callContext.setCurrentOperation(Operation.PRE_DESTROY);
callContext.setCurrentAllowedStates(null);
final Method remove = instance.bean instanceof SessionBean ? beanContext.getCreateMethod() : null;
final List<InterceptorData> callbackInterceptors = beanContext.getCallbackInterceptors();
final InterceptorStack interceptorStack = new InterceptorStack(instance.bean, remove, Operation.PRE_DESTROY, callbackInterceptors, instance.interceptors);
// Transaction Demarcation for Singleton PostConstruct method
TransactionType transactionType;
if (beanContext.getComponentType() == BeanType.SINGLETON) {
final Set<Method> callbacks = callbackInterceptors.get(callbackInterceptors.size() - 1).getPreDestroy();
if (callbacks.isEmpty()) {
transactionType = TransactionType.RequiresNew;
} else {
transactionType = beanContext.getTransactionType(callbacks.iterator().next());
if (transactionType == TransactionType.Required) {
transactionType = TransactionType.RequiresNew;
}
}
} else {
transactionType = beanContext.isBeanManagedTransaction() ? TransactionType.BeanManaged : TransactionType.NotSupported;
}
final TransactionPolicy transactionPolicy = EjbTransactionUtil.createTransactionPolicy(transactionType, callContext);
try {
// Call the chain
final CdiEjbBean<Object> bean = beanContext.get(CdiEjbBean.class);
if (bean != null) {
// TODO: see if it should be called before or after next call
bean.getInjectionTarget().preDestroy(instance.bean);
}
interceptorStack.invoke();
if (instance.creationalContext != null) {
instance.creationalContext.release();
}
} catch (final Throwable e) {
// RollBack Transaction
EjbTransactionUtil.handleSystemException(transactionPolicy, e, callContext);
} finally {
EjbTransactionUtil.afterInvoke(transactionPolicy, callContext);
}
} catch (final Throwable re) {
logger.error("Singleton shutdown failed: " + beanContext.getDeploymentID(), re);
}
}
use of org.apache.openejb.core.transaction.TransactionType in project tomee by apache.
the class TransactionRule method apply.
@Override
public Statement apply(final Statement base, final Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
final TransactionAttribute annotation = description.getAnnotation(TransactionAttribute.class);
final Transactional annotation2 = description.getAnnotation(Transactional.class);
if (annotation == null && annotation2 == null) {
base.evaluate();
return;
}
final BeanContext beanContext = getBeanContext();
final Method method = beanContext.getManagedClass().getMethod(description.getMethodName());
final TransactionType transactionType = TransactionType.get(annotation == null ? TransactionAttributeType.valueOf(annotation2.value().name()) : annotation.value());
beanContext.getMethodContext(method).setTransactionType(transactionType);
ThreadContext tc = ThreadContext.getThreadContext();
final boolean tcCreated;
if (tc == null) {
tcCreated = true;
tc = ThreadContext.enter(new ThreadContext(beanContext, null));
} else {
tcCreated = false;
}
final TransactionPolicy policy = EjbTransactionUtil.createTransactionPolicy(transactionType, tc);
try {
base.evaluate();
} finally {
if (rollback) {
policy.setRollbackOnly();
}
EjbTransactionUtil.afterInvoke(policy, tc);
if (tcCreated) {
ThreadContext.exit(tc);
}
}
}
};
}
Aggregations