KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > controller > connection > AbstractConnectionManager


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2005 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Emmanuel Cecchet.
22  * Contributor(s): Mathieu Peltier.
23  */

24
25 package org.objectweb.cjdbc.controller.connection;
26
27 import java.sql.Connection JavaDoc;
28 import java.sql.SQLException JavaDoc;
29 import java.util.Hashtable JavaDoc;
30
31 import org.objectweb.cjdbc.common.exceptions.UnreachableBackendException;
32 import org.objectweb.cjdbc.common.i18n.Translate;
33 import org.objectweb.cjdbc.common.log.Trace;
34 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags;
35 import org.objectweb.cjdbc.common.xml.XmlComponent;
36
37 /**
38  * A <code>ConnectionManager</code> object is responsible to talk directly
39  * with a database backend.
40  *
41  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
42  * @author <a HREF="mailto:Mathieu.Peltier@inrialpes.fr">Mathieu Peltier </a>
43  * @author <a HREF="mailto:Nicolas.Modrzyk@inrialpes.fr">Nicolas Modrzyk </a>
44  * @version 1.0
45  */

46 public abstract class AbstractConnectionManager
47     implements
48       XmlComponent,
49       Cloneable JavaDoc
50 {
51   /*
52    * How the code is organized ? 1. Member variables 2. Connection handling 3.
53    * Getter/Setter (possibly in alphabetical order)
54    */

55
56   /** Logger instance. */
57   static Trace logger = Trace
58                                          .getLogger("org.objectweb.cjdbc.controller.connection");
59
60   /** URL of the <code>DatabaseBackend</code> owning this connection manager. */
61   protected String JavaDoc backendUrl;
62
63   /**
64    * Name of the <code>DatabaseBackend</code> owning this connection manager.
65    */

66   protected String JavaDoc backendName;
67
68   /** Backend connection login to be used by this connection manager. */
69   protected String JavaDoc rLogin;
70
71   /** Backend connection password to be used by this connection manager. */
72   protected String JavaDoc rPassword;
73
74   /** The class name of the driver */
75   protected String JavaDoc driverClassName;
76
77   /**
78    * The path to the driver if null the default directory is used
79    */

80   protected String JavaDoc driverPath;
81
82   /** <code>true</code> if the connection pool has been initialized. */
83   protected boolean initialized;
84
85   /** Hastable of connections associated to a transaction. */
86   private transient Hashtable JavaDoc connectionForTransaction;
87
88   /** Virtual Login to be that use this connection manager */
89   private String JavaDoc vLogin;
90
91   /*
92    * Constructor(s)
93    */

94
95   /**
96    * Creates a new <code>AbstractConnectionManager</code> instance: assigns
97    * login/password and instanciates transaction id/connection mapping.
98    *
99    * @param backendUrl URL of the <code>DatabaseBackend</code> owning this
100    * connection manager
101    * @param backendName name of the <code>DatabaseBackend</code> owning this
102    * connection manager
103    * @param rLogin backend connection login to be used by this connection
104    * manager
105    * @param rPassword backend connection password to be used by this connection
106    * manager
107    * @param driverPath path for driver
108    * @param driverClassName class name for driver
109    */

110   public AbstractConnectionManager(String JavaDoc backendUrl, String JavaDoc backendName,
111       String JavaDoc rLogin, String JavaDoc rPassword, String JavaDoc driverPath, String JavaDoc driverClassName)
112   {
113     if (backendUrl == null)
114       throw new IllegalArgumentException JavaDoc(
115           "Illegal null database backend URL in AbstractConnectionManager constructor");
116
117     if (backendName == null)
118       throw new IllegalArgumentException JavaDoc(
119           "Illegal null database backend name in AbstractConnectionManager constructor");
120
121     if (rLogin == null)
122       throw new IllegalArgumentException JavaDoc(
123           "Illegal null database backend login in AbstractConnectionManager constructor");
124
125     if (rPassword == null)
126       throw new IllegalArgumentException JavaDoc(
127           "Illegal null database backend password in AbstractConnectionManager constructor");
128
129     if (driverPath != null)
130     {
131       if (driverClassName == null)
132       {
133         throw new IllegalArgumentException JavaDoc(
134             "Illegal null database backend driverClassName in AbstractConnectionManager constructor");
135       }
136     }
137     this.backendUrl = backendUrl;
138     this.backendName = backendName;
139     this.rLogin = rLogin;
140     this.rPassword = rPassword;
141     this.driverPath = driverPath;
142     this.driverClassName = driverClassName;
143     connectionForTransaction = new Hashtable JavaDoc();
144
145   }
146
147   /**
148    * Copy this connection manager and replace the name of the backend and its
149    * url Every other parameter is the same
150    *
151    * @param url the url to the backend associated to this ConnectionManager
152    * @param name the name of the backend
153    * @return <code>AbstractConnectionManager</code>
154    * @throws Exception if clone fails
155    */

156   public AbstractConnectionManager copy(String JavaDoc url, String JavaDoc name)
157       throws Exception JavaDoc
158   {
159     AbstractConnectionManager connectionManager = (AbstractConnectionManager) this
160         .clone();
161     connectionManager.backendName = name;
162     connectionManager.backendUrl = url;
163     return connectionManager;
164   }
165
166   /*
167    * Connection handling
168    */

169
170   /**
171    * Initializes the connection(s) to the database. The caller must ensure that
172    * the driver has already been loaded else an exception will be thrown.
173    *
174    * @exception SQLException if an error occurs.
175    */

176   public abstract void initializeConnections() throws SQLException JavaDoc;
177
178   /**
179    * Releases all the connections to the database.
180    *
181    * @exception SQLException if an error occurs.
182    */

183   public abstract void finalizeConnections() throws SQLException JavaDoc;
184
185   /**
186    * Get a connection from DriverManager.
187    *
188    * @return a new connection or null if Driver.getConnection() failed.
189    * @see DriverManager#getConnection(String, String, String, String, String)
190    */

191   public Connection JavaDoc getConnectionFromDriver()
192
193   {
194     try
195     {
196       return DriverManager.getConnection(backendUrl, rLogin, rPassword,
197           driverPath, driverClassName);
198     }
199     catch (SQLException JavaDoc ignore)
200     {
201       if (logger.isDebugEnabled())
202       {
203         logger.debug("failed to get connection for driver ", ignore);
204       }
205       return null;
206     }
207   }
208
209   /**
210    * Gets a connection from the pool (round-robin).
211    *
212    * @return a <code>Connection</code> or <code>null</code> if no connection
213    * is available or if the connection has not been initialized.
214    * @throws UnreachableBackendException if the backend must be disabled
215    */

216   public abstract Connection JavaDoc getConnection() throws UnreachableBackendException;
217
218   /**
219    * Gets a new connection for a transaction. This function calls
220    * {@link #getConnection()}to get the connection and store the mapping
221    * between the connection and the transaction id.
222    *
223    * @param transactionId the transaction id.
224    * @return a <code>Connection</code> or <code>null</code> if no connection
225    * is available .
226    * @throws UnreachableBackendException if the backend must be disabled
227    * @see #getConnection()
228    */

229   public Connection JavaDoc getConnection(long transactionId)
230       throws UnreachableBackendException
231   {
232     Long JavaDoc lTid = new Long JavaDoc(transactionId);
233     Connection JavaDoc c = getConnection();
234     if (c != null)
235     {
236       if (connectionForTransaction.put(lTid, c) != null)
237       {
238         logger
239             .error("A new connection for transaction "
240                 + lTid
241                 + " has been opened but there was a remaining connection for this transaction that has not been closed.");
242       }
243     }
244     return c;
245   }
246
247   /**
248    * Retrieves a connection used for a transaction. This connection must have
249    * been allocated by calling {@link #getConnection(long)}.
250    *
251    * @param transactionId the transaction id.
252    * @return a <code>Connection</code> or <code>null</code> if no connection
253    * has been found for this transaction id.
254    * @see #getConnection(long)
255    */

256   public Connection JavaDoc retrieveConnection(long transactionId)
257   {
258     Long JavaDoc id = new Long JavaDoc(transactionId);
259     synchronized (connectionForTransaction)
260     {
261       return (Connection JavaDoc) connectionForTransaction.get(id);
262     }
263   }
264
265   /**
266    * Releases a connection.
267    *
268    * @param connection the connection to release.
269    */

270   public abstract void releaseConnection(Connection JavaDoc connection);
271
272   /**
273    * Releases a connection used for a transaction. The corresponding connection
274    * is released by calling {@link #releaseConnection(Connection)}.
275    *
276    * @param transactionId the transaction id.
277    * @see #releaseConnection(Connection)
278    */

279   public void releaseConnection(long transactionId)
280   {
281     Connection JavaDoc c = (Connection JavaDoc) connectionForTransaction.remove(new Long JavaDoc(
282         transactionId));
283
284     if (c == null)
285       logger.error(Translate.get("connection.transaction.unknown",
286           transactionId));
287     else
288       releaseConnection(c);
289   }
290
291   /**
292    * Delete a connection that is no more valid.
293    *
294    * @param connection the connection to delete.
295    */

296   public abstract void deleteConnection(Connection JavaDoc connection);
297
298   /**
299    * Delete a bad connection that was used for a transaction. The corresponding
300    * connection is deleted by calling {@link #deleteConnection(Connection)}.
301    *
302    * @param transactionId the transaction id.
303    * @see #releaseConnection(Connection)
304    */

305   public void deleteConnection(long transactionId)
306   {
307     Connection JavaDoc c = (Connection JavaDoc) connectionForTransaction.remove(new Long JavaDoc(
308         transactionId));
309
310     if (c == null)
311       logger.error(Translate.get("connection.transaction.unknown",
312           transactionId));
313     else
314       deleteConnection(c);
315   }
316
317   /**
318    * Tests if the connections have been initialized.
319    *
320    * @return <code>true</code> if the connections have been initialized.
321    */

322   public boolean isInitialized()
323   {
324     return initialized;
325   }
326
327   /*
328    * Getter/setter methods
329    */

330
331   /**
332    * Returns the login used by this connection manager.
333    *
334    * @return a <code>String</code> value.
335    */

336   public String JavaDoc getLogin()
337   {
338     return rLogin;
339   }
340
341   /**
342    * Sets the login to be used by this connection manager.
343    *
344    * @param rLogin the login to set.
345    */

346   public void setLogin(String JavaDoc rLogin)
347   {
348     this.rLogin = rLogin;
349   }
350
351   /**
352    * Returns the password used by this connection manager.
353    *
354    * @return a <code>String</code> value.
355    */

356   public String JavaDoc getPassword()
357   {
358     return rPassword;
359   }
360
361   /**
362    * Sets the password to be used by this connection manager.
363    *
364    * @param rPassword the password to set.
365    */

366   public void setPassword(String JavaDoc rPassword)
367   {
368     this.rPassword = rPassword;
369   }
370
371   /*
372    * Debug/monitoring information
373    */

374
375   /**
376    * Gets xml formatted information on this connection manager
377    *
378    * @return xml formatted string that conforms to c-jdbc.dtd
379    */

380   public abstract String JavaDoc getXmlImpl();
381
382   /**
383    * @see org.objectweb.cjdbc.common.xml.XmlComponent#getXml()
384    */

385   public String JavaDoc getXml()
386   {
387     StringBuffer JavaDoc info = new StringBuffer JavaDoc();
388     info.append("<" + DatabasesXmlTags.ELT_ConnectionManager + " "
389         + DatabasesXmlTags.ATT_vLogin + "=\"" + vLogin + "\" " + ""
390         + DatabasesXmlTags.ATT_rLogin + "=\"" + rLogin + "\" " + ""
391         + DatabasesXmlTags.ATT_rPassword + "=\"" + rPassword + "\" " + ">");
392     info.append(this.getXmlImpl());
393     info.append("</" + DatabasesXmlTags.ELT_ConnectionManager + ">");
394     return info.toString();
395   }
396
397   /**
398    * Ensures that the connections are closed when the object is garbage
399    * collected.
400    *
401    * @exception Throwable if an error occurs.
402    */

403   protected void finalize() throws Throwable JavaDoc
404   {
405     if (isInitialized())
406       finalizeConnections();
407     super.finalize();
408   }
409
410   /**
411    * @return Returns the vLogin.
412    */

413   public String JavaDoc getVLogin()
414   {
415     return vLogin;
416   }
417
418   /**
419    * @param login The vLogin to set.
420    */

421   public void setVLogin(String JavaDoc login)
422   {
423     vLogin = login;
424   }
425
426   /**
427    * Get the current number of connections open for this connection manager.
428    *
429    * @return the current number of open connections
430    */

431   public abstract int getCurrentNumberOfConnections();
432
433   /**
434    * Returns the driverClassName value.
435    *
436    * @return Returns the driverClassName.
437    */

438   public String JavaDoc getDriverClassName()
439   {
440     return driverClassName;
441   }
442
443   /**
444    * Sets the driverClassName value.
445    *
446    * @param driverClassName The driverClassName to set.
447    */

448   public void setDriverClassName(String JavaDoc driverClassName)
449   {
450     this.driverClassName = driverClassName;
451   }
452
453   /**
454    * Returns the driverPath value.
455    *
456    * @return Returns the driverPath.
457    */

458   public String JavaDoc getDriverPath()
459   {
460     return driverPath;
461   }
462
463   /**
464    * Sets the driverPath value.
465    *
466    * @param driverPath The driverPath to set.
467    */

468   public void setDriverPath(String JavaDoc driverPath)
469   {
470     this.driverPath = driverPath;
471   }
472
473   protected abstract Object JavaDoc clone() throws CloneNotSupportedException JavaDoc;
474 }
Popular Tags