001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.dao.jdbc.aop;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    
020    import java.util.Stack;
021    
022    import javax.sql.DataSource;
023    
024    import org.springframework.aop.TargetSource;
025    
026    /**
027     * @author Michael Young
028     */
029    public class DynamicDataSourceTargetSource implements TargetSource {
030    
031            public Stack<String> getMethodStack() {
032                    Stack<String> methodStack = _methodStack.get();
033    
034                    if (methodStack == null) {
035                            methodStack = new Stack<String>();
036    
037                            _methodStack.set(methodStack);
038                    }
039    
040                    return methodStack;
041            }
042    
043            public Operation getOperation() {
044                    Operation operation = _operationType.get();
045    
046                    if (operation == null) {
047                            operation = Operation.WRITE;
048    
049                            _operationType.set(operation);
050                    }
051    
052                    return operation;
053            }
054    
055            public Object getTarget() throws Exception {
056                    Operation operationType = getOperation();
057    
058                    if (operationType == Operation.READ) {
059                            if (_log.isTraceEnabled()) {
060                                    _log.trace("Returning read data source");
061                            }
062    
063                            return _readDataSource;
064                    }
065                    else {
066                            if (_log.isTraceEnabled()) {
067                                    _log.trace("Returning write data source");
068                            }
069    
070                            return _writeDataSource;
071                    }
072            }
073    
074            public Class<DataSource> getTargetClass() {
075                    return DataSource.class;
076            }
077    
078            public boolean isStatic() {
079                    return false;
080            }
081    
082            public String popMethod() {
083                    Stack<String> methodStack = getMethodStack();
084    
085                    String method = methodStack.pop();
086    
087                    setOperation(Operation.WRITE);
088    
089                    return method;
090            }
091    
092            public void pushMethod(String method) {
093                    Stack<String> methodStack = getMethodStack();
094    
095                    methodStack.push(method);
096            }
097    
098            public void releaseTarget(Object target) throws Exception {
099            }
100    
101            public void setOperation(Operation operation) {
102                    if (_log.isDebugEnabled()) {
103                            _log.debug("Method stack " + getMethodStack());
104                    }
105    
106                    if (!inOperation() || (operation == Operation.WRITE)) {
107                            _operationType.set(operation);
108                    }
109            }
110    
111            public void setReadDataSource(DataSource readDataSource) {
112                    _readDataSource = readDataSource;
113            }
114    
115            public void setWriteDataSource(DataSource writeDataSource) {
116                    _writeDataSource = writeDataSource;
117            }
118    
119            protected boolean inOperation() {
120                    Stack<String> methodStack = getMethodStack();
121    
122                    return !methodStack.empty();
123            }
124    
125            private static Log _log = LogFactoryUtil.getLog(
126                    DynamicDataSourceTargetSource.class);
127    
128            private static ThreadLocal<Stack<String>> _methodStack =
129                    new ThreadLocal<Stack<String>>();
130            private static ThreadLocal<Operation> _operationType =
131                    new ThreadLocal<Operation>();
132    
133            private DataSource _readDataSource;
134            private DataSource _writeDataSource;
135    
136    }