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
26
27
28
29
30
31
32
33
34
35
36
37
38 package com.gargoylesoftware.base.resource.jdbc;
39
40 import com.gargoylesoftware.base.resource.ManagedResource;
41 import com.gargoylesoftware.base.resource.ResourceException;
42 import com.gargoylesoftware.base.resource.ResourceFactory;
43 import com.gargoylesoftware.base.resource.ResourceManager;
44 import java.sql.Connection;
45 import java.sql.DriverManager;
46 import java.sql.SQLException;
47
48 /***
49 * A ResourceFactory for JDBC connections
50 *
51 * @version $Revision: 1.5 $
52 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
53 */
54 public class JDBCResourceFactory extends ResourceFactory {
55
56 private final String databaseName_;
57 private final String userName_;
58 private final String password_;
59
60
61 /***
62 * Create the factory. The database driver must have been registered prior
63 * to creating an instance of this class. This constructor will always try
64 * to allocate one connection right away to ensure that the database
65 * information was entered correctly.
66 *
67 * @param databaseName The name of the database
68 * @param userName The user id that we will use to connect to the database
69 * @param password The password for the specified user
70 * @exception SQLException If an error occurs
71 */
72 public JDBCResourceFactory(
73 final String databaseName,
74 final String userName,
75 final String password )
76 throws
77 SQLException {
78 this( databaseName, userName, password, true );
79 }
80
81
82 /***
83 * Create the factory. The database driver must have been registered prior
84 * to creating an instance of this class.
85 *
86 * @param databaseName The name of the database
87 * @param userName The user id that we will use to connect to the database
88 * @param password The password for the specified user
89 * @param verifyThatConnectionCanBeOpened If true than one connection will
90 * be immediately allocated and then freed from the specified database
91 * @exception SQLException If an error occurs
92 */
93 public JDBCResourceFactory(
94 final String databaseName,
95 final String userName,
96 final String password,
97 final boolean verifyThatConnectionCanBeOpened )
98 throws
99 SQLException {
100
101 if( databaseName == null ) {
102 throw new NullPointerException( "databaseName" );
103 }
104 if( userName == null ) {
105 throw new NullPointerException( "userName" );
106 }
107 if( password == null ) {
108 throw new NullPointerException( "password" );
109 }
110
111 databaseName_ = databaseName;
112 userName_ = userName;
113 password_ = password;
114
115 if( verifyThatConnectionCanBeOpened == true ) {
116 ensureDatabaseCanBeOpened();
117 }
118 }
119
120
121 /***
122 * Reinitialize the resource to a known state. This is required for
123 * resource pooling as all resources being returned from a pool must have
124 * been initialized to a known state.
125 *
126 * @param resource the resource to reinitialize
127 * @return true if the resource was successfully reinitialized
128 */
129 public boolean reinitializeResourceIfPossible(
130 ManagedResource resource ) {
131 final ConnectionWrapper wrapper = ( ConnectionWrapper )resource;
132
133 boolean result = false;
134
135 try {
136 if( wrapper.isClosed() == false ) {
137 result = true;
138
139 wrapper.commit();
140 wrapper.setAutoCommit( true );
141 wrapper.closeAnyOpenStatements();
142 wrapper.closeAnyOpenMetaDatas();
143 }
144 }
145 catch( final SQLException e ) {
146
147 result = false;
148 }
149
150 return result;
151 }
152
153
154 /***
155 * Allocate a resource for the specified store
156 *
157 * @param resourceManager The resource manager that owns this factory
158 * @return The new resource
159 * @exception Exception If an error occurs
160 */
161 protected ManagedResource getResourceImpl(
162 final ResourceManager resourceManager )
163 throws
164 Exception {
165
166 return new ConnectionWrapper(
167 DriverManager.getConnection( databaseName_, userName_, password_ ) );
168 }
169
170
171 /***
172 * Release the specified resource. It must have been allocated by the
173 * specified store
174 *
175 * @param resource The resource that we are releasing
176 * @param resourceManager The manager that is controlling this factory
177 * @exception Exception If an error occurs
178 */
179 protected void releaseResourceImpl(
180 final ResourceManager resourceManager,
181 final ManagedResource resource )
182 throws
183 Exception {
184
185 final ConnectionWrapper wrapper = ( ConnectionWrapper )resource;
186 if( wrapper.isClosed() == false ) {
187 wrapper.close();
188 }
189 }
190
191
192 /***
193 * Allocate a real database connection from the DriverManager
194 *
195 * @param databaseName The name of the database
196 * @param userName The user id that we will use to connect to the database
197 * @param password The password for the specified user
198 * @return A new connection
199 * @exception SQLException If an error occurs
200 */
201 protected final Connection allocateRealConnection(
202 final String databaseName,
203 final String userName,
204 final String password )
205 throws
206 SQLException {
207
208 return DriverManager.getConnection( databaseName, userName, password );
209 }
210
211
212 /***
213 * Free a real database connection
214 *
215 * @param connection The connection to release
216 * @exception SQLException If an error occurs
217 */
218 protected final void freeRealConnection(
219 final Connection connection )
220 throws
221 SQLException {
222
223 connection.close();
224 }
225
226
227 private void ensureDatabaseCanBeOpened()
228 throws SQLException {
229
230 final ResourceManager resourceManager = new ResourceManager( "EnsureDatabaseCanBeOpened" );
231 try {
232 final ConnectionWrapper connection = ( ConnectionWrapper )getResource( resourceManager );
233 releaseResource( resourceManager, connection );
234 }
235 catch( final ResourceException e ) {
236 final Throwable enclosedException = e.getEnclosedException();
237 if( enclosedException instanceof SQLException ) {
238 throw ( SQLException )enclosedException;
239 }
240
241 throw e;
242 }
243 }
244 }
245