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