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.concurrent.atomic.AtomicInteger;
021    
022    import javax.persistence.EntityManager;
023    import javax.persistence.EntityTransaction;
024    import javax.persistence.FlushModeType;
025    import javax.persistence.LockModeType;
026    import javax.persistence.Query;
027    
028    import org.apache.geronimo.transaction.manager.TransactionImpl;
029    import org.apache.geronimo.transaction.manager.TransactionManagerImpl;
030    
031    /**
032     * InternalCMPEntityManagerExtended is an EntityManager wrapper that CMPEntityManagerExtended wraps the
033     * real EntityManager with and registers with the transaction.
034     *
035     * @version $Rev: 487175 $ $Date: 2006-12-14 03:10:31 -0800 (Thu, 14 Dec 2006) $
036     */
037    public class InternalCMPEntityManagerExtended implements EntityManager, EntityManagerWrapper {
038    
039        private final EntityManager entityManager;
040        private final String persistenceUnit;
041        private final TransactionManagerImpl transactionManager;
042        //Does this need to be thread safe???
043        private final AtomicInteger count = new AtomicInteger();
044    
045        public InternalCMPEntityManagerExtended(EntityManager entityManager, String persistenceUnit, TransactionManagerImpl transactionManager) {
046            this.entityManager = entityManager;
047            this.persistenceUnit = persistenceUnit;
048            this.transactionManager = transactionManager;
049            if (transactionManager.getTransaction() != null) {
050                joinTransaction();
051            }
052        }
053    
054        void registerBean() {
055            count.getAndIncrement();
056        }
057    
058        void beanRemoved() {
059            if (count.decrementAndGet() ==0 ) {
060                entityManager.close();
061                EntityManagerExtendedRegistry.clearEntityManager(persistenceUnit);
062            }
063    
064        }
065    
066        public EntityManager getEntityManager() {
067            return entityManager;
068        }
069    
070        public void persist(Object o) {
071            entityManager.persist(o);
072        }
073    
074        public <T>T merge(T t) {
075            return entityManager.merge(t);
076        }
077    
078        public void remove(Object o) {
079            entityManager.remove(o);
080        }
081    
082        public <T>T find(Class<T> aClass, Object o) {
083            return entityManager.find(aClass, o);
084        }
085    
086        public <T>T getReference(Class<T> aClass, Object o) {
087            return entityManager.getReference(aClass, o);
088        }
089    
090        public void flush() {
091            entityManager.flush();
092        }
093    
094        public void setFlushMode(FlushModeType flushModeType) {
095            entityManager.setFlushMode(flushModeType);
096        }
097    
098        public FlushModeType getFlushMode() {
099            return entityManager.getFlushMode();
100        }
101    
102        public void lock(Object o, LockModeType lockModeType) {
103            entityManager.lock(o, lockModeType);
104        }
105    
106        public void refresh(Object o) {
107            entityManager.refresh(o);
108        }
109    
110        public void clear() {
111            entityManager.clear();
112        }
113    
114        public boolean contains(Object o) {
115            return entityManager.contains(o);
116        }
117    
118        public Query createQuery(String s) {
119            return entityManager.createQuery(s);
120        }
121    
122        public Query createNamedQuery(String s) {
123            return entityManager.createNamedQuery(s);
124        }
125    
126        public Query createNativeQuery(String s) {
127            return entityManager.createNativeQuery(s);
128        }
129    
130        public Query createNativeQuery(String s, Class aClass) {
131            return entityManager.createNativeQuery(s, aClass);
132        }
133    
134        public Query createNativeQuery(String s, String s1) {
135            return entityManager.createNativeQuery(s, s1);
136        }
137    
138        public void close() {
139            //a no-op
140        }
141    
142        public boolean isOpen() {
143            return true;
144        }
145    
146        public EntityTransaction getTransaction() {
147            throw new IllegalStateException("You cannot call getTransaction on a container managed EntityManager");
148        }
149    
150        public void joinTransaction() {
151                TransactionImpl transaction = (TransactionImpl) transactionManager.getTransaction();
152                //This checks section 5.6.3.1, throwing an EJBException if there is already a PersistenceContext.
153                transaction.setEntityManager(persistenceUnit, this);
154            entityManager.joinTransaction();
155        }
156    
157        public Object getDelegate() {
158            return entityManager.getDelegate();
159        }
160    
161    }