1
2
3
4
5
6
7 package org.hibernate.connection;
8
9
10 import java.sql.Connection;
11 import java.sql.Driver;
12 import java.sql.SQLException;
13 import java.util.ArrayList;
14 import java.util.Iterator;
15 import java.util.Map;
16 import java.util.Properties;
17
18 import org.hibernate.HibernateException;
19 import org.hibernate.cfg.Environment;
20 import org.hibernate.util.ReflectHelper;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24
25
26
27
28
29
30
31
32
33 public class SimpleConnectionProvider implements ConnectionProvider {
34
35 private String url;
36 private Properties connectionProps;
37 private Integer isolation;
38 private final ArrayList pool = new ArrayList();
39 private int poolSize;
40 private int checkedOut = 0;
41 private boolean autocommit;
42 private Driver driver;
43
44 private static final Logger log = LoggerFactory.getLogger(SimpleConnectionProvider.class);
45
46 public void configure(Properties props) throws HibernateException {
47
48 String driverClass = props.getProperty(Environment.DRIVER);
49
50 poolSize = getInt(Environment.POOL_SIZE, props, 20);
51 log.info("Using Hibernate built-in connection pool (not for production use!)");
52 log.info("Hibernate connection pool size: " + poolSize);
53
54 autocommit = getBoolean(Environment.AUTOCOMMIT, props);
55 log.info("autocommit mode: " + autocommit);
56
57 isolation = getInteger(Environment.ISOLATION, props);
58 if (isolation!=null)
59 log.info( "JDBC isolation level: " + Environment.isolationLevelToString( isolation.intValue() ) );
60
61 if (driverClass==null) {
62 log.warn("no JDBC Driver class was specified by property " + Environment.DRIVER);
63 }
64 else {
65 try {
66
67 driver = (Driver) Class.forName(driverClass, true, Thread.currentThread().getContextClassLoader()).newInstance();
68 }
69 catch (Exception e) {
70 try {
71 driver = (Driver) ReflectHelper.classForName(driverClass).newInstance();
72 }
73 catch (Exception e1) {
74 log.error(e1.getMessage());
75 throw new HibernateException(e1);
76 }
77 }
78 }
79
80 url = props.getProperty( Environment.URL );
81 if ( url == null ) {
82 String msg = "JDBC URL was not specified by property " + Environment.URL;
83 log.error( msg );
84 throw new HibernateException( msg );
85 }
86
87 connectionProps = ConnectionProviderFactory.getConnectionProperties( props );
88
89 log.info( "using driver: " + driverClass + " at URL: " + url );
90
91 if ( log.isDebugEnabled() ) {
92 log.info( "connection properties: " + connectionProps );
93 }
94 else if ( log.isInfoEnabled() ) {
95 log.info( "connection properties: " + maskOut(connectionProps, "password") );
96 }
97
98 }
99
100 public Connection getConnection() throws SQLException {
101
102 if ( log.isTraceEnabled() ) log.trace( "total checked-out connections: " + checkedOut );
103
104 synchronized (pool) {
105 if ( !pool.isEmpty() ) {
106 int last = pool.size() - 1;
107 if ( log.isTraceEnabled() ) {
108 log.trace("using pooled JDBC connection, pool size: " + last);
109 checkedOut++;
110 }
111 Connection pooled = (Connection) pool.remove(last);
112 if (isolation!=null) pooled.setTransactionIsolation( isolation.intValue() );
113 if ( pooled.getAutoCommit()!=autocommit ) pooled.setAutoCommit(autocommit);
114 return pooled;
115 }
116 }
117
118 log.debug("opening new JDBC connection");
119 Connection conn = driver.connect(url, connectionProps);
120 if (isolation!=null) conn.setTransactionIsolation( isolation.intValue() );
121 if ( conn.getAutoCommit()!=autocommit ) conn.setAutoCommit(autocommit);
122
123 if ( log.isDebugEnabled() ) {
124 log.debug( "created connection to: " + url + ", Isolation Level: " + conn.getTransactionIsolation() );
125 }
126 if ( log.isTraceEnabled() ) checkedOut++;
127
128 return conn;
129 }
130
131 public void closeConnection(Connection conn) throws SQLException {
132
133 if ( log.isDebugEnabled() ) checkedOut--;
134
135 synchronized (pool) {
136 int currentSize = pool.size();
137 if ( currentSize < poolSize ) {
138 if ( log.isTraceEnabled() ) log.trace("returning connection to pool, pool size: " + (currentSize + 1) );
139 pool.add(conn);
140 return;
141 }
142 }
143
144 log.debug("closing JDBC connection");
145
146 conn.close();
147
148 }
149
150 protected void finalize() {
151 close();
152 }
153
154 public void close() {
155
156 log.info("cleaning up connection pool: " + url);
157
158 Iterator iter = pool.iterator();
159 while ( iter.hasNext() ) {
160 try {
161 ( (Connection) iter.next() ).close();
162 }
163 catch (SQLException sqle) {
164 log.warn("problem closing pooled connection", sqle);
165 }
166 }
167 pool.clear();
168
169 }
170
171
172
173
174 public boolean supportsAggressiveRelease() {
175 return false;
176 }
177
178
179
180
181
182
183
184
185
186
187
188
189
190 public static boolean getBoolean(String name, Map values) {
191 return getBoolean( name, values, false );
192 }
193
194
195
196
197
198
199
200
201
202
203 public static boolean getBoolean(String name, Map values, boolean defaultValue) {
204 Object value = values.get( name );
205 if ( value == null ) {
206 return defaultValue;
207 }
208 if ( Boolean.class.isInstance( value ) ) {
209 return ( (Boolean) value ).booleanValue();
210 }
211 if ( String.class.isInstance( value ) ) {
212 return Boolean.parseBoolean( (String) value );
213 }
214 throw new HibernateException(
215 "Could not determine how to handle configuration value [name=" + name + ", value=" + value + "] as boolean"
216 );
217 }
218
219
220
221
222
223
224
225
226
227
228 public static int getInt(String name, Map values, int defaultValue) {
229 Object value = values.get( name );
230 if ( value == null ) {
231 return defaultValue;
232 }
233 if ( Integer.class.isInstance( value ) ) {
234 return ( (Integer) value ).intValue();
235 }
236 if ( String.class.isInstance( value ) ) {
237 return Integer.parseInt( (String) value );
238 }
239 throw new HibernateException(
240 "Could not determine how to handle configuration value [name=" + name +
241 ", value=" + value + "(" + value.getClass().getName() + ")] as int"
242 );
243 }
244
245
246
247
248
249
250
251
252
253 public static Integer getInteger(String name, Map values) {
254 Object value = values.get( name );
255 if ( value == null ) {
256 return null;
257 }
258 if ( Integer.class.isInstance( value ) ) {
259 return (Integer) value;
260 }
261 if ( String.class.isInstance( value ) ) {
262 return Integer.valueOf( (String) value );
263 }
264 throw new HibernateException(
265 "Could not determine how to handle configuration value [name=" + name +
266 ", value=" + value + "(" + value.getClass().getName() + ")] as Integer"
267 );
268 }
269
270
271
272
273
274
275
276
277
278 public static Properties maskOut(Properties props, String key) {
279 Properties clone = ( Properties ) props.clone();
280 if ( clone.get( key ) != null ) {
281 clone.setProperty( key, "****" );
282 }
283 return clone;
284 }
285 }
286
287
288
289
290
291
292