    001    // Copyright 2008, 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.hibernate;
    016
    017    import org.apache.tapestry5.hibernate.HibernateSessionManager;
    018    import org.apache.tapestry5.hibernate.annotations.CommitAfter;
    019    import org.apache.tapestry5.model.MutableComponentModel;
    020    import org.apache.tapestry5.plastic.MethodAdvice;
    021    import org.apache.tapestry5.plastic.MethodInvocation;
    022    import org.apache.tapestry5.plastic.PlasticClass;
    023    import org.apache.tapestry5.plastic.PlasticMethod;
    024    import org.apache.tapestry5.services.transform.ComponentClassTransformWorker2;
    025    import org.apache.tapestry5.services.transform.TransformationSupport;
    026
    027    /**
    028     * Searches for methods that have the {@link org.apache.tapestry5.hibernate.annotations.CommitAfter} annotation and adds
    029     * logic around the method to commit or abort the transaction. The commit/abort logic is the same as for the
    030     * {@link org.apache.tapestry5.hibernate.HibernateTransactionDecorator} service.
    031     */
    032    public class CommitAfterWorker implements ComponentClassTransformWorker2
    033    {
    034        private final HibernateSessionManager manager;
    035
    036        private final MethodAdvice advice = new MethodAdvice()
    037        {
    038            private void abort()
    039            {
    040                try
    041                {
    042                    manager.abort();
    043                } catch (Exception e)
    044                {
    045                    // Ignore.
    046                }
    047            }
    048
    049            public void advise(MethodInvocation invocation)
    050            {
    051                try
    052                {
    053                    invocation.proceed();
    054
    055                    // Success or checked exception:
    056
    057                    manager.commit();
    058                } catch (RuntimeException ex)
    059                {
    060                    abort();
    061
    062                    throw ex;
    063                }
    064            }
    065        };
    066
    067        public CommitAfterWorker(HibernateSessionManager manager)
    068        {
    069            this.manager = manager;
    070        }
    071
    072        public void transform(PlasticClass plasticClass, TransformationSupport support, MutableComponentModel model)
    073        {
    074            for (PlasticMethod method : plasticClass.getMethodsWithAnnotation(CommitAfter.class))
    075            {
    076                method.addAdvice(advice);
    077            }
    078        }
    079    }