1 25 package org.objectweb.jonas.jdbc; 26 27 import java.io.PrintWriter ; 28 import java.sql.DriverManager ; 29 import java.util.HashSet ; 30 import java.util.Iterator ; 31 32 import javax.resource.ResourceException ; 33 import javax.resource.spi.ConnectionEvent ; 34 import javax.resource.spi.ConnectionEventListener ; 35 import javax.resource.spi.ConnectionRequestInfo ; 36 import javax.resource.spi.LocalTransaction ; 37 import javax.resource.spi.ManagedConnection ; 38 import javax.resource.spi.ManagedConnectionMetaData ; 39 import javax.resource.spi.security.PasswordCredential ; 40 import javax.security.auth.Subject ; 41 import javax.sql.DataSource ; 42 import javax.sql.PooledConnection ; 43 import javax.sql.XAConnection ; 44 import javax.transaction.xa.XAResource ; 45 46 import org.objectweb.util.monolog.api.BasicLevel; 47 import org.objectweb.util.monolog.api.Logger; 48 49 52 public class ManagedConnectionImpl implements ManagedConnection , javax.resource.spi.LocalTransaction { 53 54 public Logger trace = null; 55 56 protected PrintWriter out = null; 57 58 protected DataSource factory = null; 59 60 protected HashSet cels = null; 61 62 protected boolean inLocalTransaction = false; 63 64 ManagedConnectionFactoryImpl mcf = null; 65 66 java.sql.Connection connection = null; 67 68 PooledConnection poolCon = null; 69 70 XAConnection xaCon = null; 71 72 PasswordCredential pc = null; 73 74 DriverWrapper wrapper = null; 75 76 private XAResource 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 93 private final boolean isDebugOn; 94 95 public ManagedConnectionImpl(ManagedConnectionFactoryImpl _mcf, PasswordCredential _pc, java.sql.Connection _con, 96 PooledConnection _pcon, XAConnection _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 (); 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 ch, Exception ex) { 116 ConnectionEvent ce = null; 117 if (ex == null) { 118 ce = new ConnectionEvent (this, code); 119 } else { 120 ce = new ConnectionEvent (this, code, ex); 121 } 122 if (ch != null) { 123 ce.setConnectionHandle(ch); 124 } 125 for (Iterator it = cels.iterator(); it.hasNext();) { 126 switch (code) { 127 case ConnectionEvent.CONNECTION_CLOSED: 128 ((ConnectionEventListener ) it.next()).connectionClosed(ce); 129 break; 130 case ConnectionEvent.LOCAL_TRANSACTION_STARTED: 131 ((ConnectionEventListener ) it.next()).localTransactionStarted(ce); 132 break; 133 case ConnectionEvent.LOCAL_TRANSACTION_COMMITTED: 134 ((ConnectionEventListener ) it.next()).localTransactionCommitted(ce); 135 break; 136 case ConnectionEvent.LOCAL_TRANSACTION_ROLLEDBACK: 137 ((ConnectionEventListener ) it.next()).localTransactionRolledback(ce); 138 break; 139 case ConnectionEvent.CONNECTION_ERROR_OCCURRED: 140 ((ConnectionEventListener ) it.next()).connectionErrorOccurred(ce); 141 break; 142 default: 143 throw new IllegalArgumentException ("Illegal eventType: " + code); 144 } 145 } 146 } 147 148 public synchronized boolean getAutoCommit() throws ResourceException { 149 return isAutoCommit; 150 } 151 152 public synchronized void setAutoCommit(boolean ac) throws ResourceException { 153 isAutoCommit = ac; 154 try { 155 if (connection != null) { 156 connection.setAutoCommit(ac); 157 } 158 } catch (Exception e) { 159 throw new ResourceException (e.getMessage()); 160 } 161 } 162 163 166 public void addConnectionEventListener(ConnectionEventListener listener) { 167 cels.add(listener); 168 } 169 170 173 public synchronized void associateConnection(Object con) throws ResourceException { 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 ("The managedConnection cannot associate this connection: " + con); 183 } 184 } 185 186 189 public void cleanup() throws ResourceException { 190 if (inLocalTransaction) throw new ResourceException ("A local transaction is not complete"); 191 clearSignature(); 192 } 193 194 197 public synchronized void destroy() throws ResourceException { 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 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 e) { 212 trace.log(BasicLevel.ERROR, "", e, "ManagedConnectionImpl", "destroy"); 213 throw new ResourceException (e); 214 } 215 connection = null; 216 } 217 } 218 219 222 public Object getConnection(Subject subject, ConnectionRequestInfo cxRequestInfo) throws ResourceException { 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 e) { 232 trace.log(BasicLevel.ERROR, "", e, "ManagedConnectionImpl", "getConnection"); 233 throw new ResourceException (e.getMessage()); 234 } 235 } 236 237 240 public LocalTransaction getLocalTransaction() throws ResourceException { 241 return (LocalTransaction ) this; 242 } 243 244 247 public PrintWriter getLogWriter() { 248 return out; 249 } 250 251 255 public ManagedConnectionMetaData getMetaData() throws ResourceException { 256 return new MetaDataImpl(this); 257 } 258 259 262 public XAResource getXAResource() throws ResourceException { 263 if (isDebugOn) { 264 trace.log(BasicLevel.DEBUG, ""); 265 } 266 if (inLocalTransaction) 267 throw new ResourceException ( 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 ex) { 274 throw new ResourceException ("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 290 public void removeConnectionEventListener(ConnectionEventListener listener) { 291 cels.remove(listener); 292 } 293 294 297 public void setLogWriter(PrintWriter _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 349 public long getSignature(long sig) { 350 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 366 public long getSignature() { 367 return (signature); 368 } 369 370 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 { 391 clearSignature(ch.key, true); 392 signalEvent(ConnectionEvent.CONNECTION_CLOSED, ch, null); 393 } 394 395 396 397 398 public void begin() throws ResourceException { 399 if (inLocalTransaction) throw new ResourceException ("The managedConnection is already in a LocalTransaction"); 400 try { 401 inLocalTransaction = true; 402 connection.setAutoCommit(false); 403 } catch (Exception ex) { 404 } 405 } 406 407 public void commit() throws ResourceException { 408 try { 409 connection.commit(); 410 connection.setAutoCommit(true); 411 inLocalTransaction = false; 412 } catch (Exception ex) { 413 } 414 } 415 416 public void rollback() throws ResourceException { 417 try { 418 connection.rollback(); 419 connection.setAutoCommit(true); 420 inLocalTransaction = false; 421 } catch (Exception ex) { 422 } 423 } 424 425 } 426 | Popular Tags |