1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.dao.jdbc.aop;
16  
17  import com.liferay.portal.kernel.log.Log;
18  import com.liferay.portal.kernel.log.LogFactoryUtil;
19  
20  import java.util.Stack;
21  
22  import javax.sql.DataSource;
23  
24  import org.springframework.aop.TargetSource;
25  
26  /**
27   * <a href="DynamicDataSourceTargetSource.java.html"><b><i>View Source</i></b>
28   * </a>
29   *
30   * @author Michael Young
31   */
32  public class DynamicDataSourceTargetSource implements TargetSource {
33  
34      public Stack<String> getMethodStack() {
35          Stack<String> methodStack = _methodStack.get();
36  
37          if (methodStack == null) {
38              methodStack = new Stack<String>();
39  
40              _methodStack.set(methodStack);
41          }
42  
43          return methodStack;
44      }
45  
46      public Operation getOperation() {
47          Operation operation = _operationType.get();
48  
49          if (operation == null) {
50              operation = Operation.WRITE;
51  
52              _operationType.set(operation);
53          }
54  
55          return operation;
56      }
57  
58      public Object getTarget() throws Exception {
59          Operation operationType = getOperation();
60  
61          if (operationType == Operation.READ) {
62              if (_log.isTraceEnabled()) {
63                  _log.trace("Returning read data source");
64              }
65  
66              return _readDataSource;
67          }
68          else {
69              if (_log.isTraceEnabled()) {
70                  _log.trace("Returning write data source");
71              }
72  
73              return _writeDataSource;
74          }
75      }
76  
77      public Class<DataSource> getTargetClass() {
78          return DataSource.class;
79      }
80  
81      public boolean isStatic() {
82          return false;
83      }
84  
85      public String popMethod() {
86          Stack<String> methodStack = getMethodStack();
87  
88          String method = methodStack.pop();
89  
90          setOperation(Operation.WRITE);
91  
92          return method;
93      }
94  
95      public void pushMethod(String method) {
96          Stack<String> methodStack = getMethodStack();
97  
98          methodStack.push(method);
99      }
100 
101     public void releaseTarget(Object target) throws Exception {
102     }
103 
104     public void setOperation(Operation operation) {
105         if (_log.isDebugEnabled()) {
106             _log.debug("Method stack " + getMethodStack());
107         }
108 
109         if (!inOperation() || (operation == Operation.WRITE)) {
110             _operationType.set(operation);
111         }
112     }
113 
114     public void setReadDataSource(DataSource readDataSource) {
115         _readDataSource = readDataSource;
116     }
117 
118     public void setWriteDataSource(DataSource writeDataSource) {
119         _writeDataSource = writeDataSource;
120     }
121 
122     protected boolean inOperation() {
123         Stack<String> methodStack = getMethodStack();
124 
125         return !methodStack.empty();
126     }
127 
128     private static Log _log = LogFactoryUtil.getLog(
129         DynamicDataSourceTargetSource.class);
130 
131     private static ThreadLocal<Stack<String>> _methodStack =
132         new ThreadLocal<Stack<String>>();
133     private static ThreadLocal<Operation> _operationType =
134         new ThreadLocal<Operation>();
135 
136     private DataSource _readDataSource;
137     private DataSource _writeDataSource;
138 
139 }