001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.spring.transaction;
016    
017    import com.liferay.portal.cache.transactional.TransactionalPortalCacheHelper;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.util.StringPool;
021    
022    import java.lang.reflect.Method;
023    
024    import org.aopalliance.intercept.MethodInterceptor;
025    import org.aopalliance.intercept.MethodInvocation;
026    
027    import org.springframework.transaction.TransactionStatus;
028    import org.springframework.transaction.interceptor.TransactionAspectSupport;
029    import org.springframework.transaction.interceptor.TransactionAttribute;
030    import org.springframework.transaction.interceptor.TransactionAttributeSource;
031    
032    /**
033     * @author Shuyang Zhou
034     */
035    public class TransactionInterceptor
036            extends TransactionAspectSupport implements MethodInterceptor {
037    
038            public Object invoke(MethodInvocation methodInvocation) throws Throwable {
039                    Method method = methodInvocation.getMethod();
040    
041                    Class<?> targetClass = null;
042    
043                    Object thisObject = methodInvocation.getThis();
044    
045                    if (thisObject != null) {
046                            targetClass = thisObject.getClass();
047                    }
048    
049                    TransactionAttributeSource transactionAttributeSource =
050                            getTransactionAttributeSource();
051    
052                    TransactionAttribute transactionAttribute =
053                            transactionAttributeSource.getTransactionAttribute(
054                                    method, targetClass);
055    
056                    Class<?> declaringClass = method.getDeclaringClass();
057    
058                    String joinPointIdentification = StringPool.BLANK;
059    
060                    if (_log.isDebugEnabled()) {
061                            joinPointIdentification =
062                                    declaringClass.getName().concat(StringPool.PERIOD).concat(
063                                            method.getName());
064                    }
065    
066                    TransactionInfo transactionInfo = createTransactionIfNecessary(
067                            getTransactionManager(), transactionAttribute,
068                            joinPointIdentification);
069    
070                    TransactionStatus transactionStatus =
071                            transactionInfo.getTransactionStatus();
072    
073                    boolean newTransaction = transactionStatus.isNewTransaction();
074    
075                    if (newTransaction) {
076                            TransactionalPortalCacheHelper.begin();
077                    }
078    
079                    Object returnValue = null;
080    
081                    try {
082                            returnValue = methodInvocation.proceed();
083                    }
084                    catch (Throwable throwable) {
085                            if (newTransaction) {
086                                    TransactionalPortalCacheHelper.rollback();
087                            }
088    
089                            completeTransactionAfterThrowing(transactionInfo, throwable);
090    
091                            throw throwable;
092                    }
093                    finally {
094                            cleanupTransactionInfo(transactionInfo);
095                    }
096    
097                    commitTransactionAfterReturning(transactionInfo);
098    
099                    if (newTransaction) {
100                            TransactionalPortalCacheHelper.commit();
101                    }
102    
103                    return returnValue;
104            }
105    
106            private static Log _log = LogFactoryUtil.getLog(
107                    TransactionInterceptor.class);
108    
109    }