KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > teamkonzept > db > TKDBManager


1
2 package com.teamkonzept.db;
3
4 import java.sql.*;
5 import java.util.Enumeration JavaDoc;
6 import java.util.Properties JavaDoc;
7
8 import com.teamkonzept.lib.*;
9 import org.apache.log4j.Category;
10
11 /**
12  * A manager for database connections of an application context.
13  * <br><br>
14  * Each thread is assigned to an application context. For each context this class
15  * manages a pool of database connections using an object of class {@link TKDBConnectionManager TKDBConnectionManager}.
16  * <br><br>
17  * Having initialized the database pool for each context,
18  * a concrete connection is assigned to each thread after the first request,
19  * until an explicit release of the connection.
20  * <br><br>
21  * Simultaneously, a thread can maintain several opened connections to different databases.
22  * Each context is then assigned to a single connection. By changing the context a thread
23  * may switch to another database connection.
24  * <br><br>
25  * This class is never instantiated.
26  * <br><br>
27  * @author $Author: alex $
28  * @version $Revision: 1.26 $
29  * @see TKDBConnectionManager
30  */

31 public class TKDBManager {
32
33     /** Logging Category */
34     private static final Category CAT = Category.getInstance(TKDBManager.class);
35
36     /**
37      * A hashtable, which maps each context to its connection manager.
38      * <br><br>
39      * key(Object aContext) =&gt; value(TKDBConnectionManager aConnectionManager)
40      */

41 // private static TKHashtable contextManager = new TKHashtable();
42

43     /**
44      * A hashtable, which maps each thread to the connection manager
45      * of its actual context.
46      * <br><br>
47      * key(Thread aThread) =&gt; value(TKDBConnectionManager aConnectionManager)
48      */

49 // private static TKHashtable threadManager = new TKHashtable();
50

51     /**
52     * aktueller Kontext
53     */

54     // Thread, Context
55
// private static TKHashtable currentContext = new TKHashtable();
56

57     /**
58      * A hashtable, which maps each thread to a hashtable of all contexts and the
59      * connection managers assigned to the contexts, where the thread has registered.
60      * <br><br>
61      * key(Thread aThread) =&gt; value(TKHashtable aTKHashtable(key (Object aContext) =&gt;
62      * value(TKDBConnectionManager aConnectionManager)))
63      */

64 // private static TKHashtable threadContexts = new TKHashtable();
65

66     /**
67     * Default Context
68     */

69 // public final static Object DEFAULT_CONTEXT = "com.teamkonzept.db.TKDBManagerDefaultContext";
70

71     /**
72      * Ensures, that for the specified context exists a <code>TKDBConnectionManager</code>.
73      * <br><br>
74      * The specified context becomes the actual context of the specified thread.
75      * <br>
76      * Returns the responsible <code>TKDBConnectionManager</code>.
77      *
78      * @param thread gets the specified context as actual context
79      * @return the responsible <code>TKDBConnectionManager</code> of the specified thread.
80      */

81 // private static synchronized TKDBConnectionManager ensureManager( Thread thread, Object context )
82
// {
83
// TKDBConnectionManager currManager = (TKDBConnectionManager)contextManager.get(context);
84
// if ( currManager == null )
85
// {
86

87 // final Object currContext = getCurrentContext();
88
// if (currContext != null) {
89
// // hole den Manager zum aktuellen Kontext
90
// currManager = (TKDBConnectionManager)contextManager.get( currContext );
91
// }
92

93 // // final boolean toClone;
94
// if (currManager == null) {
95
// // hole den default-Manager
96
// currManager = (TKDBConnectionManager)contextManager.get(DEFAULT_CONTEXT);
97
// if (currManager == null) {
98
// // erzeuge einen neuen Manager
99
// // currManager = new TKDBConnectionManager();
100
// currManager = TKDBConnectionManager.getInstance();
101
// // toClone = false;
102
// }
103
// // else {
104
// // toClone = true;
105
// // }
106
// }
107
// // else {
108
// // toClone = true;
109
// // }
110
// // if ( toClone )
111
// // {
112

113 // // currManager = (TKDBConnectionManager)currManager.clone();
114
// // }
115
// contextManager.put(context, currManager);
116
// }
117
// threadManager.put(thread, currManager);
118
// return currManager;
119
// return TKDBConnectionManager.getInstance();
120
// }
121

122     /**
123      * Registers the specified thread at this <code>TKDBManager</code>.
124      * @param currThread the thread to be registered.
125      */

126     protected static final void register( Thread JavaDoc currThread )
127     {
128 // threadContexts.put( currThread, new TKHashtable() );
129
}
130
131     /**
132      * Registers the current thread at this <code>TKDBManager</code>.
133      */

134     public static void register()
135     {
136 // register( Thread.currentThread() );
137
}
138
139     /**
140      * Registers the current thread at this <code>TKDBManager</code>
141      * and sets the specified context as its initial context.
142      *
143      * @param initialContext the initial context to be assigned to the current thread.
144      */

145     public static void register( Object JavaDoc initialContext )
146     {
147 // Thread currThread = Thread.currentThread();
148
// register( currThread );
149
// try {
150
// enterContext( currThread, initialContext, false );
151
// }
152
// catch( SQLException e ) {
153
// throw new Error("Impossible error");
154
// }
155
}
156
157     /**
158      * Changes the context of the specified thread to the specified nextContext.
159      * Depending on the specified value of leaveOldContext, the connection in the
160      * previous context is released.
161      *
162      * @param currThread the thread, of which the context has to be changed.
163      * @param nextContext this context replaces the previous context of the specified thread.
164      * @param leaveOldContext indicates if the connection in the previous context is released.
165      * @throws SQLException normaler SQL Fehler
166      */

167     protected static void enterContext( Thread JavaDoc currThread, Object JavaDoc nextContext, boolean leaveOldContext ) throws SQLException
168     {
169         if( leaveOldContext ) {
170 // TKDBConnectionManager connManager =
171
// (TKDBConnectionManager) threadManager.get( currThread );
172
// if( connManager != null ) {
173
// connManager.freeConnection();
174
// }
175
TKDBConnectionManager.getInstance().freeConnection();
176         }
177
178 // TKHashtable contextHash = (TKHashtable)threadContexts.get( currThread );
179
// contextHash.put( nextContext, ensureManager( currThread, nextContext ) );
180
// currentContext.put( currThread, nextContext );
181
}
182
183     /**
184      * Replaces the context of the current thread with the specified nextContext.
185      */

186      /*
187     private static void enterContext( Object nextContext )
188     {
189         try {
190             enterContext( Thread.currentThread(), nextContext, false );
191         }
192         catch( SQLException e ) {
193             throw new Error("Impossible error");
194         }
195     }
196 */

197     /**
198      * Replaces the context of the current thread with the specified nextContext.
199      * Depending on the specified value of leaveOldContext, the connection in the
200      * previous context is released.
201      *
202      * @param nextContext this context replaces the previous context of the specified thread.
203      * @param leaveOldContext indicates if the connection in the previous context is released.
204      * @throws SQLException
205      */

206      /*
207     private static void enterContext( Object nextContext, boolean leaveOldContext )
208         throws SQLException
209     {
210         enterContext( Thread.currentThread(), nextContext, leaveOldContext );
211     }
212 */

213     /**
214      * Closes all opened connections in the <code>TKDBConnectionManager</code> assigned to
215      * the current thread.
216     */

217     protected static void resetContext()
218     {
219         getManager().resetConnections();
220     }
221
222     /**
223      * Deregisters the current thread from this <code>TKDBManager</code>.
224      * The specified value of doClose indicates, if all the connections contained
225      * in the <code>TKDBConnectionManager</code> assigned to the current thread are
226      * closed or only released.
227      *
228      * @param doClose if <code>true</code> close connections of the current thread
229      * else only release them for other threads.
230      * @throws SLQException normaler SQL Fehler
231      */

232     public static synchronized void deregister( boolean doClose ) throws SQLException
233     {
234         
235 // Thread currThread = Thread.currentThread();
236

237 // threadManager.remove( currThread );
238
// TKHashtable contexts = (TKHashtable)threadContexts.remove( currThread );
239
// if( contexts == null ) return;
240

241 // Enumeration e = contexts.elements();
242
// if( doClose ) {
243
// while( e.hasMoreElements() ) {
244
// ((TKDBConnectionManager)e.nextElement()).closeConnection();
245
// }
246
// }
247
// else {
248
// while( e.hasMoreElements() ) {
249
// ((TKDBConnectionManager)e.nextElement()).freeConnection();
250
// }
251
// }
252
TKDBConnectionManager.getInstance().freeConnection();
253     }
254
255     /**
256      * Returns the <code>TKDBConnectionManager</code> assigned to the actual context of the current thread.
257      * @return the connection manager of the current thread.
258     */

259     public static TKDBConnectionManager getManager()
260     {
261 // Thread currThread = Thread.currentThread();
262
// TKDBConnectionManager currManager = (TKDBConnectionManager)threadManager.get( currThread );
263
// if( currManager == null ) {
264
// currManager = ensureManager( currThread, DEFAULT_CONTEXT );
265
// }
266
// return currManager;
267
return TKDBConnectionManager.getInstance();
268     }
269
270     /**
271      * Returns the connection of the current thread in the actual context
272      * @throws SQLException
273      */

274     public static Connection getConnection() throws SQLException
275     {
276         return getManager().getConnection();
277     }
278
279
280     /**
281       * Using the methods <code>beginTransaction</code>, <code>commitTransaction</code>
282       * and <code>rollbackTransaction</code>, it is possible to encapsulate several queries
283       * in one transaction.
284       * <br>
285       * Usage:
286       * <br>
287       * <pre>
288       * TKDBManager.beginTransaction();
289       * try{
290       * q_1.execute();
291       * q_1.close();
292       * .
293       * .
294       * .
295       * q_n.execute();
296       * q_n.close();
297       * commitTransaction();
298       * }
299       * catch(Throwable e){
300       * TKDBManager.rollbackTransaction();
301       * }
302       * </pre>
303       * <br>
304       * It is important to call <code>close</code> for each <code>TKQuery</code>,
305       * because only then the statement will be completed and SQLExceptions will be thrown.
306       * <br>
307       * As well important is to catch <code>Throwable</code>, because <code>close</close> may
308       * throw a <code>SQLError</code>!
309       * <br>
310       *
311       * For details see method {@link #executeAsTran(TKQuery [] queryArray) executeAsTran}
312      * @throws SQLException
313       */

314     public static void beginTransaction() throws SQLException
315     {
316         getManager().beginTransaction();
317     }
318
319     /**
320      * Commits a transaction begun in the <code>TKDBConnection</code>
321      * in the actual context of the current thread
322      * <i>(connection is retrieved over <code>TKDBConnectionManager</code>)</i>
323      * @throws SQLException
324      */

325     public static void commitTransaction() throws SQLException
326     {
327         getManager().commitTransaction();
328     }
329
330     /**
331      * Rollbacks a transaction begun in the <code>TKDBConnection</code>
332      * in the actual context of the current thread
333      * <i>(connection is retrieved over <code>TKDBConnectionManager</code>)</i>
334      */

335     public static void rollbackTransaction() throws SQLException
336     {
337         getManager().rollbackTransaction();
338     }
339
340     /**
341      * Rollbacks a transaction begun in the <code>TKDBConnection</code>
342      * in the actual context of the current thread
343      * <i>(connection is retrieved over <code>TKDBConnectionManager</code>)</i>.
344      * <br>
345      * Is called by {@link executeAsTran(TKQuery [] queryArray) executeAsTran}
346      * in the catch-clause and analyzes the specified <code>Throwable</code>.
347      * Throws a <code>TKSQLError</code>, which encapsulates a <code>SQLException</code>.
348      * @param t Ursprungsexception
349      */

350     public static void safeRollbackTransaction(Throwable JavaDoc t)
351     {
352         try{
353             CAT.error("Rollback Reason: ", t);
354             rollbackTransaction();
355
356         }
357         catch(SQLException e){
358             CAT.debug("SQLException during rollback", e);
359         }
360
361         if (t instanceof SQLException)
362         {
363             throw new TKSQLError("Rollback: " + t.getMessage(), (SQLException) t);
364         }
365
366         if (t instanceof TKSQLError)
367         {
368             throw new TKSQLError("Rollback: " + t.getMessage(), ((TKSQLError) t).getSQLException());
369         }
370
371         throw new TKSQLError("Rollback: " + t.getMessage());
372     }
373
374
375     /**
376      * Closes all queries within the connection of the actual context,
377      * not implementing the interface <code>SensitiveQuery</code>
378      * by calling the queries&acute; <code>close</code> method.
379      * @throws SQLException
380      */

381     public static void closeNonsensitiveQueries() throws SQLException
382     {
383         getManager().closeNonsensitiveQueries();
384     }
385
386
387
388     /**
389       * Executes the queries in the specified queryArray within one transaction.
390       * If one <code>TKQuery</code> throws an exception, all
391       * queries are rollbacked.
392       * <br>
393       * This method should be used, if the returned resultsets are not needed.
394       * @param queryArray Array of TKQuery, to be executed within a transaction
395       */

396     public static void executeAsTran(TKQuery [] queryArray) {
397         try{
398             beginTransaction();
399             int i;
400             for(i = 0; i < queryArray.length; i++){
401                 queryArray[i].execute();
402                 queryArray[i].close();
403             }
404             commitTransaction();
405         }
406         catch( Throwable JavaDoc t){
407             safeRollbackTransaction(t);
408         }
409     }
410
411     //***************************************************************************
412
/**
413         Erzeugt ein neues Query-Objekt im aktuellen Kontext des laufenden Threads.
414         Die Query-Klasse wird im uebergebenen Java-Package gesucht.
415     */

416     /*
417     public static TKQuery newQuery( String queryId, String basePackage )
418         throws SQLException
419         {return getManager()._newQuery( queryId, basePackage );}
420     */

421     /**
422         Erzeugt ein neues Query-Objekt im aktuellen Kontext des laufenden Threads.
423         Die Query-Klasse wird im default-Base-Package gesucht.
424     */

425     /*
426     public static TKQuery newQuery( String queryId ) throws SQLException
427         {return getManager()._newQuery( queryId );}
428     */

429     /**
430         Erzeugt ein neues Query-Objekt im aktuellen Kontext des laufenden Threads.
431         Die Query-Klasse wird übergeben oder anhand der uebergebenen Objektes gesucht.
432     */

433     /*
434     public static TKQuery newQuery( TKPackageInformer query ) throws SQLException
435          { return getManager()._newQuery( query ); }
436     */

437     //***************************************************************************
438

439     /**
440       * Returns an instance of the specified queryClass registered in the
441       * <code>TKDBConnectionManager</code> responsible for the actual context
442       * of the current thread.
443       *
444       * @param queryClass the class to instantiate a new <code>TKQuery</code>
445       * @see TKQuery
446       * @see TKDBConnectionManager
447       * @see TKDBConnection
448      * @return die erzeugte Query
449     */

450     public static TKQuery newQuery( Class JavaDoc queryClass ) throws SQLException
451     {
452         return getManager().newQuery( queryClass );
453     }
454
455     /**
456         Setzt das Default-Java-Package in dem nach Query-Klassen fuer den
457         aktuellen Kontext des laufenden Threads gesucht wird
458     */

459     /*
460     public static void setBasePackage( String basePackage )
461         {getManager()._setBasePackage( basePackage );}
462     */

463
464     /**
465       * Sets all values within the <code>TKDBConnectionManager</code> responsible
466       * for the context of the current thread, necessary to connect to database.
467       * @param dbId a string which determines the vendor of the used database
468       * @param serverId the connect string
469       * @param prop properties of the used database connection
470       * (database, user_name, password, server, ...)
471       */

472     public static void prepareConnection(Properties JavaDoc prop )
473         throws SQLException
474     {
475         getManager().prepareConnection( prop );
476     }
477
478     /**
479       * Closes the connection of the current thread.
480       */

481     public static void closeConnection() throws SQLException
482     {
483         getManager().closeConnection();
484     }
485
486     /**
487       * Releases the connection of the current thread, so it can be used later.
488       */

489     public static void freeConnection() throws SQLException
490     {
491         getManager().freeConnection();
492     }
493
494     /**
495       * Limits the number of opened connections of the current thread to
496       * the specified value of count.
497       */

498     public static void limitConnections( int count )
499     {
500         getManager().limitConnections( count );
501     }
502         
503     /**
504     * Liefert den aktuellen Kontext des Threads
505     */

506 // private static Object getCurrentContext()
507
// {
508
//return currentContext.get( Thread.currentThread() );
509
// return TKDBConnectionManager.getInstance();
510
// }
511
/**
512       * Returns the vendor of database out of the connect data within
513       * the <code>TKDBConnectionManager</code> responsible for the actual context
514       * of the current thread.
515       */

516     public static int getDBVendor()
517     {
518         TKConnectData connectData = getManager().getConnectionData();
519         
520         if(connectData == null){
521             return QueryConstants.DONTKNOW;
522         }
523         if(connectData instanceof TKOracleConnectData){
524             return QueryConstants.ORACLE;
525         }
526         if(connectData instanceof TKSybaseConnectData){
527             return QueryConstants.SYBASE;
528         }
529         if(connectData instanceof TKPostgreSQLConnectData){
530             return QueryConstants.POSTGRESQL;
531         }
532         else{
533             return QueryConstants.DONTKNOW;
534         }
535         
536     }
537
538
539 }
540
541
Popular Tags