Merge "provide ready-use maven setting for easy build"
[sdnc/core.git] / dblib / common / src / main / java / org / apache / tomcat / jdbc / pool / ProxyConnection.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openecomp
4  * ================================================================================
5  * Copyright (C) 2016 - 2017 AT&T
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 /*
22  * Licensed to the Apache Software Foundation (ASF) under one or more
23  * contributor license agreements.  See the NOTICE file distributed with
24  * this work for additional information regarding copyright ownership.
25  * The ASF licenses this file to You under the Apache License, Version 2.0
26  * (the "License"); you may not use this file except in compliance with
27  * the License.  You may obtain a copy of the License at
28  *
29  *      http://www.apache.org/licenses/LICENSE-2.0
30  *
31  * Unless required by applicable law or agreed to in writing, software
32  * distributed under the License is distributed on an "AS IS" BASIS,
33  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34  * See the License for the specific language governing permissions and
35  * limitations under the License.
36  */
37 package org.apache.tomcat.jdbc.pool;
38
39 import java.lang.reflect.InvocationTargetException;
40 import java.lang.reflect.Method;
41 import java.sql.SQLException;
42
43 import javax.sql.XAConnection;
44 /**
45  * A ProxyConnection object is the bottom most interceptor that wraps an object of type
46  * {@link PooledConnection}. The ProxyConnection intercepts three methods:
47  * <ul>
48  *   <li>{@link java.sql.Connection#close()} - returns the connection to the pool. May be called multiple times.</li>
49  *   <li>{@link java.lang.Object#toString()} - returns a custom string for this object</li>
50  *   <li>{@link javax.sql.PooledConnection#getConnection()} - returns the underlying connection</li>
51  * </ul>
52  * By default method comparisons is done on a String reference level, unless the {@link PoolConfiguration#setUseEquals(boolean)} has been called
53  * with a <code>true</code> argument.
54  */
55 public class ProxyConnection extends JdbcInterceptor {
56
57     protected PooledConnection connection = null;
58
59     protected ConnectionPool pool = null;
60
61     public PooledConnection getConnection() {
62         return connection;
63     }
64
65     public void setConnection(PooledConnection connection) {
66         this.connection = connection;
67     }
68
69     public ConnectionPool getPool() {
70         return pool;
71     }
72
73     public void setPool(ConnectionPool pool) {
74         this.pool = pool;
75     }
76
77     protected ProxyConnection(ConnectionPool parent, PooledConnection con,
78             boolean useEquals) {
79         pool = parent;
80         connection = con;
81         setUseEquals(useEquals);
82     }
83
84     @Override
85     public void reset(ConnectionPool parent, PooledConnection con) {
86         this.pool = parent;
87         this.connection = con;
88     }
89
90     public boolean isWrapperFor(Class<?> iface) {
91         if (iface == XAConnection.class && connection.getXAConnection()!=null) {
92             return true;
93         } else {
94             return (iface.isInstance(connection.getConnection()));
95         }
96     }
97
98
99     public Object unwrap(Class<?> iface) throws SQLException {
100         if (iface == PooledConnection.class) {
101             return connection;
102         }else if (iface == XAConnection.class) {
103             return connection.getXAConnection();
104         } else if (isWrapperFor(iface)) {
105             return connection.getConnection();
106         } else {
107             throw new SQLException("Not a wrapper of "+iface.getName());
108         }
109     }
110
111     @Override
112     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
113         if (compare(ISCLOSED_VAL,method)) {
114             return Boolean.valueOf(isClosed());
115         }
116         if (compare(CLOSE_VAL,method)) {
117             if (connection==null) return null; //noop for already closed.
118             PooledConnection poolc = this.connection;
119             this.connection = null;
120             pool.returnConnection(poolc);
121             return null;
122         } else if (compare(TOSTRING_VAL,method)) {
123             return this.toString();
124         } else if (compare(GETCONNECTION_VAL,method) && connection!=null) {
125             return connection.getConnection();
126         } else if (method.getDeclaringClass().equals(XAConnection.class)) {
127             try {
128                 return method.invoke(connection.getXAConnection(),args);
129             }catch (Throwable t) {
130                 if (t instanceof InvocationTargetException) {
131                     throw t.getCause() != null ? t.getCause() : t;
132                 } else {
133                     throw t;
134                 }
135             }
136         }
137         if (isClosed()) throw new SQLException("Connection has already been closed.");
138         if (compare(UNWRAP_VAL,method)) {
139             return unwrap((Class<?>)args[0]);
140         } else if (compare(ISWRAPPERFOR_VAL,method)) {
141             return Boolean.valueOf(this.isWrapperFor((Class<?>)args[0]));
142         }
143         try {
144             PooledConnection poolc = connection;
145             if (poolc!=null) {
146                 return method.invoke(poolc.getConnection(),args);
147             } else {
148                 throw new SQLException("Connection has already been closed.");
149             }
150         }catch (Throwable t) {
151             if (t instanceof InvocationTargetException) {
152                 throw t.getCause() != null ? t.getCause() : t;
153             } else {
154                 throw t;
155             }
156         }
157     }
158
159     public boolean isClosed() {
160         return connection==null || connection.isDiscarded();
161     }
162
163     public PooledConnection getDelegateConnection() {
164         return connection;
165     }
166
167     public ConnectionPool getParentPool() {
168         return pool;
169     }
170
171     @Override
172     public String toString() {
173         return "ProxyConnection["+(connection!=null?connection.toString():"null")+"]";
174     }
175
176 }