KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > conn > PooledConnectionImpl


1 /*****************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  ****************************************************************/

19
20
21 package org.apache.cayenne.conn;
22
23 import java.sql.Connection JavaDoc;
24 import java.sql.SQLException JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Collections JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.List JavaDoc;
29
30 import javax.sql.ConnectionEvent JavaDoc;
31 import javax.sql.ConnectionEventListener JavaDoc;
32 import javax.sql.DataSource JavaDoc;
33 import javax.sql.PooledConnection JavaDoc;
34
35 /**
36  * PooledConnectionImpl is an implementation of a pooling wrapper for the database
37  * connection as per JDBC3 spec. Most of the modern JDBC drivers should have its own
38  * implementation that may be used instead of this class.
39  *
40  * @author Andrus Adamchik
41  */

42 public class PooledConnectionImpl implements PooledConnection JavaDoc {
43
44     private Connection JavaDoc connectionObj;
45     private List JavaDoc connectionEventListeners;
46     private boolean hadErrors;
47     private DataSource JavaDoc connectionSource;
48     private String JavaDoc userName;
49     private String JavaDoc password;
50
51     protected PooledConnectionImpl() {
52         // TODO: maybe remove synchronization and use
53
// FastArrayList from commons-collections? After
54
// all the only listener is usually pool manager.
55
this.connectionEventListeners = Collections.synchronizedList(new ArrayList JavaDoc(10));
56     }
57
58     /** Creates new PooledConnection */
59     public PooledConnectionImpl(DataSource JavaDoc connectionSource, String JavaDoc userName,
60             String JavaDoc password) {
61
62         this();
63
64         this.connectionSource = connectionSource;
65         this.userName = userName;
66         this.password = password;
67
68     }
69
70     public void reconnect() throws SQLException JavaDoc {
71         if (connectionObj != null) {
72             try {
73                 connectionObj.close();
74             }
75             catch (SQLException JavaDoc ex) {
76                 // ignore exception, since connection is expected
77
// to be in a bad state
78
}
79             finally {
80                 connectionObj = null;
81             }
82         }
83
84         connectionObj = (userName != null) ? connectionSource.getConnection(
85                 userName,
86                 password) : connectionSource.getConnection();
87     }
88
89     public void addConnectionEventListener(ConnectionEventListener JavaDoc listener) {
90         synchronized (connectionEventListeners) {
91             if (!connectionEventListeners.contains(listener))
92                 connectionEventListeners.add(listener);
93         }
94     }
95
96     public void removeConnectionEventListener(ConnectionEventListener JavaDoc listener) {
97         synchronized (connectionEventListeners) {
98             connectionEventListeners.remove(listener);
99         }
100     }
101
102     public void close() throws SQLException JavaDoc {
103
104         synchronized (connectionEventListeners) {
105             // remove all listeners
106
connectionEventListeners.clear();
107         }
108
109         if (connectionObj != null) {
110             try {
111                 connectionObj.close();
112             }
113             finally {
114                 connectionObj = null;
115             }
116         }
117     }
118
119     public Connection JavaDoc getConnection() throws SQLException JavaDoc {
120         if (connectionObj == null) {
121             reconnect();
122         }
123
124         // set autocommit to false to return connection
125
// always in consistent state
126
if (!connectionObj.getAutoCommit()) {
127
128             try {
129                 connectionObj.setAutoCommit(true);
130             }
131             catch (SQLException JavaDoc sqlEx) {
132                 // try applying Sybase patch
133
ConnectionWrapper.sybaseAutoCommitPatch(connectionObj, sqlEx, true);
134             }
135         }
136
137         connectionObj.clearWarnings();
138         return new ConnectionWrapper(connectionObj, this);
139     }
140
141     protected void returnConnectionToThePool() throws SQLException JavaDoc {
142         // do not return to pool bad connections
143
if (hadErrors)
144             close();
145         else
146             // notify the listeners that connection is no longer used by application...
147
this.connectionClosedNotification();
148     }
149
150     /**
151      * This method creates and sents an event to listeners when an error occurs in the
152      * underlying connection. Listeners can have special logic to analyze the error and do
153      * things like closing this PooledConnection (if the error is fatal), etc...
154      */

155     public void connectionErrorNotification(SQLException JavaDoc exception) {
156         // hint for later to avoid returning bad connections to the pool
157
hadErrors = true;
158
159         synchronized (connectionEventListeners) {
160             if (connectionEventListeners.size() == 0)
161                 return;
162
163             ConnectionEvent JavaDoc closedEvent = new ConnectionEvent JavaDoc(this, exception);
164             Iterator JavaDoc listeners = connectionEventListeners.iterator();
165             while (listeners.hasNext()) {
166                 ConnectionEventListener JavaDoc nextListener = (ConnectionEventListener JavaDoc) listeners
167                         .next();
168                 nextListener.connectionErrorOccurred(closedEvent);
169             }
170         }
171     }
172
173     /**
174      * Creates and sends an event to listeners when a user closes java.sql.Connection
175      * object belonging to this PooledConnection.
176      */

177     protected void connectionClosedNotification() {
178         synchronized (connectionEventListeners) {
179             if (connectionEventListeners.size() == 0)
180                 return;
181
182             ConnectionEvent JavaDoc closedEvent = new ConnectionEvent JavaDoc(this);
183             Iterator JavaDoc listeners = connectionEventListeners.iterator();
184
185             while (listeners.hasNext()) {
186                 ConnectionEventListener JavaDoc nextListener = (ConnectionEventListener JavaDoc) listeners
187                         .next();
188                 nextListener.connectionClosed(closedEvent);
189             }
190         }
191     }
192 }
193
Popular Tags