1 23 24 package org.objectweb.perseus.connector.ra.fos; 25 26 import org.objectweb.perseus.fos.api.FosAccess; 27 import org.objectweb.perseus.fos.api.FosException; 28 import org.objectweb.perseus.fos.api.FosLoggerFactory; 29 import org.objectweb.perseus.fos.api.FosStructure; 30 import org.objectweb.perseus.fos.api.FosTransaction; 31 import org.objectweb.perseus.fos.lib.FosTxContext; 32 import org.objectweb.util.monolog.api.BasicLevel; 33 import org.objectweb.util.monolog.api.Logger; 34 35 import java.io.PrintWriter ; 36 import java.util.ArrayList ; 37 import java.util.Iterator ; 38 import javax.resource.ResourceException ; 39 import javax.resource.spi.ConnectionEvent ; 40 import javax.resource.spi.ConnectionEventListener ; 41 import javax.resource.spi.ConnectionRequestInfo ; 42 import javax.resource.spi.LocalTransaction ; 43 import javax.resource.spi.ManagedConnection ; 44 import javax.resource.spi.ManagedConnectionMetaData ; 45 import javax.security.auth.Subject ; 46 import javax.transaction.xa.XAResource ; 47 48 51 public class FosManagedConnection 52 implements ManagedConnection , LocalTransaction , 53 javax.resource.cci.LocalTransaction { 54 private static final ArrayList NOLISTENERS = new ArrayList (); 55 58 private Logger logger; 59 63 private FosManagedConnectionFactory managedConnectionFactory; 64 68 private ArrayList associatedConnections = new ArrayList (1); 69 72 private ArrayList associatedListeners; 73 76 private FosTxContext localTransactionTxContext; 77 80 private FosXAResource xaResource; 81 86 private boolean autoCommit; 87 88 95 FosManagedConnection(Logger el, FosManagedConnectionFactory fmcf) { 96 logger = el; 97 if (FosLoggerFactory.DEBUG) 98 logger.log(BasicLevel.DEBUG, 99 "Constructs a new FosManagedConnection"); 100 managedConnectionFactory = fmcf; 101 associatedListeners = NOLISTENERS; 102 try { 103 cleanup(); 104 } catch (ResourceException re) { 105 } 107 } 108 109 114 synchronized void dissociateConnection(Object conn) throws ResourceException { 115 if (FosLoggerFactory.DEBUG) 116 logger.log(BasicLevel.DEBUG, "Dissociates Connection: " + conn); 117 int ind = associatedConnections.indexOf(conn); 118 if (FosLoggerFactory.DEBUG) 119 logger.log(BasicLevel.DEBUG, "Index within the associatedConnections: " + ind); 120 if (ind == -1) 121 throw new ResourceException ("FOS: cannot dissociate an unknown Connection."); 122 ConnectionEvent ce = new ConnectionEvent (this, 123 ConnectionEvent.CONNECTION_CLOSED); 124 ce.setConnectionHandle(conn); 125 for (Iterator it = associatedListeners.iterator(); it.hasNext();) 126 ((ConnectionEventListener ) it.next()).connectionClosed(ce); 127 associatedConnections.remove(ind); 128 if (associatedConnections.size() == 0) 129 cleanup(); 130 } 131 132 135 public synchronized void setAutoCommit(boolean b) throws ResourceException { 136 autoCommit = b; 137 } 138 139 142 public boolean getAutoCommit() throws ResourceException { 143 return autoCommit; 144 } 145 146 148 152 public Object getConnection(Subject subject, ConnectionRequestInfo info) 153 throws ResourceException { 154 FosConnectionImpl rac = ((FosConnectionFactory) managedConnectionFactory.getConnectionFactory()).createConnection(); 155 rac.initialize(this); 156 return rac; 157 } 158 159 162 public void cleanup() throws ResourceException { 163 if (FosLoggerFactory.DEBUG) 164 logger.log(BasicLevel.DEBUG, "Cleans up ManagedConnection"); 165 int clsize = associatedConnections.size(); 166 if (clsize != 0) { 167 while (clsize-- > 0) 168 associatedConnections.remove(0); 169 logger.log(BasicLevel.WARN, "Fos ManagedConnection still has associated Fos Connections (" + clsize + ")!"); 170 } 171 if (associatedListeners != NOLISTENERS) { 172 clsize = associatedListeners.size(); 173 if (clsize != 0) { 174 while (clsize-- > 0) 175 associatedListeners.remove(0); 176 logger.log(BasicLevel.WARN, "Fos ManagedConnection still has associated Listeners (" + clsize + ")!"); 177 } 178 } 179 localTransactionTxContext = null; 180 if (xaResource != null) { 181 managedConnectionFactory.getXAResourceFactory().releaseXAResource(xaResource); 182 xaResource = null; 183 } 184 autoCommit = true; 185 } 186 187 190 public void destroy() throws ResourceException { 191 cleanup(); 192 logger = null; 193 managedConnectionFactory = null; 194 associatedConnections = null; 195 associatedListeners = null; 196 localTransactionTxContext = null; 197 xaResource = null; 198 } 199 200 204 public synchronized void associateConnection(Object o) throws ResourceException { 205 if (FosLoggerFactory.DEBUG) 206 logger.log(BasicLevel.DEBUG, "Associates Connection: " + o); 207 if (!associatedConnections.contains(o)) 208 associatedConnections.add(o); 209 else 210 logger.log(BasicLevel.WARN, "Connection: " + o 211 + "has already been associated: ignored!"); 212 } 213 214 219 public synchronized void addConnectionEventListener( 220 ConnectionEventListener listener) { 221 if (associatedListeners == NOLISTENERS) 222 associatedListeners = new ArrayList (); 223 if (FosLoggerFactory.DEBUG) 224 logger.log(BasicLevel.DEBUG, "Associates ConnectionEventListener: " 225 + listener); 226 if (!associatedListeners.contains(listener)) 227 associatedListeners.add(listener); 228 else 229 logger.log(BasicLevel.WARN, "ConnectionEventListener: " + listener 230 + "has already been associated: ignored!"); 231 } 232 233 238 public synchronized void removeConnectionEventListener( 239 ConnectionEventListener listener) { 240 if (associatedListeners == NOLISTENERS) 241 logger.log(BasicLevel.WARN, 242 "No associated ConnectionEventListener: ignored!"); 243 int ind = associatedListeners.indexOf(listener); 244 if (FosLoggerFactory.DEBUG) 245 logger.log(BasicLevel.DEBUG, 246 "Index within the associatedListeners: " + ind); 247 if (ind == -1) 248 logger.log(BasicLevel.WARN, "ConnectionEventListener" + listener 249 + "not associated here: ignored!"); 250 else 251 associatedListeners.remove(ind); 252 } 253 254 257 public synchronized XAResource getXAResource() throws ResourceException { 258 try { 259 if (localTransactionTxContext != null) 260 throw new ResourceException ( 261 "Try switching to XA running mode while a LocalTransaction has been begun!"); 262 if (xaResource == null) { 263 xaResource = managedConnectionFactory.getXAResourceFactory().createXAResource(); 264 if (FosLoggerFactory.DEBUG) 265 logger.log(BasicLevel.DEBUG, "Creates a new XAResource: " + xaResource); 266 } 267 return xaResource; 268 } catch (FosException fe) { 269 ResourceException re = new ResourceException ("FOS: [nested exception]."); 270 re.setLinkedException(fe); 271 throw re; 272 } 273 } 274 275 public LocalTransaction getLocalTransaction() throws ResourceException { 276 return this; 277 } 278 279 public ManagedConnectionMetaData getMetaData() throws ResourceException { 280 return null; 281 } 282 283 286 public void setLogWriter(PrintWriter writer) throws ResourceException { 287 throw new ResourceException ("FOS: logging to PrintWriter not supported yet."); 288 } 289 290 293 public PrintWriter getLogWriter() throws ResourceException { 294 throw new ResourceException ("FOS: logging to PrintWriter not supported yet."); 295 } 296 297 299 302 public synchronized void begin() throws ResourceException { 303 if (localTransactionTxContext != null) 304 throw new ResourceException ("FOS: a LocalTransaction has already begun."); 305 try { 306 localTransactionTxContext 307 = (FosTxContext) managedConnectionFactory.getTxContextFactory() 308 .createTxContext(); 309 localTransactionTxContext.begin(); 310 if (FosLoggerFactory.DEBUG) 311 logger.log(BasicLevel.DEBUG, "LocalTransaction begin - txContext: " 312 + localTransactionTxContext); 313 if (xaResource != null) 314 logger.log(BasicLevel.WARN, 315 "Begins a LocalTransaction on a ManagedConnection that runs in XA mode!"); 316 ConnectionEvent ce = new ConnectionEvent (this, 317 ConnectionEvent.LOCAL_TRANSACTION_STARTED); 318 for (Iterator it = associatedListeners.iterator(); it.hasNext();) 319 ((ConnectionEventListener ) it.next()).localTransactionStarted(ce); 320 } catch (FosException fe) { 321 ResourceException re = new ResourceException ( 322 "FOS: cannot begin LocalTransaction [nested exception]."); 323 re.setLinkedException(fe); 324 throw re; 325 } 326 } 327 328 331 public synchronized void commit() throws ResourceException { 332 if (localTransactionTxContext == null) 333 throw new ResourceException ("FOS: no LocalTransaction has been begun."); 334 if (FosLoggerFactory.DEBUG) 335 logger.log(BasicLevel.DEBUG, "LocalTransaction commit - txContext: " 336 + localTransactionTxContext); 337 try { 338 localTransactionTxContext.commit(); 339 managedConnectionFactory.getTxContextFactory().releaseTxContext(localTransactionTxContext); 340 localTransactionTxContext = null; 341 ConnectionEvent ce = new ConnectionEvent (this, 342 ConnectionEvent.LOCAL_TRANSACTION_COMMITTED); 343 for (Iterator it = associatedListeners.iterator(); it.hasNext();) 344 ((ConnectionEventListener ) it.next()).localTransactionCommitted(ce); 345 } catch (FosException fe) { 346 ResourceException re = new ResourceException ( 347 "FOS: cannot commit LocalTransaction [nested exception]."); 348 re.setLinkedException(fe); 349 throw re; 350 } 351 } 352 353 356 public synchronized void rollback() throws ResourceException { 357 if (localTransactionTxContext == null) 358 throw new ResourceException ("FOS: no LocalTransaction has been begun."); 359 if (FosLoggerFactory.DEBUG) 360 logger.log(BasicLevel.DEBUG, "LocalTransaction rollback - txContext: " 361 + localTransactionTxContext); 362 try { 363 localTransactionTxContext.rollback(); 364 managedConnectionFactory.getTxContextFactory().releaseTxContext(localTransactionTxContext); 365 localTransactionTxContext = null; 366 ConnectionEvent ce = new ConnectionEvent (this, 367 ConnectionEvent.LOCAL_TRANSACTION_ROLLEDBACK); 368 for (Iterator it = associatedListeners.iterator(); it.hasNext();) 369 ((ConnectionEventListener ) it.next()).localTransactionRolledback(ce); 370 } catch (FosException fe) { 371 ResourceException re = new ResourceException ( 372 "FOS: cannot rollback LocalTransaction [nested exception]."); 373 re.setLinkedException(fe); 374 throw re; 375 } 376 } 377 378 380 389 public synchronized void delete(String dirof, String id) throws FosException { 390 if (localTransactionTxContext != null) { 391 if (FosLoggerFactory.DEBUG) 392 logger.log(BasicLevel.DEBUG, "Performs DELETE under LocalTransaction mode."); 393 localTransactionTxContext.delete(dirof, id); 394 return; 395 } 396 if (xaResource != null) { 397 if (FosLoggerFactory.DEBUG) 398 logger.log(BasicLevel.DEBUG, "Performs DELETE under XA mode."); 399 xaResource.getTxContext().delete(dirof, id); 400 return; 401 } 402 if (!autoCommit) 403 throw new FosException( 404 "Auto-commit OFF: cannot perform FosAccess operation with no transaction context!"); 405 if (FosLoggerFactory.DEBUG) 407 logger.log(BasicLevel.DEBUG, "Performs DELETE under AUTO-COMMIT mode."); 408 FosTransaction txContext 409 = managedConnectionFactory.getTxContextFactory().createTxContext(); 410 txContext.begin(); 411 try { 412 txContext.delete(dirof, id); 413 txContext.commit(); 414 managedConnectionFactory.getTxContextFactory().releaseTxContext(txContext); 415 } catch (FosException fe) { 416 txContext.rollback(); 417 managedConnectionFactory.getTxContextFactory().releaseTxContext(txContext); 418 throw new FosException("Problem while running in auto-commit mode.", fe); 419 } 420 } 421 422 427 public void deleteDir(String dirof) throws FosException { 428 FosTransaction txContext 429 = managedConnectionFactory.getTxContextFactory().createTxContext(); 430 try { 431 txContext.deleteDir(dirof); 432 managedConnectionFactory.getTxContextFactory().releaseTxContext(txContext); 433 } catch (FosException fe) { 434 managedConnectionFactory.getTxContextFactory().releaseTxContext(txContext); 435 throw fe; 436 } 437 } 438 439 448 public synchronized boolean exist(String dirof, String id) throws FosException { 449 if (localTransactionTxContext != null) { 450 if (FosLoggerFactory.DEBUG) 451 logger.log(BasicLevel.DEBUG, "Performs EXIST under LocalTransaction mode."); 452 return localTransactionTxContext.exist(dirof, id); 453 } 454 if (xaResource != null) { 455 if (FosLoggerFactory.DEBUG) 456 logger.log(BasicLevel.DEBUG, "Performs EXIST under XA mode."); 457 return xaResource.getTxContext().exist(dirof, id); 458 } 459 if (!autoCommit) 460 throw new FosException( 461 "Auto-commit OFF: cannot perform FosAccess operation with no transaction context!"); 462 if (FosLoggerFactory.DEBUG) 464 logger.log(BasicLevel.DEBUG, "Performs EXIST under AUTO-COMMIT mode."); 465 FosTransaction txContext 466 = managedConnectionFactory.getTxContextFactory().createTxContext(); 467 txContext.begin(); 468 try { 469 boolean res = txContext.exist(dirof, id); 470 txContext.commit(); 471 managedConnectionFactory.getTxContextFactory().releaseTxContext(txContext); 472 return res; 473 } catch (FosException fe) { 474 txContext.rollback(); 475 managedConnectionFactory.getTxContextFactory().releaseTxContext(txContext); 476 throw new FosException("Problem while running in auto-commit mode.", fe); 477 } 478 } 479 480 485 public boolean existDir(String dirof) throws FosException { 486 FosTransaction txContext 487 = managedConnectionFactory.getTxContextFactory().createTxContext(); 488 try { 489 boolean res = txContext.existDir(dirof); 490 managedConnectionFactory.getTxContextFactory().releaseTxContext(txContext); 491 return res; 492 } catch (FosException fe) { 493 managedConnectionFactory.getTxContextFactory().releaseTxContext(txContext); 494 throw fe; 495 } 496 } 497 498 508 public synchronized void read(String dirof, String id, FosStructure fs, 509 FosAccess conn, Object ctxt) 510 throws FosException { 511 if (localTransactionTxContext != null) { 512 if (FosLoggerFactory.DEBUG) 513 logger.log(BasicLevel.DEBUG, "Performs READ under LocalTransaction mode."); 514 localTransactionTxContext.read(dirof, id, fs, conn, ctxt); 515 return; 516 } 517 if (xaResource != null) { 518 if (FosLoggerFactory.DEBUG) 519 logger.log(BasicLevel.DEBUG, "Performs READ under XA mode."); 520 xaResource.getTxContext().read(dirof, id, fs, conn, ctxt); 521 return; 522 } 523 if (!autoCommit) 524 throw new FosException( 525 "Auto-commit OFF: cannot perform FosAccess operation with no transaction context!"); 526 if (FosLoggerFactory.DEBUG) 528 logger.log(BasicLevel.DEBUG, "Performs READ under AUTO-COMMIT mode."); 529 FosTxContext txContext 530 = (FosTxContext) managedConnectionFactory.getTxContextFactory() 531 .createTxContext(); 532 txContext.begin(); 533 try { 534 txContext.read(dirof, id, fs, conn, ctxt); 535 txContext.commit(); 536 managedConnectionFactory.getTxContextFactory().releaseTxContext(txContext); 537 } catch (FosException fe) { 538 txContext.rollback(); 539 managedConnectionFactory.getTxContextFactory().releaseTxContext(txContext); 540 throw new FosException("Problem while running in auto-commit mode.", fe); 541 } 542 } 543 544 551 public synchronized Iterator scan(String dirof) throws FosException { 552 if (localTransactionTxContext != null) { 553 if (FosLoggerFactory.DEBUG) 554 logger.log(BasicLevel.DEBUG, "Performs SCAN under LocalTransaction mode."); 555 return localTransactionTxContext.scan(dirof); 556 } 557 if (xaResource != null) { 558 if (FosLoggerFactory.DEBUG) 559 logger.log(BasicLevel.DEBUG, "Performs SCAN under XA mode."); 560 return xaResource.getTxContext().scan(dirof); 561 } 562 if (!autoCommit) 563 throw new FosException( 564 "Auto-commit OFF: cannot perform FosAccess operation with no transaction context!"); 565 if (FosLoggerFactory.DEBUG) 567 logger.log(BasicLevel.DEBUG, "Performs SCAN under AUTO-COMMIT mode."); 568 FosTransaction txContext 569 = managedConnectionFactory.getTxContextFactory().createTxContext(); 570 txContext.begin(); 571 try { 572 Iterator res = txContext.scan(dirof); 573 txContext.commit(); 574 managedConnectionFactory.getTxContextFactory().releaseTxContext(txContext); 575 return res; 576 } catch (FosException fe) { 577 txContext.rollback(); 578 managedConnectionFactory.getTxContextFactory().releaseTxContext(txContext); 579 throw new FosException("Problem while running in auto-commit mode.", fe); 580 } 581 } 582 583 594 public synchronized void write(String dirof, String id, FosStructure fs, 595 FosAccess conn, Object ctxt) 596 throws FosException { 597 if (localTransactionTxContext != null) { 598 if (FosLoggerFactory.DEBUG) 599 logger.log(BasicLevel.DEBUG, "Performs WRITE under LocalTransaction mode."); 600 localTransactionTxContext.write(dirof, id, fs, conn, ctxt); 601 return; 602 } 603 if (xaResource != null) { 604 if (FosLoggerFactory.DEBUG) 605 logger.log(BasicLevel.DEBUG, "Performs WRITE under XA mode."); 606 xaResource.getTxContext().write(dirof, id, fs, conn, ctxt); 607 return; 608 } 609 if (!autoCommit) 610 throw new FosException( 611 "Auto-commit OFF: cannot perform FosAccess operation with no transaction context!"); 612 if (FosLoggerFactory.DEBUG) 614 logger.log(BasicLevel.DEBUG, "Performs WRITE under AUTO-COMMIT mode."); 615 FosTxContext txContext 616 = (FosTxContext) managedConnectionFactory.getTxContextFactory() 617 .createTxContext(); 618 txContext.begin(); 619 try { 620 txContext.write(dirof, id, fs, conn, ctxt); 621 txContext.commit(); 622 managedConnectionFactory.getTxContextFactory().releaseTxContext(txContext); 623 } catch (FosException fe) { 624 txContext.rollback(); 625 managedConnectionFactory.getTxContextFactory().releaseTxContext(txContext); 626 throw new FosException("Problem while running in auto-commit mode.", fe); 627 } 628 } 629 } | Popular Tags |