1 package com.explosion.expfmodules.rdbmsconn.connect;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.net.URL;
26 import java.sql.Connection;
27 import java.sql.Driver;
28 import java.sql.DriverManager;
29 import java.sql.SQLException;
30 import java.util.ArrayList;
31 import java.util.Iterator;
32 import java.util.List;
33 import java.util.Properties;
34 import java.util.StringTokenizer;
35
36 import org.apache.log4j.LogManager;
37 import org.apache.log4j.Logger;
38
39 import com.explosion.expfmodules.rdbmsconn.DriverDescriptorManager;
40 import com.explosion.expfmodules.rdbmsconn.DriverDescriptorPreference;
41 import com.explosion.expfmodules.rdbmsconn.RdbmsConnConstants;
42 import com.explosion.utilities.PropertiesUtils;
43 import com.explosion.utilities.classes.StandardClassLoader;
44 import com.explosion.utilities.exception.EnhancedException;
45 import com.explosion.utilities.exception.ExceptionManagerFactory;
46 import com.explosion.utilities.preferences.Preference;
47 import com.explosion.utilities.preferences.groups.PreferenceGroup;
48
49 /***
50 * This class creates database connections to specific databases. Its intended
51 * use is toprovide a Connection object back to the Caller whch the caller can
52 * then use to make jdbc calls.
53 *
54 */
55
56 public class ConnectionFactory
57 {
58
59 private static Logger log = LogManager.getLogger(ConnectionFactory.class);
60
61 /***
62 * This method will create a connection to a database using a standard
63 * propertiesentry
64 */
65 public Connection createConnection(String connectionName, String propertiesFile) throws Exception
66 {
67 Properties props = PropertiesUtils.loadProperties(propertiesFile);
68 return (createConnection(connectionName, props));
69 }
70
71 /***
72 * This method prepares the connection for use.
73 * Sets autocommit and other values
74 * @param conn
75 * @throws SQLException
76 */
77 private void prepareConnection(Connection conn) throws SQLException
78 {
79 conn.setAutoCommit(false);
80 }
81
82 /***
83 * This method will create a connection to a database using a standard
84 * propertiesentry
85 */
86 public Connection createConnection(String connectionName, Properties props) throws Exception
87 {
88 Connection connection = null;
89 String url = null;
90 try
91 {
92 String driver = props.getProperty(connectionName + "." + "driver");
93 if (driver == null)
94 throw new Exception("Database property 'driver' not found for connection '" + connectionName + "'.");
95
96 url = props.getProperty(connectionName + "." + "url");
97 if (url == null)
98 throw new Exception("Database property 'url' not found for connection '" + connectionName + "'.");
99
100 String user = props.getProperty(connectionName + "." + "user");
101 if (user == null)
102 throw new Exception("Database property 'user' not found for connection '" + connectionName + "'.");
103
104 String password = props.getProperty(connectionName + "." + "password");
105 if (password == null)
106 throw new Exception("Database property 'password' not found for connection '" + connectionName + "'.");
107
108 log.debug("Found properties Url: "+url+", user:"+user+", password:"+password);
109
110 String classpath = props.getProperty(connectionName + "." + "classpath");
111 if (classpath != null)
112 {
113 log.debug("Using independant based connection with classpath " + classpath);
114 List list = new ArrayList();
115 StringTokenizer tokenizer = new StringTokenizer(classpath, ",");
116 while (tokenizer.hasMoreTokens())
117 {
118 list.add(new File(tokenizer.nextToken()));
119 }
120 connection = openDefinedConnection(driver, list, url, user, password);
121 }
122 else
123 {
124 connection = openEmbeddedConnection(driver, url, user, password);
125 }
126
127
128 return connection;
129 }
130 catch (Exception e)
131 {
132 throw new UnableToConnectException("Unable to connect to database '" + url + "'. Reason:: ", e);
133 }
134
135 }
136
137 /***
138 * This method will create a connection to a database using a
139 * ConnectionDescriptor
140 *
141 * @param connectionDescriptor
142 * @return @throws Exception
143 */
144 public Connection createConnection(PreferenceGroup connectionDescriptor, DriverDescriptorManager manager) throws Exception
145 {
146 PreferenceGroup driverDescriptor = manager.getGroup((String) connectionDescriptor.getPreferenceValue(RdbmsConnConstants.CD_DRIVER));
147 log.debug("Using descriptor " + driverDescriptor + " to attempt to log on to database.");
148 if (driverDescriptor == null)
149 throw new Exception("Driver '" + (String) connectionDescriptor.getPreferenceValue(RdbmsConnConstants.CD_DRIVER) + "' is not defined.");
150
151 return createConnection(connectionDescriptor, driverDescriptor);
152 }
153
154 /***
155 * This method will create a connection to a database using a
156 * ConnectionDescriptor and a driverDescriptor
157 *
158 * @param connectionDescriptor
159 * @param driverDescriptor
160 * @return @throws Exception
161 */
162 private Connection createConnection(PreferenceGroup connectionDescriptor, PreferenceGroup driverDescriptor) throws Exception
163 {
164 try
165 {
166 String driverName = (String) driverDescriptor.getPreferenceValue(RdbmsConnConstants.DRVR_NAME);
167 boolean isEmbedded = ((Boolean) driverDescriptor.getPreferenceValue(RdbmsConnConstants.DRVR_EMBEDDED)).booleanValue();
168 DriverDescriptorPreference driverDescriptorPreference = (DriverDescriptorPreference) driverDescriptor.getPreference(RdbmsConnConstants.DRVR_NAME);
169 Preference locations = (Preference) driverDescriptor.getPreference(RdbmsConnConstants.DRVR_LOCATION);
170
171 if (driverName == null)
172 throw new Exception("Insufficient information specified for Driver '" + (String) connectionDescriptor.getPreferenceValue(RdbmsConnConstants.CD_DRIVER)
173 + "' to be able to make a connection to a database.");
174
175 String url = (String) connectionDescriptor.getPreferenceValue(RdbmsConnConstants.CD_URL);
176 String user = (String) connectionDescriptor.getPreferenceValue(RdbmsConnConstants.CD_USER);
177 String password = (String) connectionDescriptor.getPreferenceValue(RdbmsConnConstants.CD_PASS);
178
179 if (isEmbedded)
180 {
181 log.debug("Using embedded driver: " + driverName);
182 return openEmbeddedConnection(driverName, url, user, password);
183 }
184 else
185 {
186 log.debug("Using configured driver: " + driverName + ".");
187 return openDefinedConnection(driverName, locations.getValues(), url, user, password, driverDescriptorPreference);
188 }
189 }
190 catch (Exception e)
191 {
192 throw new UnableToConnectException("Unable to establish connection. ", e);
193 }
194 }
195
196 /***
197 * Connects to a database using the Embedded DriverManager rather than an
198 * independant Driver
199 *
200 * @param driverName
201 * @param url
202 * @param user
203 * @param password
204 * @return @throws SQLException
205 * @throws InstantiationException
206 * @throws IllegalAccessException
207 * @throws ClassNotFoundException
208 */
209 public Connection openEmbeddedConnection(String driverName, String url, String user, String password) throws SQLException, InstantiationException, IllegalAccessException,
210 ClassNotFoundException, UnableToConnectException
211 {
212 log.debug("Using url '" + url + "' and user '" + user + "'.");
213 DriverManager.registerDriver((Driver) Class.forName(driverName).newInstance());
214 Connection conn = null;
215 conn = DriverManager.getConnection(url, user, password);
216
217 if (conn == null)
218 {
219 throw new UnableToConnectException("Unable to connect to database. Database returned no errors but connection failed.");
220 }
221
222
223 prepareConnection(conn);
224
225 return conn;
226 }
227
228 /***
229 * Connects to a database using the an independent Driver
230 *
231 * @param driverName
232 * @param classpath
233 * @param url
234 * @param user
235 * @param password
236 * @return @throws SQLException
237 * @throws InstantiationException
238 * @throws IllegalAccessException
239 * @throws ClassNotFoundException
240 */
241 private Connection openDefinedConnection(String driverName, List classPath, String url, String user, String password) throws SQLException, IllegalArgumentException, EnhancedException,
242 IOException, InstantiationException, IllegalAccessException, ClassNotFoundException
243 {
244 return openDefinedConnection(driverName, classPath, url, user, password, null);
245 }
246
247 /***
248 * Connects to a database using the an independent Driver
249 *
250 * @param driverName
251 * @param classpath
252 * @param url
253 * @param user
254 * @param password
255 * @param driverDescriptorPreference
256 * @return @throws SQLException
257 * @throws InstantiationException
258 * @throws IllegalAccessException
259 * @throws ClassNotFoundException
260 */
261 private Connection openDefinedConnection(String driverName, List classPath, String url, String user, String password, DriverDescriptorPreference driverDescriptorPreference)
262 throws SQLException, IllegalArgumentException, EnhancedException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException
263 {
264 log.debug("Using url '" + url + "' and user '" + user + "'.");
265 java.util.Properties info = new java.util.Properties();
266 if (user != null)
267 {
268 info.put("user", user);
269 }
270
271 if (password != null)
272 {
273 info.put("password", password);
274 }
275
276 Driver driver = null;
277 if (driverDescriptorPreference != null)
278 {
279
280
281
282
283
284
285
286
287
288
289
290
291 driver = driverDescriptorPreference.getDriver();
292
293 if (driver == null)
294 {
295 driver = getDriver(driverName, classPath);
296 driverDescriptorPreference.setDriver(driver);
297 }
298 }
299 else
300 {
301 driver = getDriver(driverName, classPath);
302 }
303
304 log.debug("Driver found and instantiated " + driver + ". About to call driver.connect()");
305
306 Connection conn = null;
307 try
308 {
309 conn = driver.connect(url, info);
310 if (conn == null)
311 {
312 throw new UnableToConnectException("Unable to connect to database. Database returned no errors but connection failed.");
313 }
314 }
315 catch (Throwable e)
316 {
317 ExceptionManagerFactory.getExceptionManager().manageException(e, "Error while connecting to database.");
318 }
319
320
321 prepareConnection(conn);
322
323 return conn;
324 }
325
326 /***
327 * Loads an instance of a Driver from a jarfile
328 *
329 * @param driverName
330 * @param jarFile
331 * @return
332 */
333 private Driver getDriver(String driverName, List classPathFiles) throws EnhancedException, IllegalArgumentException, IOException, InstantiationException, IllegalAccessException,
334 ClassNotFoundException
335 {
336
337 if (classPathFiles != null)
338 {
339 if (classPathFiles.size() > 0)
340 {
341
342 String[] repo = new String[classPathFiles.size()];
343 int index = 0;
344 for (Iterator it = classPathFiles.iterator(); it.hasNext();)
345 {
346 File file = (File) it.next();
347 URL url = file.toURL();
348 String urlString = url.getProtocol() + ":" + url.getPath();
349 repo[index] = urlString;
350 index++;
351 }
352
353 StandardClassLoader loader = new StandardClassLoader(repo);
354
355 log.debug("Instantiating driver " + driverName);
356 return (Driver) Class.forName(driverName, true, loader).newInstance();
357 }
358 else
359 {
360 throw new DriverNotSpecifiedException("Unable to load driver for connection because no driver files have been specified.");
361 }
362 }
363 else
364 {
365 throw new InvalidDriverConfigurationException("Unable to load driver for connection because no file containing a driver has been specified.");
366 }
367 }
368
369 }