001
014
015 package com.liferay.portal.dao.jdbc.aop;
016
017 import com.liferay.portal.kernel.dao.jdbc.aop.MasterDataSource;
018 import com.liferay.portal.kernel.util.StringPool;
019 import com.liferay.portal.spring.aop.ChainableMethodAdvice;
020 import com.liferay.portal.spring.aop.ServiceBeanAopCacheManager;
021
022 import java.lang.reflect.Method;
023
024 import org.aopalliance.intercept.MethodInvocation;
025
026 import org.springframework.transaction.interceptor.TransactionAttribute;
027 import org.springframework.transaction.interceptor.TransactionAttributeSource;
028
029
033 public class DynamicDataSourceAdvice extends ChainableMethodAdvice {
034
035 @Override
036 public Object before(MethodInvocation methodInvocation) throws Throwable {
037 Operation operation = Operation.WRITE;
038
039 Object targetBean = methodInvocation.getThis();
040
041 Class<?> targetClass = targetBean.getClass();
042
043 Method targetMethod = methodInvocation.getMethod();
044
045 MasterDataSource masterDataSource =
046 ServiceBeanAopCacheManager.getAnnotation(
047 methodInvocation, MasterDataSource.class,
048 _nullMasterDataSource);
049
050 if (masterDataSource == _nullMasterDataSource) {
051 TransactionAttribute transactionAttribute =
052 _transactionAttributeSource.getTransactionAttribute(
053 targetMethod, targetClass);
054
055 if ((transactionAttribute != null) &&
056 transactionAttribute.isReadOnly()) {
057
058 operation = Operation.READ;
059 }
060 }
061
062 _dynamicDataSourceTargetSource.setOperation(operation);
063
064 String targetClassName = targetClass.getName();
065
066 _dynamicDataSourceTargetSource.pushMethod(
067 targetClassName.concat(StringPool.PERIOD).concat(
068 targetMethod.getName()));
069
070 return null;
071 }
072
073 @Override
074 public void duringFinally(MethodInvocation methodInvocation) {
075 _dynamicDataSourceTargetSource.popMethod();
076 }
077
078 public void setDynamicDataSourceTargetSource(
079 DynamicDataSourceTargetSource dynamicDataSourceTargetSource) {
080
081 _dynamicDataSourceTargetSource = dynamicDataSourceTargetSource;
082 }
083
084 public void setTransactionAttributeSource(
085 TransactionAttributeSource transactionAttributeSource) {
086
087 _transactionAttributeSource = transactionAttributeSource;
088 }
089
090 @Override
091 protected void setServiceBeanAopCacheManager(
092 ServiceBeanAopCacheManager serviceBeanAopCacheManager) {
093
094 if (this.serviceBeanAopCacheManager != null) {
095 return;
096 }
097
098 this.serviceBeanAopCacheManager = serviceBeanAopCacheManager;
099
100 serviceBeanAopCacheManager.registerAnnotationChainableMethodAdvice(
101 MasterDataSource.class, null);
102 }
103
104 private static MasterDataSource _nullMasterDataSource =
105 new MasterDataSource() {
106
107 @Override
108 public Class<? extends MasterDataSource> annotationType() {
109 return MasterDataSource.class;
110 }
111
112 };
113
114 private DynamicDataSourceTargetSource _dynamicDataSourceTargetSource;
115 private TransactionAttributeSource _transactionAttributeSource;
116
117 }