/jboss-as-7.1.1.Final/ejb3/src/main/java/org/jboss/as/ejb3/component/entity/interceptors/EntityBeanEjbCreateMethodInterceptorFactory.java
Java | 156 lines | 95 code | 26 blank | 35 comment | 8 complexity | f09e301e488e577241d1ce9f4a61d163 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
1/*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2010, Red Hat Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */
22package org.jboss.as.ejb3.component.entity.interceptors;
23
24import java.lang.reflect.InvocationTargetException;
25import java.lang.reflect.Method;
26import java.util.concurrent.atomic.AtomicReference;
27
28import javax.transaction.Status;
29import javax.transaction.Synchronization;
30import javax.transaction.TransactionSynchronizationRegistry;
31
32import org.jboss.as.ee.component.Component;
33import org.jboss.as.ee.component.interceptors.InvocationType;
34import org.jboss.as.ejb3.component.entity.EntityBeanComponent;
35import org.jboss.as.ejb3.component.entity.EntityBeanComponentInstance;
36import org.jboss.invocation.Interceptor;
37import org.jboss.invocation.InterceptorContext;
38import org.jboss.invocation.InterceptorFactory;
39import org.jboss.invocation.InterceptorFactoryContext;
40import org.jboss.invocation.Interceptors;
41
42import static org.jboss.as.ejb3.EjbMessages.MESSAGES;
43
44/**
45 * Interceptor factory for entity beans that class the corresponding ejbCreate method.
46 * <p/>
47 * This is a post construct interceptor for the Ejb(Local)Object view
48 *
49 * @author Stuart Douglas
50 */
51public class EntityBeanEjbCreateMethodInterceptorFactory implements InterceptorFactory {
52
53 public static final EntityBeanEjbCreateMethodInterceptorFactory INSTANCE = new EntityBeanEjbCreateMethodInterceptorFactory();
54
55 protected EntityBeanEjbCreateMethodInterceptorFactory() {
56 }
57
58 @Override
59 public Interceptor create(InterceptorFactoryContext context) {
60 final Object existing = context.getContextData().get(EntityBeanComponent.PRIMARY_KEY_CONTEXT_KEY);
61
62 final AtomicReference<Object> primaryKeyReference = new AtomicReference<Object>();
63 context.getContextData().put(EntityBeanComponent.PRIMARY_KEY_CONTEXT_KEY, primaryKeyReference);
64
65 final Method ejbCreate = (Method) context.getContextData().get(EntityBeanHomeCreateInterceptorFactory.EJB_CREATE_METHOD_KEY);
66 final Method ejbPostCreate = (Method) context.getContextData().get(EntityBeanHomeCreateInterceptorFactory.EJB_POST_CREATE_METHOD_KEY);
67 final Object[] params = (Object[]) context.getContextData().get(EntityBeanHomeCreateInterceptorFactory.PARAMETERS_KEY);
68
69 return new Interceptor() {
70 @Override
71 public Object processInvocation(final InterceptorContext context) throws Exception {
72
73 if (existing != null) {
74 primaryKeyReference.set(existing);
75 return existing;
76 }
77 final Component component = context.getPrivateData(Component.class);
78 if (!(component instanceof EntityBeanComponent)) {
79 throw MESSAGES.unexpectedComponent(component, EntityBeanComponent.class);
80 }
81 final EntityBeanComponent entityBeanComponent = (EntityBeanComponent) component;
82 //grab an unasociated entity bean from the pool
83 final EntityBeanComponentInstance instance = entityBeanComponent.acquireUnAssociatedInstance();
84
85 //call the ejbCreate method
86 final Object primaryKey = invokeEjbCreate(context, ejbCreate, instance, params);
87 instance.associate(primaryKey);
88 primaryKeyReference.set(primaryKey);
89
90 //now add the instance to the cache, so it is usable
91 //note that we do not release it back to the pool
92 //the cache will do that when it is expired or removed
93
94 boolean synchronizationRegistered = false;
95 boolean exception = false;
96 entityBeanComponent.getCache().create(instance);
97
98 try {
99
100 invokeEjbPostCreate(context, ejbPostCreate, instance, params);
101
102 //if a transaction is active we register a sync
103 //and if the transaction is rolled back we release the instance back into the pool
104
105 final TransactionSynchronizationRegistry transactionSynchronizationRegistry = entityBeanComponent.getTransactionSynchronizationRegistry();
106 if (transactionSynchronizationRegistry.getTransactionKey() != null) {
107 transactionSynchronizationRegistry.registerInterposedSynchronization(new Synchronization() {
108 @Override
109 public void beforeCompletion() {
110
111 }
112
113 @Override
114 public void afterCompletion(final int status) {
115 entityBeanComponent.getCache().release(instance, status == Status.STATUS_COMMITTED);
116 }
117 });
118 synchronizationRegistered = true;
119 }
120 return context.proceed();
121 } catch (Exception e) {
122 entityBeanComponent.getCache().release(instance, false);
123 exception = true;
124 throw e;
125 } finally {
126 if (!synchronizationRegistered && !exception) {
127 entityBeanComponent.getCache().release(instance, true);
128 }
129 }
130 }
131
132
133 };
134
135 }
136
137 protected void invokeEjbPostCreate(final InterceptorContext context, final Method ejbPostCreate, final EntityBeanComponentInstance instance, final Object[] params) throws Exception {
138 try {
139 ejbPostCreate.invoke(instance.getInstance(), params);
140 } catch (InvocationTargetException e) {
141 throw Interceptors.rethrow(e.getCause());
142 }
143 }
144
145 protected Object invokeEjbCreate(final InterceptorContext context, final Method ejbCreate, final EntityBeanComponentInstance instance, final Object[] params) throws Exception {
146 final InvocationType invocationType = context.getPrivateData(InvocationType.class);
147 try {
148 context.putPrivateData(InvocationType.class, InvocationType.ENTITY_EJB_CREATE);
149 return ejbCreate.invoke(instance.getInstance(), params);
150 } catch (InvocationTargetException e) {
151 throw Interceptors.rethrow(e.getCause());
152 } finally {
153 context.putPrivateData(InvocationType.class, invocationType);
154 }
155 }
156}