    001// Copyright 2011, 2012, 2014 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
    015package org.apache.tapestry5.internal.jpa;
    016
    017import javax.persistence.EntityManager;
    018import javax.persistence.EntityTransaction;
    019import javax.persistence.PersistenceContext;
    020
    021import org.apache.tapestry5.jpa.EntityManagerManager;
    022import org.apache.tapestry5.jpa.annotations.CommitAfter;
    023import org.apache.tapestry5.plastic.MethodAdvice;
    024import org.apache.tapestry5.plastic.MethodInvocation;
    025
    026public class CommitAfterMethodAdvice implements MethodAdvice
    027{
    028    private final EntityManagerManager manager;
    029
    030    public CommitAfterMethodAdvice(final EntityManagerManager manager)
    031    {
    032        this.manager = manager;
    033    }
    034
    035    @Override
    036    public void advise(final MethodInvocation invocation)
    037    {
    038
    039        if (invocation.hasAnnotation(CommitAfter.class))
    040        {
    041
    042                        final PersistenceContext annotation = invocation.getAnnotation(PersistenceContext.class);
    043                final EntityTransaction transaction = getTransaction(annotation);
    044
    045                if (transaction != null && !transaction.isActive())
    046                {
    047                    transaction.begin();
    048                }
    049
    050                try
    051                {
    052                    invocation.proceed();
    053                } catch (final RuntimeException e)
    054                {
    055                    if (transaction != null && transaction.isActive())
    056                    {
    057                        rollbackTransaction(transaction);
    058                    }
    059
    060                    throw e;
    061                }
    062
    063                // Success or checked exception:
    064
    065                if (transaction != null && transaction.isActive())
    066                {
    067                    transaction.commit();
    068                }
    069
    070        }
    071        else
    072        {
    073                invocation.proceed();
    074        }
    075
    076    }
    077
    078    private void rollbackTransaction(EntityTransaction transaction)
    079    {
    080        try
    081        {
    082            transaction.rollback();
    083        } catch (Exception e)
    084        { // Ignore
    085        }
    086    }
    087
    088    private EntityTransaction getTransaction(PersistenceContext annotation)
    089    {
    090        EntityManager em = JpaInternalUtils.getEntityManager(manager, annotation);
    091
    092        if (em == null)
    093            return null;
    094
    095        return em.getTransaction();
    096    }
    097
    098}