KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas > jdbc > ManagedConnectionImpl


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 1999-2005 Bull S.A.
4  * Contact: jonas-team@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: ManagedConnectionImpl.java,v 1.8 2005/05/04 14:09:00 benoitf Exp $
23  * --------------------------------------------------------------------------
24  */

25 package org.objectweb.jonas.jdbc;
26
27 import java.io.PrintWriter JavaDoc;
28 import java.sql.DriverManager JavaDoc;
29 import java.util.HashSet JavaDoc;
30 import java.util.Iterator JavaDoc;
31
32 import javax.resource.ResourceException JavaDoc;
33 import javax.resource.spi.ConnectionEvent JavaDoc;
34 import javax.resource.spi.ConnectionEventListener JavaDoc;
35 import javax.resource.spi.ConnectionRequestInfo JavaDoc;
36 import javax.resource.spi.LocalTransaction JavaDoc;
37 import javax.resource.spi.ManagedConnection JavaDoc;
38 import javax.resource.spi.ManagedConnectionMetaData JavaDoc;
39 import javax.resource.spi.security.PasswordCredential JavaDoc;
40 import javax.security.auth.Subject JavaDoc;
41 import javax.sql.DataSource JavaDoc;
42 import javax.sql.PooledConnection JavaDoc;
43 import javax.sql.XAConnection JavaDoc;
44 import javax.transaction.xa.XAResource JavaDoc;
45
46 import org.objectweb.util.monolog.api.BasicLevel;
47 import org.objectweb.util.monolog.api.Logger;
48
49 /**
50  * @author Eric hardesty
51  */

