ManagedConnectionImpl.java

00001  /*
00002  * JOnAS: Java(TM) Open Application Server
00003  * Copyright (C) 1999 Bull S.A.
00004  * Contact: jonas-team@objectweb.org
00005  * 
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or any later version.
00010  * 
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00019  * USA
00020  *
00021  * Initial developer(s): Eric HARDESTY
00022  * --------------------------------------------------------------------------
00023  * $Id: ManagedConnectionImpl.java,v 1.6 2004/12/14 16:13:51 ehardesty Exp $
00024  * --------------------------------------------------------------------------
00025  */
00026 package org.objectweb.jonas.jdbc;
00027 
00028 import java.io.PrintWriter;
00029 import java.sql.DriverManager;
00030 import java.util.HashSet;
00031 import java.util.Iterator;
00032 
00033 import javax.resource.ResourceException;
00034 import javax.resource.spi.ConnectionEvent;
00035 import javax.resource.spi.ConnectionEventListener;
00036 import javax.resource.spi.ConnectionRequestInfo;
00037 import javax.resource.spi.LocalTransaction;
00038 import javax.resource.spi.ManagedConnection;
00039 import javax.resource.spi.ManagedConnectionMetaData;
00040 import javax.resource.spi.security.PasswordCredential;
00041 import javax.security.auth.Subject;
00042 import javax.sql.DataSource;
00043 import javax.sql.PooledConnection;
00044 import javax.sql.XAConnection;
00045 import javax.transaction.xa.XAResource;
00046 
00047 import org.objectweb.util.monolog.api.BasicLevel;
00048 import org.objectweb.util.monolog.api.Logger;
00049 
00050 
00051 public class ManagedConnectionImpl  
00052         implements ManagedConnection,  
00053         javax.resource.spi.LocalTransaction {
00054         
00055         public Logger trace = null;
00056         
00057         protected PrintWriter out = null;
00058   
00059     protected DataSource factory = null;
00060   
00061     protected HashSet cels = null;
00062         
00063         protected boolean inLocalTransaction = false;
00064     
00065     ManagedConnectionFactoryImpl mcf = null;
00066     java.sql.Connection connection = null;
00067     PooledConnection poolCon = null;
00068     XAConnection xaCon = null;
00069     PasswordCredential pc = null;
00070     DriverWrapper wrapper = null;
00071     
00072     private XAResource xares;
00073         
00074     private boolean isAutoCommit = true;
00075     private boolean closed = false;
00076     private long [] sigList;
00077     private int maxSigs;
00078     private long signature;
00079     private long lastSig;
00080 
00081     public ManagedConnectionImpl(ManagedConnectionFactoryImpl _mcf,
00082                                   PasswordCredential _pc,  
00083                                   java.sql.Connection _con,
00084                                   PooledConnection _pcon, XAConnection _xa,
00085                                   DriverWrapper wrp) {
00086         
00087         mcf = _mcf;
00088         pc = _pc;
00089                 connection = _con;
00090                 poolCon = _pcon;
00091         xaCon = _xa;
00092         wrapper = wrp;
00093         xares = null;
00094                 out = mcf.pw;
00095         cels = new HashSet();
00096         maxSigs = 50;
00097         sigList = new long[maxSigs];
00098         signature = 0;
00099         lastSig = 0;
00100         trace = mcf.trace;
00101         }
00102         
00103         public void signalEvent(int code, Object ch, Exception ex) {
00104         ConnectionEvent ce = null;
00105         if (ex == null) {
00106             ce = new ConnectionEvent(this, code);
00107         } else {
00108             ce = new ConnectionEvent(this, code, ex);
00109         }
00110         if (ch != null) {
00111             ce.setConnectionHandle(ch);
00112         }
00113         for (Iterator it=cels.iterator(); it.hasNext();) {
00114             switch (code) {
00115                 case ConnectionEvent.CONNECTION_CLOSED:
00116                     ((ConnectionEventListener) it.next()).connectionClosed(ce);
00117                     break;
00118                 case ConnectionEvent.LOCAL_TRANSACTION_STARTED:
00119                     ((ConnectionEventListener) it.next()).localTransactionStarted(ce);
00120                     break;
00121                 case ConnectionEvent.LOCAL_TRANSACTION_COMMITTED:
00122                     ((ConnectionEventListener) it.next()).localTransactionCommitted(ce);
00123                     break;
00124                 case ConnectionEvent.LOCAL_TRANSACTION_ROLLEDBACK:
00125                     ((ConnectionEventListener) it.next()).localTransactionRolledback(ce);
00126                     break;
00127                 case ConnectionEvent.CONNECTION_ERROR_OCCURRED:
00128                     ((ConnectionEventListener) it.next()).connectionErrorOccurred(ce);
00129                     break;
00130                 default:
00131                     throw new IllegalArgumentException("Illegal eventType: "+code);
00132             }
00133         }
00134     }
00135         
00136         public synchronized boolean getAutoCommit() throws ResourceException {
00137         return isAutoCommit;
00138     }
00139 
00140         public synchronized void setAutoCommit(boolean ac) 
00141                 throws ResourceException {
00142         isAutoCommit = ac;
00143         try {
00144             if (connection != null) {
00145                 connection.setAutoCommit(ac);
00146             }
00147         } catch (Exception e) {
00148             throw new ResourceException(e.getMessage());
00149         }
00150   }
00151         
00155         public void addConnectionEventListener(ConnectionEventListener listener) {
00156                 cels.add(listener);
00157         }
00158 
00162         public synchronized void associateConnection(Object con) 
00163         throws ResourceException { 
00164         trace.log(BasicLevel.DEBUG, "connection:"+con);
00165         if (con instanceof ConnectionImpl ) {
00166             ConnectionImpl ci = (ConnectionImpl) con;
00167             long sig = getNewSignature(true);
00168             ci.setSignature(sig);
00169         } else {
00170             throw new ResourceException(
00171                 "The managedConnection cannot associate this connection: "+con);
00172         }
00173     }
00174 
00178     public void cleanup() throws ResourceException {
00179         if (inLocalTransaction) 
00180             throw new ResourceException("A local transaction is not complete");
00181          clearSignature();
00182     }
00183 
00187     public synchronized void destroy() throws ResourceException {
00188         trace.log(BasicLevel.DEBUG, "destroy mc="+this+" with connection="+connection);
00189         try {
00190             if (wrapper != null) {
00191                 DriverManager.deregisterDriver(wrapper);
00192             }
00193         } catch (Exception ex) {
00194             trace.log(BasicLevel.ERROR,"Unable to deregister Driver wrapper" + ex);
00195         }
00196         if (connection != null) {
00197             try {
00198                 connection.close();
00199             } catch (Exception e) {
00200                 trace.log(BasicLevel.ERROR,"",e,"ManagedConnectionImpl","destroy");
00201                 throw new ResourceException(e.getMessage());
00202             }
00203             connection = null;
00204         }
00205   }
00206     
00210     public Object getConnection(Subject subject,ConnectionRequestInfo cxRequestInfo) 
00211     throws ResourceException {
00212 
00213         trace.log(BasicLevel.DEBUG,"subject:"+subject+" connectionRequest:"+cxRequestInfo);        
00214 
00215         long sig = getNewSignature(true);
00216 
00217         try {
00218             return new ConnectionImpl(this, connection, sig, out);
00219         } catch (Exception e) {
00220             trace.log(BasicLevel.ERROR,"",e,"ManagedConnectionImpl", "getConnection");        
00221             throw new ResourceException(e.getMessage());
00222         }
00223     }
00224 
00228     public LocalTransaction getLocalTransaction() throws ResourceException {
00229         return (LocalTransaction) this;
00230     }
00231     
00235     public PrintWriter getLogWriter() {
00236         return out;
00237     }
00242     public ManagedConnectionMetaData getMetaData() 
00243         throws ResourceException { 
00244         return new MetaDataImpl(this);
00245     }
00246 
00250     public XAResource getXAResource() throws ResourceException {
00251         trace.log(BasicLevel.DEBUG, "");
00252         if (inLocalTransaction)
00253             throw new ResourceException(
00254             "The managedConnection is already in a local transaction and an XA resource cannot be obtained");
00255         if (xares == null) {
00256             if (xaCon != null) {
00257                 try {
00258                     xares = xaCon.getXAResource();
00259                 } catch (Exception ex) {
00260                     throw new ResourceException(
00261                       "Unable to obtain XAResource: "+ex.getMessage()); 
00262                 }
00263             } else {
00264                 trace.log(BasicLevel.DEBUG, "JDBC driver doesn't support XA, simulate it with "+xares);
00265             }
00266             xares = new XAResourceImpl(this, xares);
00267         }
00268         return xares;
00269     }
00270 
00275     public void removeConnectionEventListener(
00276                    ConnectionEventListener listener) {
00277         cels.remove(listener);
00278     }
00279 
00283     public void setLogWriter(PrintWriter _out) {
00284         out = _out;
00285     }
00286 
00287     public
00288     void addSignature(long sig)
00289     {
00290       int off = -1;
00291       for (int i=0;i<maxSigs;i++)
00292         if (sigList[i] == 0)
00293         {
00294           off = i;
00295           break;
00296         }
00297       
00298       if (off > -1)
00299         sigList[off] = sig;
00300       else
00301       {
00302         maxSigs += 20;
00303         long [] tmp = new long[maxSigs];
00304         System.arraycopy(sigList, 0, tmp, 0, maxSigs-20);
00305         sigList = tmp;
00306         sigList[maxSigs-20] = sig;
00307       }
00308     }
00309   
00310     public
00311     void clearSignature()
00312     {
00313       for (int i=0;i<maxSigs;i++)
00314         sigList[i] = 0;
00315       signature = 0;
00316     }
00317   
00318     public
00319     void clearSignature(long sig, boolean clear)
00320     {
00321       for (int i=0;i<maxSigs;i++) {
00322           if (sig == sigList[i])
00323           {
00324             sigList[i] = 0;
00325             break;
00326           }
00327       }
00328       if (clear) {
00329           signature = 0;
00330       }
00331     }
00332   
00333     public
00334     void setSignature(long sig)
00335     {
00336       if (signature == 0) {
00337           signature = sig;
00338       }
00339     }
00340   
00347     public 
00348     long getSignature(long sig)
00349     {
00350 //   find signature
00351       long retSig = 0;
00352       if (sig > 0)
00353       {
00354         for (int i=0;i<maxSigs;i++)
00355           if (sig == sigList[i])
00356           {
00357             retSig = sig;
00358             break;
00359           } 
00360       }
00361       return (retSig);
00362     }
00363     
00368     public 
00369     long getSignature() {
00370       return (signature);
00371     }
00372 
00377     public 
00378     long getNewSignature(boolean setSig) {
00379         long sig = System.currentTimeMillis();
00380         if (sig <= lastSig && lastSig != 0) {
00381             sig = lastSig++;
00382         }
00383         trace.log(BasicLevel.DEBUG,"Sig is "+sig+" last Sig was "+lastSig);        
00384         lastSig = sig;
00385         addSignature(sig);
00386         if (setSig) {
00387             signature = sig;
00388         }
00389         return sig;
00390     }
00391 
00392 
00393     public void close(ConnectionImpl ch) throws ResourceException {
00394         clearSignature(ch.key, true);
00395         signalEvent(ConnectionEvent.CONNECTION_CLOSED,ch,null);
00396     }
00397     
00398     /**********************************************************/
00400     /**********************************************************/
00401     public void begin() throws ResourceException {
00402         if (inLocalTransaction) 
00403             throw new ResourceException(
00404                 "The managedConnection is already in a LocalTransaction");
00405         try {
00406             inLocalTransaction = true;
00407             connection.setAutoCommit(false);
00408         } catch (Exception ex) {
00409         }
00410     }
00411     
00412     public void commit() throws ResourceException {
00413         try {
00414             connection.commit();
00415             connection.setAutoCommit(true);
00416             inLocalTransaction = false;
00417         } catch (Exception ex) {
00418         }
00419     }
00420     
00421     public void rollback() throws ResourceException {
00422         try {
00423             connection.rollback();
00424             connection.setAutoCommit(true);
00425             inLocalTransaction = false;
00426         } catch (Exception ex) {
00427         }
00428     }
00429         
00430 }

Generated on Tue Feb 15 15:05:16 2005 for JOnAS by  doxygen 1.3.9.1