1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  package com.liferay.portal.dao.jdbc.aop;
21  
22  import com.liferay.portal.kernel.log.Log;
23  import com.liferay.portal.kernel.log.LogFactoryUtil;
24  
25  import java.util.Stack;
26  
27  import javax.sql.DataSource;
28  
29  import org.springframework.aop.TargetSource;
30  
31  /**
32   * <a href="DynamicDataSourceTargetSource.java.html"><b><i>View Source</i></b>
33   * </a>
34   *
35   * @author Michael Young
36   *
37   */
38  public class DynamicDataSourceTargetSource implements TargetSource {
39  
40      public Stack<String> getMethodStack() {
41          Stack<String> methodStack = _methodStackThreadLocal.get();
42  
43          if (methodStack == null) {
44              methodStack = new Stack<String>();
45  
46              _methodStackThreadLocal.set(methodStack);
47          }
48  
49          return methodStack;
50      }
51  
52      public Operation getOperation() {
53          Operation operation = _operationTypeThreadLocal.get();
54  
55          if (operation == null) {
56              operation = Operation.WRITE;
57  
58              _operationTypeThreadLocal.set(operation);
59          }
60  
61          return operation;
62      }
63  
64      public Object getTarget() throws Exception {
65          Operation operationType = getOperation();
66  
67          if (operationType == Operation.READ) {
68              if (_log.isTraceEnabled()) {
69                  _log.trace("Returning read data source");
70              }
71  
72              return _readDataSource;
73          }
74          else {
75              if (_log.isTraceEnabled()) {
76                  _log.trace("Returning write data source");
77              }
78  
79              return _writeDataSource;
80          }
81      }
82  
83      public Class<DataSource> getTargetClass() {
84          return DataSource.class;
85      }
86  
87      public boolean isStatic() {
88          return false;
89      }
90  
91      public String popMethod() {
92          Stack<String> methodStack = getMethodStack();
93  
94          String method = methodStack.pop();
95  
96          setOperation(Operation.WRITE);
97  
98          return method;
99      }
100 
101     public void pushMethod(String method) {
102         Stack<String> methodStack = getMethodStack();
103 
104         methodStack.push(method);
105     }
106 
107     public void releaseTarget(Object target) throws Exception {
108     }
109 
110     public void setOperation(Operation operation) {
111         if (_log.isDebugEnabled()) {
112             _log.debug("Method stack " + getMethodStack());
113         }
114 
115         if (!inOperation() || (operation == Operation.WRITE)) {
116             _operationTypeThreadLocal.set(operation);
117         }
118     }
119 
120     public void setReadDataSource(DataSource readDataSource) {
121         _readDataSource = readDataSource;
122     }
123 
124     public void setWriteDataSource(DataSource writeDataSource) {
125         _writeDataSource = writeDataSource;
126     }
127 
128     protected boolean inOperation() {
129         Stack<String> methodStack = getMethodStack();
130 
131         return !methodStack.empty();
132     }
133 
134     private static Log _log =
135         LogFactoryUtil.getLog(DynamicDataSourceTargetSource.class);
136 
137     private static ThreadLocal<Stack<String>> _methodStackThreadLocal =
138         new ThreadLocal<Stack<String>>();
139     private static ThreadLocal<Operation> _operationTypeThreadLocal =
140         new ThreadLocal<Operation>();
141 
142     private DataSource _readDataSource;
143     private DataSource _writeDataSource;
144 
145 }