001    /****************************************************************
002     * Licensed to the Apache Software Foundation (ASF) under one   *
003     * or more contributor license agreements.  See the NOTICE file *
004     * distributed with this work for additional information        *
005     * regarding copyright ownership.  The ASF licenses this file   *
006     * to you under the Apache License, Version 2.0 (the            *
007     * "License"); you may not use this file except in compliance   *
008     * with the License.  You may obtain a copy of the License at   *
009     *                                                              *
010     *   http://www.apache.org/licenses/LICENSE-2.0                 *
011     *                                                              *
012     * Unless required by applicable law or agreed to in writing,   *
013     * software distributed under the License is distributed on an  *
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
015     * KIND, either express or implied.  See the License for the    *
016     * specific language governing permissions and limitations      *
017     * under the License.                                           *
018     ****************************************************************/
019    package org.apache.james.mailbox.jpa;
020    
021    import javax.persistence.EntityManager;
022    import javax.persistence.EntityManagerFactory;
023    import javax.persistence.EntityTransaction;
024    import javax.persistence.PersistenceException;
025    
026    import org.apache.james.mailbox.exception.MailboxException;
027    import org.apache.james.mailbox.store.transaction.TransactionalMapper;
028    
029    /**
030     * JPA implementation of TransactionMapper. This class is not thread-safe!
031     *
032     */
033    public abstract class JPATransactionalMapper extends TransactionalMapper {
034    
035        protected EntityManagerFactory entityManagerFactory;
036        protected EntityManager entityManager;
037        
038        public JPATransactionalMapper(final EntityManagerFactory entityManagerFactory) {
039            this.entityManagerFactory = entityManagerFactory;
040        }
041    
042        /**
043         * Return the currently used {@link EntityManager} or a new one if none exists.
044         * 
045         * @return entitymanger
046         */
047        public EntityManager getEntityManager() {
048            if (entityManager != null)
049                return entityManager;
050            entityManager = entityManagerFactory.createEntityManager();
051            return entityManager;
052        }
053    
054        /**
055         * @see org.apache.james.mailbox.store.transaction.TransactionalMapper#begin()
056         */
057        protected void begin() throws MailboxException {
058            try {
059                getEntityManager().getTransaction().begin();
060            } catch (PersistenceException e) {
061                throw new MailboxException("Begin of transaction failed", e);
062            }
063        }
064    
065        /**
066         * Commit the Transaction and close the EntityManager
067         */
068        protected void commit() throws MailboxException {
069            try {
070                getEntityManager().getTransaction().commit();
071            } catch (PersistenceException e) {
072                throw new MailboxException("Commit of transaction failed",e);
073            }
074        }
075    
076        /**
077         * @see org.apache.james.mailbox.store.transaction.TransactionalMapper#rollback()
078         */
079        protected void rollback() throws MailboxException {
080            EntityTransaction transaction = entityManager.getTransaction();
081            // check if we have a transaction to rollback
082            if (transaction.isActive()) {
083                getEntityManager().getTransaction().rollback();
084            }
085        }
086    
087        /**
088         * Close open {@link EntityManager}
089         */
090        public void endRequest() {
091            if (entityManager != null) {
092                if (entityManager.isOpen())
093                    entityManager.close();
094                entityManager = null;
095            }
096        }
097    
098        
099    }