001    // Copyright 2011, 2012 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    // http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry5.internal.jpa;
016    
017    import org.apache.tapestry5.jpa.EntityManagerManager;
018    import org.apache.tapestry5.plastic.MethodAdvice;
019    import org.apache.tapestry5.plastic.MethodInvocation;
020    
021    import javax.persistence.EntityManager;
022    import javax.persistence.EntityTransaction;
023    import javax.persistence.PersistenceContext;
024    
025    public class CommitAfterMethodAdvice implements MethodAdvice
026    {
027        private final EntityManagerManager manager;
028    
029        private final PersistenceContext annotation;
030    
031        public CommitAfterMethodAdvice(final EntityManagerManager manager, PersistenceContext annotation)
032        {
033            this.manager = manager;
034            this.annotation = annotation;
035        }
036    
037        public void advise(final MethodInvocation invocation)
038        {
039            final EntityTransaction transaction = getTransaction();
040    
041            if (transaction != null && !transaction.isActive())
042            {
043                transaction.begin();
044            }
045    
046            try
047            {
048                invocation.proceed();
049            } catch (final RuntimeException e)
050            {
051                if (transaction != null && transaction.isActive())
052                {
053                    rollbackTransaction(transaction);
054                }
055    
056                throw e;
057            }
058    
059            // Success or checked exception:
060    
061            if (transaction != null && transaction.isActive())
062            {
063                transaction.commit();
064            }
065    
066        }
067    
068        private void rollbackTransaction(EntityTransaction transaction)
069        {
070            try
071            {
072                transaction.rollback();
073            } catch (Exception e)
074            { // Ignore
075            }
076        }
077    
078        private EntityTransaction getTransaction()
079        {
080            EntityManager em = JpaInternalUtils.getEntityManager(manager, annotation);
081    
082            if (em == null)
083                return null;
084    
085            return em.getTransaction();
086        }
087    
088    }