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.EntityManager;
023    import javax.persistence.FlushModeType;
024    import javax.persistence.LockModeType;
025    import javax.persistence.Query;
026    import javax.persistence.EntityTransaction;
027    import javax.persistence.EntityManagerFactory;
028    import javax.persistence.TransactionRequiredException;
029    import javax.transaction.Status;
030    
031    import org.apache.geronimo.transaction.manager.TransactionManagerImpl;
032    import org.apache.geronimo.transaction.manager.TransactionImpl;
033    
034    /**
035     * @version $Rev: 487175 $ $Date: 2006-12-14 03:10:31 -0800 (Thu, 14 Dec 2006) $
036     */
037    public class CMPEntityManagerTxScoped implements EntityManager {
038    
039        private final TransactionManagerImpl transactionManager;
040        private final String persistenceUnit;
041        private final EntityManagerFactory entityManagerFactory;
042        private final Map entityManagerProperties;
043    
044        public CMPEntityManagerTxScoped(TransactionManagerImpl transactionManager, String persistenceUnit, EntityManagerFactory entityManagerFactory, Map entityManagerProperties) {
045            this.transactionManager = transactionManager;
046            this.persistenceUnit = persistenceUnit;
047            this.entityManagerFactory = entityManagerFactory;
048            this.entityManagerProperties = entityManagerProperties;
049        }
050    
051        private EntityManager getEntityManager(boolean activeRequired) {
052            TransactionImpl transaction = (TransactionImpl) transactionManager.getTransaction();
053            if (activeRequired && (transaction == null || transaction.getStatus() != Status.STATUS_ACTIVE)) {
054                throw new TransactionRequiredException("No active transaction");
055            }
056            if (transaction == null) {
057                return null;
058            }
059            EntityManagerWrapper entityManagerWrapper = (EntityManagerWrapper) transaction.getEntityManager(persistenceUnit);
060            if (entityManagerWrapper == null) {
061                EntityManager entityManager = createEntityManager();
062                entityManagerWrapper = new EntityManagerWrapperTxScoped(entityManager);
063                transaction.setEntityManager(persistenceUnit, entityManagerWrapper);
064            }
065            return entityManagerWrapper.getEntityManager();
066        }
067    
068        private EntityManager createEntityManager() {
069            EntityManager entityManager;
070            if (entityManagerProperties == null) {
071                entityManager = entityManagerFactory.createEntityManager();
072            } else {
073                entityManager = entityManagerFactory.createEntityManager(entityManagerProperties);
074            }
075            return entityManager;
076        }
077    
078    
079        public void persist(Object o) {
080            EntityManager entityManager = getEntityManager(true);
081            if (entityManager != null) {
082                entityManager.persist(o);
083            } else {
084                entityManager = createEntityManager();
085                try {
086                    entityManager.persist(o);
087                } finally {
088                    entityManager.close();
089                }
090            }
091        }
092    
093        public <T>T merge(T t) {
094            EntityManager entityManager = getEntityManager(true);
095            if (entityManager != null) {
096                return entityManager.merge(t);
097            } else {
098                entityManager = createEntityManager();
099                try {
100                    return entityManager.merge(t);
101                } finally {
102                    entityManager.close();
103                }
104            }
105        }
106    
107        public void remove(Object o) {
108            EntityManager entityManager = getEntityManager(true);
109            if (entityManager != null) {
110                entityManager.remove(o);
111            } else {
112                entityManager = createEntityManager();
113                try {
114                    entityManager.remove(o);
115                } finally {
116                    entityManager.close();
117                }
118            }
119        }
120    
121        public <T>T find(Class<T> aClass, Object o) {
122            EntityManager entityManager = getEntityManager(false);
123            if (entityManager != null) {
124                return entityManager.find(aClass, o);
125            } else {
126                entityManager = createEntityManager();
127                try {
128                    return entityManager.find(aClass, o);
129                } finally {
130                    entityManager.close();
131                }
132            }
133        }
134    
135        public <T>T getReference(Class<T> aClass, Object o) {
136            EntityManager entityManager = getEntityManager(false);
137            if (entityManager != null) {
138                return entityManager.getReference(aClass, o);
139            } else {
140                entityManager = createEntityManager();
141                try {
142                    return entityManager.getReference(aClass, o);
143                } finally {
144                    entityManager.close();
145                }
146            }
147        }
148    
149        public void flush() {
150            EntityManager entityManager = getEntityManager(false);
151            if (entityManager != null) {
152                entityManager.flush();
153            } else {
154                entityManager = createEntityManager();
155                try {
156                    entityManager.flush();
157                } finally {
158                    entityManager.close();
159                }
160            }
161        }
162    
163        public void setFlushMode(FlushModeType flushModeType) {
164            EntityManager entityManager = getEntityManager(false);
165            if (entityManager != null) {
166                 entityManager.setFlushMode(flushModeType);
167            } else {
168                entityManager = createEntityManager();
169                try {
170                     entityManager.setFlushMode(flushModeType);
171                } finally {
172                    entityManager.close();
173                }
174            }
175        }
176    
177        public FlushModeType getFlushMode() {
178            EntityManager entityManager = getEntityManager(false);
179            if (entityManager != null) {
180                return entityManager.getFlushMode();
181            } else {
182                entityManager = createEntityManager();
183                try {
184                    return entityManager.getFlushMode();
185                } finally {
186                    entityManager.close();
187                }
188            }
189        }
190    
191        public void lock(Object o, LockModeType lockModeType) {
192            EntityManager entityManager = getEntityManager(false);
193            if (entityManager != null) {
194                 entityManager.lock(o, lockModeType);
195            } else {
196                entityManager = createEntityManager();
197                try {
198                     entityManager.lock(o, lockModeType);
199                } finally {
200                    entityManager.close();
201                }
202            }
203        }
204    
205        public void refresh(Object o) {
206            EntityManager entityManager = getEntityManager(true);
207            if (entityManager != null) {
208                 entityManager.refresh(o);
209            } else {
210                entityManager = createEntityManager();
211                try {
212                     entityManager.refresh(o);
213                } finally {
214                    entityManager.close();
215                }
216            }
217        }
218    
219        public void clear() {
220            EntityManager entityManager = getEntityManager(false);
221            if (entityManager != null) {
222                 entityManager.clear();
223            } else {
224                entityManager = createEntityManager();
225                try {
226                     entityManager.clear();
227                } finally {
228                    entityManager.close();
229                }
230            }
231        }
232    
233        public boolean contains(Object o) {
234            EntityManager entityManager = getEntityManager(false);
235            if (entityManager != null) {
236                return entityManager.contains(o);
237            } else {
238                entityManager = createEntityManager();
239                try {
240                    return entityManager.contains(o);
241                } finally {
242                    entityManager.close();
243                }
244            }
245        }
246    
247        public Query createQuery(String s) {
248            EntityManager entityManager = getEntityManager(false);
249            if (entityManager != null) {
250                return entityManager.createQuery(s);
251            } else {
252                entityManager = createEntityManager();
253                try {
254                    return entityManager.createQuery(s);
255                } finally {
256                    entityManager.close();
257                }
258            }
259        }
260    
261        public Query createNamedQuery(String s) {
262            EntityManager entityManager = getEntityManager(false);
263            if (entityManager != null) {
264                return entityManager.createNamedQuery(s);
265            } else {
266                entityManager = createEntityManager();
267                try {
268                    return entityManager.createNamedQuery(s);
269                } finally {
270                    entityManager.close();
271                }
272            }
273        }
274    
275        public Query createNativeQuery(String s) {
276            EntityManager entityManager = getEntityManager(false);
277            if (entityManager != null) {
278                return entityManager.createNativeQuery(s);
279            } else {
280                entityManager = createEntityManager();
281                try {
282                    return entityManager.createNativeQuery(s);
283                } finally {
284                    entityManager.close();
285                }
286            }
287        }
288    
289        public Query createNativeQuery(String s, Class aClass) {
290            EntityManager entityManager = getEntityManager(false);
291            if (entityManager != null) {
292                return entityManager.createNativeQuery(s, aClass);
293            } else {
294                entityManager = createEntityManager();
295                try {
296                    return entityManager.createNativeQuery(s, aClass);
297                } finally {
298                    entityManager.close();
299                }
300            }
301        }
302    
303        public Query createNativeQuery(String s, String s1) {
304            EntityManager entityManager = getEntityManager(false);
305            if (entityManager != null) {
306                return entityManager.createNativeQuery(s, s1);
307            } else {
308                entityManager = createEntityManager();
309                try {
310                    return entityManager.createNativeQuery(s, s1);
311                } finally {
312                    entityManager.close();
313                }
314            }
315        }
316    
317        public void close() {
318            throw new IllegalStateException("You cannot call close on a Container Managed Entity Manager");
319        }
320    
321        public boolean isOpen() {
322            return true;
323        }
324    
325        public EntityTransaction getTransaction() {
326            throw new IllegalStateException("You cannot call getTransaction on a container managed EntityManager");
327        }
328    
329        public void joinTransaction() {
330            throw new IllegalStateException("You cannot call joinTransaction on a container managed EntityManager");
331        }
332    
333        public Object getDelegate() {
334            EntityManager entityManager = getEntityManager(false);
335            if (entityManager != null) {
336                return entityManager.getDelegate();
337            } else {
338                entityManager = createEntityManager();
339                try {
340                    return entityManager.getDelegate();
341                } finally {
342                    entityManager.close();
343                }
344            }
345        }
346    
347        private static class EntityManagerWrapperTxScoped implements EntityManagerWrapper {
348            private final EntityManager entityManager;
349    
350            public EntityManagerWrapperTxScoped(EntityManager entityManager) {
351                if (entityManager == null) {
352                    throw new IllegalArgumentException("Need a non-null entity manager");
353                }
354                this.entityManager = entityManager;
355            }
356    
357            public void close() {
358                    entityManager.close();
359            }
360    
361            public EntityManager getEntityManager() {
362                return entityManager;
363            }
364        }
365    }