1 /*
2 * PROJECT : DAR Runtime and Tools
3 * COPYRIGHT : Copyright (C) 1999-2004 tim.stephenson@enableit.org
4 * LICENSE : GNU LESSER GENERAL PUBLIC LICENSE
5 * Version 2.1, February 1999
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 package org.enableit.db;
22
23 import java.sql.Connection;
24 import java.sql.Driver;
25 import java.sql.DriverManager;
26 import java.sql.SQLException;
27 import java.util.Properties;
28
29 import javax.naming.Binding;
30 import javax.naming.InitialContext;
31 import javax.naming.LinkRef;
32 import javax.naming.NamingEnumeration;
33 import javax.sql.DataSource;
34
35 import org.apache.log4j.Logger;
36 import org.enableit.db.beans.Provider;
37 import org.enableit.db.beans.ProviderChoice;
38 import org.enableit.db.beans.ProviderExt;
39
40
41 /***
42 * Factory for database connections.
43 *
44 * <p>This is a functional replacement for the
45 * <code>ConnectionFactory</code> that has been deprecated
46 * as it contains a great deal of legacy (and not very clean) code.</p>
47 * @author TimSt
48 */
49 public class ConnFactory {
50 /***
51 * The Log4J <code>Category</code> doing the logging.
52 * Same <code>Category</code> is used throughout the package.
53 */
54 private static Logger logger = Logger.getLogger(ConnFactory.class);
55
56 /***
57 * Constructor, prevents public construction.
58 */
59 protected ConnFactory() {
60 logger.info("METHOD_ENTRY constructor");
61 logger.info("METHOD_EXIT constructor");
62 }
63
64 /***
65 * Returns a connection to the database identified within the
66 * supplied provider.
67 *
68 * <p>Parameters may be empty strings, but may not be null. </p>
69 *
70 * @param provider Contains connection details.
71 *
72 * @return Connection
73 *
74 * @throws DBException
75 * in the event of a problem creating the connection
76 */
77 public static Connection getConnection(final Provider provider)
78 throws DBException {
79 logger.info("METHOD_ENTRY getConnection(Provider), provider="
80 + ProviderExt.toString(provider));
81
82 Connection conn = null;
83 ProviderChoice pc = provider.getProviderChoice();
84
85 if (pc.getJdbc2DatasourceName() == null) {
86 logger.warn("Provider configured for JDBC1 style.");
87
88 if (provider.getDriver().getClassName() == null) {
89 registerDriverFromUrl(provider.getUrl());
90 } else {
91 registerDriver(provider.getDriver().getClassName());
92 }
93
94 String connectionString = provider.getUrl();
95
96 // TODO: Is this Sybase specific??
97 Properties props = new Properties();
98
99 props.put("user", provider.getUsername());
100 props.put("password", provider.getPassword());
101
102 logger.info("Connection string: " + connectionString);
103
104 try {
105 conn = DriverManager.getConnection(connectionString, props);
106 } catch (SQLException e) {
107 throw new DBException("Unable to obtain connection: "
108 + e.getMessage(), e);
109 }
110 } else {
111 logger.warn("Provider configured for JDBC2 style.");
112 conn = getConnection(pc.getJdbc2DatasourceName());
113 }
114
115 logger.info("METHOD_EXIT getConnection(Provider)");
116
117 return conn;
118 }
119
120 /***
121 * Register the named driver class with <code>DriverManager</code>.
122 * @param driver Name of driver class.
123 */
124 protected static void registerDriver(String driver) {
125 try {
126 DriverManager.registerDriver((Driver) ConnFactory.class.getClassLoader()
127 .loadClass(driver)
128 .newInstance());
129 } catch (Exception e) {
130 logger.warn("Unable to register driver named: " + driver);
131 }
132 }
133
134 /***
135 * Attempt to decode the JDBC URL and register the driver if it is of
136 * known type.
137 *
138 * @param url Database URL to connect to.
139 */
140 protected static void registerDriverFromUrl(final String url) {
141 if (url.indexOf("microsoft") > -1) {
142 registerDriver("com.microsoft.jdbc.sqlserver.SQLServerDriver");
143 } else if (url.indexOf("oracle:thin") > -1) {
144 registerDriver("oracle.jdbc.driver.OracleDriver");
145 } else if (url.indexOf("sybase") > -1) {
146 registerDriver("com.sybase.jdbc2.jdbc.SybDriver");
147 } else if (url.indexOf("mysql") > -1) {
148 registerDriver("org.gjt.mm.mysql.Driver");
149 } else {
150 logger.warn("Unrecognised database, attempting to continue"
151 + " without registering driver.");
152 }
153 }
154
155 /***
156 * Obtain connection for the named configuration.
157 *
158 * <p><b>Implementation Note:</b> The name will first be treated as a JDBC2
159 * <code>DataSource</code> name to be looked up in the local naming
160 * context. If that fails the ConnectionFactory will fall back on its own
161 * configuration to attempt to obtain a connection.
162 *
163 * @param name Data source configuration name.
164 * @return Connection
165 * @throws DBException If the named configuration is not found.
166 * @see #getConnectionNames
167 */
168 public static Connection getConnection(final String name)
169 throws DBException {
170 logger.info("METHOD_ENTRY getConnection name=" + name);
171
172 Connection conn = null;
173
174 try {
175 // TODO: Caching this could avoid a significant delay in each lookup
176 // when JNDI context is not the correct place to look
177 InitialContext ic = null;
178
179 try {
180 ic = new InitialContext();
181
182 // debug
183 if (logger.isDebugEnabled()) {
184 NamingEnumeration enum = ic.listBindings(
185 "java:comp/env/jdbc");
186
187 while (enum.hasMore()) {
188 Binding binding = (Binding) enum.nextElement();
189
190 logger.warn("Found data source: [" + binding.getName()
191 + "]");
192 logger.warn("... with type: " + binding.getClassName());
193 logger.warn("... object = " + binding.getObject());
194
195 //binding.
196 if (binding.getObject() instanceof LinkRef) {
197 LinkRef ref = (LinkRef) binding.getObject();
198
199 logger.warn("Have reference: " + ref.getLinkName());
200
201 Object obj = ic.lookupLink("java:comp/env/"
202 + ref.getLinkName());
203
204 logger.warn("... object = " + obj);
205 }
206 }
207 }
208
209 // TODO: If web-app ds name is not same as underlying JNDI name
210 // there are problems in JBoss at least following the reference
211 // to the real datasouce
212 // 1st try internal component name
213 // This is the recommended but not mandated location for J2EE
214 // components to find environment vars
215 //Context envContext = (Context) ic.lookup("java:comp/env/") ;
216 DataSource ds = (DataSource) ic.lookup("java:comp/env/" + name);
217
218 //Object obj = ic.lookup("java:comp/env/" + name) ;
219 //logger.info("'DataSource' found: " + obj) ;
220 conn = ds.getConnection();
221 } catch (Exception e) {
222 try {
223 logger.warn("Cannot access datasource 'java:comp/env/"
224 + name + "'");
225
226 if (logger.isDebugEnabled()) {
227 logger.warn("... detail is: " + e.getClass().getName()
228 + ":" + e.getMessage());
229 }
230
231 DataSource ds = (DataSource) ic.lookup(name);
232
233 conn = ds.getConnection();
234 } catch (Exception e2) {
235 logger.warn("Cannot access datasource '" + name + "'");
236
237 if (logger.isDebugEnabled()) {
238 logger.warn("... detail is: " + e2.getClass().getName()
239 + ":" + e2.getMessage());
240 }
241
242 // This is the way JBoss binds JNDI vars
243 DataSource ds = (DataSource) ic.lookup("java:" + name);
244
245 conn = ds.getConnection();
246 }
247 }
248 } catch (Exception e) {
249 logger.warn("Exception looking up datasource named: " + name + "; "
250 + e.getMessage(), e);
251 }
252
253 logger.info("METHOD_EXIT getConnection");
254
255 return conn;
256 }
257 }
This page was automatically generated by Maven