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