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