52 public class ManagedConnectionImpl implements ManagedConnection JavaDoc, javax.resource.spi.LocalTransaction JavaDoc {
53
54     public Logger trace = null;
55
56     protected PrintWriter JavaDoc out = null;
57
58     protected DataSource JavaDoc factory = null;
59
60     protected HashSet JavaDoc cels = null;
61
62     protected boolean inLocalTransaction = false;
63
64     ManagedConnectionFactoryImpl mcf = null;
65
66     java.sql.Connection JavaDoc connection = null;
67
68     PooledConnection JavaDoc poolCon = null;
69
70     XAConnection JavaDoc xaCon = null;
71
72     PasswordCredential JavaDoc pc = null;
73
74     DriverWrapper wrapper = null;
75
76     private XAResource JavaDoc xares;
77
78     private boolean isAutoCommit = true;
79
80     private boolean closed = false;
81
82     private long[] sigList;
83
84     private int maxSigs;
85
86     private long signature;
87
88     private long lastSig;
89
90     /**
91      * Logging (debug enabled)
92      */

93     private final boolean isDebugOn;
94
95     public ManagedConnectionImpl(ManagedConnectionFactoryImpl _mcf, PasswordCredential JavaDoc _pc, java.sql.Connection JavaDoc _con,
96             PooledConnection JavaDoc _pcon, XAConnection JavaDoc _xa, DriverWrapper wrp) {
97
98         mcf = _mcf;
99         pc = _pc;
100         connection = _con;
101         poolCon = _pcon;
102         xaCon = _xa;
103         wrapper = wrp;
104         xares = null;
105         out = mcf.pw;
106         cels = new HashSet JavaDoc();
107         maxSigs = 50;
108         sigList = new long[maxSigs];
109         signature = 0;
110         lastSig = 0;
111         trace = mcf.trace;
112         isDebugOn = trace.isLoggable(BasicLevel.DEBUG);
113     }
114
115     public void signalEvent(int code, Object JavaDoc ch, Exception JavaDoc ex) {
116         ConnectionEvent JavaDoc ce = null;
117         if (ex == null) {
118             ce = new ConnectionEvent JavaDoc(this, code);
119         } else {
120             ce = new ConnectionEvent JavaDoc(this, code, ex);
121         }
122         if (ch != null) {
123             ce.setConnectionHandle(ch);
124         }
125         for (Iterator JavaDoc it = cels.iterator(); it.hasNext();) {
126             switch (code) {
127                 case ConnectionEvent.CONNECTION_CLOSED:
128                     ((ConnectionEventListener JavaDoc) it.next()).connectionClosed(ce);
129                     break;
130                 case ConnectionEvent.LOCAL_TRANSACTION_STARTED:
131                     ((ConnectionEventListener JavaDoc) it.next()).localTransactionStarted(ce);
132                     break;
133                 case ConnectionEvent.LOCAL_TRANSACTION_COMMITTED:
134                     ((ConnectionEventListener JavaDoc) it.next()).localTransactionCommitted(ce);
135                     break;
136                 case ConnectionEvent.LOCAL_TRANSACTION_ROLLEDBACK:
137                     ((ConnectionEventListener JavaDoc) it.next()).localTransactionRolledback(ce);
138                     break;
139                 case ConnectionEvent.CONNECTION_ERROR_OCCURRED:
140                     ((ConnectionEventListener JavaDoc) it.next()).connectionErrorOccurred(ce);
141                     break;
142                 default:
143                     throw new IllegalArgumentException JavaDoc("Illegal eventType: " + code);
144             }
145         }
146     }
147
148     public synchronized boolean getAutoCommit() throws ResourceException JavaDoc {
149         return isAutoCommit;
150     }
151
152     public synchronized void setAutoCommit(boolean ac) throws ResourceException JavaDoc {
153         isAutoCommit = ac;
154         try {
155             if (connection != null) {
156                 connection.setAutoCommit(ac);
157             }
158         } catch (Exception JavaDoc e) {
159             throw new ResourceException JavaDoc(e.getMessage());
160         }
161     }
162
163     /**
164      * Adds a connection event listener.
165      */

166     public void addConnectionEventListener(ConnectionEventListener JavaDoc listener) {
167         cels.add(listener);
168     }
169
170     /**
171      * Change the association of a connection handle
172      */

173     public synchronized void associateConnection(Object JavaDoc con) throws ResourceException JavaDoc {
174         if (isDebugOn) {
175             trace.log(BasicLevel.DEBUG, "connection:" + con);
176         }
177         if (con instanceof ConnectionImpl) {
178             ConnectionImpl ci = (ConnectionImpl) con;
179             long sig = getNewSignature(true);
180             ci.setSignature(sig);
181         } else {
182             throw new ResourceException JavaDoc("The managedConnection cannot associate this connection: " + con);
183         }
184     }
185
186     /**
187      * Cleanup the ManagedConnection instance.
188      */

189     public void cleanup() throws ResourceException JavaDoc {
190         if (inLocalTransaction) throw new ResourceException JavaDoc("A local transaction is not complete");
191         clearSignature();
192     }
193
194     /**
195      * Destroys the physical connection.
196      */

197     public synchronized void destroy() throws ResourceException JavaDoc {
198         if (isDebugOn) {
199             trace.log(BasicLevel.DEBUG, "destroy mc=" + this + " with connection=" + connection);
200         }
201         try {
202             if (wrapper != null) {
203                 DriverManager.deregisterDriver(wrapper);
204             }
205         } catch (Exception JavaDoc ex) {
206             trace.log(BasicLevel.ERROR, "Unable to deregister Driver wrapper", ex);
207         }
208         if (connection != null) {
209             try {
210                 connection.close();
211             } catch (Exception JavaDoc e) {
212                 trace.log(BasicLevel.ERROR, "", e, "ManagedConnectionImpl", "destroy");
213                 throw new ResourceException JavaDoc(e);
214             }
215             connection = null;
216         }
217     }
218
219     /**
220      * Create a connection handle
221      */

222     public Object JavaDoc getConnection(Subject JavaDoc subject, ConnectionRequestInfo JavaDoc cxRequestInfo) throws ResourceException JavaDoc {
223         if (isDebugOn) {
224             trace.log(BasicLevel.DEBUG, "subject:" + subject + " connectionRequest:" + cxRequestInfo);
225         }
226
227         long sig = getNewSignature(true);
228
229         try {
230             return new ConnectionImpl(this, connection, sig, out);
231         } catch (Exception JavaDoc e) {
232             trace.log(BasicLevel.ERROR, "", e, "ManagedConnectionImpl", "getConnection");
233             throw new ResourceException JavaDoc(e.getMessage());
234         }
235     }
236
237     /**
238      * Returns an javax.resource.spi.LocalTransaction instance.
239      */

240     public LocalTransaction JavaDoc getLocalTransaction() throws ResourceException JavaDoc {
241         return (LocalTransaction JavaDoc) this;
242     }
243
244     /**
245      * Gets the log writer for this ManagedConnection instance.
246      */

247     public PrintWriter JavaDoc getLogWriter() {
248         return out;
249     }
250
251     /**
252      * Gets the metadata information for this connection's underlying EIS
253      * resource manager instance.
254      */

255     public ManagedConnectionMetaData JavaDoc getMetaData() throws ResourceException JavaDoc {
256         return new MetaDataImpl(this);
257     }
258
259     /**
260      * Check if the mc is in local transaction
261      */

262     public XAResource JavaDoc getXAResource() throws ResourceException JavaDoc {
263         if (isDebugOn) {
264             trace.log(BasicLevel.DEBUG, "");
265         }
266         if (inLocalTransaction)
267             throw new ResourceException JavaDoc(
268                     "The managedConnection is already in a local transaction and an XA resource cannot be obtained");
269         if (xares == null) {
270             if (xaCon != null) {
271                 try {
272                     xares = xaCon.getXAResource();
273                 } catch (Exception JavaDoc ex) {
274                     throw new ResourceException JavaDoc("Unable to obtain XAResource: ", ex);
275                 }
276             } else {
277                 if (isDebugOn) {
278                     trace.log(BasicLevel.DEBUG, "JDBC driver doesn't support XA, simulate it with " + xares);
279                 }
280             }
281             xares = new XAResourceImpl(this, xares);
282         }
283         return xares;
284     }
285
286     /**
287      * Removes an already registered connection event listener from the
288      * ManagedConnection instance
289      */

290     public void removeConnectionEventListener(ConnectionEventListener JavaDoc listener) {
291         cels.remove(listener);
292     }
293
294     /**
295      * Sets the log writer for this ManagedConnection instance.
296      */

297     public void setLogWriter(PrintWriter JavaDoc _out) {
298         out = _out;
299     }
300
301     public void addSignature(long sig) {
302         int off = -1;
303         for (int i = 0; i < maxSigs; i++)
304             if (sigList[i] == 0) {
305                 off = i;
306                 break;
307             }
308
309         if (off > -1)
310             sigList[off] = sig;
311         else {
312             maxSigs += 20;
313             long[] tmp = new long[maxSigs];
314             System.arraycopy(sigList, 0, tmp, 0, maxSigs - 20);
315             sigList = tmp;
316             sigList[maxSigs - 20] = sig;
317         }
318     }
319
320     public void clearSignature() {
321         for (int i = 0; i < maxSigs; i++)
322             sigList[i] = 0;
323         signature = 0;
324     }
325
326     public void clearSignature(long sig, boolean clear) {
327         for (int i = 0; i < maxSigs; i++) {
328             if (sig == sigList[i]) {
329                 sigList[i] = 0;
330                 break;
331             }
332         }
333         if (clear) {
334             signature = 0;
335         }
336     }
337
338     public void setSignature(long sig) {
339         if (signature == 0) {
340             signature = sig;
341         }
342     }
343
344     /**
345      * Gets the signature value passed in if found in the signature hash table
346      * @param long sig value to find in signature table
347      * @return long signature value or 0 if not found
348      */

349     public long getSignature(long sig) {
350         // find signature
351
long retSig = 0;
352         if (sig > 0) {
353             for (int i = 0; i < maxSigs; i++)
354                 if (sig == sigList[i]) {
355                     retSig = sig;
356                     break;
357                 }
358         }
359         return (retSig);
360     }
361
362     /**
363      * Gets the current signature value
364      * @return long current signature value
365      */

366     public long getSignature() {
367         return (signature);
368     }
369
370     /**
371      * Gets the next signature value
372      * @return long next signature value
373      */

374     public long getNewSignature(boolean setSig) {
375         long sig = System.currentTimeMillis();
376         if (sig <= lastSig && lastSig != 0) {
377             sig = lastSig++;
378         }
379         if (isDebugOn) {
380             trace.log(BasicLevel.DEBUG, "Sig is " + sig + " last Sig was " + lastSig);
381         }
382         lastSig = sig;
383         addSignature(sig);
384         if (setSig) {
385             signature = sig;
386         }
387         return sig;
388     }
389
390     public void close(ConnectionImpl ch) throws ResourceException JavaDoc {
391         clearSignature(ch.key, true);
392         signalEvent(ConnectionEvent.CONNECTION_CLOSED, ch, null);
393     }
394
395     /** ******************************************************* */
396     /** IMPLEMENTATION OF INTERFACE LocalTransaction * */
397     /** ******************************************************* */
398     public void begin() throws ResourceException JavaDoc {
399         if (inLocalTransaction) throw new ResourceException JavaDoc("The managedConnection is already in a LocalTransaction");
400         try {
401             inLocalTransaction = true;
402             connection.setAutoCommit(false);
403         } catch (Exception JavaDoc ex) {
404         }
405     }
406
407     public void commit() throws ResourceException JavaDoc {
408         try {
409             connection.commit();
410             connection.setAutoCommit(true);
411             inLocalTransaction = false;
412         } catch (Exception JavaDoc ex) {
413         }
414     }
415
416     public void rollback() throws ResourceException JavaDoc {
417         try {
418             connection.rollback();
419             connection.setAutoCommit(true);
420             inLocalTransaction = false;
421         } catch (Exception JavaDoc ex) {
422         }
423     }
424
425 }
426
Popular Tags