001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    
018    package org.apache.geronimo.persistence;
019    
020    import java.util.Map;
021    
022    import javax.persistence.*;
023    import javax.persistence.TransactionRequiredException;
024    import javax.transaction.*;
025    import org.apache.geronimo.transaction.manager.TransactionImpl;
026    import org.apache.geronimo.transaction.manager.TransactionManagerImpl;
027    
028    /**
029     * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
030     */
031    public class CMPEntityManagerTxScoped implements EntityManager {
032    
033        private final TransactionManagerImpl transactionManager;
034        private final String persistenceUnit;
035        private final EntityManagerFactory entityManagerFactory;
036        private final Map entityManagerProperties;
037    
038        public CMPEntityManagerTxScoped(TransactionManagerImpl transactionManager, String persistenceUnit, EntityManagerFactory entityManagerFactory, Map entityManagerProperties) {
039            this.transactionManager = transactionManager;
040            this.persistenceUnit = persistenceUnit;
041            this.entityManagerFactory = entityManagerFactory;
042            this.entityManagerProperties = entityManagerProperties;
043        }
044    
045        private EntityManager getEntityManager(boolean activeRequired) {
046            TransactionImpl transaction = (TransactionImpl) transactionManager.getTransaction();
047            if (activeRequired && (transaction == null || transaction.getStatus() != Status.STATUS_ACTIVE)) {
048                throw new TransactionRequiredException("No active transaction");
049            }
050            if (transaction == null) {
051                return null;
052            }
053            EntityManagerWrapper entityManagerWrapper = (EntityManagerWrapper) transactionManager.getResource(persistenceUnit);
054            if (entityManagerWrapper == null) {
055                EntityManager entityManager = createEntityManager();
056                entityManagerWrapper = new EntityManagerWrapperTxScoped(entityManager);
057                transactionManager.putResource(persistenceUnit, entityManagerWrapper);
058                try {
059                    transaction.registerSynchronization(entityManagerWrapper);
060                } catch (javax.transaction.RollbackException e) {
061                    throw (TransactionRequiredException) new TransactionRequiredException("No active transaction").initCause(e);
062                } catch (SystemException e) {
063                    throw (TransactionRequiredException) new TransactionRequiredException("No active transaction").initCause(e);
064                }
065            }
066            return entityManagerWrapper.getEntityManager();
067        }
068    
069        private EntityManager createEntityManager() {
070            EntityManager entityManager;
071            if (entityManagerProperties == null) {
072                entityManager = entityManagerFactory.createEntityManager();
073            } else {
074                entityManager = entityManagerFactory.createEntityManager(entityManagerProperties);
075            }
076            return entityManager;
077        }
078    
079    
080        public void persist(Object o) {
081            EntityManager entityManager = getEntityManager(true);
082            if (entityManager != null) {
083                entityManager.persist(o);
084            } else {
085                entityManager = createEntityManager();
086                try {
087                    entityManager.persist(o);
088                } finally {
089                    entityManager.close();
090                }
091            }
092        }
093    
094        public <T> T merge(T t) {
095            EntityManager entityManager = getEntityManager(true);
096            if (entityManager != null) {
097                return entityManager.merge(t);
098            } else {
099                entityManager = createEntityManager();
100                try {
101                    return entityManager.merge(t);
102                } finally {
103                    entityManager.close();
104                }
105            }
106        }
107    
108        public void remove(Object o) {
109            EntityManager entityManager = getEntityManager(true);
110            if (entityManager != null) {
111                entityManager.remove(o);
112            } else {
113                entityManager = createEntityManager();
114                try {
115                    entityManager.remove(o);
116                } finally {
117                    entityManager.close();
118                }
119            }
120        }
121    
122        public <T> T find(Class<T> aClass, Object o) {
123            EntityManager entityManager = getEntityManager(false);
124            if (entityManager != null) {
125                return entityManager.find(aClass, o);
126            } else {
127                entityManager = createEntityManager();
128                try {
129                    return entityManager.find(aClass, o);
130                } finally {
131                    entityManager.close();
132                }
133            }
134        }
135    
136        public <T> T getReference(Class<T> aClass, Object o) {
137            EntityManager entityManager = getEntityManager(false);
138            if (entityManager != null) {
139                return entityManager.getReference(aClass, o);
140            } else {
141                entityManager = createEntityManager();
142                try {
143                    return entityManager.getReference(aClass, o);
144                } finally {
145                    entityManager.close();
146                }
147            }
148        }
149    
150        public void flush() {
151            EntityManager entityManager = getEntityManager(false);
152            if (entityManager != null) {
153                entityManager.flush();
154            } else {
155                entityManager = createEntityManager();
156                try {
157                    entityManager.flush();
158                } finally {
159                    entityManager.close();
160                }
161            }
162        }
163    
164        public void setFlushMode(FlushModeType flushModeType) {
165            EntityManager entityManager = getEntityManager(false);
166            if (entityManager != null) {
167                entityManager.setFlushMode(flushModeType);
168            } else {
169                entityManager = createEntityManager();
170                try {
171                    entityManager.setFlushMode(flushModeType);
172                } finally {
173                    entityManager.close();
174                }
175            }
176        }
177    
178        public FlushModeType getFlushMode() {
179            EntityManager entityManager = getEntityManager(false);
180            if (entityManager != null) {
181                return entityManager.getFlushMode();
182            } else {
183                entityManager = createEntityManager();
184                try {
185                    return entityManager.getFlushMode();
186                } finally {
187                    entityManager.close();
188                }
189            }
190        }
191    
192        public void lock(Object o, LockModeType lockModeType) {
193            EntityManager entityManager = getEntityManager(false);
194            if (entityManager != null) {
195                entityManager.lock(o, lockModeType);
196            } else {
197                entityManager = createEntityManager();
198                try {
199                    entityManager.lock(o, lockModeType);
200                } finally {
201                    entityManager.close();
202                }
203            }
204        }
205    
206        public void refresh(Object o) {
207            EntityManager entityManager = getEntityManager(true);
208            if (entityManager != null) {
209                entityManager.refresh(o);
210            } else {
211                entityManager = createEntityManager();
212                try {
213                    entityManager.refresh(o);
214                } finally {
215                    entityManager.close();
216                }
217            }
218        }
219    
220        public void clear() {
221            EntityManager entityManager = getEntityManager(false);
222            if (entityManager != null) {
223                entityManager.clear();
224            } else {
225                entityManager = createEntityManager();
226                try {
227                    entityManager.clear();
228                } finally {
229                    entityManager.close();
230                }
231            }
232        }
233    
234        public boolean contains(Object o) {
235            EntityManager entityManager = getEntityManager(false);
236            if (entityManager != null) {
237                return entityManager.contains(o);
238            } else {
239                entityManager = createEntityManager();
240                try {
241                    return entityManager.contains(o);
242                } finally {
243                    entityManager.close();
244                }
245            }
246        }
247    
248        public Query createQuery(String s) {
249            EntityManager entityManager = getEntityManager(false);
250            if (entityManager != null) {
251                return entityManager.createQuery(s);
252            } else {
253                entityManager = createEntityManager();
254                return new NoTxQueryWrapper(entityManager, entityManager.createQuery(s));
255            }
256        }
257    
258        public Query createNamedQuery(String s) {
259            EntityManager entityManager = getEntityManager(false);
260            if (entityManager != null) {
261                return entityManager.createNamedQuery(s);
262            } else {
263                entityManager = createEntityManager();
264                return new NoTxQueryWrapper(entityManager, entityManager.createNamedQuery(s));
265            }
266        }
267    
268        public Query createNativeQuery(String s) {
269            EntityManager entityManager = getEntityManager(false);
270            if (entityManager != null) {
271                return entityManager.createNativeQuery(s);
272            } else {
273                entityManager = createEntityManager();
274                return new NoTxQueryWrapper(entityManager, entityManager.createNativeQuery(s));
275            }
276        }
277    
278        public Query createNativeQuery(String s, Class aClass) {
279            EntityManager entityManager = getEntityManager(false);
280            if (entityManager != null) {
281                return entityManager.createNativeQuery(s, aClass);
282            } else {
283                entityManager = createEntityManager();
284                return new NoTxQueryWrapper(entityManager, entityManager.createNativeQuery(s, aClass));
285            }
286        }
287    
288        public Query createNativeQuery(String s, String s1) {
289            EntityManager entityManager = getEntityManager(false);
290            if (entityManager != null) {
291                return entityManager.createNativeQuery(s, s1);
292            } else {
293                entityManager = createEntityManager();
294                return new NoTxQueryWrapper(entityManager, entityManager.createNativeQuery(s, s1));
295            }
296        }
297    
298        public void close() {
299            throw new IllegalStateException("You cannot call close on a Container Managed Entity Manager");
300        }
301    
302        public boolean isOpen() {
303            return true;
304        }
305    
306        public EntityTransaction getTransaction() {
307            throw new IllegalStateException("You cannot call getTransaction on a container managed EntityManager");
308        }
309    
310        public void joinTransaction() {
311            throw new IllegalStateException("You cannot call joinTransaction on a container managed EntityManager");
312        }
313    
314        public Object getDelegate() {
315            EntityManager entityManager = getEntityManager(false);
316            if (entityManager != null) {
317                return entityManager.getDelegate();
318            } else {
319                entityManager = createEntityManager();
320                try {
321                    return entityManager.getDelegate();
322                } finally {
323                    entityManager.close();
324                }
325            }
326        }
327    
328        private static class EntityManagerWrapperTxScoped implements EntityManagerWrapper, Synchronization {
329            private final EntityManager entityManager;
330    
331            public EntityManagerWrapperTxScoped(EntityManager entityManager) {
332                if (entityManager == null) {
333                    throw new IllegalArgumentException("Need a non-null entity manager");
334                }
335                this.entityManager = entityManager;
336            }
337    
338            public void close() {
339                entityManager.close();
340            }
341    
342            public EntityManager getEntityManager() {
343                return entityManager;
344            }
345    
346            public void beforeCompletion() {
347            }
348    
349            public void afterCompletion(int i) {
350                close();
351            }
352        }
353    }