]> source.dussan.org Git - vaadin-framework.git/blob
d41c70688dce1dc882d6f5e26749bf16cefaaa0e
[vaadin-framework.git] /
1 /*
2  * Copyright 2000-2021 Vaadin Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 package com.vaadin.v7.data.util.sqlcontainer.connection;
17
18 import java.io.IOException;
19 import java.io.ObjectOutputStream;
20 import java.sql.Connection;
21 import java.sql.DriverManager;
22 import java.sql.SQLException;
23 import java.sql.Statement;
24 import java.util.HashSet;
25 import java.util.Locale;
26 import java.util.Set;
27
28 /**
29  * Simple implementation of the JDBCConnectionPool interface. Handles loading
30  * the JDBC driver, setting up the connections and ensuring they are still
31  * usable upon release.
32  *
33  * @deprecated As of 8.0, no replacement available.
34  */
35 @SuppressWarnings("serial")
36 @Deprecated
37 public class SimpleJDBCConnectionPool implements JDBCConnectionPool {
38
39     private int initialConnections = 5;
40     private int maxConnections = 20;
41
42     private String driverName;
43     private String connectionUri;
44     private String userName;
45     private String password;
46
47     private transient Set<Connection> availableConnections;
48     private transient Set<Connection> reservedConnections;
49
50     private boolean initialized;
51
52     public SimpleJDBCConnectionPool(String driverName, String connectionUri,
53             String userName, String password) throws SQLException {
54         if (driverName == null) {
55             throw new IllegalArgumentException(
56                     "JDBC driver class name must be given.");
57         }
58         if (connectionUri == null) {
59             throw new IllegalArgumentException(
60                     "Database connection URI must be given.");
61         }
62         if (userName == null) {
63             throw new IllegalArgumentException(
64                     "Database username must be given.");
65         }
66         if (password == null) {
67             throw new IllegalArgumentException(
68                     "Database password must be given.");
69         }
70         this.driverName = driverName;
71         this.connectionUri = connectionUri;
72         this.userName = userName;
73         this.password = password;
74
75         /* Initialize JDBC driver */
76         try {
77             Class.forName(driverName).newInstance();
78         } catch (Exception ex) {
79             throw new RuntimeException("Specified JDBC Driver: " + driverName
80                     + " - initialization failed.", ex);
81         }
82     }
83
84     public SimpleJDBCConnectionPool(String driverName, String connectionUri,
85             String userName, String password, int initialConnections,
86             int maxConnections) throws SQLException {
87         this(driverName, connectionUri, userName, password);
88         this.initialConnections = initialConnections;
89         this.maxConnections = maxConnections;
90     }
91
92     private void initializeConnections() throws SQLException {
93         availableConnections = new HashSet<Connection>(initialConnections);
94         reservedConnections = new HashSet<Connection>(initialConnections);
95         for (int i = 0; i < initialConnections; i++) {
96             availableConnections.add(createConnection());
97         }
98         initialized = true;
99     }
100
101     @Override
102     public synchronized Connection reserveConnection() throws SQLException {
103         if (!initialized) {
104             initializeConnections();
105         }
106         if (availableConnections.isEmpty()) {
107             if (reservedConnections.size() < maxConnections) {
108                 availableConnections.add(createConnection());
109             } else {
110                 throw new SQLException("Connection limit has been reached.");
111             }
112         }
113
114         Connection c = availableConnections.iterator().next();
115         availableConnections.remove(c);
116         reservedConnections.add(c);
117
118         return c;
119     }
120
121     @Override
122     public synchronized void releaseConnection(Connection conn) {
123         if (conn == null || !initialized) {
124             return;
125         }
126         /* Try to roll back if necessary */
127         try {
128             if (!conn.getAutoCommit()) {
129                 conn.rollback();
130             }
131         } catch (SQLException e) {
132             /* Roll back failed, close and discard connection */
133             try {
134                 conn.close();
135             } catch (SQLException e1) {
136                 /* Nothing needs to be done */
137             }
138             reservedConnections.remove(conn);
139             return;
140         }
141         reservedConnections.remove(conn);
142         availableConnections.add(conn);
143     }
144
145     private Connection createConnection() throws SQLException {
146         Connection c = DriverManager.getConnection(connectionUri, userName,
147                 password);
148         c.setAutoCommit(false);
149         if (driverName.toLowerCase(Locale.ROOT).contains("mysql")) {
150             try {
151                 Statement s = c.createStatement();
152                 s.execute("SET SESSION sql_mode = 'ANSI'");
153                 s.close();
154             } catch (Exception e) {
155                 // Failed to set ansi mode; continue
156             }
157         }
158         return c;
159     }
160
161     @Override
162     public void destroy() {
163         for (Connection c : availableConnections) {
164             try {
165                 c.close();
166             } catch (SQLException e) {
167                 // No need to do anything
168             }
169         }
170         for (Connection c : reservedConnections) {
171             try {
172                 c.close();
173             } catch (SQLException e) {
174                 // No need to do anything
175             }
176         }
177
178     }
179
180     private void writeObject(ObjectOutputStream out) throws IOException {
181         initialized = false;
182         out.defaultWriteObject();
183     }
184
185 }