Index: 3rdParty_sources/ironjacamar/org/jboss/jca/Version.java.in =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/Version.java.in (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/Version.java.in (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,55 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca; + +/** + * The version class + * @author Jesper Pedersen + */ +public class Version +{ + /** The project */ + public static final String PROJECT = "WildFly/IronJacamar"; + + /** The version */ + public static final String VERSION = "@VERSION@"; + + /** Full version */ + public static final String FULL_VERSION = PROJECT + " " + VERSION; + + /** + * Constructor + */ + private Version() + { + } + + /** + * Main + * @param args The arguments + */ + public static void main(String[] args) + { + System.out.println(FULL_VERSION); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/CoreBundle.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/CoreBundle.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/CoreBundle.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,632 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core; + +import org.jboss.logging.annotations.Message; +import org.jboss.logging.annotations.MessageBundle; + +/** + * The core bundle. + * + * Message ids ranging from 000000 to 009999 inclusively. + */ +@MessageBundle(projectCode = "IJ") +public interface CoreBundle +{ + + // CACHED CONNECTION MANAGER (100) + + /** + * Some connections were not closed + * @return The value + */ + @Message(id = 151, value = "Some connections were not closed, see the log for the allocation stacktraces") + public String someConnectionsWereNotClosed(); + + /** + * Trying to return an unknown connection + * @param connection The connection + * @return The value + */ + @Message(id = 152, value = "Trying to return an unknown connection: %s") + public String tryingToReturnUnknownConnection(String connection); + + // WORK MANAGER (200) + + /** + * SecurityContext setup failed + * @param message The throwable description + * @return The value + */ + @Message(id = 251, value = "SecurityContext setup failed: %s") + public String securityContextSetupFailed(String message); + + /** + * SecurityContext setup failed since CallbackSecurity was null + * @return The value + */ + @Message(id = 252, value = "SecurityContext setup failed since CallbackSecurity was null") + public String securityContextSetupFailedSinceCallbackSecurityWasNull(); + + /** + * Work is null + * @return The value + */ + @Message(id = 253, value = "Work is null") + public String workIsNull(); + + /** + * StartTimeout is negative + * @param startTimeout timeout of start + * @return The value + */ + @Message(id = 254, value = "StartTimeout is negative: %s") + public String startTimeoutIsNegative(long startTimeout); + + /** + * Interrupted while requesting permit + * @return The value + */ + @Message(id = 255, value = "Interrupted while requesting permit") + public String interruptedWhileRequestingPermit(); + + /** + * Work execution context must be null because work instance implements WorkContextProvider + * @return The value + */ + @Message(id = 256, value = "Work execution context must be null because " + + "work instance implements WorkContextProvider") + public String workExecutionContextMustNullImplementsWorkContextProvider(); + + /** + * Run method is synchronized + * @param classname class name of work + * @return The value + */ + @Message(id = 257, value = "%s: Run method is synchronized") + public String runMethodIsSynchronized(String classname); + + /** + * Release method is synchronized + * @param classname class name of work + * @return The value + */ + @Message(id = 258, value = "%s: Release method is synchronized") + public String releaseMethodIsSynchronized(String classname); + + /** + * Unsupported WorkContext class + * @param classname class name of work + * @return The value + */ + @Message(id = 259, value = "Unsupported WorkContext class: %s") + public String unsupportedWorkContextClass(String classname); + + /** + * Duplicate TransactionWorkContext class + * @param classname class name of work + * @return The value + */ + @Message(id = 260, value = "Duplicate TransactionWorkContext class: %s") + public String duplicateTransactionWorkContextClass(String classname); + + /** + * Duplicate SecurityWorkContext class + * @param classname class name of work + * @return The value + */ + @Message(id = 261, value = "Duplicate SecurityWorkContext class: %s") + public String duplicateSecurityWorkContextClass(String classname); + + /** + * Duplicate HintWorkContext class + * @param classname class name of work + * @return The value + */ + @Message(id = 262, value = "Duplicate HintWorkContext class: %s") + public String duplicateHintWorkContextClass(String classname); + + /** + * WorkManager shutdown + * @return The value + */ + @Message(id = 263, value = "WorkManager is shutting down") + public String workmanagerShutdown(); + + /** + * SecurityContext setup failed since CallbackSecurity::Domain was empty + * @return The value + */ + @Message(id = 264, value = "SecurityContext setup failed since CallbackSecurity::Domain was empty") + public String securityContextSetupFailedSinceCallbackSecurityDomainWasEmpty(); + + /** + * ResourceAdapterAssociation failed + * @param clz The class name + * @return The value + */ + @Message(id = 265, value = "ResourceAdapterAssociation failed for %s") + public String resourceAdapterAssociationFailed(String clz); + + /** + * Invalid number of parameters + * @param number The number + * @param c The command + * @return The value + */ + @Message(id = 266, value = "Invalid number of parameters %d (%s)") + public String invalidNumberOfParameters(int number, String c); + + // CONNECTION MANAGER LISTENER (300) + + /** + * Not correct type in class cast + * @param classname class name of work + * @return The value + */ + @Message(id = 351, value = "Not correct type: %s") + public String notCorrectTypeWhenClassCast(String classname); + + /** + * Failure to delist resource + * @param obj listener instance + * @return The value + */ + @Message(id = 352, value = "Failure to delist resource: %s") + public String failureDelistResource(Object obj); + + /** + * Error in delist + * @return The value + */ + @Message(id = 353, value = "Error in delist") + public String errorInDelist(); + + /** + * Unfinished local transaction - error getting local transaction from + * @param obj listener instance + * @return The value + */ + @Message(id = 354, value = "Unfinished local transaction - error getting local transaction from %s") + public String unfinishedLocalTransaction(Object obj); + + /** + * Unfinished local transaction but managed connection does not provide a local transaction + * @param obj listener instance + * @return The value + */ + @Message(id = 355, value = "Unfinished local transaction but managed connection does not " + + "provide a local transaction: %s") + public String unfinishedLocalTransactionNotProvideLocalTransaction(Object obj); + + /** + * System exception when failedToEnlist equals currentTx + * @param throwable throwable instance + * @param currentTx current transaction instance + * @return The value + */ + @Message(id = 356, value = "Failed to enlist: %s tx=%s") + public String systemExceptionWhenFailedToEnlistEqualsCurrentTx(Object throwable, Object currentTx); + + /** + * Error in dissociate + * @return The value + */ + @Message(id = 357, value = "Error in dissociate") + public String errorInDissociate(); + + // CONNECTION MANAGER (400) + + /** + * The connection manager is shutdown + * @param jndiName jndi name + * @return The value + */ + @Message(id = 451, value = "The connection manager is shutdown: %s") + public String connectionManagerIsShutdown(String jndiName); + + /** + * Method getManagedConnection retry wait was interrupted + * @param jndiName jndi name + * @return The value + */ + @Message(id = 452, value = "Method getManagedConnection retry wait was interrupted: %s") + public String getManagedConnectionRetryWaitInterrupted(String jndiName); + + /** + * Unable to get managed connection for + * @param jndiName jndi name + * @return The value + */ + @Message(id = 453, value = "Unable to get managed connection for %s") + public String unableGetManagedConnection(String jndiName); + + /** + * You are trying to use a connection factory that has been shut down ManagedConnectionFactory is null + * @return The value + */ + @Message(id = 454, value = "You are trying to use a connection factory that has been shut down: " + + "ManagedConnectionFactory is null") + public String tryingUseConnectionFactoryShutDown(); + + /** + * Wrong ManagedConnectionFactory sent to allocateConnection + * @param pool The ManagedConnectionFactory used for the pool + * @param mcf The ManagedConnectionFactory passed in + * @return The value + */ + @Message(id = 455, value = "Wrong ManagedConnectionFactory sent to allocateConnection (Pool=%s, MCF=%s)") + public String wrongManagedConnectionFactorySentToAllocateConnection(Object pool, Object mcf); + + /** + * Unchecked throwable in ManagedConnection.getConnection() + * @param obj ConnectionListener instance + * @return The value + */ + @Message(id = 456, value = "Unchecked throwable in ManagedConnection.getConnection() cl=%s") + public String uncheckedThrowableInManagedConnectionGetConnection(Object obj); + + /** + * Unchecked throwable in managedConnectionReconnected() + * @param obj ConnectionListener instance + * @return The value + */ + @Message(id = 457, value = "Unchecked throwable in managedConnectionReconnected() cl=%s") + public String uncheckedThrowableInManagedConnectionReconnected(Object obj); + + /** + * This method is not supported + * @return The value + */ + @Message(id = 458, value = "This method is not supported") + public String thisMethodNotSupported(); + + /** + * Transaction is not active + * @param obj transaction instance + * @return The value + */ + @Message(id = 459, value = "Transaction is not active: tx=%s") + public String transactionNotActive(Object obj); + + /** + * Error checking for a transaction. + * @return The value + */ + @Message(id = 460, value = "Error checking for a transaction") + public String errorCheckingForTransaction(); + + /** + * Could not enlist in transaction on entering meta-aware object + * @return The value + */ + @Message(id = 461, value = "Could not enlist in transaction on entering meta-aware object") + public String notEnlistInTransactionOnEnteringMetaAwareObject(); + + /** + * Could not delist resource, probably a transaction rollback + * @return The value + */ + @Message(id = 462, value = "Could not delist resource, probably a transaction rollback") + public String couldNotDelistResourceThenTransactionRollback(); + + /** + * Unable to set XAResource transaction timeout + * @param jndiName jndi name + * @return The value + */ + @Message(id = 463, value = "Unable to set XAResource transaction timeout: %s") + public String unableSetXAResourceTransactionTimeout(String jndiName); + + /** + * Unable to find connection listener + * @return The value + */ + @Message(id = 464, value = "Unable to find connection listener") + public String unableToFindConnectionListener(); + + /** + * Connection is null + * @return The value + */ + @Message(id = 465, value = "Connection is null") + public String connectionIsNull(); + + /** + * Enlistment not enabled + * @return The value + */ + @Message(id = 466, value = "Enlistment not enabled") + public String enlistmentNotEnabled(); + + /** + * Managed connection not lazy enlistable + * @param mc The managed connection + * @return The value + */ + @Message(id = 467, value = "Managed connection not lazy enlistable: %s") + public String managedConnectionNotLazyEnlistable(Object mc); + + /** + * Connection listener already enlisted + * @param cl The connection listener + * @return The value + */ + @Message(id = 468, value = "Connection listener already enlisted: %s") + public String connectionListenerAlreadyEnlisted(Object cl); + + /** + * Error during enlistment + * @return The value + */ + @Message(id = 469, value = "Error during enlistment") + public String errorDuringEnlistment(); + + /** + * You are trying to use a connection factory that has been shut down + * @param name The name + * @return The value + */ + @Message(id = 470, value = "You are trying to use a connection factory that has been shut down: %s") + public String tryingUseConnectionFactoryShutDown(String name); + + // TRANSACTION SYNCHRONIZER (500) + + // POOL MANAGER (600) + + /** + * Unable to get managed connection pool + * @return The value + */ + @Message(id = 651, value = "Unable to get managed connection pool") + public String unableGetManagedConnectionPool(); + + /** + * Unable to obtain lock + * @return The value + */ + @Message(id = 652, value = "Unable to obtain lock") + public String unableObtainLock(); + + /** + * The pool has been shutdown + * @param pool The pool + * @param mcp The managed connection pool + * @return The value + */ + @Message(id = 653, value = "The pool has been shutdown (%s,%s)") + public String thePoolHasBeenShutdown(String pool, String mcp); + + /** + * Interrupted while requesting connection + * @param end time of end + * @return The value + */ + @Message(id = 654, value = "Interrupted while requesting connection: Waited %s ms") + public String interruptedWhileRequestingConnection(long end); + + /** + * No ManagedConnections available within configured blocking timeout + * @param blockingTimeout timeout of blocking + * @return The value + */ + @Message(id = 655, value = "No managed connections available within configured blocking timeout (%s [ms])") + public String noMManagedConnectionsAvailableWithinConfiguredBlockingTimeout(long blockingTimeout); + + /** + * This should never happen + * @return The value + */ + @Message(id = 656, value = "This should never happen") + public String shouldNeverHappen(); + + /** + * Interrupted while requesting permit + * @param end time of end + * @return The value + */ + @Message(id = 657, value = "Interrupted while requesting permit: Waited %s ms") + public String interruptedWhileRequestingPermit(long end); + + /** + * Unexpected throwable while trying to create a connection: + * @param obj connection listener instance + * @return The value + */ + @Message(id = 658, value = "Unexpected throwable while trying to create a connection: %s") + public String unexpectedThrowableWhileTryingCreateConnection(Object obj); + + /** + * Unable to get connection listener + * @return The value + */ + @Message(id = 659, value = "Unable to get connection listener") + public String unableGetConnectionListener(); + + // NAMING (700) + + /** + * Deployment failed since jndi name is already deployed + * @param className class name + * @param jndiName jndi name + * @return The value + */ + @Message(id = 751, value = "Deployment %s failed, %s is already deployed") + public String deploymentFailedSinceJndiNameHasDeployed(String className, String jndiName); + + // RESOURCE ADPATER REPOSITORY (800) + + /** + * ResourceAdapter instance not active + * @return The value + */ + @Message(id = 851, value = "Resource adapter instance not active") + public String resourceAdapterInstanceNotActive(); + + /** + * Validation exception + * @return The value + */ + @Message(id = 852, value = "Validation exception") + public String validationException(); + + /** + * The activation spec class is no longer available + * @return The value + */ + @Message(id = 853, value = "The activation spec class is no longer available") + public String activationSpecClassNotAvailable(); + + /** + * The resource adapter is no longer available + * @return The value + */ + @Message(id = 854, value = "The resource adapter is no longer available") + public String resourceAdapterNotAvailable(); + + /** + * Key isn't registered + * @param key key name + * @return The value + */ + @Message(id = 855, value = "%s isn't registered") + public String keyNotRegistered(String key); + + /** + * Unable to lookup resource adapter in MDR + * @param uniqueId key name + * @return The value + */ + @Message(id = 856, value = "Unable to lookup resource adapter in MDR: %s") + public String unableLookupResourceAdapterInMDR(String uniqueId); + + // RECOVERY (900) + + /** + * Error during connection close + * @return The value + */ + @Message(id = 951, value = "Error during connection close") + public String errorDuringConnectionClose(); + + /** + * Error during recovery initialization + * @return The value + */ + @Message(id = 952, value = "Error during recovery initialization") + public String errorDuringRecoveryInitialization(); + + /** + * Error during recovery shutdown + * @return The value + */ + @Message(id = 953, value = "Error during recovery shutdown") + public String errorDuringRecoveryShutdown(); + + // SECURITY (1000) + + + // TRANSCATION (1100) + + /** + * Trying to start a new tx when old is not complete + * @param oldXid old xid + * @param newXid new xid + * @param flags flags + * @return The value + */ + @Message(id = 1151, value = "Trying to start a new transaction when old is not complete: Old: %s, New %s, Flags %s") + public String tryingStartNewTxWhenOldNotComplete(Object oldXid, Object newXid, int flags); + + /** + * Trying to start a new tx with wrong flags + * @param xid xid + * @param flags flags + * @return The value + */ + @Message(id = 1152, value = "Trying to start a new transaction with wrong flags: New %s, Flags %s") + public String tryingStartNewTxWithWrongFlags(Object xid, int flags); + + /** + * Error trying to start local tx + * @return The value + */ + @Message(id = 1153, value = "Error trying to start local transaction") + public String errorTryingStartLocalTx(); + + /** + * Throwable trying to start local transaction + * @return The value + */ + @Message(id = 1154, value = "Throwable trying to start local transaction") + public String throwableTryingStartLocalTx(); + + /** + * Wrong xid in commit + * @param currentXid current xid + * @param xid xid + * @return The value + */ + @Message(id = 1155, value = "Wrong xid in commit: Expected: %s, Got: %s") + public String wrongXidInCommit(Object currentXid, Object xid); + + /** + * Could not commit local tx + * @return The value + */ + @Message(id = 1156, value = "Could not commit local transaction") + public String couldNotCommitLocalTx(); + + /** + * Forget not supported in local tx + * @return The value + */ + @Message(id = 1157, value = "Forget not supported in local transaction") + public String forgetNotSupportedInLocalTx(); + + /** + * No recover with local-tx only resource managers + * @return The value + */ + @Message(id = 1158, value = "No recovery for LocalTransaction only resource manager") + public String noRecoverWithLocalTxResourceManagers(); + + /** + * Wrong xid in rollback + * @param currentXid current xid + * @param xid xid + * @return The value + */ + @Message(id = 1159, value = "Wrong xid in rollback: Expected: %s, Got: %s") + public String wrongXidInRollback(Object currentXid, Object xid); + + + /** + * Could not rollback local tx + * @return The value + */ + @Message(id = 1160, value = "Could not rollback local transaction") + public String couldNotRollbackLocalTx(); + + // METADATA REPOSITORY (1200) +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/CoreLogger.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/CoreLogger.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/CoreLogger.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,656 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core; + +import org.jboss.logging.BasicLogger; +import org.jboss.logging.annotations.Cause; +import org.jboss.logging.annotations.LogMessage; +import org.jboss.logging.annotations.Message; +import org.jboss.logging.annotations.MessageLogger; + +import static org.jboss.logging.Logger.Level.ERROR; +import static org.jboss.logging.Logger.Level.INFO; +import static org.jboss.logging.Logger.Level.WARN; + +/** + * The core logger. + * + * Message ids ranging from 000000 to 009999 inclusively. + */ +@MessageLogger(projectCode = "IJ") +public interface CoreLogger extends BasicLogger +{ + + // CACHED CONNECTION MANAGER (100) + + /** + * Closing connection + * @param handle The hande + */ + @LogMessage(level = INFO) + @Message(id = 100, value = "Closing a connection for you. Please close them yourself: %s") + public void closingConnection(Object handle); + + /** + * Closing connection + * @param handle The hande + * @param t The exception + */ + @LogMessage(level = INFO) + public void closingConnection(Object handle, @Cause Throwable t); + + /** + * Closing connection results in throwable + * @param t The exception + */ + @LogMessage(level = INFO) + @Message(id = 102, value = "Throwable trying to close a connection for you, please close it yourself") + public void closingConnectionThrowable(@Cause Throwable t); + + /** + * No close method for closing connection + * @param clz The class name + */ + @LogMessage(level = INFO) + @Message(id = 103, value = "Could not find a close method on alleged connection object (%s). " + + "Please close your own connections") + public void closingConnectionNoClose(String clz); + + + // WORK MANAGER (200) + + /** + * SecurityContext setup failed + * @param description throwable description + * @param t The exception + */ + @LogMessage(level = ERROR) + @Message(id = 201, value = "SecurityContext setup failed: %s") + public void securityContextSetupFailed(String description, @Cause Throwable t); + + /** + * SecurityContext setup failed since CallbackSecurity was null + */ + @LogMessage(level = ERROR) + @Message(id = 202, value = "SecurityContext setup failed since CallbackSecurity was null") + public void securityContextSetupFailedCallbackSecurityNull(); + + + // CONNECTION MANAGER LISTENER (300) + + /** + * Registered a null handle for managedConnection + * @param managedConnection The managedConnection instance + */ + @LogMessage(level = INFO) + @Message(id = 301, value = "Registered a null handle for managed connection: %s") + public void registeredNullHandleManagedConnection(Object managedConnection); + + /** + * Unregistered handle that was not registered + * @param handle Unregistered handle + * @param managedConnection The managedConnection instance + */ + @LogMessage(level = INFO) + @Message(id = 302, value = "Unregistered handle that was not registered: %s" + + " for managed connection: %s") + public void unregisteredHandleNotRegistered(Object handle, Object managedConnection); + + /** + * Unregistered a null handle for managedConnection + * @param managedConnection The managedConnection instance + */ + @LogMessage(level = INFO) + @Message(id = 303, value = "Unregistered a null handle for managed connection: %s") + public void unregisteredNullHandleManagedConnection(Object managedConnection); + + /** + * Connection error occured + * @param cl AbstractConnectionListener instance + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 305, value = "Connection error occured: %s") + public void connectionErrorOccured(Object cl, @Cause Throwable t); + + /** + * Unknown Connection error occured + * @param cl AbstractConnectionListener instance + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 306, value = "Unknown connection error occured: %s") + public void unknownConnectionErrorOccured(Object cl, @Cause Throwable t); + + /** + * Notified of error on a different managed connection + */ + @LogMessage(level = WARN) + @Message(id = 307, value = "Notified of error on a different managed connection") + public void notifiedErrorDifferentManagedConnection(); + + /** + * throwable from unregister connection + * @param t The exception + */ + @LogMessage(level = INFO) + @Message(id = 311, value = "Throwable from unregister connection") + public void throwableFromUnregisterConnection(@Cause Throwable t); + + /** + * Error while closing connection handle + * @param t The exception + */ + @LogMessage(level = ERROR) + @Message(id = 312, value = "Error while closing connection handle") + public void errorWhileClosingConnectionHandle(@Cause Throwable t); + + /** + * There is something wrong with the pooling + * @param t The exception + */ + @LogMessage(level = ERROR) + @Message(id = 313, value = "There is something wrong with the pooling") + public void somethingWrongWithPooling(@Cause Throwable t); + + /** + * Error during beforeCompletion + * @param cl AbstractConnectionListener instance + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 314, value = "Error during beforeCompletion: %s") + public void beforeCompletionErrorOccured(Object cl, @Cause Throwable t); + + /** + * Active handles + * @param pool The name of the pool + * @param number The number of active handles + */ + @LogMessage(level = ERROR) + @Message(id = 315, value = "Pool %s has %d active handles") + public void activeHandles(String pool, int number); + + /** + * Active handle + * @param handle The handle + * @param e The trace + */ + @LogMessage(level = ERROR) + @Message(id = 316, value = "Handle allocation: %s") + public void activeHandle(Object handle, @Cause Exception e); + + /** + * TxConnectionListener boundary + * @param e The trace + */ + @LogMessage(level = ERROR) + @Message(id = 317, value = "Transaction boundary") + public void txConnectionListenerBoundary(@Cause Exception e); + + /** + * TxConnectionListener delisting failed + * @param pool The name of the pool + * @param e The trace + */ + @LogMessage(level = ERROR) + @Message(id = 318, value = "Delisting resource in pool %s failed") + public void delistingFailed(String pool, @Cause Exception e); + + // CONNECTION MANAGER (400) + + /** + * Error during tidy up connection + * @param cl The ConnectionListener name + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 401, value = "Error during tidy up connection: %s") + public void errorDuringTidyUpConnection(Object cl, @Cause Throwable t); + + /** + * resourceException in returning connection + * @param mc The ManagedConnection name + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 402, value = "ResourceException in returning connection: %s") + public void resourceExceptionReturningConnection(Object mc, @Cause Throwable t); + + /** + * reconnecting a connection handle that still has a managedConnection + * @param mc The ManagedConnection name + * @param connection connection object + */ + @LogMessage(level = WARN) + @Message(id = 403, value = "Reconnecting a connection handle that still has a managed connection: %s %s") + public void reconnectingConnectionHandleHasManagedConnection(Object mc, Object connection); + + /** + * Unchecked throwable in managedConnectionDisconnected() + * @param cl The ConnectionListener name + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 404, value = "Unchecked throwable in managedConnectionDisconnected() cl=%s") + public void uncheckedThrowableInManagedConnectionDisconnected(Object cl, @Cause Throwable t); + + /** + * Multiple LocalTransaction connection listener enlisted + * @param name The pool name + * @param cl The ConnectionListener + */ + @LogMessage(level = WARN) + @Message(id = 405, value = "Multiple LocalTransaction connection listeners enlisted for %s, cl=%s") + public void multipleLocalTransactionConnectionListenerEnlisted(String name, Object cl); + + /** + * Throwable in returning connection + * @param mc The ManagedConnection name + * @param t The exception + */ + @LogMessage(level = ERROR) + @Message(id = 406, value = "Throwable in returning connection: %s") + public void throwableReturningConnection(Object mc, @Cause Throwable t); + + /** + * No lazy enlistment available + * @param pool The pool name + */ + @LogMessage(level = WARN) + @Message(id = 407, value = "No lazy enlistment available for %s") + public void noLazyEnlistmentAvailable(String pool); + + /** + * Deprecated pool + * @param oldPool The old pool name + * @param newPool The new pool name + */ + @LogMessage(level = WARN) + @Message(id = 408, value = "Deprecated pool: %s, using %s instead") + public void deprecatedPool(String oldPool, String newPool); + + // TRANSACTION SYNCHRONIZER (500) + + /** + * Thread is not the enlisting thread + * @param currentThread current thread + * @param enlistingThread enlisting thread + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 501, value = "Thread %s is not the enlisting thread %s") + public void threadIsnotEnlistingThread(Object currentThread, Object enlistingThread, @Cause Throwable t); + + /** + * Transaction error in before completion + * @param transaction transaction + * @param synch Synchronization + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 502, value = "Transaction %s error in beforeCompletion %s") + public void transactionErrorInBeforeCompletion(Object transaction, Object synch, @Cause Throwable t); + + /** + * Transaction error in after completion + * @param transaction transaction + * @param synch Synchronization + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 503, value = "Transaction %s error in afterCompletion %s") + public void transactionErrorInAfterCompletion(Object transaction, Object synch, @Cause Throwable t); + + /** + * Transaction not found + * @param transaction transaction + */ + @LogMessage(level = WARN) + @Message(id = 504, value = "Transaction not found: %s") + public void transactionNotFound(Object transaction); + + + // POOL MANAGER (600) + + /** + * ConnectionValidator has been interrupted + */ + @LogMessage(level = INFO) + @Message(id = 601, value = "ConnectionValidator has been interrupted") + public void returningConnectionValidatorInterrupted(); + + /** + * ConnectionValidator ignored unexpected runtime exception + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 602, value = "ConnectionValidator ignored unexpected runtime exception") + public void connectionValidatorIgnoredUnexpectedRuntimeException(@Cause Throwable t); + + /** + * ConnectionValidator ignored unexpected error + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 603, value = "ConnectionValidator ignored unexpected error") + public void connectionValidatorIgnoredUnexpectedError(@Cause Throwable t); + + /** + * Throwable while attempting to get a new connection + * @param cl The ConnectionListener + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 604, value = "Throwable while attempting to get a new connection: %s") + public void throwableWhileAttemptingGetNewGonnection(Object cl, @Cause Throwable t); + + /** + * Destroying connection that could not be successfully matched + * @param cl The ConnectionListener + * @param mcf managed connection factory + */ + @LogMessage(level = WARN) + @Message(id = 605, value = "Destroying connection that could not be successfully matched %s for %s") + public void destroyingConnectionNotSuccessfullyMatched(Object cl, Object mcf); + + /** + * Throwable while trying to match ManagedConnection, destroying connection + * @param cl The ConnectionListener + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 606, value = "Throwable while trying to match managed connection, destroying connection: %s") + public void throwableWhileTryingMatchManagedConnection(Object cl, @Cause Throwable t); + + /** + * ResourceException cleaning up ManagedConnection + * @param cl The ConnectionListener + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 607, value = "ResourceException cleaning up managed connection: %s") + public void resourceExceptionCleaningUpManagedConnection(Object cl, @Cause Throwable t); + + /** + * Destroying returned connection, maximum pool size exceeded + * @param cl The ConnectionListener + */ + @LogMessage(level = WARN) + @Message(id = 608, value = "Destroying returned connection, maximum pool size exceeded %s") + public void destroyingReturnedConnectionMaximumPoolSizeExceeded(Object cl); + + /** + * Attempt to return connection twice + * @param cl The ConnectionListener + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 609, value = "Attempt to return connection twice: %s") + public void attemptReturnConnectionTwice(Object cl, @Cause Throwable t); + + /** + * Unable to fill pool + * @param t The exception + * @param jndiName the jndi-name + */ + @LogMessage(level = WARN) + @Message(id = 610, value = "Unable to fill pool: %s") + public void unableFillPool(@Cause Throwable t, String jndiName); + + /** + * Background validation was specified with a non compliant ManagedConnectionFactory interface + */ + @LogMessage(level = WARN) + @Message(id = 611, value = "Warning: Background validation was specified with a non compliant " + + "ManagedConnectionFactory interface") + public void backgroundValidationNonCompliantManagedConnectionFactory(); + + /** + * Destroying connection that could not be successfully matched + * @param cl The ConnectionListener + */ + @LogMessage(level = WARN) + @Message(id = 612, value = "Destroying connection that could not be successfully matched: %s") + public void destroyingConnectionNotSuccessfullyMatched(Object cl); + + /** + * Throwable while trying to match ManagedConnection, destroying connection + * @param cl The ConnectionListener + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 613, value = "Throwable while trying to match managed connection, destroying connection: %s") + public void throwableWhileTryingMatchManagedConnectionThenDestroyingConnection(Object cl, @Cause Throwable t); + + /** + * Exception during createSubject() + * @param jndiName The jndi-name + * @param description throwable description + * @param t The exception + */ + @LogMessage(level = ERROR) + @Message(id = 614, value = "Exception during createSubject() for %s: %s") + public void exceptionDuringCreateSubject(String jndiName, String description, @Cause Throwable t); + + /** + * Going to destroy connection listener during shutdown + * @param poolName The pool name + * @param mc The managed connection + */ + @LogMessage(level = WARN) + @Message(id = 615, value = "Destroying active connection in pool: %s (%s)") + public void destroyingActiveConnection(String poolName, Object mc); + + /** + * Connection leak + * @param poolName The pool name + * @param id The connection listener id + * @param time The timestamp + * @param t The trace + */ + @LogMessage(level = ERROR) + @Message(id = 616, value = "Leak detected in pool: %s (%s) (%d)") + public void connectionLeak(String poolName, String id, long time, @Cause Throwable t); + + /** + * Invalid incrementer policy + * @param clz The class name + */ + @LogMessage(level = WARN) + @Message(id = 617, value = "Invalid incrementer capacity policy: %s") + public void invalidCapacityIncrementer(String clz); + + /** + * Invalid decrementer policy + * @param clz The class name + */ + @LogMessage(level = WARN) + @Message(id = 618, value = "Invalid decrementer capacity policy: %s") + public void invalidCapacityDecrementer(String clz); + + /** + * Invalid policy option + * @param key The property name + * @param value The property value + * @param policy The class name + */ + @LogMessage(level = WARN) + @Message(id = 619, value = "Invalid property '%s' with value '%s' for %s") + public void invalidCapacityOption(String key, String value, String policy); + + /** + * ValidateOnMatch was specified with a non compliant ManagedConnectionFactory interface + * @param mcf The ManagedConnectionFactory + */ + @LogMessage(level = WARN) + @Message(id = 620, value = "Warning: ValidateOnMatch validation was specified with a non compliant " + + "ManagedConnectionFactory: %s") + public void validateOnMatchNonCompliantManagedConnectionFactory(String mcf); + + /** + * Destroying connection that could not be validated + * @param cl The ConnectionListener + */ + @LogMessage(level = WARN) + @Message(id = 621, value = "Destroying connection that could not be validated: %s") + public void destroyingConnectionNotValidated(Object cl); + + /** + * Unsupported pool implementation + * @param clz The pool + */ + @LogMessage(level = WARN) + @Message(id = 622, value = "Unsupported pool implementation: %s") + public void unsupportedPoolImplementation(String clz); + + // NAMING (700) + + /** + * Exception during unbind + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 701, value = "Exception during unbind") + public void exceptionDuringUnbind(@Cause Throwable t); + + + // RESOURCE ADPATER REPOSITORY (800) + + + // RECOVERY (900) + + /** + * Error during connection close + * @param t The exception + */ + @LogMessage(level = WARN) + @Message(id = 901, value = "Error during connection close") + public void exceptionDuringConnectionClose(@Cause Throwable t); + + /** + * Error during inflow crash recovery + * @param rar The resource adapter class name + * @param as The activation spec + * @param t The exception + */ + @LogMessage(level = ERROR) + @Message(id = 902, value = "Error during inflow crash recovery for '%s' (%s)") + public void exceptionDuringCrashRecoveryInflow(String rar, Object as, @Cause Throwable t); + + /** + * Error creating Subject for crash recovery + * @param jndiName The JNDI name + * @param reason The reason + * @param t The exception + */ + @LogMessage(level = ERROR) + @Message(id = 903, value = "Error creating Subject for crash recovery: %s (%s)") + public void exceptionDuringCrashRecoverySubject(String jndiName, String reason, @Cause Throwable t); + + /** + * No security domain defined for crash recovery + * @param jndiName The JNDI name + */ + @LogMessage(level = WARN) + @Message(id = 904, value = "No security domain defined for crash recovery: %s") + public void noCrashRecoverySecurityDomain(String jndiName); + + /** + * Subject for crash recovery was null + * @param jndiName The JNDI name + */ + @LogMessage(level = WARN) + @Message(id = 905, value = "Subject for crash recovery was null: %s") + public void nullSubjectCrashRecovery(String jndiName); + + /** + * Error during crash recovery + * @param jndiName The JNDI name + * @param reason The reason + * @param t The exception + */ + @LogMessage(level = ERROR) + @Message(id = 906, value = "Error during crash recovery: %s (%s)") + public void exceptionDuringCrashRecovery(String jndiName, String reason, @Cause Throwable t); + + // SECURITY (1000) + + /** + * No users.properties were found + */ + @LogMessage(level = WARN) + @Message(id = 1001, value = "No users.properties were found") + public void noUsersPropertiesFound(); + + /** + * Error while loading users.properties + * @param t The exception + */ + @LogMessage(level = ERROR) + @Message(id = 1002, value = "Error while loading users.properties") + public void errorWhileLoadingUsersProperties(@Cause Throwable t); + + /** + * No roles.properties were found + */ + @LogMessage(level = WARN) + @Message(id = 1003, value = "No roles.properties were found") + public void noRolesPropertiesFound(); + + /** + * Error while loading roles.properties + * @param t The exception + */ + @LogMessage(level = ERROR) + @Message(id = 1004, value = "Error while loading roles.properties") + public void errorWhileLoadingRolesProperties(@Cause Throwable t); + + /** + * No callback.properties were found + */ + @LogMessage(level = WARN) + @Message(id = 1005, value = "No callback.properties were found") + public void noCallbackPropertiesFound(); + + /** + * Error while loading callback.properties + * @param t The exception + */ + @LogMessage(level = ERROR) + @Message(id = 1006, value = "Error while loading callback.properties") + public void errorWhileLoadingCallbackProperties(@Cause Throwable t); + + // TRANSCATION (1100) + + /** + * Prepare called on a local tx + */ + @LogMessage(level = WARN) + @Message(id = 1101, value = "Prepare called on a local tx. Use of local transactions on a JTA " + + "transaction with more than one branch may result in inconsistent data in some cases of failure") + public void prepareCalledOnLocaltx(); + + + // METADATA REPOSITORY (1200) +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/bootstrap/CloneableBootstrapContext.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/bootstrap/CloneableBootstrapContext.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/bootstrap/CloneableBootstrapContext.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,106 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.bootstrap; + +import org.jboss.jca.core.api.workmanager.WorkManager; + +import javax.resource.spi.BootstrapContext; +import javax.resource.spi.ResourceAdapter; +import javax.resource.spi.XATerminator; +import javax.transaction.TransactionSynchronizationRegistry; + +/** + * The cloneable bootstrap context interface which defines + * the contract for all BootstrapContext implementations + * @author Jesper Pedersen + */ +public interface CloneableBootstrapContext extends Cloneable, BootstrapContext +{ + /** + * Get the id of the bootstrap context + * @return The value + */ + public String getId(); + + /** + * Set the id of the bootstrap context + * @param v The value + */ + public void setId(String v); + + /** + * Get the name of the bootstrap context + * @return The value + */ + public String getName(); + + /** + * Set the resource adapter + * @param ra The handle + */ + public void setResourceAdapter(ResourceAdapter ra); + + /** + * Set the transaction synchronization registry + * @param tsr The handle + */ + public void setTransactionSynchronizationRegistry(TransactionSynchronizationRegistry tsr); + + /** + * Set the work manager - internal use only + * @param wm The handle + */ + public void setWorkManager(WorkManager wm); + + /** + * Get the name of the work manager + * @return The value + */ + public String getWorkManagerName(); + + /** + /** + * Set the name of the work manager + * @param wmn The name + */ + public void setWorkManagerName(String wmn); + + /** + * Set the XA terminator + * @param xt The handle + */ + public void setXATerminator(XATerminator xt); + + /** + * Shutdown + */ + public void shutdown(); + + /** + * Clone the BootstrapContext implementation + * @return A copy of the implementation + * @exception CloneNotSupportedException Thrown if the copy operation isn't supported + * + */ + public CloneableBootstrapContext clone() throws CloneNotSupportedException; +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/bootstrap/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/bootstrap/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/bootstrap/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +The API for the IronJacamar Core/Bootstrap module. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/ConnectionManager.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/ConnectionManager.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/ConnectionManager.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,80 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.connectionmanager; + +import org.jboss.jca.core.api.connectionmanager.listener.ConnectionListener; + +import javax.resource.ResourceException; +import javax.resource.spi.ConnectionRequestInfo; +import javax.resource.spi.LazyAssociatableConnectionManager; +import javax.resource.spi.LazyEnlistableConnectionManager; +import javax.resource.spi.ManagedConnection; +import javax.resource.spi.ManagedConnectionFactory; + +/** + * The JBoss specific connection manager interface. + * + * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +public interface ConnectionManager extends javax.resource.spi.ConnectionManager, + LazyAssociatableConnectionManager, + LazyEnlistableConnectionManager +{ + /** + * Associate a managed connection to a logical connection + * + * @param connection The connection + * @param mcf The managed connection factory + * @param cri The connection request information + * @return The managed connection + * @exception ResourceException Thrown if an error occurs + */ + public ManagedConnection associateManagedConnection(Object connection, ManagedConnectionFactory mcf, + ConnectionRequestInfo cri) + throws ResourceException; + + /** + * Dissociate a managed connection from a logical connection. The return value + * of this method will indicate if the managed connection has more connections + * attached (false), or if it was return to the pool (true). + * + * If the managed connection is return to the pool its cleanup method + * will be called + * + * @param connection The connection + * @param mc The managed connection + * @param mcf The managed connection factory + * @return True if the managed connection was freed; otherwise false + * @exception ResourceException Thrown if an error occurs + */ + public boolean dissociateManagedConnection(Object connection, ManagedConnection mc, ManagedConnectionFactory mcf) + throws ResourceException; + + /** + * Kill given connection listener wrapped connection instance. + * @param cl connection listener that wraps connection + * @param kill kill connection or not + */ + public void returnManagedConnection(ConnectionListener cl, boolean kill); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/ccm/CachedConnectionManager.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/ccm/CachedConnectionManager.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/ccm/CachedConnectionManager.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,123 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.api.connectionmanager.ccm; + +import org.jboss.jca.core.api.connectionmanager.listener.ConnectionCacheListener; +import org.jboss.jca.core.api.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.spi.connectionmanager.ComponentStack; +import org.jboss.jca.core.spi.transaction.usertx.UserTransactionListener; + +import java.util.Map; + +import javax.transaction.TransactionManager; + +/** + * CacheConnectionManager. + * + * @author Jesper Pedersen + */ +public interface CachedConnectionManager extends UserTransactionListener, ComponentStack +{ + /** + * Gets transaction manager. + * @return transaction manager + */ + public TransactionManager getTransactionManager(); + + /** + * Is debug enabled + * @return True if enabled; otherwise false + */ + public boolean isDebug(); + + /** + * Set debug flag + * @param v The value + */ + public void setDebug(boolean v); + + /** + * Is error enabled + * @return True if enabled; otherwise false + */ + public boolean isError(); + + /** + * Set error flag + * @param v The value + */ + public void setError(boolean v); + + /** + * Is ignore unknown connections on close enabled + * @return True if enabled; otherwise false + */ + public boolean isIgnoreUnknownConnections(); + + /** + * Set ignore unknown connections flag + * @param v The value + */ + public void setIgnoreUnknownConnections(boolean v); + + /** + * Register connection. + * @param cm connection manager + * @param cl connection listener + * @param connection connection handle + */ + public void registerConnection(ConnectionCacheListener cm, ConnectionListener cl, + Object connection); + + /** + * Unregister connection. + * @param cm connection manager + * @param cl connection listener + * @param connection connection handle + */ + public void unregisterConnection(ConnectionCacheListener cm, ConnectionListener cl, + Object connection); + + /** + * Get the number of connections currently in use - if debug is enabled + * @return The value + */ + public int getNumberOfConnections(); + + /** + * List the connections in use - if debug is enabled + * + * The return value is the connection key, and its allocation stack trace + * @return The map + */ + public Map listConnections(); + + /** + * Start + */ + public void start(); + + /** + * Stop + */ + public void stop(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/ccm/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/ccm/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/ccm/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the API for the cached connection manager. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/listener/ConnectionCacheListener.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/listener/ConnectionCacheListener.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/listener/ConnectionCacheListener.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,31 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2006, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.api.connectionmanager.listener; + +/** + * Connection cache listener. + * + * @author Jesper Pedersen + */ +public interface ConnectionCacheListener +{ +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/listener/ConnectionListener.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/listener/ConnectionListener.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/listener/ConnectionListener.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,40 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2006, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.api.connectionmanager.listener; + +import javax.resource.spi.ConnectionEventListener; +import javax.resource.spi.ManagedConnection; + +/** + * Connection listener. + * + * @author Jesper Pedersen + */ +public interface ConnectionListener extends ConnectionEventListener, Comparable +{ + /** + * Retrieve the managed connection for this listener. + * + * @return the managed connection + */ + public ManagedConnection getManagedConnection(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/listener/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/listener/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/listener/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the connection listener API. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +The API for the IronJacamar Core/ConnectionManager module. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/pool/FlushMode.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/pool/FlushMode.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/pool/FlushMode.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,49 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.api.connectionmanager.pool; + +/** + * Flush strategy mode + * @author Jesper Pedersen + */ +public enum FlushMode +{ + /** + * Invalid + */ + INVALID, + + /** + * Idle + */ + IDLE, + + /** + * Gracefully + */ + GRACEFULLY, + + /** + * All + */ + ALL; +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/pool/Pool.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/pool/Pool.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/pool/Pool.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,82 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2006, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.api.connectionmanager.pool; + +import javax.resource.spi.ConnectionRequestInfo; +import javax.security.auth.Subject; + +/** + * A pool. + * + * @author Jesper Pedersen + */ +public interface Pool +{ + /** + * Gets pool name. + * @return pool name + */ + public String getName(); + + /** + * Flush idle connections from the pool + */ + public void flush(); + + /** + * Flush the pool + * @param kill Kill all connections + */ + public void flush(boolean kill); + + /** + * Flush the pool + * @param mode The flush mode + */ + public void flush(FlushMode mode); + + /** + * Test if a connection can be obtained + * @return True if it was possible to get a connection; otherwise false + */ + public boolean testConnection(); + + /** + * Test if a connection can be obtained + * @param cri Optional connection request info object + * @param subject Optional subject + * @return True if it was possible to get a connection; otherwise false + */ + public boolean testConnection(ConnectionRequestInfo cri, Subject subject); + + /** + * Get the statistics + * @return The value + */ + public PoolStatistics getStatistics(); + + /** + * Dump the queued threads + * @return The strack traces of the queued thread, or empty if none + */ + public String[] dumpQueuedThreads(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/pool/PoolConfiguration.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/pool/PoolConfiguration.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/pool/PoolConfiguration.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,334 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.connectionmanager.pool; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +/** + * The pool configuration. + * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +public class PoolConfiguration +{ + /** Minumum size of the pool */ + private AtomicInteger minSize; + + /** Initial size of the pool */ + private AtomicInteger initialSize; + + /** Maximum size of the pool */ + private AtomicInteger maxSize; + + /** Blocking timeout. In milliseconds */ + private AtomicLong blockingTimeout; + + /** Idle timeout period. Default 30 mins */ + private AtomicInteger idleTimeoutMinutes; + + /** Validate on match validation */ + private AtomicBoolean validateOnMatch; + + /** Background validation */ + private AtomicBoolean backgroundValidation; + + /** Background validation - millis */ + private AtomicLong backgroundValidationMillis; + + /** Prefill pool*/ + private AtomicBoolean prefill; + + /** Strict minumum, default false */ + private AtomicBoolean strictMin; + + /** + * Do we want to immeadiately break when a connection cannot be matched and + * not evaluate the rest of the pool? + */ + private AtomicBoolean useFastFail; + + /** Fairness of semaphore permits, default true */ + private AtomicBoolean fair; + + /** + * Constructor + */ + public PoolConfiguration() + { + minSize = new AtomicInteger(0); + initialSize = null; + maxSize = new AtomicInteger(20); + blockingTimeout = new AtomicLong(30000); + idleTimeoutMinutes = new AtomicInteger(30); + validateOnMatch = new AtomicBoolean(false); + backgroundValidation = new AtomicBoolean(false); + backgroundValidationMillis = new AtomicLong(0); + prefill = new AtomicBoolean(false); + strictMin = new AtomicBoolean(false); + useFastFail = new AtomicBoolean(false); + fair = new AtomicBoolean(true); + } + + /** + * @return the minSize + */ + public int getMinSize() + { + if (minSize.get() > maxSize.get()) + return maxSize.get(); + + return minSize.get(); + } + + /** + * @param minSize the minSize to set + */ + public void setMinSize(int minSize) + { + this.minSize.set(minSize); + } + + /** + * @return the initialSize + */ + public int getInitialSize() + { + if (initialSize == null) + return getMinSize(); + + if (initialSize.get() > maxSize.get()) + return maxSize.get(); + + return initialSize.get(); + } + + /** + * @param initialSize the initialSize to set + */ + public void setInitialSize(int initialSize) + { + if (this.initialSize == null) + this.initialSize = new AtomicInteger(0); + + this.initialSize.set(initialSize); + } + + /** + * @return the maxSize + */ + public int getMaxSize() + { + if (maxSize.get() < minSize.get()) + return minSize.get(); + + return maxSize.get(); + } + + /** + * @param maxSize the maxSize to set + */ + public void setMaxSize(int maxSize) + { + this.maxSize.set(maxSize); + } + + /** + * @return the blockingTimeout + */ + public long getBlockingTimeout() + { + return blockingTimeout.get(); + } + + /** + * @param blockingTimeout the blockingTimeout to set + */ + public void setBlockingTimeout(long blockingTimeout) + { + this.blockingTimeout.set(blockingTimeout); + } + + /** + * @return the idleTimeout + */ + public int getIdleTimeoutMinutes() + { + return idleTimeoutMinutes.get(); + } + + /** + * @param idleTimeout the idleTimeout to set + */ + public void setIdleTimeoutMinutes(int idleTimeout) + { + this.idleTimeoutMinutes.set(idleTimeout); + } + + /** + * @return Should validate on match validation be performed + */ + public boolean isValidateOnMatch() + { + return validateOnMatch.get(); + } + + /** + * @param v Should validate on match validation be performed + */ + public void setValidateOnMatch(boolean v) + { + this.validateOnMatch.set(v); + } + + /** + * @return Should background validation be performed + */ + public boolean isBackgroundValidation() + { + if (isValidateOnMatch()) + return false; + + return backgroundValidation.get(); + } + + /** + * @param v Should background validation be performed + */ + public void setBackgroundValidation(boolean v) + { + this.backgroundValidation.set(v); + } + + /** + * Get the background validation millis setting + * @return The value + */ + public long getBackgroundValidationMillis() + { + return backgroundValidationMillis.get(); + } + + /** + * Set the background validation millis setting + * @param v The value + */ + public void setBackgroundValidationMillis(long v) + { + this.backgroundValidationMillis.set(v); + } + + /** + * @return the prefill + */ + public boolean isPrefill() + { + return prefill.get() || (initialSize != null && initialSize.get() > 0); + } + + /** + * @param prefill the prefill to set + */ + public void setPrefill(boolean prefill) + { + this.prefill.set(prefill); + } + + /** + * @return the strictMin + */ + public boolean isStrictMin() + { + return strictMin.get(); + } + + /** + * @param strictMin the strictMin to set + */ + public void setStrictMin(boolean strictMin) + { + this.strictMin.set(strictMin); + } + + /** + * @return the fair + */ + public boolean isFair() + { + return fair.get(); + } + + /** + * @param useFair the fair value + */ + public void setFair(boolean useFair) + { + this.fair.set(useFair); + } + + /** + * @return the useFastFail + */ + public boolean isUseFastFail() + { + return useFastFail.get(); + } + + + /** + * @param useFastFail the useFastFail to set + */ + public void setUseFastFail(boolean useFastFail) + { + this.useFastFail.set(useFastFail); + } + + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("PoolConfiguration@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[minSize=").append(minSize.get()); + sb.append(" initialSize=").append(initialSize != null ? initialSize.get() : "null"); + sb.append(" maxSize=").append(maxSize.get()); + sb.append(" blockingTimeout=").append(blockingTimeout.get()); + sb.append(" idleTimeoutMinutes=").append(idleTimeoutMinutes.get()); + sb.append(" validateOnMatch=").append(validateOnMatch.get()); + sb.append(" backgroundValidation=").append(backgroundValidation.get()); + sb.append(" backgroundValidationMillis=").append(backgroundValidationMillis.get()); + sb.append(" prefill=").append(prefill.get()); + sb.append(" strictMin=").append(strictMin.get()); + sb.append(" useFastFail=").append(useFastFail.get()); + sb.append(" fair=").append(fair.get()); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/pool/PoolStatistics.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/pool/PoolStatistics.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/pool/PoolStatistics.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,188 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.api.connectionmanager.pool; + +import org.jboss.jca.core.spi.statistics.StatisticsPlugin; + +/** + * The pool statistics + * + * @author Jesper Pedersen + */ +public interface PoolStatistics extends StatisticsPlugin +{ + /** + * Get active count + * @return The value + */ + public int getActiveCount(); + + /** + * Get the available count + * @return The value + */ + public int getAvailableCount(); + + /** + * Get the average time spent waiting on a connection (milliseconds) + * @return The value + */ + public long getAverageBlockingTime(); + + /** + * Get the average time spent creating a connection (milliseconds) + * @return The value + */ + public long getAverageCreationTime(); + + /** + * Get the average time spent obtaining a connection (milliseconds) + * @return The value + */ + public long getAverageGetTime(); + + /** + * Get the average time for a connection in the pool (milliseconds) + * @return The value + */ + public long getAveragePoolTime(); + + /** + * Get the average time spent using a connection (milliseconds) + * @return The value + */ + public long getAverageUsageTime(); + + /** + * Get the blocking failure count + * @return The value + */ + public int getBlockingFailureCount(); + + /** + * Get created count + * @return The value + */ + public int getCreatedCount(); + + /** + * Get destroyed count + * @return The value + */ + public int getDestroyedCount(); + + /** + * Get idle count + * @return The value + */ + public int getIdleCount(); + + /** + * Get in use count + * @return The value + */ + public int getInUseCount(); + + /** + * Get max creation time (milliseconds) + * @return The value + */ + public long getMaxCreationTime(); + + /** + * Get max get time (milliseconds) + * @return The value + */ + public long getMaxGetTime(); + + /** + * Get max pool time (milliseconds) + * @return The value + */ + public long getMaxPoolTime(); + + /** + * Get max usage time (milliseconds) + * @return The value + */ + public long getMaxUsageTime(); + + /** + * Get max used count + * @return The value + */ + public int getMaxUsedCount(); + + /** + * Get max wait count + * @return The value + */ + public int getMaxWaitCount(); + + /** + * Get max wait time (milliseconds) + * @return The value + */ + public long getMaxWaitTime(); + + /** + * Get timed out + * @return The value + */ + public int getTimedOut(); + + /** + * Get the total time spent waiting on connections (milliseconds) + * @return The value + */ + public long getTotalBlockingTime(); + + /** + * Get the total time spent creating connections (milliseconds) + * @return The value + */ + public long getTotalCreationTime(); + + /** + * Get the total time spent obtaining connections (milliseconds) + * @return The value + */ + public long getTotalGetTime(); + + /** + * Get the total time for connections in the pool (milliseconds) + * @return The value + */ + public long getTotalPoolTime(); + + /** + * Get the total time spent using connections (milliseconds) + * @return The value + */ + public long getTotalUsageTime(); + + /** + * Get wait count + * @return The value + */ + public int getWaitCount(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/pool/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/pool/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/connectionmanager/pool/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the pool API for the connection manager. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/AdminObject.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/AdminObject.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/AdminObject.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,133 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.management; + +import org.jboss.jca.core.spi.statistics.Statistics; +import org.jboss.jca.core.spi.statistics.StatisticsPlugin; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; + +/** + * Represents an admin object instance + * + * @author Jesper Pedersen + */ +public class AdminObject +{ + /** The object instance */ + private WeakReference instance; + + /** The config property's */ + private List configProperties; + + /** jndi name */ + private String jndiName; + + /** + * Constructor + * @param ao The admin object instance + */ + public AdminObject(Object ao) + { + this.instance = new WeakReference(ao); + this.configProperties = null; + } + + /** + * Get the admin object instance. + * + * Note, that the value may be null if the admin object was + * undeployed and this object wasn't cleared up correctly. + * @return The instance + */ + public Object getAdminObject() + { + return instance.get(); + } + + /** + * Get the list of config property's + * @return The value + */ + public List getConfigProperties() + { + if (configProperties == null) + configProperties = new ArrayList(1); + + return configProperties; + } + + /** + * Get the jndiName. + * + * @return the jndiName. + */ + public String getJndiName() + { + return jndiName; + } + + /** + * Set the jndiName. + * + * @param jndiName The jndiName to set. + */ + public void setJndiName(String jndiName) + { + this.jndiName = jndiName; + } + + /** + * Get the statistics + * @return The value; null if no statistics is available + */ + public StatisticsPlugin getStatistics() + { + if (getAdminObject() != null && getAdminObject() instanceof Statistics) + { + return ((Statistics)getAdminObject()).getStatistics(); + } + + return null; + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("AdminObject@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[instance=").append(getAdminObject()); + sb.append(" configProperties=").append(configProperties); + sb.append(" statistics=").append(getStatistics()); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ConfigProperty.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ConfigProperty.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ConfigProperty.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,107 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.management; + +/** + * Represents a config property + * + * @author Jesper Pedersen + */ +public class ConfigProperty +{ + /** The name */ + private String name; + + /** The dynamic flag */ + private boolean dynamic; + + /** The confidential flag */ + private boolean confidential; + + /** + * Constructor + * @param name The name + */ + public ConfigProperty(String name) + { + this(name, false, false); + } + + /** + * Constructor + * @param name The name + * @param dynamic Does this config property support dynamic updates + * @param confidential Is this config property confidential + */ + public ConfigProperty(String name, boolean dynamic, boolean confidential) + { + this.name = name; + this.dynamic = dynamic; + this.confidential = confidential; + } + + /** + * Get the name + * @return The value + */ + public String getName() + { + return name; + } + + /** + * Get the dynamic flag + * @return The value + */ + public boolean isDynamic() + { + return dynamic; + } + + /** + * Get the confidential flag + * @return The value + */ + public boolean isConfidential() + { + return confidential; + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("ConfigProperty@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[name=").append(name); + sb.append(" dynamic=").append(dynamic); + sb.append(" confidential=").append(confidential); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ConnectionFactory.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ConnectionFactory.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ConnectionFactory.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,176 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.management; + +import org.jboss.jca.core.api.connectionmanager.pool.Pool; +import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration; + +import java.lang.ref.WeakReference; + +/** + * Represents a managed connection factory instance + * + * @author Jeff Zhang + */ +public class ConnectionFactory +{ + /** The connection factory */ + private WeakReference connectionFactory; + + /** The managed connection factory */ + private ManagedConnectionFactory managedConnectionFactory; + + /** jndi name */ + private String jndiName; + + /** The pool instance */ + private WeakReference pool; + + /** The pool configuration instance */ + private WeakReference poolConfiguration; + + /** + * Constructor + * @param cf The connection factory + * @param mcf The managed connection factory instance + */ + public ConnectionFactory(Object cf, javax.resource.spi.ManagedConnectionFactory mcf) + { + this.connectionFactory = new WeakReference(cf); + this.managedConnectionFactory = new ManagedConnectionFactory(mcf); + this.pool = null; + this.poolConfiguration = null; + } + + /** + * Get the connection factory instance. + * + * Note, that the value may be null if the connection factory was + * undeployed and this object wasn't cleared up correctly. + * @return The instance + */ + public Object getConnectionFactory() + { + return connectionFactory.get(); + } + + /** + * Get the managed connection factory instance. + * + * Note, that the value may be null if the managed connection factory was + * undeployed and this object wasn't cleared up correctly. + * @return The instance + */ + public ManagedConnectionFactory getManagedConnectionFactory() + { + return managedConnectionFactory; + } + + /** + * Get the pool instance. + * + * Note, that the value may be null if the pool was + * undeployed and this object wasn't cleared up correctly. + * @return The instance + */ + public Pool getPool() + { + if (pool == null) + return null; + + return pool.get(); + } + + /** + * Set the pool + * @param p The pool + */ + public void setPool(Pool p) + { + this.pool = new WeakReference(p); + } + + /** + * Get the pool configuration instance. + * + * Note, that the value may be null if the pool configuration was + * undeployed and this object wasn't cleared up correctly. + * @return The instance + */ + public PoolConfiguration getPoolConfiguration() + { + if (poolConfiguration == null) + return null; + + return poolConfiguration.get(); + } + + /** + * Set the pool configuration + * @param pc The pool configuration + */ + public void setPoolConfiguration(PoolConfiguration pc) + { + this.poolConfiguration = new WeakReference(pc); + } + + /** + * Get the jndiName. + * + * @return the jndiName. + */ + public String getJndiName() + { + return jndiName; + } + + /** + * Set the jndiName. + * + * @param jndiName The jndiName to set. + */ + public void setJndiName(String jndiName) + { + this.jndiName = jndiName; + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("ConnectionFactory@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[jndiName=").append(getJndiName()); + sb.append(" connectionFactory=").append(getConnectionFactory()); + sb.append(" managedConnectionFactory=").append(getManagedConnectionFactory()); + sb.append(" pool=").append(getPool()); + sb.append(" poolconfiguration=").append(getPoolConfiguration()); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ConnectionManager.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ConnectionManager.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ConnectionManager.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,100 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.management; + +import java.lang.ref.WeakReference; + +/** + * Represents a connector instance + * + * @author Jesper Pedersen + * @author Jeff Zhang + */ +public class ConnectionManager implements ManagedEnlistmentTrace +{ + /** The unique id */ + private String uniqueId; + + + /** The enlistment trace */ + private WeakReference enlistmentTrace; + + + /** + * Constructor + * @param uniqueId The unique id + */ + public ConnectionManager(String uniqueId) + { + this.uniqueId = uniqueId; + } + + /** + * Get the unique id + * @return The value + */ + public String getUniqueId() + { + return uniqueId; + } + + /** + * Get the resource adapter + * @return The value + */ + + @Override + public Boolean getEnlistmentTrace() + { + if (enlistmentTrace == null) + return null; + + return enlistmentTrace.get(); + } + + /** + * Set the enlistmentTrace + * @param enlistmentTrace The enlistmentTrace module + */ + public void setEnlistmentTrace(Boolean enlistmentTrace) + { + this.enlistmentTrace = new WeakReference(enlistmentTrace); + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("Connector@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[uniqueId=").append(uniqueId); + sb.append(" enlistmentTrace=").append(getEnlistmentTrace()); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/Connector.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/Connector.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/Connector.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,148 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.management; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a connector instance + * + * @author Jesper Pedersen + * @author Jeff Zhang + */ +public class Connector +{ + /** The unique id */ + private String uniqueId; + + /** The resource adapter instance */ + private ResourceAdapter resourceAdapter; + + /** The connection factories */ + private List connectionFactories; + + /** The admin objects */ + private List adminObjects; + + /** The connection managers */ + private List connectionManagers; + + + /** + * Constructor + * @param uniqueId The unique id + */ + public Connector(String uniqueId) + { + this.uniqueId = uniqueId; + this.resourceAdapter = null; + this.connectionFactories = null; + this.adminObjects = null; + this.connectionManagers = null; + } + + /** + * Get the unique id + * @return The value + */ + public String getUniqueId() + { + return uniqueId; + } + + /** + * Get the resource adapter + * @return The value + */ + public ResourceAdapter getResourceAdapter() + { + return resourceAdapter; + } + + /** + * Set the resource adapter + * @param ra The value + */ + public void setResourceAdapter(ResourceAdapter ra) + { + this.resourceAdapter = ra; + } + + /** + * Get the list of connection factories + * @return The value + */ + public List getConnectionFactories() + { + if (connectionFactories == null) + connectionFactories = new ArrayList(1); + + return connectionFactories; + } + + /** + * Get the list of admin objects + * @return The value + */ + public List getAdminObjects() + { + if (adminObjects == null) + adminObjects = new ArrayList(1); + + return adminObjects; + } + + /** + * Get the list of connection managers + * @return The value + */ + public List getConnectionManagers() + { + if (connectionManagers == null) + connectionManagers = new ArrayList(1); + + return connectionManagers; + } + + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("Connector@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[uniqueId=").append(uniqueId); + sb.append(" resourceAdapter=").append(resourceAdapter); + sb.append(" connectionFactories=").append(connectionFactories); + sb.append(" adminObjects=").append(adminObjects); + sb.append(" connectionManagers=").append(connectionManagers); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/DataSource.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/DataSource.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/DataSource.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,211 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.management; + +import org.jboss.jca.core.api.connectionmanager.pool.Pool; +import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration; +import org.jboss.jca.core.spi.statistics.StatisticsPlugin; + +import java.lang.ref.WeakReference; + +/** + * Represents a datasource instance + * + * @author Jeff Zhang + */ +public class DataSource implements ManagedEnlistmentTrace +{ + /** xa datasource or not */ + private boolean xa; + + /** jndi name */ + private String jndiName; + + /** The pool instance */ + private WeakReference pool; + + /** The pool configuration instance */ + private WeakReference poolConfiguration; + + /** The statistics */ + private WeakReference statistics; + + /** The enlistment trace */ + private WeakReference enlistmentTrace; + + + /** + * Constructor + * @param xa datasource is xa or not + */ + public DataSource(boolean xa) + { + this.xa = xa; + } + + /** + * xa datasource + * @return true if it xa datasource + */ + public boolean isXA() + { + return xa; + } + + /** + * Get the pool instance. + * + * Note, that the value may be null if the pool was + * undeployed and this object wasn't cleared up correctly. + * @return The instance + */ + public Pool getPool() + { + if (pool == null) + return null; + + return pool.get(); + } + + /** + * Set the pool + * @param p The pool + */ + public void setPool(Pool p) + { + this.pool = new WeakReference(p); + } + + /** + * Get the pool configuration instance. + * + * Note, that the value may be null if the pool configuration was + * undeployed and this object wasn't cleared up correctly. + * @return The instance + */ + public PoolConfiguration getPoolConfiguration() + { + if (poolConfiguration == null) + return null; + + return poolConfiguration.get(); + } + + /** + * Set the pool configuration + * @param pc The pool configuration + */ + public void setPoolConfiguration(PoolConfiguration pc) + { + this.poolConfiguration = new WeakReference(pc); + } + + /** + * Get the jndiName. + * + * @return the jndiName. + */ + public String getJndiName() + { + return jndiName; + } + + /** + * Set the jndiName. + * @param v The value + */ + public void setJndiName(String v) + { + this.jndiName = v; + } + + /** + * Get the statistics instance. + * + * Note, that the value may be null if the statistics module was + * undeployed and this object wasn't cleared up correctly. + * @return The instance + */ + public StatisticsPlugin getStatistics() + { + if (statistics == null) + return null; + + return statistics.get(); + } + + + /** + * Set the statistics + * @param v The statistics module + */ + public void setStatistics(StatisticsPlugin v) + { + this.statistics = new WeakReference(v); + } + + /** + * Get the enlistmentTrace instance. + * + * Note, that the value may be null if the enlistmentTrace module was + * undeployed and this object wasn't cleared up correctly. + * @return The instance + */ + @Override + public Boolean getEnlistmentTrace() + { + if (enlistmentTrace == null) + return null; + + return enlistmentTrace.get(); + } + + /** + * Set the enlistmentTrace + * @param enlistmentTrace The enlistmentTrace module + */ + public void setEnlistmentTrace(Boolean enlistmentTrace) + { + this.enlistmentTrace = new WeakReference(enlistmentTrace); + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("DataSource@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append(" xa=").append(isXA()); + sb.append(" jndiName=").append(getJndiName()); + sb.append(" pool=").append(getPool()); + sb.append(" poolconfiguration=").append(getPoolConfiguration()); + sb.append(" statistics=").append(getStatistics()); + sb.append(" enlistmentTrace=").append(getEnlistmentTrace()); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ManagedConnectionFactory.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ManagedConnectionFactory.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ManagedConnectionFactory.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,111 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.management; + +import org.jboss.jca.core.spi.statistics.Statistics; +import org.jboss.jca.core.spi.statistics.StatisticsPlugin; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a managed connection factory instance + * + * @author Jesper Pedersen + * @author Jeff Zhang + */ +public class ManagedConnectionFactory +{ + /** The object instance */ + private WeakReference instance; + + /** The config property's */ + private List configProperties; + + /** + * Constructor + * @param mcf The managed connection factory instance + */ + public ManagedConnectionFactory(javax.resource.spi.ManagedConnectionFactory mcf) + { + this.instance = new WeakReference(mcf); + this.configProperties = null; + } + + /** + * Get the managed connection factory instance. + * + * Note, that the value may be null if the managed connection factory was + * undeployed and this object wasn't cleared up correctly. + * @return The instance + */ + public javax.resource.spi.ManagedConnectionFactory getManagedConnectionFactory() + { + return instance.get(); + } + + /** + * Get the list of config property's + * @return The value + */ + public List getConfigProperties() + { + if (configProperties == null) + configProperties = new ArrayList(1); + + return configProperties; + } + + /** + * Get the statistics + * @return The value; null if no statistics is available + */ + public StatisticsPlugin getStatistics() + { + if (getManagedConnectionFactory() != null && getManagedConnectionFactory() instanceof Statistics) + { + return ((Statistics)getManagedConnectionFactory()).getStatistics(); + } + + return null; + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("ManagedConnectionFactory@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[instance=").append(getManagedConnectionFactory()); + sb.append(" configProperties=").append(configProperties); + sb.append(" statistics=").append(getStatistics()); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ManagedEnlistmentTrace.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ManagedEnlistmentTrace.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ManagedEnlistmentTrace.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,35 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2016, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.management; + +/** + * Created by maeste on 11/10/16. + */ +public interface ManagedEnlistmentTrace +{ + /** + * Gets enlistment trace + * @return {@code true} if enlistment trace is enabled + */ + Boolean getEnlistmentTrace(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ManagementRepository.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ManagementRepository.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ManagementRepository.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,86 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.management; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * The management repository + * + * @author Jesper Pedersen + * @author Jeff Zhang + */ +public class ManagementRepository +{ + /** Resource adapter archives */ + private List connectors; + + /** data sources */ + private List datasources; + + /** + * Constructor + */ + public ManagementRepository() + { + this.connectors = Collections.synchronizedList(new ArrayList(1)); + this.datasources = Collections.synchronizedList(new ArrayList(1)); + } + + /** + * Get the list of connectors + * @return The value + */ + public List getConnectors() + { + return connectors; + } + + /** + * Get the list of connectors + * @return The value + */ + public List getDataSources() + { + return datasources; + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("ManagementRepository@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[connectors=").append(connectors); + sb.append(" datasources=").append(datasources); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ResourceAdapter.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ResourceAdapter.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/ResourceAdapter.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,110 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.management; + +import org.jboss.jca.core.spi.statistics.Statistics; +import org.jboss.jca.core.spi.statistics.StatisticsPlugin; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a resource adapter instance + * + * @author Jesper Pedersen + */ +public class ResourceAdapter +{ + /** The object instance */ + private WeakReference instance; + + /** The config property's */ + private List configProperties; + + /** + * Constructor + * @param ra The resource adapter instance + */ + public ResourceAdapter(javax.resource.spi.ResourceAdapter ra) + { + this.instance = new WeakReference(ra); + this.configProperties = null; + } + + /** + * Get the resource adapter instance. + * + * Note, that the value may be null if the resource adapter was + * undeployed and this object wasn't cleared up correctly. + * @return The instance + */ + public javax.resource.spi.ResourceAdapter getResourceAdapter() + { + return instance.get(); + } + + /** + * Get the list of config property's + * @return The value + */ + public List getConfigProperties() + { + if (configProperties == null) + configProperties = new ArrayList(1); + + return configProperties; + } + + /** + * Get the statistics + * @return The value; null if no statistics is available + */ + public StatisticsPlugin getStatistics() + { + if (getResourceAdapter() != null && getResourceAdapter() instanceof Statistics) + { + return ((Statistics)getResourceAdapter()).getStatistics(); + } + + return null; + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("ResourceAdapter@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[instance=").append(getResourceAdapter()); + sb.append(" configProperties=").append(configProperties); + sb.append(" statistics=").append(getStatistics()); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/management/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains management view of the container in a non-technology specific way. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +The API for the IronJacamar Core module. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/DistributableContext.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/DistributableContext.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/DistributableContext.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,103 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.workmanager; + +import javax.resource.spi.work.WorkContext; + +/** + * Properties for distribution of work instances + */ +public class DistributableContext implements WorkContext +{ + private static final long serialVersionUID = 1L; + + /** The distribute key */ + public static final String DISTRIBUTE = "org.jboss.jca.core.api.workmanager.Distribute"; + + /** The workmanager key */ + public static final String WORKMANAGER = "org.jboss.jca.core.api.workmanager.WorkManager"; + + private Boolean distribute; + private String workManager; + + /** + * Constructor + */ + public DistributableContext() + { + this.distribute = null; + this.workManager = null; + } + + /** + * {@inheritDoc} + */ + public String getName() + { + return "DistributableContext"; + } + + /** + * {@inheritDoc} + */ + public String getDescription() + { + return "Distribution properties"; + } + + /** + * Set the distribute value + * @param v The value + */ + public void setDistribute(Boolean v) + { + this.distribute = v; + } + + /** + * Get the distribute value + * @return The value + */ + public Boolean getDistribute() + { + return distribute; + } + + /** + * Set the work manager value + * @param v The value + */ + public void setWorkManager(String v) + { + this.workManager = v; + } + + /** + * Get the work manager value + * @return The value + */ + public String getWorkManager() + { + return workManager; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/DistributedWorkManager.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/DistributedWorkManager.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/DistributedWorkManager.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,162 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.workmanager; + +import org.jboss.jca.core.spi.workmanager.notification.NotificationListener; +import org.jboss.jca.core.spi.workmanager.policy.Policy; +import org.jboss.jca.core.spi.workmanager.selector.Selector; +import org.jboss.jca.core.spi.workmanager.transport.Transport; + +import java.util.Collection; + +import javax.resource.spi.work.Work; +import javax.resource.spi.work.WorkException; + +/** + * The JBoss specific distributed work manager interface + */ +public interface DistributedWorkManager extends javax.resource.spi.work.DistributableWorkManager, WorkManager +{ + /** + * Get the policy + * @return The value + */ + public Policy getPolicy(); + + /** + * Set the policy + * @param v The value + */ + public void setPolicy(Policy v); + + /** + * Get the selector + * @return The value + */ + public Selector getSelector(); + + /** + * Set the selector + * @param v The value + */ + public void setSelector(Selector v); + + /** + * Get the transport + * @return The value + */ + public Transport getTransport(); + + /** + * Set the transport + * @param v The value + */ + public void setTransport(Transport v); + + /** + * Is distributed statistics enabled + * @return True if enabled; otherwise false + */ + public boolean isDistributedStatisticsEnabled(); + + /** + * Set the distributed statistics enabled flag + * @param v The value + */ + public void setDistributedStatisticsEnabled(boolean v); + + /** + * Get the notification listeners attached + * @return The value + */ + public Collection getNotificationListeners(); + + /** + * Toggle distribution of Work instances for doWork + * @param v The value + */ + public void setDoWorkDistributionEnabled(boolean v); + + /** + * Is distribution of Work instances for doWork enabled + * @return True if enabled, otherwise false + */ + public boolean isDoWorkDistributionEnabled(); + + /** + * Toggle distribution of Work instances for startWork + * @param v The value + */ + public void setStartWorkDistributionEnabled(boolean v); + + /** + * Is distribution of Work instances for startWork enabled + * @return True if enabled, otherwise false + */ + public boolean isStartWorkDistributionEnabled(); + + /** + * Toggle distribution of Work instances for scheduleWork + * @param v The value + */ + public void setScheduleWorkDistributionEnabled(boolean v); + + /** + * Is distribution of Work instances for scheduleWork enabled + * @return True if enabled, otherwise false + */ + public boolean isScheduleWorkDistributionEnabled(); + + /** + * doWork locally + * @param work The work + * @exception WorkException Thrown if an error occurs + */ + public void localDoWork(Work work) throws WorkException; + + /** + * scheduleWork locally + * @param work The work + * @exception WorkException Thrown if an error occurs + */ + public void localScheduleWork(Work work) throws WorkException; + + /** + * startWork locally + * @param work The work + * @return The delay + * @exception WorkException Thrown if an error occurs + */ + public long localStartWork(Work work) throws WorkException; + + /** + * Get the distributed statistics + * @return The value + */ + public DistributedWorkManagerStatistics getDistributedStatistics(); + + /** + * Initialize + */ + public void initialize(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/DistributedWorkManagerStatistics.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/DistributedWorkManagerStatistics.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/DistributedWorkManagerStatistics.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,35 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.workmanager; + +/** + * The JBoss distributed work manager statistics + */ +public interface DistributedWorkManagerStatistics extends WorkManagerStatistics +{ + /** + * Initialize the statistics + * @param values The values + */ + public void initialize(DistributedWorkManagerStatisticsValues values); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/DistributedWorkManagerStatisticsValues.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/DistributedWorkManagerStatisticsValues.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/DistributedWorkManagerStatisticsValues.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,221 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.workmanager; + +import java.io.Serializable; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * The JBoss distributed work manager statistics values + */ +public class DistributedWorkManagerStatisticsValues implements Serializable +{ + /** Serial version UID */ + private static final long serialVersionUID = 1L; + + /** Successful */ + private int successful; + + /** Failed */ + private int failed; + + /** DoWork: Accepted */ + private int doWorkAccepted; + + /** DoWork: Rejected */ + private int doWorkRejected; + + /** ScheduleWork: Accepted */ + private int scheduleWorkAccepted; + + /** ScheduleWork: Rejected */ + private int scheduleWorkRejected; + + /** StartWork: Accepted */ + private int startWorkAccepted; + + /** StartWork: Rejected */ + private int startWorkRejected; + + + + private static final String SUCCESSFUL = "SUCCESSFUL"; + private static final String FAILED = "FAILED"; + private static final String DO_WORK_ACCEPTED = "DO_WORK_ACCEPTED"; + private static final String DO_WORK_REJECTED = "DO_WORK_REJECTED"; + private static final String SCHEDULE_WORK_ACCEPTED = "SCHEDULE_WORK_ACCEPTED"; + private static final String SCHEDULE_WORK_REJECTED = "SCHEDULE_WORK_REJECTED"; + private static final String START_WORK_ACCEPTED = "START_WORK_ACCEPTED"; + private static final String START_WORK_REJECTED = "START_WORK_REJECTED"; + + /** + * create an instance from a Map + * @param map the map + * @return the instance + */ + public static DistributedWorkManagerStatisticsValues fromMap(Map map) + { + return new DistributedWorkManagerStatisticsValues(map.get(SUCCESSFUL), map.get(FAILED), map.get(DO_WORK_ACCEPTED), + map.get(DO_WORK_REJECTED), map.get(SCHEDULE_WORK_ACCEPTED), map.get(SCHEDULE_WORK_REJECTED), + map.get(START_WORK_ACCEPTED), map.get(START_WORK_REJECTED)); + + } + + /** + * return a map representing the instance + * @return the map + */ + public Map toMap() + { + Map returnMap = new LinkedHashMap(8); + returnMap.put(SUCCESSFUL, this.getWorkSuccessful()); + returnMap.put(FAILED, this.getWorkFailed()); + returnMap.put(DO_WORK_ACCEPTED, this.getDoWorkAccepted()); + returnMap.put(DO_WORK_REJECTED, this.getDoWorkRejected()); + returnMap.put(SCHEDULE_WORK_ACCEPTED, this.getScheduleWorkAccepted()); + returnMap.put(SCHEDULE_WORK_ACCEPTED, this.getScheduleWorkRejected()); + returnMap.put(START_WORK_ACCEPTED, this.getStartWorkAccepted()); + returnMap.put(START_WORK_REJECTED, this.getStartWorkRejected()); + return returnMap; + } + + + + /** + * Constructor + * @param successful successful + * @param failed failed + * @param doWorkAccepted doWorkAccepted + * @param doWorkRejected doWorkRejected + * @param scheduleWorkAccepted scheduleWorkAccepted + * @param scheduleWorkRejected scheduleWorkRejected + * @param startWorkAccepted startWorkAccepted + * @param startWorkRejected startWorkRejected + */ + public DistributedWorkManagerStatisticsValues(int successful, + int failed, + int doWorkAccepted, + int doWorkRejected, + int scheduleWorkAccepted, + int scheduleWorkRejected, + int startWorkAccepted, + int startWorkRejected) + { + this.successful = successful; + this.failed = failed; + this.doWorkAccepted = doWorkAccepted; + this.doWorkRejected = doWorkRejected; + this.scheduleWorkAccepted = scheduleWorkAccepted; + this.scheduleWorkRejected = scheduleWorkRejected; + this.startWorkAccepted = startWorkAccepted; + this.startWorkRejected = startWorkRejected; + } + + /** + * {@inheritDoc} + */ + public int getWorkSuccessful() + { + return successful; + } + + /** + * {@inheritDoc} + */ + public int getWorkFailed() + { + return failed; + } + + /** + * {@inheritDoc} + */ + public int getDoWorkAccepted() + { + return doWorkAccepted; + } + + /** + * {@inheritDoc} + */ + public int getDoWorkRejected() + { + return doWorkRejected; + } + + /** + * {@inheritDoc} + */ + public int getScheduleWorkAccepted() + { + return scheduleWorkAccepted; + } + + /** + * {@inheritDoc} + */ + public int getScheduleWorkRejected() + { + return scheduleWorkRejected; + } + + /** + * {@inheritDoc} + */ + public int getStartWorkAccepted() + { + return startWorkAccepted; + } + + /** + * {@inheritDoc} + */ + public int getStartWorkRejected() + { + return startWorkRejected; + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("DistributedWorkManagerStatisticsValues@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[successful=").append(getWorkSuccessful()); + sb.append(" failed=").append(getWorkFailed()); + sb.append(" doWorkAccepted=").append(getDoWorkAccepted()); + sb.append(" doWorkRejected=").append(getDoWorkRejected()); + sb.append(" scheduleWorkAccepted=").append(getScheduleWorkAccepted()); + sb.append(" scheduleWorkRejected=").append(getScheduleWorkRejected()); + sb.append(" startWorkAccepted=").append(getStartWorkAccepted()); + sb.append(" startWorkRejected=").append(getStartWorkRejected()); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/StatisticsExecutor.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/StatisticsExecutor.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/StatisticsExecutor.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,39 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.workmanager; + +import org.jboss.threads.BlockingExecutor; + +/** + * A BlockingExecutor delegator to keep track of numberOfFreeThreads + * + * @author Stefano Maestri + */ +public interface StatisticsExecutor extends BlockingExecutor +{ + /** + * get the calculated number of free threads + * @return number of free threads + */ + long getNumberOfFreeThreads(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/WorkManager.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/WorkManager.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/WorkManager.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,166 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.workmanager; + +import org.jboss.jca.core.spi.graceful.GracefulShutdown; +import org.jboss.jca.core.spi.security.Callback; +import org.jboss.jca.core.spi.security.SecurityIntegration; +import org.jboss.jca.core.spi.transaction.xa.XATerminator; + +import javax.resource.spi.ResourceAdapter; + +import org.jboss.threads.BlockingExecutor; + +/** + * The JBoss specific work manager interface + */ +public interface WorkManager extends javax.resource.spi.work.WorkManager, GracefulShutdown, Cloneable +{ + /** + * Get the unique id of the work manager + * @return The value + */ + public String getId(); + + /** + * Set the id of the work manager + * @param v The value + */ + public void setId(String v); + + /** + * Get the name of the work manager + * @return The value + */ + public String getName(); + + /** + * Set the name of the work manager + * @param v The value + */ + public void setName(String v); + + /** + * Set the resource adapter + * @param ra The handle + */ + public void setResourceAdapter(ResourceAdapter ra); + + /** + * Retrieve the executor for short running tasks + * @return The executor + */ + public StatisticsExecutor getShortRunningThreadPool(); + + /** + * Set the executor for short running tasks + * @param executor The executor + */ + public void setShortRunningThreadPool(BlockingExecutor executor); + + /** + * Retrieve the executor for long running tasks + * @return The executor + */ + public StatisticsExecutor getLongRunningThreadPool(); + + /** + * Set the executor for long running tasks + * @param executor The executor + */ + public void setLongRunningThreadPool(BlockingExecutor executor); + + /** + * Get the XATerminator + * @return The XA terminator + */ + public XATerminator getXATerminator(); + + /** + * Set the XATerminator + * @param xaTerminator The XA terminator + */ + public void setXATerminator(XATerminator xaTerminator); + + /** + * Is spec compliant + * @return True if spec compliant; otherwise false + */ + public boolean isSpecCompliant(); + + /** + * Set spec compliant flag + * @param v The value + */ + public void setSpecCompliant(boolean v); + + /** + * Is statistics enabled + * @return True if enabled; otherwise false + */ + public boolean isStatisticsEnabled(); + + /** + * Set the statistics enabled flag + * @param v The value + */ + public void setStatisticsEnabled(boolean v); + + /** + * Get the callback security module + * @return The value + */ + public Callback getCallbackSecurity(); + + /** + * Set callback security module + * @param v The value + */ + public void setCallbackSecurity(Callback v); + + /** + * Get the security integration module + * @return The value + */ + public SecurityIntegration getSecurityIntegration(); + + /** + * Set security integration module + * @param v The value + */ + public void setSecurityIntegration(SecurityIntegration v); + + /** + * Get the statistics + * @return The value + */ + public WorkManagerStatistics getStatistics(); + + /** + * Clone the WorkManager implementation + * @return A copy of the implementation + * @exception CloneNotSupportedException Thrown if the copy operation isn't supported + * + */ + public WorkManager clone() throws CloneNotSupportedException; +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/WorkManagerStatistics.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/WorkManagerStatistics.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/WorkManagerStatistics.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,88 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.api.workmanager; + +/** + * The JBoss work manager statistics + */ +public interface WorkManagerStatistics +{ + /** + * Work: Active + * @return The value + */ + public int getWorkActive(); + + /** + * Work: Successful + * @return The value + */ + public int getWorkSuccessful(); + + /** + * Work: Failed + * @return The value + */ + public int getWorkFailed(); + + /** + * DoWork: Accepted + * @return The value + */ + public int getDoWorkAccepted(); + + /** + * DoWork: Rejected + * @return The value + */ + public int getDoWorkRejected(); + + /** + * ScheduleWork: Accepted + * @return The value + */ + public int getScheduleWorkAccepted(); + + /** + * ScheduleWork: Rejected + * @return The value + */ + public int getScheduleWorkRejected(); + + /** + * StartWork: Accepted + * @return The value + */ + public int getStartWorkAccepted(); + + /** + * StartWork: Rejected + * @return The value + */ + public int getStartWorkRejected(); + + /** + * Clear the statistics + */ + public void clear(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/api/workmanager/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +The API for the IronJacamar Core/WorkManager module. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/bootstrapcontext/BaseCloneableBootstrapContext.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/bootstrapcontext/BaseCloneableBootstrapContext.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/bootstrapcontext/BaseCloneableBootstrapContext.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,296 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.bootstrapcontext; + +import org.jboss.jca.core.api.bootstrap.CloneableBootstrapContext; +import org.jboss.jca.core.api.workmanager.DistributableContext; +import org.jboss.jca.core.api.workmanager.WorkManager; +import org.jboss.jca.core.workmanager.WorkManagerCoordinator; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.Timer; + +import javax.resource.spi.ResourceAdapter; +import javax.resource.spi.XATerminator; +import javax.resource.spi.work.HintsContext; +import javax.resource.spi.work.SecurityContext; +import javax.resource.spi.work.TransactionContext; +import javax.resource.spi.work.WorkContext; +import javax.transaction.TransactionSynchronizationRegistry; + +/** + * The base implementation of the cloneable bootstrap context + * @author Jesper Pedersen + */ +public class BaseCloneableBootstrapContext implements CloneableBootstrapContext +{ + /** Transaction synchronization registry */ + private TransactionSynchronizationRegistry transactionSynchronizationRegistry; + + /** Work Manager */ + private WorkManager workManager; + + /** Work Manager name */ + private String workManagerName; + + /** XATerminator */ + private XATerminator xaTerminator; + + /** Supported contexts */ + private Set supportedContexts; + + /** Timers */ + private List timers; + + /** The id */ + private String id; + + /** The name */ + private String name; + + /** + * Constructor + */ + public BaseCloneableBootstrapContext() + { + this.transactionSynchronizationRegistry = null; + this.workManager = null; + this.workManagerName = null; + this.xaTerminator = null; + this.supportedContexts = new HashSet(4); + + this.supportedContexts.add(HintsContext.class); + this.supportedContexts.add(SecurityContext.class); + this.supportedContexts.add(TransactionContext.class); + this.supportedContexts.add(DistributableContext.class); + + this.timers = null; + + this.id = null; + this.name = null; + } + + /** + * {@inheritDoc} + */ + public String getId() + { + return id; + } + + /** + * {@inheritDoc} + */ + public void setId(String v) + { + id = v; + } + + /** + * Get the name of the bootstrap context + * @return The value + */ + public String getName() + { + return name; + } + + /** + * Set the name of the bootstrap context + * @param v The value + */ + public void setName(String v) + { + name = v; + } + + /** + * Set the resource adapter + * @param ra The handle + */ + public void setResourceAdapter(ResourceAdapter ra) + { + if (workManager != null) + workManager.setResourceAdapter(ra); + } + + /** + * Get the transaction synchronization registry + * @return The handle + */ + public TransactionSynchronizationRegistry getTransactionSynchronizationRegistry() + { + return transactionSynchronizationRegistry; + } + + /** + * Set the transaction synchronization registry + * @param tsr The handle + */ + public void setTransactionSynchronizationRegistry(TransactionSynchronizationRegistry tsr) + { + this.transactionSynchronizationRegistry = tsr; + } + + /** + * Get the work manager + * @return The handle + */ + public WorkManager getWorkManager() + { + if (workManager == null) + workManager = WorkManagerCoordinator.getInstance().createWorkManager(id, workManagerName); + + return workManager; + } + + /** + * Set the work manager + * @param wm The handle + */ + public void setWorkManager(WorkManager wm) + { + this.workManager = wm; + } + + /** + * Get the work manager name + * @return The value + */ + public String getWorkManagerName() + { + return workManagerName; + } + + /** + * Set the work manager name + * @param wmn The value + */ + public void setWorkManagerName(String wmn) + { + this.workManagerName = wmn; + } + + /** + * Get the XA terminator + * @return The handle + */ + public XATerminator getXATerminator() + { + return xaTerminator; + } + + /** + * Set the XA terminator + * @param xt The handle + */ + public void setXATerminator(XATerminator xt) + { + this.xaTerminator = xt; + } + + /** + * Create a timer + * @return The timer + */ + public Timer createTimer() + { + StringBuilder sb = new StringBuilder(); + + if (name != null) + { + sb.append(name); + if (id != null) + sb.append(":"); + } + + if (id != null) + sb.append(id); + + Timer t = null; + + if (sb.length() > 0) + { + t = new Timer(sb.toString(), true); + } + else + { + t = new Timer(true); + } + + if (timers == null) + timers = new ArrayList(); + + timers.add(t); + + return t; + } + + /** + * Is the work context supported ? + * @param workContextClass The work context class + * @return True if supported; otherwise false + */ + public boolean isContextSupported(Class workContextClass) + { + if (workContextClass == null) + return false; + + return supportedContexts.contains(workContextClass); + } + + /** + * Shutdown + */ + public void shutdown() + { + if (timers != null) + { + for (Timer t : timers) + { + t.cancel(); + t.purge(); + } + } + } + + /** + * Clone the BootstrapContext implementation + * @return A copy of the implementation + * @exception CloneNotSupportedException Thrown if the copy operation isn't supported + * + */ + public CloneableBootstrapContext clone() throws CloneNotSupportedException + { + BaseCloneableBootstrapContext bcbc = (BaseCloneableBootstrapContext)super.clone(); + bcbc.setTransactionSynchronizationRegistry(getTransactionSynchronizationRegistry()); + bcbc.setXATerminator(getXATerminator()); + bcbc.setName(getName()); + bcbc.setWorkManagerName(getWorkManagerName()); + + return bcbc; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/bootstrapcontext/BootstrapContextCoordinator.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/bootstrapcontext/BootstrapContextCoordinator.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/bootstrapcontext/BootstrapContextCoordinator.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,302 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.bootstrapcontext; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.bootstrap.CloneableBootstrapContext; +import org.jboss.jca.core.workmanager.WorkManagerCoordinator; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.jboss.logging.Logger; + +/** + * Coordinator for BootstrapContext instances + * @author Jesper Pedersen + */ +public class BootstrapContextCoordinator +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + BootstrapContextCoordinator.class.getName()); + + /** The instance */ + private static final BootstrapContextCoordinator INSTANCE = new BootstrapContextCoordinator(); + + /** The bootstrap contexts */ + private ConcurrentMap bootstrapContexts; + + /** The default bootstrap context */ + private CloneableBootstrapContext defaultBootstrapContext; + + /** The activate bootstrap contexts */ + private Map activeBootstrapContexts; + + /** The ref count for activate bootstrap contexts */ + private Map refCountBootstrapContexts; + + /** + * Constructor + */ + private BootstrapContextCoordinator() + { + this.bootstrapContexts = new ConcurrentHashMap(); + this.defaultBootstrapContext = null; + this.activeBootstrapContexts = new HashMap(); + this.refCountBootstrapContexts = new HashMap(); + } + + /** + * Get the instance + * @return The instance + */ + public static BootstrapContextCoordinator getInstance() + { + return INSTANCE; + } + + /** + * Register bootstrap context + * @param bc The bootstrap context + */ + public void registerBootstrapContext(CloneableBootstrapContext bc) + { + if (bc != null) + { + if (bc.getName() == null || bc.getName().trim().equals("")) + throw new IllegalArgumentException("The name of BootstrapContext is invalid: " + bc); + + if (!bootstrapContexts.keySet().contains(bc.getName())) + { + bootstrapContexts.put(bc.getName(), bc); + } + } + } + + /** + * Unregister boostrap context + * @param bc The bootstrap context + */ + public void unregisterBootstrapContext(CloneableBootstrapContext bc) + { + if (bc != null) + { + if (bc.getName() == null || bc.getName().trim().equals("")) + throw new IllegalArgumentException("The name of BootstrapContext is invalid: " + bc); + + if (bootstrapContexts.keySet().contains(bc.getName())) + { + bootstrapContexts.remove(bc.getName()); + } + } + } + + /** + * Get the default bootstrap context + * @return The bootstrap context + */ + public CloneableBootstrapContext getDefaultBootstrapContext() + { + return defaultBootstrapContext; + } + + /** + * Set the default bootstrap context + * @param bc The bootstrap context + */ + public void setDefaultBootstrapContext(CloneableBootstrapContext bc) + { + log.tracef("Default BootstrapContext: %s", bc); + + String currentName = null; + + if (defaultBootstrapContext != null) + currentName = defaultBootstrapContext.getName(); + + defaultBootstrapContext = bc; + + if (bc != null) + { + bootstrapContexts.put(bc.getName(), bc); + } + else if (currentName != null) + { + bootstrapContexts.remove(currentName); + } + } + + /** + * Create a bootstrap context + * @param id The id of the bootstrap context + * @return The bootstrap context + */ + public synchronized CloneableBootstrapContext createBootstrapContext(String id) + { + return createBootstrapContext(id, null); + } + + /** + * Get a bootstrap context + * @param id The id of the bootstrap context + * @param name The name of the bootstrap context; if null default value is used + * @return The bootstrap context + */ + public synchronized CloneableBootstrapContext createBootstrapContext(String id, String name) + { + if (id == null || id.trim().equals("")) + throw new IllegalArgumentException("The id of BootstrapContext is invalid: " + id); + + // Check for an active work manager + if (activeBootstrapContexts.keySet().contains(id)) + { + Integer i = refCountBootstrapContexts.get(id); + refCountBootstrapContexts.put(id, Integer.valueOf(i.intValue() + 1)); + + return activeBootstrapContexts.get(id); + } + + try + { + // Create a new instance + CloneableBootstrapContext template = null; + if (name != null) + { + template = bootstrapContexts.get(name); + } + else + { + template = defaultBootstrapContext; + } + + if (template == null) + throw new IllegalArgumentException("The BootstrapContext wasn't found: " + name); + + CloneableBootstrapContext bc = template.clone(); + bc.setId(id); + + org.jboss.jca.core.api.workmanager.WorkManager wm = + WorkManagerCoordinator.getInstance().createWorkManager(id, bc.getWorkManagerName()); + + bc.setWorkManager(wm); + + activeBootstrapContexts.put(id, bc); + refCountBootstrapContexts.put(id, Integer.valueOf(1)); + + log.tracef("Created BootstrapContext: %s", bc); + + return bc; + } + catch (Throwable t) + { + throw new IllegalStateException("The BootstrapContext couldn't be created: " + name, t); + } + } + + /** + * Remove a bootstrap context + * @param id The id of the bootstrap context + */ + public synchronized void removeBootstrapContext(String id) + { + if (id == null || id.trim().equals("")) + throw new IllegalArgumentException("The id of BootstrapContext is invalid: " + id); + + Integer i = refCountBootstrapContexts.get(id); + if (i != null) + { + int newValue = i.intValue() - 1; + if (newValue == 0) + { + CloneableBootstrapContext cbc = activeBootstrapContexts.remove(id); + refCountBootstrapContexts.remove(id); + + cbc.shutdown(); + + WorkManagerCoordinator.getInstance().removeWorkManager(id); + } + else + { + refCountBootstrapContexts.put(id, Integer.valueOf(newValue)); + } + } + } + + /** + * Create an identifier + * @param raClz The resource adapter class name + * @param cps The config properties + * @return The id + */ + public String createIdentifier(String raClz, Map cps) + { + return createIdentifier(raClz, cps, null); + } + + /** + * Create an identifier + * @param raClz The resource adapter class name + * @param cps The config properties + * @param bootstrapContextName The name of the bootstrap context + * @return The id + */ + public String createIdentifier(String raClz, Map cps, String bootstrapContextName) + { + if (defaultBootstrapContext == null) + throw new IllegalArgumentException("No default BootstrapContext defined"); + + StringBuffer sb = new StringBuffer(); + + sb.append(raClz); + + if (cps != null && cps.size() > 0) + { + sb.append(";"); + + Iterator> iterator = cps.entrySet().iterator(); + while (iterator.hasNext()) + { + Map.Entry entry = iterator.next(); + sb.append(entry.getKey()).append("=").append(entry.getValue()); + + if (iterator.hasNext()) + sb.append(":"); + } + } + + sb.append("-"); + if (bootstrapContextName != null && !bootstrapContextName.trim().equals("")) + { + sb.append(bootstrapContextName); + } + else + { + sb.append(defaultBootstrapContext.getName()); + } + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/bootstrapcontext/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/bootstrapcontext/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/bootstrapcontext/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,6 @@ + +This package contains implementations of the BootstrapContext interface. +

+IronJacamar extends javax.resource.spi.BootstrapContext with a org.jboss.jca.core.api.CloneableBootstrapContext +interface in order to allow different implementations to be used for the resource adapter deployments. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/BeanValidation.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/BeanValidation.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/BeanValidation.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,138 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.bv; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.validation.Configuration; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; + +/** + * Bean validation implementation backed by Hibernate Validator + * + * @author Jesper Pedersen + * @version $Revision: $ + */ +public class BeanValidation +{ + /** Validator factory */ + private static final String VALIDATOR_FACTORY = "java:/ValidatorFactory"; + + /** Validator */ + private static final String VALIDATOR = "java:/Validator"; + + /** The validator factory */ + private ValidatorFactory validatorFactory; + + /** The validator */ + private Validator validator; + + /** + * Constructor + */ + public BeanValidation() + { + Configuration configuration = Validation.byDefaultProvider().configure(); + Configuration conf = configuration.traversableResolver(new JCATraversableResolver()); + + validatorFactory = conf.buildValidatorFactory(); + validator = validatorFactory.getValidator(); + } + + /** + * Get the validator factory + * @return The factory + */ + public ValidatorFactory getValidatorFactory() + { + return validatorFactory; + } + + /** + * Get the validator + * @return The validator + */ + public Validator getValidator() + { + return validator; + } + + /** + * Start + * @exception Throwable If an error occurs + */ + public void start() throws Throwable + { + Context context = null; + try + { + context = new InitialContext(); + + context.rebind(VALIDATOR_FACTORY, new SerializableValidatorFactory(validatorFactory)); + context.rebind(VALIDATOR, new SerializableValidator(validator)); + } + finally + { + try + { + if (context != null) + context.close(); + } + catch (NamingException ne) + { + // Ignore + } + } + } + + /** + * Stop + * @exception Throwable If an error occurs + */ + public void stop() throws Throwable + { + Context context = null; + try + { + context = new InitialContext(); + + context.unbind(VALIDATOR); + context.unbind(VALIDATOR_FACTORY); + } + finally + { + try + { + if (context != null) + context.close(); + } + catch (NamingException ne) + { + // Ignore + } + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/BeanValidationUtil.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/BeanValidationUtil.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/BeanValidationUtil.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,67 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.bv; + +import javax.validation.Configuration; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; + +/** + * Bean validation utility + * + * @author Jesper Pedersen + * @version $Revision: $ + */ +public class BeanValidationUtil +{ + /** + * Constructor + */ + private BeanValidationUtil() + { + } + + /** + * Create a validator factory + * @return The factory + */ + public static ValidatorFactory createValidatorFactory() + { + Configuration configuration = Validation.byDefaultProvider().configure(); + Configuration conf = configuration.traversableResolver(new JCATraversableResolver()); + + return conf.buildValidatorFactory(); + } + + /** + * Create a validator + * @return The validator + */ + public static Validator createValidator() + { + ValidatorFactory vf = createValidatorFactory(); + + return vf.getValidator(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/JCATraversableResolver.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/JCATraversableResolver.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/JCATraversableResolver.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,91 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.bv; + +import java.lang.annotation.ElementType; + +import javax.validation.Path; +import javax.validation.TraversableResolver; + +/** + * JCATraversableResolver + * @author Jeff Zhang + * @version $Revision: $ + */ +public class JCATraversableResolver implements TraversableResolver +{ + /** + * Determine if Bean Validation is allowed to reach the property state + * + * @param traversableObject + * object hosting traversableProperty or null if + * validateValue is called + * @param traversableProperty + * the traversable property. + * @param rootBeanType + * type of the root object passed to the Validator. + * @param pathToTraversableObject + * path from the root object to traversableObject + * (using the path specification defined by Bean Validator). + * @param elementType + * either FIELD or METHOD. + * + * @return true if Bean Validation is allowed to reach the + * property state, false otherwise. + */ + public boolean isReachable(Object traversableObject, Path.Node traversableProperty, + Class rootBeanType, Path pathToTraversableObject, + ElementType elementType) + { + return true; + } + + /** + * Determine if Bean Validation is allowed to cascade validation on the bean + * instance returned by the property value marked as @Valid. + * Note that this method is called only if isReachable returns true for the + * same set of arguments and if the property is marked as @Valid + * + * @param traversableObject + * object hosting traversableProperty or null if + * validateValue is called + * @param traversableProperty + * the traversable property. + * @param rootBeanType + * type of the root object passed to the Validator. + * @param pathToTraversableObject + * path from the root object to traversableObject + * (using the path specification defined by Bean Validator). + * @param elementType + * either FIELD or METHOD. + * + * @return true if Bean Validation is allowed to cascade + * validation, false otherwise. + */ + public boolean isCascadable(Object traversableObject, + Path.Node traversableProperty, Class rootBeanType, + Path pathToTraversableObject, ElementType elementType) + { + return true; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/SerializableValidator.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/SerializableValidator.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/SerializableValidator.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,137 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.bv; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.Validator; +import javax.validation.executable.ExecutableValidator; +import javax.validation.metadata.BeanDescriptor; + +/** + * Serializable validator + * + * @author Jesper Pedersen + * @version $Revision: $ + */ +public class SerializableValidator implements Validator, Serializable +{ + /** Serial version uid */ + private static final long serialVersionUID = 2L; + + /** The validator */ + private transient Validator validator; + + /** + * Constructor + */ + public SerializableValidator() + { + this(BeanValidationUtil.createValidator()); + } + + /** + * Constructor + * @param v The validator + */ + public SerializableValidator(Validator v) + { + this.validator = v; + } + + /** + * {@inheritDoc} + */ + public BeanDescriptor getConstraintsForClass(Class clazz) + { + return validator.getConstraintsForClass(clazz); + } + + /** + * {@inheritDoc} + */ + public Set> validate(T object, Class... groups) + { + return validator.validate(object, groups); + } + + /** + * {@inheritDoc} + */ + public Set> validateProperty(T object, String propertyName, Class... groups) + { + return validator.validateProperty(object, propertyName, groups); + } + + /** + * {@inheritDoc} + */ + public Set> validateValue(Class beanType, + String propertyName, + Object value, + Class... groups) + { + return validator.validateValue(beanType, propertyName, value, groups); + } + + /** + * {@inheritDoc} + */ + public T unwrap(Class type) + { + return validator.unwrap(type); + } + + /** + * {@inheritDoc} + */ + public ExecutableValidator forExecutables() + { + return validator.forExecutables(); + } + + /** + * Write the object - Nothing is written as the validator factory is transient + * @param out The output stream + * @exception IOException Thrown if an error occurs + */ + private void writeObject(ObjectOutputStream out) throws IOException + { + } + + /** + * Read the object - Nothing is read as the validator factory is transient. + * A new instance is created + * @param out The output stream + * @exception IOException Thrown if an error occurs + */ + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException + { + validator = BeanValidationUtil.createValidator(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/SerializableValidatorFactory.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/SerializableValidatorFactory.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/SerializableValidatorFactory.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,152 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.bv; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +import javax.validation.ConstraintValidatorFactory; +import javax.validation.MessageInterpolator; +import javax.validation.ParameterNameProvider; +import javax.validation.TraversableResolver; +import javax.validation.Validator; +import javax.validation.ValidatorContext; +import javax.validation.ValidatorFactory; + +/** + * Serializable validator factory + * + * @author Jesper Pedersen + * @version $Revision: $ + */ +public class SerializableValidatorFactory implements ValidatorFactory, Serializable +{ + /** Serial version uid */ + private static final long serialVersionUID = 2L; + + /** The validator factory */ + private transient ValidatorFactory validatorFactory; + + /** + * Constructor + */ + public SerializableValidatorFactory() + { + this(BeanValidationUtil.createValidatorFactory()); + } + + /** + * Constructor + * @param vf The validator factory + */ + public SerializableValidatorFactory(ValidatorFactory vf) + { + this.validatorFactory = vf; + } + + /** + * {@inheritDoc} + */ + public MessageInterpolator getMessageInterpolator() + { + return validatorFactory.getMessageInterpolator(); + } + + /** + * {@inheritDoc} + */ + public Validator getValidator() + { + return validatorFactory.getValidator(); + } + + /** + * {@inheritDoc} + */ + public ValidatorContext usingContext() + { + return validatorFactory.usingContext(); + } + + /** + * {@inheritDoc} + */ + public T unwrap(Class type) + { + return validatorFactory.unwrap(type); + } + + /** + * {@inheritDoc} + */ + public ConstraintValidatorFactory getConstraintValidatorFactory() + { + return validatorFactory.getConstraintValidatorFactory(); + } + + /** + * {@inheritDoc} + */ + public TraversableResolver getTraversableResolver() + { + return validatorFactory.getTraversableResolver(); + } + + /** + * {@inheritDoc} + */ + public ParameterNameProvider getParameterNameProvider() + { + return validatorFactory.getParameterNameProvider(); + } + + /** + * {@inheritDoc} + */ + public void close() + { + validatorFactory.close(); + } + + /** + * Write the object - Nothing is written as the validator factory is transient + * @param out The output stream + * @exception IOException Thrown if an error occurs + */ + private void writeObject(ObjectOutputStream out) throws IOException + { + } + + /** + * Read the object - Nothing is read as the validator factory is transient. + * A new instance is created + * @param out The output stream + * @exception IOException Thrown if an error occurs + */ + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException + { + validatorFactory = BeanValidationUtil.createValidatorFactory(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the bean validation service. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/AbstractConnectionManager.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/AbstractConnectionManager.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/AbstractConnectionManager.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,1077 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager; + +import org.jboss.jca.common.api.metadata.common.FlushStrategy; +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.connectionmanager.ccm.CachedConnectionManager; +import org.jboss.jca.core.api.management.ManagedEnlistmentTrace; +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.connectionmanager.listener.ConnectionState; +import org.jboss.jca.core.connectionmanager.pool.api.Pool; +import org.jboss.jca.core.spi.graceful.GracefulCallback; +import org.jboss.jca.core.spi.security.SubjectFactory; +import org.jboss.jca.core.spi.transaction.TransactionIntegration; + +import java.util.Collection; +import java.util.Set; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.resource.ResourceException; +import javax.resource.spi.ConnectionRequestInfo; +import javax.resource.spi.ManagedConnection; +import javax.resource.spi.ManagedConnectionFactory; +import javax.resource.spi.RetryableException; +import javax.resource.spi.security.PasswordCredential; +import javax.security.auth.Subject; +import javax.transaction.SystemException; +import javax.transaction.Transaction; + +import org.jboss.logging.Messages; + +/** + * AbstractConnectionManager. + * + * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +public abstract class AbstractConnectionManager implements ConnectionManager +{ + /** Empty graceful shutdown call back */ + private static final GracefulCallback EMPTY_CALL_BACK = new GracefulCallback() + { + @Override public void cancel() + { + // do nothing + } + + @Override public void done() + { + // do nothing + } + }; + + + /** Log instance */ + private final CoreLogger log; + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** The pool */ + private Pool pool; + + /** Security domain */ + private String securityDomain; + + /** SubjectFactory */ + private SubjectFactory subjectFactory; + + /** The flush strategy */ + private FlushStrategy flushStrategy; + + /** Number of retry to allocate connection */ + private int allocationRetry; + + /** Interval between retries */ + private long allocationRetryWaitMillis; + + /** Startup/ShutDown flag */ + private final AtomicBoolean shutdown = new AtomicBoolean(false); + + /** Scheduled executor for graceful shutdown */ + private ScheduledExecutorService scheduledExecutorService; + + /** Graceful job */ + private ScheduledFuture scheduledGraceful; + + /** Graceful call back. A non-null value indicates shutdown is prepared but has not started. */ + private volatile GracefulCallback gracefulCallback; + + /** Cached connection manager */ + private CachedConnectionManager cachedConnectionManager; + + /** Jndi name */ + private String jndiName; + + /** Sharable */ + private boolean sharable; + + /** Enlistment */ + protected boolean enlistment; + + /** Connectable */ + protected boolean connectable; + + /** Tracking */ + protected Boolean tracking; + + /** Enlistment trace */ + protected ManagedEnlistmentTrace enlistmentTrace; + + /** + * Creates a new instance of connection manager. + */ + protected AbstractConnectionManager() + { + this.log = getLogger(); + this.scheduledExecutorService = null; + this.scheduledGraceful = null; + this.gracefulCallback = null; + } + + /** + * Get the logger. + * @return The value + */ + protected abstract CoreLogger getLogger(); + + /** + * Set the pool. + * @param pool the pool + */ + public void setPool(Pool pool) + { + this.pool = pool; + } + + /** + * Get the pool. + * @return the pool + */ + public Pool getPool() + { + return pool; + } + + /** + * Sets cached connection manager. + * @param cachedConnectionManager cached connection manager + */ + public void setCachedConnectionManager(CachedConnectionManager cachedConnectionManager) + { + this.cachedConnectionManager = cachedConnectionManager; + } + + /** + * Gets cached connection manager. + * @return cached connection manager + */ + public CachedConnectionManager getCachedConnectionManager() + { + return cachedConnectionManager; + } + + /** + * {@inheritDoc} + */ + public boolean cancelShutdown() + { + if (scheduledGraceful != null) + { + boolean result = scheduledGraceful.cancel(false); + + if (result) + { + shutdown.set(false); + + if (gracefulCallback != null) + gracefulCallback.cancel(); + + if (pool != null) + pool.cancelShutdown(); + + scheduledGraceful = null; + gracefulCallback = null; + } + else + { + return false; + } + } + else if (shutdown.get()) + { + shutdown.set(false); + + if (gracefulCallback != null) + gracefulCallback.cancel(); + + if (pool != null) + pool.cancelShutdown(); + + gracefulCallback = null; + } + else + { + return false; + } + + return true; + } + + /** + * {@inheritDoc} + */ + public void prepareShutdown() + { + prepareShutdown(0, null); + } + + /** + * {@inheritDoc} + */ + public void prepareShutdown(GracefulCallback cb) + { + prepareShutdown(0, cb); + } + + /** + * {@inheritDoc} + */ + public void prepareShutdown(int seconds) + { + prepareShutdown(seconds, null); + } + + /** + * {@inheritDoc} + */ + public void prepareShutdown(int seconds, GracefulCallback cb) + { + shutdown.set(true); + + // use gracefulCallback as an indicator that shutdown is prepared and not started, for that reason this field + // will never be null after preparation and before shutdown (this prevents adding an extra field, + // shutdownPrepared, or having to replace shutdown by a state field) + if (gracefulCallback == null) + gracefulCallback = cb == null ? EMPTY_CALL_BACK : cb; + + if (pool != null) + pool.prepareShutdown(); + + if (seconds > 0) + { + if (scheduledGraceful == null) + { + if (scheduledExecutorService == null) + scheduledExecutorService = Executors.newScheduledThreadPool(1); + + scheduledGraceful = + scheduledExecutorService.schedule(new ConnectionManagerShutdown(this), seconds, TimeUnit.SECONDS); + } + } + else + { + if (pool != null && pool.isIdle()) + { + synchronized (this) + { + // skip shutdown if there is another thread already taking care of it + if (gracefulCallback == null) + return; + } + shutdown(); + } + } + } + + /** + * {@inheritDoc} + */ + public void shutdown() + { + getLogger().debugf("%s: shutdown", jndiName); + final GracefulCallback gracefulCallback; + final ScheduledExecutorService scheduledExecutorService; + synchronized (this) + { + shutdown.set(true); + gracefulCallback = this.gracefulCallback; + this.gracefulCallback = null; + scheduledExecutorService = this.scheduledExecutorService; + this.scheduledExecutorService = null; + } + + if (pool != null) + pool.shutdown(); + + if (scheduledExecutorService != null) + { + if (scheduledGraceful != null && !scheduledGraceful.isDone()) + scheduledGraceful.cancel(true); + + scheduledGraceful = null; + scheduledExecutorService.shutdownNow(); + } + + if (gracefulCallback != null) + { + gracefulCallback.done(); + } + } + + /** + * {@inheritDoc} + */ + public boolean isShutdown() + { + return shutdown.get(); + } + + /** + * {@inheritDoc} + */ + public int getDelay() + { + if (scheduledGraceful != null) + return (int)scheduledGraceful.getDelay(TimeUnit.SECONDS); + + if (shutdown.get()) + return Integer.MIN_VALUE; + + return Integer.MAX_VALUE; + } + + /** + * Gets jndi name. + * @return jndi name + */ + public String getJndiName() + { + return jndiName; + } + + /** + * Sets jndi name. + * @param jndiName jndi name + */ + public void setJndiName(String jndiName) + { + this.jndiName = jndiName; + } + + /** + * Is sharable + * @return The value + */ + public boolean isSharable() + { + return sharable; + } + + /** + * Set the sharable flag + * @param v The value + */ + public void setSharable(boolean v) + { + this.sharable = v; + + log.tracef("sharable=%s", sharable); + } + + /** + * Is enlistment + * @return The value + */ + public boolean isEnlistment() + { + return enlistment; + } + + /** + * Set the enlistment flag + * @param v The value + */ + public void setEnlistment(boolean v) + { + this.enlistment = v; + + log.tracef("enlistment=%s", enlistment); + } + + /** + * Is connectable + * @return The value + */ + public boolean isConnectable() + { + return connectable; + } + + /** + * Set the connectable flag + * @param v The value + */ + public void setConnectable(boolean v) + { + this.connectable = v; + + log.tracef("connectable=%s", connectable); + } + + /** + * Get tracking + * @return The value + */ + public Boolean getTracking() + { + return tracking; + } + + /** + * Set the tracking flag + * @param v The value + */ + public void setTracking(Boolean v) + { + this.tracking = v; + + log.tracef("tracking=%s", tracking); + } + + /** + * Get enlistment trace + * @return The value + */ + public ManagedEnlistmentTrace getEnlistmentTrace() + { + return enlistmentTrace; + } + + /** + * Set the enlistment trace flag + * @param v The value + */ + public void setEnlistmentTrace(ManagedEnlistmentTrace v) + { + this.enlistmentTrace = v; + + log.tracef("enlistment_trace=%s", enlistmentTrace); + } + + /** + * {@inheritDoc} + */ + public String getSecurityDomain() + { + return securityDomain; + } + + /** + * Sets security domain + * @param securityDomain security domain + */ + public void setSecurityDomain(String securityDomain) + { + this.securityDomain = securityDomain; + } + + /** + * {@inheritDoc} + */ + public SubjectFactory getSubjectFactory() + { + return subjectFactory; + } + + /** + * Sets subject factory. + * @param subjectFactory subject factory + */ + public void setSubjectFactory(SubjectFactory subjectFactory) + { + this.subjectFactory = subjectFactory; + } + + /** + * Get the flush strategy + * @return The value + */ + public FlushStrategy getFlushStrategy() + { + return flushStrategy; + } + + /** + * Set the flush strategy + * @param v The value + */ + public void setFlushStrategy(FlushStrategy v) + { + this.flushStrategy = v; + } + + /** + * Gets managed connection factory. + * @return managed connection factory + */ + public javax.resource.spi.ManagedConnectionFactory getManagedConnectionFactory() + { + if (pool == null) + { + log.tracef("No pooling strategy found! for connection manager : %s", this); + return null; + } + else + { + return pool.getManagedConnectionFactory(); + } + + } + + /** + * Set the number of allocation retries + * @param number retry number + */ + public void setAllocationRetry(int number) + { + if (number >= 0) + allocationRetry = number; + } + + /** + * Get the number of allocation retries + * @return The number of retries + */ + public int getAllocationRetry() + { + return allocationRetry; + } + + /** + * Set the wait time between each allocation retry + * @param millis wait in ms + */ + public void setAllocationRetryWaitMillis(long millis) + { + if (millis > 0) + allocationRetryWaitMillis = millis; + } + + /** + * Get the wait time between each allocation retry + * @return The millis + */ + public long getAllocationRetryWaitMillis() + { + return allocationRetryWaitMillis; + } + + /** + * Public for use in testing pooling functionality by itself. + * called by both allocateConnection and reconnect. + * + * @param subject a Subject value + * @param cri a ConnectionRequestInfo value + * @return a ManagedConnection value + * @exception ResourceException if an error occurs + */ + public ConnectionListener getManagedConnection(Subject subject, ConnectionRequestInfo cri) throws ResourceException + { + return getManagedConnection(null, subject, cri); + } + + /** + * Get the managed connection from the pool. + * + * @param transaction the transaction for track by transaction + * @param subject the subject + * @param cri the ConnectionRequestInfo + * @return a managed connection + * @exception ResourceException if an error occurs + */ + protected ConnectionListener getManagedConnection(Transaction transaction, Subject subject, + ConnectionRequestInfo cri) throws ResourceException + { + Exception failure = null; + + if (shutdown.get()) + { + throw new ResourceException(bundle.connectionManagerIsShutdown(jndiName)); + } + + // First attempt + boolean isInterrupted = Thread.interrupted(); + boolean innerIsInterrupted = false; + try + { + return pool.getConnection(transaction, subject, cri); + } + catch (ResourceException e) + { + failure = e; + + // Retry? + if (allocationRetry != 0 || e instanceof RetryableException) + { + int to = allocationRetry; + + if (allocationRetry == 0 && e instanceof RetryableException) + to = 1; + + for (int i = 0; i < to; i++) + { + if (shutdown.get()) + { + throw new ResourceException(bundle.connectionManagerIsShutdown(jndiName)); + } + + log.tracef("%s: Attempting allocation retry (%s, %s, %s)", jndiName, transaction, subject, cri); + + if (Thread.currentThread().isInterrupted()) + { + Thread.interrupted(); + innerIsInterrupted = true; + } + + try + { + if (allocationRetryWaitMillis != 0) + { + Thread.sleep(allocationRetryWaitMillis); + } + + return pool.getConnection(transaction, subject, cri); + } + catch (ResourceException re) + { + failure = re; + } + catch (InterruptedException ie) + { + failure = ie; + innerIsInterrupted = true; + } + } + } + } + catch (Exception e) + { + failure = e; + } + finally + { + if (isInterrupted || innerIsInterrupted) + { + Thread.currentThread().interrupt(); + + if (innerIsInterrupted) + throw new ResourceException(bundle.getManagedConnectionRetryWaitInterrupted(jndiName), failure); + } + } + + // If we get here all retries failed, throw the lastest failure + throw new ResourceException(bundle.unableGetManagedConnection(jndiName), failure); + } + + /** + * Kill given connection listener wrapped connection instance. + * @param bcl connection listener that wraps connection + * @param kill kill connection or not + */ + public void returnManagedConnection(org.jboss.jca.core.api.connectionmanager.listener.ConnectionListener bcl, + boolean kill) + { + // Hack - We know that we can type cast it + ConnectionListener cl = (ConnectionListener)bcl; + + Pool localStrategy = cl.getPool(); + if (localStrategy != pool || shutdown.get()) + { + kill = true; + } + + try + { + if (!kill && cl.getState().equals(ConnectionState.NORMAL)) + { + cl.tidyup(); + } + } + catch (Throwable t) + { + log.errorDuringTidyUpConnection(cl, t); + kill = true; + } + + try + { + localStrategy.returnConnection(cl, kill); + } + catch (ResourceException re) + { + // We can receive notification of an error on the connection + // before it has been assigned to the pool. Reduce the noise for + // these errors + if (kill) + { + log.debug("ResourceException killing connection", re); + } + else + { + log.resourceExceptionReturningConnection(cl.getManagedConnection(), re); + } + } + catch (Exception e) + { + try + { + // Something is very wrong, so lets set the state up-front + if (cl.getState().equals(ConnectionState.NORMAL)) + cl.setState(ConnectionState.DESTROY); + + localStrategy.returnConnection(cl, true); + } + catch (Throwable t) + { + log.throwableReturningConnection(cl.getManagedConnection(), t); + } + } + + if (shutdown.get() && pool.isIdle()) + { + synchronized (this) + { + // skip shutdown if there is another thread already taking care of it + if (gracefulCallback == null) + return; + } + shutdown(); + } + } + + /** + * {@inheritDoc} + */ + public Object allocateConnection(ManagedConnectionFactory mcf, ConnectionRequestInfo cri) throws ResourceException + { + //Check for pooling! + if (pool == null || shutdown.get()) + { + throw new ResourceException(bundle.tryingUseConnectionFactoryShutDown(jndiName)); + } + + //it is an explicit spec requirement that equals be used for matching rather than ==. + if (!pool.getManagedConnectionFactory().equals(mcf)) + { + throw new ResourceException( + bundle.wrongManagedConnectionFactorySentToAllocateConnection(pool.getManagedConnectionFactory(), mcf)); + } + + // Pick a managed connection from the pool + Subject subject = getSubject(); + ConnectionListener cl = getManagedConnection(subject, cri); + + // Tell each connection manager the managed connection is active + reconnectManagedConnection(cl); + + // Ask the managed connection for a connection + Object connection = null; + try + { + connection = cl.getManagedConnection().getConnection(subject, cri); + } + catch (Throwable t) + { + try + { + managedConnectionDisconnected(cl); + } + catch (ResourceException re) + { + log.tracef("Get exception from managedConnectionDisconnected, maybe delist() have problem %s", re); + returnManagedConnection(cl, true); + } + throw new ResourceException(bundle.uncheckedThrowableInManagedConnectionGetConnection(cl), t); + } + + // Associate managed connection with the connection + registerAssociation(cl, connection); + + if (cachedConnectionManager != null) + { + cachedConnectionManager.registerConnection(this, cl, connection); + } + + return connection; + } + + /** + * {@inheritDoc} + */ + public void associateConnection(Object connection, ManagedConnectionFactory mcf, ConnectionRequestInfo cri) + throws ResourceException + { + associateManagedConnection(connection, mcf, cri); + } + + /** + * {@inheritDoc} + */ + public ManagedConnection associateManagedConnection(Object connection, ManagedConnectionFactory mcf, + ConnectionRequestInfo cri) + throws ResourceException + { + // Check for pooling! + if (pool == null || shutdown.get()) + { + throw new ResourceException(bundle.tryingUseConnectionFactoryShutDown(jndiName)); + } + + // It is an explicit spec requirement that equals be used for matching rather than ==. + if (!pool.getManagedConnectionFactory().equals(mcf)) + { + throw new ResourceException( + bundle.wrongManagedConnectionFactorySentToAllocateConnection(pool.getManagedConnectionFactory(), mcf)); + } + + if (connection == null) + throw new ResourceException(bundle.connectionIsNull()); + + // Pick a managed connection from the pool + Subject subject = getSubject(); + ConnectionListener cl = getManagedConnection(subject, cri); + + // Tell each connection manager the managed connection is active + reconnectManagedConnection(cl); + + // Associate managed connection with the connection + cl.getManagedConnection().associateConnection(connection); + registerAssociation(cl, connection); + + if (cachedConnectionManager != null) + { + cachedConnectionManager.registerConnection(this, cl, connection); + } + + return cl.getManagedConnection(); + } + + /** + * {@inheritDoc} + */ + public boolean dissociateManagedConnection(Object connection, ManagedConnection mc, ManagedConnectionFactory mcf) + throws ResourceException + { + if (connection == null || mc == null || mcf == null) + throw new ResourceException(bundle.unableToFindConnectionListener()); + + ConnectionListener cl = getPool().findConnectionListener(mc, connection); + + if (cl != null) + { + log.tracef("DissociateManagedConnection: cl=%s, connection=%s", cl, connection); + + if (getCachedConnectionManager() != null) + { + try + { + getCachedConnectionManager().unregisterConnection(this, cl, connection); + } + catch (Throwable t) + { + log.debug("Throwable from unregisterConnection", t); + } + } + + unregisterAssociation(cl, connection); + + if (cl.getNumberOfConnections() == 0) + { + log.tracef("DissociateManagedConnection: Returning cl=%s", cl); + + cl.dissociate(); + + log.tracef("DissociateManagedConnection: isManagedConnectionFree=%s", cl.isManagedConnectionFree()); + + if (cl.isManagedConnectionFree()) + { + // TODO - clean up TSR + + returnManagedConnection(cl, false); + + return true; + } + } + } + else + { + throw new ResourceException(bundle.unableToFindConnectionListener()); + } + + return false; + } + + /** + * {@inheritDoc} + */ + public void inactiveConnectionClosed(Object connection, ManagedConnectionFactory mcf) + { + // We don't track inactive connections + } + + /** + * Unregister association. + * @param cl connection listener + * @param c connection + */ + //does NOT put the mc back in the pool if no more handles. Doing so would introduce a race condition + //whereby the mc got back in the pool while still enlisted in the tx. + //The mc could be checked out again and used before the delist occured. + public void unregisterAssociation(ConnectionListener cl, Object c) + { + cl.unregisterConnection(c); + } + + /** + * {@inheritDoc} + */ + public void lazyEnlist(ManagedConnection mc) throws ResourceException + { + // Nothing by default + } + + /** + * Invoked to reassociate a managed connection. + * + * @param cl the managed connection + * @throws ResourceException for exception + */ + protected void reconnectManagedConnection(ConnectionListener cl) throws ResourceException + { + try + { + managedConnectionReconnected(cl); + } + catch (Throwable t) + { + disconnectManagedConnection(cl); + throw new ResourceException(bundle.uncheckedThrowableInManagedConnectionReconnected(cl), t); + } + } + + /** + * Invoked when a managed connection is no longer associated + * + * @param cl the managed connection + */ + protected void disconnectManagedConnection(ConnectionListener cl) + { + try + { + managedConnectionDisconnected(cl); + } + catch (Throwable t) + { + log.uncheckedThrowableInManagedConnectionDisconnected(cl, t); + } + } + + /** + * For polymorphism. + *

+ * + * Do not invoke directly, use reconnectManagedConnection + * which does the relevent exception handling + * @param cl connection listener + * @throws ResourceException for exception + */ + protected void managedConnectionReconnected(ConnectionListener cl) throws ResourceException + { + //Nothing as default + } + + /** + * For polymorphism. + *

+ * + * Do not invoke directly, use disconnectManagedConnection + * which does the relevent exception handling + * @param cl connection listener + * @throws ResourceException for exception + */ + protected void managedConnectionDisconnected(ConnectionListener cl) throws ResourceException + { + //Nothing as default + } + + /** + * Register connection with connection listener. + * @param cl connection listener + * @param c connection + * @throws ResourceException exception + */ + private void registerAssociation(ConnectionListener cl, Object c) throws ResourceException + { + cl.registerConnection(c); + } + + /** + * {@inheritDoc} + */ + public abstract void transactionStarted(Collection conns) throws SystemException; + + /** + * {@inheritDoc} + */ + public abstract boolean isTransactional(); + + /** + * {@inheritDoc} + */ + public abstract TransactionIntegration getTransactionIntegration(); + + /** + * Get a subject + * @return The subject + */ + private Subject getSubject() + { + Subject subject = null; + + if (subjectFactory != null && securityDomain != null) + { + subject = SecurityActions.createSubject(subjectFactory, securityDomain); + + Set credentials = SecurityActions.getPasswordCredentials(subject); + if (credentials != null && credentials.size() > 0) + { + ManagedConnectionFactory pcMcf = getManagedConnectionFactory(); + for (PasswordCredential pc : credentials) + { + pc.setManagedConnectionFactory(pcMcf); + } + } + } + + log.tracef("Subject: %s", subject); + + return subject; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManager.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManager.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManager.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,144 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager; + +import org.jboss.jca.core.api.connectionmanager.ccm.CachedConnectionManager; +import org.jboss.jca.core.connectionmanager.listener.ConnectionCacheListener; +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.connectionmanager.pool.api.Pool; +import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool; +import org.jboss.jca.core.spi.graceful.GracefulShutdown; +import org.jboss.jca.core.spi.security.SubjectFactory; +import org.jboss.jca.core.spi.transaction.TransactionIntegration; + +import javax.resource.ResourceException; +import javax.resource.spi.ManagedConnection; + +/** + * Internal connection manager contract. + *

+ *

    + *
  • Responsible for managing cached connections over transactional + * components via {@link ConnectionCacheListener}
  • + *
  • Responsible for managing connection instances using event listener
  • + *
+ *

+ * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +public interface ConnectionManager extends + org.jboss.jca.core.api.connectionmanager.ConnectionManager, + ConnectionCacheListener, + GracefulShutdown +{ + /** + * Get the pool. + * @return the pool + */ + public Pool getPool(); + + /** + * Gets cached connection manager + * @return The cached connection manager + */ + public CachedConnectionManager getCachedConnectionManager(); + + /** + * Get the number of allocation retries + * @return The number of retries + */ + public int getAllocationRetry(); + + /** + * Get the wait time between each allocation retry + * @return The millis + */ + public long getAllocationRetryWaitMillis(); + + /** + * Get the JNDI name + * @return The value + */ + public String getJndiName(); + + /** + * Set the JNDI name + * @param value The value + */ + public void setJndiName(String value); + + /** + * Get the security domain. + * @return The value + */ + public String getSecurityDomain(); + + /** + * Get the subject factory + * @return The value + */ + public SubjectFactory getSubjectFactory(); + + /** + * Unregister association. + * @param cl connection listener + * @param c connection + */ + public void unregisterAssociation(ConnectionListener cl, Object c); + + /** + * Create a managed connection listener for the managed connection. + * + * @param managedConnection the managed connection + * @param mcp the managed connection pool + * @return a new connection event listener + * @throws ResourceException for any error + */ + public ConnectionListener createConnectionListener(ManagedConnection managedConnection, ManagedConnectionPool mcp) + throws ResourceException; + + /** + * Determine whether there connection is a transactional. + * + * @return whether it is a transactional or not + */ + public boolean isTransactional(); + + /** + * Get the transaction integration. + * + * @return the transaction integration + */ + public TransactionIntegration getTransactionIntegration(); + + /** + * Is sharable + * @return The value + */ + public boolean isSharable(); + + /** + * Is enlistment + * @return The value + */ + public boolean isEnlistment(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManagerFactory.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManagerFactory.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManagerFactory.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,312 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager; + +import org.jboss.jca.common.api.metadata.common.FlushStrategy; +import org.jboss.jca.core.api.connectionmanager.ccm.CachedConnectionManager; +import org.jboss.jca.core.api.management.ManagedEnlistmentTrace; +import org.jboss.jca.core.connectionmanager.notx.NoTxConnectionManagerImpl; +import org.jboss.jca.core.connectionmanager.pool.api.Pool; +import org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl; +import org.jboss.jca.core.spi.security.SubjectFactory; +import org.jboss.jca.core.spi.transaction.TransactionIntegration; + +import javax.resource.spi.TransactionSupport.TransactionSupportLevel; +import javax.transaction.TransactionManager; + +/** + * The connection manager factory. + * @author Jesper Pedersen + */ +public class ConnectionManagerFactory +{ + /** + * Constructor + */ + public ConnectionManagerFactory() + { + } + + /** + * Create a connection manager + * @param tsl The transaction support level + * @param pool The pool for the connection manager + * @param subjectFactory The subject factory + * @param securityDomain The security domain + * @param useCcm Should the CCM be used + * @param ccm The cached connection manager + * @param sharable Enable sharable connections + * @param enlistment Enable enlistment connections + * @param connectable Enable connectable connections + * @param tracking The tracking status + * @param flushStrategy The flush strategy + * @param allocationRetry The allocation retry value + * @param allocationRetryWaitMillis The allocation retry millis value + * @return The connection manager instance + */ + public NoTxConnectionManager createNonTransactional(final TransactionSupportLevel tsl, + final Pool pool, + final SubjectFactory subjectFactory, + final String securityDomain, + final boolean useCcm, + final CachedConnectionManager ccm, + final boolean sharable, + final boolean enlistment, + final boolean connectable, + final Boolean tracking, + final FlushStrategy flushStrategy, + final Integer allocationRetry, + final Long allocationRetryWaitMillis) + { + if (tsl == null) + throw new IllegalArgumentException("TransactionSupportLevel is null"); + + if (pool == null) + throw new IllegalArgumentException("Pool is null"); + + if (flushStrategy == null) + throw new IllegalArgumentException("FlushStrategy is null"); + + NoTxConnectionManagerImpl cm = null; + + switch (tsl) + { + case NoTransaction: + cm = new NoTxConnectionManagerImpl(); + break; + + case LocalTransaction: + throw new IllegalArgumentException("Transactional connection manager not supported"); + + case XATransaction: + throw new IllegalArgumentException("Transactional connection manager not supported"); + + default: + throw new IllegalArgumentException("Unknown transaction support level " + tsl); + } + + setProperties(cm, pool, + subjectFactory, securityDomain, + useCcm, ccm, + sharable, + enlistment, + connectable, + tracking, + null, + flushStrategy, + allocationRetry, allocationRetryWaitMillis, + null); + setNoTxProperties(cm); + + return cm; + } + + /** + * Create a transactional connection manager + * @param tsl The transaction support level + * @param pool The pool for the connection manager + * @param subjectFactory The subject factory + * @param securityDomain The security domain + * @param useCcm Should the CCM be used + * @param ccm The cached connection manager + * @param sharable Enable sharable connections + * @param enlistment Enable enlistment connections + * @param connectable Enable connectable connections + * @param tracking The tracking status + * @param enlistmentTrace The enlistment trace + * @param flushStrategy The flush strategy + * @param allocationRetry The allocation retry value + * @param allocationRetryWaitMillis The allocation retry millis value + * @param txIntegration The transaction manager integration + * @param interleaving Enable interleaving + * @param xaResourceTimeout The transaction timeout for XAResource + * @param isSameRMOverride Should isSameRM be overridden + * @param wrapXAResource Should XAResource be wrapped + * @param padXid Should Xids be padded + * @return The connection manager instance + */ + public TxConnectionManager createTransactional(final TransactionSupportLevel tsl, + final Pool pool, + final SubjectFactory subjectFactory, + final String securityDomain, + final boolean useCcm, + final CachedConnectionManager ccm, + final boolean sharable, + final boolean enlistment, + final boolean connectable, + final Boolean tracking, + final ManagedEnlistmentTrace enlistmentTrace, + final FlushStrategy flushStrategy, + final Integer allocationRetry, + final Long allocationRetryWaitMillis, + final TransactionIntegration txIntegration, + final Boolean interleaving, + final Integer xaResourceTimeout, + final Boolean isSameRMOverride, + final Boolean wrapXAResource, + final Boolean padXid) + { + if (tsl == null) + throw new IllegalArgumentException("TransactionSupportLevel is null"); + + if (pool == null) + throw new IllegalArgumentException("Pool is null"); + + if (txIntegration == null) + throw new IllegalArgumentException("TransactionIntegration is null"); + + if (flushStrategy == null) + throw new IllegalArgumentException("FlushStrategy is null"); + + TxConnectionManagerImpl cm = null; + + switch (tsl) + { + case NoTransaction: + throw new IllegalArgumentException("Non transactional connection manager not supported"); + + case LocalTransaction: + cm = new TxConnectionManagerImpl(txIntegration, true); + break; + + case XATransaction: + cm = new TxConnectionManagerImpl(txIntegration, false); + break; + + default: + throw new IllegalArgumentException("Unknown transaction support level " + tsl); + } + + setProperties(cm, pool, + subjectFactory, securityDomain, + useCcm, ccm, + sharable, + enlistment, + connectable, + tracking, + enlistmentTrace, + flushStrategy, + allocationRetry, allocationRetryWaitMillis, + txIntegration.getTransactionManager()); + setTxProperties(cm, interleaving, xaResourceTimeout, isSameRMOverride, wrapXAResource, padXid); + + return cm; + } + + /** + * Common properties + * @param cm The connection manager + * @param pool The pool + * @param subjectFactory The subject factory + * @param securityDomain The security domain + * @param useCcm Should the CCM be used + * @param ccm The cached connection manager + * @param sharable Enable sharable connections + * @param enlistment Enable enlistment connections + * @param connectable Enable connectable connections + * @param tracking The tracking status + * @param enlistmentTrace The enlistment trace + * @param flushStrategy The flush strategy + * @param allocationRetry The allocation retry value + * @param allocationRetryWaitMillis The allocation retry millis value + * @param tm The transaction manager + */ + private void setProperties(AbstractConnectionManager cm, + Pool pool, + SubjectFactory subjectFactory, + String securityDomain, + boolean useCcm, + CachedConnectionManager ccm, + boolean sharable, + boolean enlistment, + boolean connectable, + Boolean tracking, + ManagedEnlistmentTrace enlistmentTrace, + FlushStrategy flushStrategy, + Integer allocationRetry, + Long allocationRetryWaitMillis, + TransactionManager tm) + { + pool.setConnectionManager(cm); + cm.setPool(pool); + + cm.setSubjectFactory(subjectFactory); + cm.setSecurityDomain(securityDomain); + + cm.setFlushStrategy(flushStrategy); + + if (allocationRetry != null) + cm.setAllocationRetry(allocationRetry.intValue()); + + if (allocationRetryWaitMillis != null) + cm.setAllocationRetryWaitMillis(allocationRetryWaitMillis.longValue()); + + if (useCcm) + cm.setCachedConnectionManager(ccm); + + cm.setSharable(sharable); + cm.setEnlistment(enlistment); + cm.setConnectable(connectable); + cm.setTracking(tracking); + cm.setEnlistmentTrace(enlistmentTrace); + } + + /** + * NoTxConnectionManager properties + * @param cm The connection manager + */ + private void setNoTxProperties(NoTxConnectionManagerImpl cm) + { + } + + /** + * TxConnectionManager properties + * @param cm The connection manager + * @param interleaving Enable interleaving + * @param xaResourceTimeout The transaction timeout for XAResource + * @param isSameRMOverride Should isSameRM be overridden + * @param wrapXAResource Should XAResource be wrapped + * @param padXid Should Xids be padded + */ + private void setTxProperties(TxConnectionManagerImpl cm, + Boolean interleaving, + Integer xaResourceTimeout, + Boolean isSameRMOverride, + Boolean wrapXAResource, + Boolean padXid) + { + if (interleaving != null) + cm.setInterleaving(interleaving.booleanValue()); + + if (xaResourceTimeout != null) + cm.setXAResourceTimeout(xaResourceTimeout.intValue()); + + cm.setIsSameRMOverride(isSameRMOverride); + + if (wrapXAResource != null) + cm.setWrapXAResource(wrapXAResource.booleanValue()); + + if (padXid != null) + cm.setPadXid(padXid.booleanValue()); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManagerShutdown.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManagerShutdown.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManagerShutdown.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,49 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager; + +/** + * Shutdown a ConnectionManager + * @author Jesper Pedersen + */ +class ConnectionManagerShutdown implements Runnable +{ + private ConnectionManager cm; + + /** + * Constructor + * @param cm The connection manager + */ + ConnectionManagerShutdown(ConnectionManager cm) + { + this.cm = cm; + } + + /** + * {@inheritDoc} + */ + public void run() + { + cm.shutdown(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionRecord.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionRecord.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionRecord.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,77 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2006, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager; + +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; + +/** + * Information about a connection. + * + * @author David Jencks + * @author Adrian Brock + * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +public class ConnectionRecord +{ + private ConnectionListener connectionListener; + private final Object connection; + + /** + * Creates a new connection record. + * @param cl connection listener + * @param connection connection handle + */ + public ConnectionRecord (final org.jboss.jca.core.api.connectionmanager.listener.ConnectionListener cl, + final Object connection) + { + this.connectionListener = (ConnectionListener)cl; + this.connection = connection; + } + + /** + * Get the connection listener + * @return The listener + */ + public ConnectionListener getConnectionListener() + { + return connectionListener; + } + + /** + * Set the connection listener + * @param cl The listener + */ + void setConnectionListener(ConnectionListener cl) + { + this.connectionListener = cl; + } + + /** + * Get the connection + * @return The connection + */ + public Object getConnection() + { + return connection; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/NoTxConnectionManager.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/NoTxConnectionManager.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/NoTxConnectionManager.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,31 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager; + +/** + * Internal connection manager contract for non-transactional contexts. + * + * @author Jesper Pedersen + */ +public interface NoTxConnectionManager extends ConnectionManager +{ +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,85 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager; + +import org.jboss.jca.core.spi.security.SubjectFactory; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Set; + +import javax.resource.spi.security.PasswordCredential; +import javax.security.auth.Subject; + +/** + * Privileged Blocks + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Constructor + */ + private SecurityActions() + { + } + + /** + * Get a Subject instance + * @param subjectFactory The subject factory + * @param domain The domain + * @return The instance + */ + static Subject createSubject(final SubjectFactory subjectFactory, final String domain) + { + if (System.getSecurityManager() == null) + return subjectFactory.createSubject(domain); + + return AccessController.doPrivileged(new PrivilegedAction() + { + public Subject run() + { + return subjectFactory.createSubject(domain); + } + }); + } + + /** + * Get the PasswordCredential from the Subject + * @param subject The subject + * @return The instances + */ + static Set getPasswordCredentials(final Subject subject) + { + if (System.getSecurityManager() == null) + return subject.getPrivateCredentials(PasswordCredential.class); + + return AccessController.doPrivileged(new PrivilegedAction>() + { + public Set run() + { + return subject.getPrivateCredentials(PasswordCredential.class); + } + }); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/TxConnectionManager.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/TxConnectionManager.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/TxConnectionManager.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,79 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager; + +import org.jboss.jca.core.spi.transaction.TransactionTimeoutConfiguration; + +/** + * Internal connection manager contract for transactional contexts. + *

+ *

    + *
  • Responsible for managing transaction operations via {@link TransactionTimeoutConfiguration}
  • + *
+ *

+ * + * @author Jesper Pedersen + */ +public interface TxConnectionManager extends ConnectionManager, TransactionTimeoutConfiguration +{ + /** + * Get the interleaving status + * @return True if interleaving; otherwise false + */ + public boolean isInterleaving(); + + /** + * Get the local transaction status + * @return True if local transactions; false if XA + */ + public boolean isLocalTransactions(); + + /** + * Get the XA resource transaction time out in seconds + * @return The value + */ + public int getXAResourceTimeout(); + + /** + * Get the IsSameRMOverride status + * @return null if no override; else true or false + */ + public Boolean getIsSameRMOverride(); + + /** + * Get the wrap XAResource status + * @return True if XAResource instances are wrapped; otherwise false + */ + public boolean getWrapXAResource(); + + /** + * Get the PadXid status + * @return True if Xids are padded; otherwise false + */ + public boolean getPadXid(); + + /** + * Is allow marked for rollback enabled + * @return True if set, otherwise false + */ + public boolean isAllowMarkedForRollback(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/CachedConnectionManagerImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/CachedConnectionManagerImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/CachedConnectionManagerImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,741 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2015, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.ccm; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.connectionmanager.ccm.CachedConnectionManager; +import org.jboss.jca.core.connectionmanager.ConnectionRecord; +import org.jboss.jca.core.connectionmanager.listener.ConnectionCacheListener; +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.connectionmanager.transaction.TransactionSynchronizer; +import org.jboss.jca.core.spi.transaction.TransactionIntegration; +import org.jboss.jca.core.spi.transaction.TxUtils; +import org.jboss.jca.core.tracer.Tracer; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.WeakHashMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.resource.ResourceException; +import javax.transaction.Synchronization; +import javax.transaction.SystemException; +import javax.transaction.Transaction; +import javax.transaction.TransactionManager; +import javax.transaction.TransactionSynchronizationRegistry; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * CacheConnectionManager. + * + * @author Jesper Pedersen + */ +public class CachedConnectionManagerImpl implements CachedConnectionManager +{ + /** Log instance */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + CachedConnectionManager.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** Debugging flag */ + private boolean debug = false; + + /** Enabled error handling for debugging */ + private boolean error = false; + + /** Ignore unknown connections */ + private boolean ignoreConnections = false; + + /** Transaction integration */ + private TransactionIntegration transactionIntegration; + + /** + * ThreadLocal that holds current calling meta-programming aware + * object, used in case someone is idiotic enough to cache a + * connection between invocations.and want the spec required + * behavior of it getting hooked up to an appropriate + * ManagedConnection on each method invocation. + */ + private final ThreadLocal> currentObjects = + new ThreadLocal>(); + + /** + * The variable objectToConnectionManagerMap holds the + * map of meta-aware object to set of connections it holds, used by + * the idiot spec compliant behavior. + */ + private final ConcurrentMap>> + objectToConnectionManagerMap = new ConcurrentHashMap>>(); + + /** + * Connection stacktraces + */ + private final Map connectionStackTraces = new WeakHashMap(); + + /** + * Creates a new instance. + * @param transactionIntegration The transaction integration + */ + public CachedConnectionManagerImpl(TransactionIntegration transactionIntegration) + { + if (transactionIntegration == null) + throw new IllegalArgumentException("TransactionIntegration is null"); + + this.transactionIntegration = transactionIntegration; + } + + /** + * Gets transaction manager. + * @return transaction manager + */ + public TransactionManager getTransactionManager() + { + return transactionIntegration.getTransactionManager(); + } + + /** + * Gets transaction synchronization registry + * @return TransactionSynchronizationRegistry + */ + public TransactionSynchronizationRegistry getTransactionSynchronizationRegistry() + { + return transactionIntegration.getTransactionSynchronizationRegistry(); + } + + /** + * {@inheritDoc} + */ + public boolean isDebug() + { + return debug; + } + + /** + * {@inheritDoc} + */ + public void setDebug(boolean v) + { + debug = v; + } + + /** + * {@inheritDoc} + */ + public boolean isError() + { + return error; + } + + /** + * {@inheritDoc} + */ + public void setError(boolean v) + { + error = v; + } + + /** + * {@inheritDoc} + */ + public boolean isIgnoreUnknownConnections() + { + return ignoreConnections; + } + + /** + * {@inheritDoc} + */ + public void setIgnoreUnknownConnections(boolean v) + { + ignoreConnections = v; + } + + /** + * {@inheritDoc} + */ + public void start() + { + if (transactionIntegration.getUserTransactionRegistry() != null) + transactionIntegration.getUserTransactionRegistry().addListener(this); + + log.debugf("start: %s", this.toString()); + } + + /** + * {@inheritDoc} + */ + public void stop() + { + log.debugf("stop: %s", this.toString()); + + if (transactionIntegration.getUserTransactionRegistry() != null) + transactionIntegration.getUserTransactionRegistry().removeListener(this); + } + + /** + * {@inheritDoc} + */ + public void userTransactionStarted() throws SystemException + { + KeyConnectionAssociation key = peekMetaAwareObject(); + + log.tracef("user tx started, key: %s", key); + + if (key != null) + { + ConcurrentMap> cmToConnectionsMap = + key.getCMToConnectionsMap(); + + Iterator>> cmToConnectionsMapIterator = + cmToConnectionsMap.entrySet().iterator(); + + while (cmToConnectionsMapIterator.hasNext()) + { + Entry> entry = + cmToConnectionsMapIterator.next(); + + ConnectionCacheListener cm = entry.getKey(); + CopyOnWriteArrayList conns = entry.getValue(); + + if (Tracer.isEnabled()) + { + for (ConnectionRecord cr : conns) + { + ConnectionListener cl = (ConnectionListener)cr.getConnectionListener(); + Tracer.ccmUserTransaction(cl.getPool().getName(), cl.getManagedConnectionPool(), + cl, cr.getConnection(), key.toString()); + } + } + + cm.transactionStarted(conns); + } + } + } + + /** + * + * @return stack last meta-aware object + */ + private KeyConnectionAssociation peekMetaAwareObject() + { + LinkedList stack = currentObjects.get(); + + if (stack != null && !stack.isEmpty()) + { + return stack.getLast(); + } + + return null; + } + + + /** + * {@inheritDoc} + */ + @SuppressWarnings("unchecked") + public void popMetaAwareObject(Set unsharableResources) throws ResourceException + { + LinkedList stack = currentObjects.get(); + KeyConnectionAssociation oldKey = stack.removeLast(); + + log.tracef("popped object: %s", oldKey); + + if (Tracer.isEnabled()) + Tracer.popCCMContext(oldKey.toString(), new Throwable("CALLSTACK")); + + if (debug) + { + if (closeAll(oldKey) && error) + { + throw new ResourceException(bundle.someConnectionsWereNotClosed()); + } + } + } + + /** + * Register connection. + * @param cm connection manager + * @param cl connection listener + * @param connection connection handle + */ + public void registerConnection(org.jboss.jca.core.api.connectionmanager.listener.ConnectionCacheListener cm, + org.jboss.jca.core.api.connectionmanager.listener.ConnectionListener cl, + Object connection) + { + if (debug) + { + synchronized (connectionStackTraces) + { + connectionStackTraces.put(connection, new Throwable("STACKTRACE")); + } + } + + KeyConnectionAssociation key = peekMetaAwareObject(); + + log.tracef("registering connection from connection manager: %s, connection : %s, key: %s", + cm, connection, key); + + if (key != null) + { + if (Tracer.isEnabled()) + { + ConnectionListener l = (ConnectionListener)cl; + Tracer.registerCCMConnection(l.getPool().getName(), l.getManagedConnectionPool(), + l, connection, key.toString()); + } + + ConnectionRecord cr = new ConnectionRecord(cl, connection); + ConcurrentMap> cmToConnectionsMap = + key.getCMToConnectionsMap(); + + CopyOnWriteArrayList conns = cmToConnectionsMap.get(cm); + if (conns == null) + { + conns = new CopyOnWriteArrayList(); + cmToConnectionsMap.put((ConnectionCacheListener)cm, conns); + } + + conns.add(cr); + } + } + + /** + * Unregister connection. + * @param cm connection manager + * @param cl connection listener + * @param connection connection handle + */ + public void unregisterConnection(org.jboss.jca.core.api.connectionmanager.listener.ConnectionCacheListener cm, + org.jboss.jca.core.api.connectionmanager.listener.ConnectionListener cl, + Object connection) + { + if (debug) + { + CloseConnectionSynchronization cas = getCloseConnectionSynchronization(false); + if (cas != null) + { + cas.remove(connection); + } + + synchronized (connectionStackTraces) + { + connectionStackTraces.remove(connection); + } + } + + KeyConnectionAssociation key = peekMetaAwareObject(); + + log.tracef("unregistering connection from connection manager: %s, connection: %s, key: %s", + cm, connection, key); + + if (key == null) + return; + + ConcurrentMap> cmToConnectionsMap = + key.getCMToConnectionsMap(); + + CopyOnWriteArrayList conns = cmToConnectionsMap.get(cm); + + // Can happen if connections are "passed" between contexts + if (conns == null) + return; + + // Note iterator of CopyOnWriteArrayList does not support remove method + // We use here remove on CopyOnWriteArrayList directly + for (ConnectionRecord connectionRecord : conns) + { + if (connectionRecord.getConnection() == connection) + { + if (Tracer.isEnabled()) + { + ConnectionListener l = (ConnectionListener)cl; + Tracer.unregisterCCMConnection(l.getPool().getName(), l.getManagedConnectionPool(), + l, connection, key.toString()); + } + + conns.remove(connectionRecord); + return; + } + } + + if (Tracer.isEnabled()) + { + ConnectionListener l = (ConnectionListener)cl; + Tracer.unknownCCMConnection(l.getPool().getName(), l.getManagedConnectionPool(), + l, connection, key.toString()); + } + + if (!ignoreConnections) + throw new IllegalStateException(bundle.tryingToReturnUnknownConnection(connection.toString())); + } + + /** + * {@inheritDoc} + */ + @SuppressWarnings("unchecked") + public void pushMetaAwareObject(final Object rawKey, Set unsharableResources) throws ResourceException + { + LinkedList stack = currentObjects.get(); + KeyConnectionAssociation key = new KeyConnectionAssociation(rawKey); + + if (stack == null) + { + log.tracef("new stack for key: %s", key); + + stack = new LinkedList(); + currentObjects.set(stack); + } + else if (stack.isEmpty()) + { + log.tracef("new stack for key: %s", key); + } + else + { + log.tracef("old stack for key: %s", stack.getLast()); + log.tracef("new stack for key: %s", key); + } + + if (Tracer.isEnabled()) + Tracer.pushCCMContext(key.toString(), new Throwable("CALLSTACK")); + + stack.addLast(key); + } + + /** + * Describe unregisterConnectionCacheListener method here. + * This is a shutdown method called by a connection manager. It will remove all reference + * to that connection manager from the cache, so cached connections from that manager + * will never be recoverable. + * Possibly this method should not exist. + * + * @param cm a ConnectionCacheListener value + */ + public void unregisterConnectionCacheListener(ConnectionCacheListener cm) + { + log.tracef("unregisterConnectionCacheListener: %s", cm); + + Iterator>> it = + objectToConnectionManagerMap.values().iterator(); + + while (it.hasNext()) + { + ConcurrentMap> cmToConnectionsMap = it.next(); + + if (cmToConnectionsMap != null) + cmToConnectionsMap.remove(cm); + } + } + + /** + * {@inheritDoc} + */ + public int getNumberOfConnections() + { + if (!debug) + return 0; + + synchronized (connectionStackTraces) + { + return connectionStackTraces.size(); + } + } + + /** + * {@inheritDoc} + */ + public Map listConnections() + { + if (!debug) + return Collections.unmodifiableMap(Collections.EMPTY_MAP); + + synchronized (connectionStackTraces) + { + HashMap result = new HashMap(); + + for (Map.Entry entry : connectionStackTraces.entrySet()) + { + Object key = entry.getKey(); + Throwable stackTrace = entry.getValue(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(baos, true); + stackTrace.printStackTrace(ps); + + result.put(key.toString(), baos.toString()); + } + + return Collections.unmodifiableMap(result); + } + } + + /** + * Close all connections. + * @param key The key + * @return true if close + */ + private boolean closeAll(KeyConnectionAssociation key) + { + ConcurrentMap> cmToConnectionsMap = + key.getCMToConnectionsMap(); + boolean unclosed = false; + + Collection> connections = cmToConnectionsMap.values(); + if (connections.size() != 0) + { + for (Iterator> i = connections.iterator(); i.hasNext();) + { + CopyOnWriteArrayList conns = i.next(); + for (ConnectionRecord cr : conns) + { + Object c = cr.getConnection(); + CloseConnectionSynchronization cas = getCloseConnectionSynchronization(true); + if (cas == null) + { + unclosed = true; + + if (Tracer.isEnabled()) + { + ConnectionListener cl = (ConnectionListener)cr.getConnectionListener(); + Tracer.closeCCMConnection(cl.getPool().getName(), cl.getManagedConnectionPool(), + cl, c, key.toString()); + } + + closeConnection(c); + } + else + { + cas.add(c); + } + } + } + } + + return unclosed; + } + + /** + * Gets close sync. instance. + * @param createIfNotFound create if not found + * @return sync. instance + */ + private CloseConnectionSynchronization getCloseConnectionSynchronization(boolean createIfNotFound) + { + try + { + Transaction tx = null; + if (getTransactionManager() != null) + { + tx = getTransactionManager().getTransaction(); + } + + if (tx != null) + { + if (createIfNotFound) + TransactionSynchronizer.lock(tx, transactionIntegration); + try + { + CloseConnectionSynchronization cas = + (CloseConnectionSynchronization)TransactionSynchronizer.getCCMSynchronization(tx, + transactionIntegration); + + if (cas == null && createIfNotFound && TxUtils.isActive(tx)) + { + cas = new CloseConnectionSynchronization(); + TransactionSynchronizer.registerCCMSynchronization(tx, cas, transactionIntegration); + } + + return cas; + } + finally + { + if (createIfNotFound) + TransactionSynchronizer.unlock(tx, transactionIntegration); + } + } + } + catch (Throwable t) + { + log.debug("Unable to synchronize with transaction", t); + } + + return null; + } + + + /** + * Close connection handle. + * @param connectionHandle connection handle + */ + private void closeConnection(Object connectionHandle) + { + try + { + Throwable exception; + + synchronized (connectionStackTraces) + { + exception = connectionStackTraces.remove(connectionHandle); + } + + Method m = SecurityActions.getMethod(connectionHandle.getClass(), "close", new Class[]{}); + + try + { + if (exception != null) + { + log.closingConnection(connectionHandle, exception); + } + else + { + log.closingConnection(connectionHandle); + } + + m.invoke(connectionHandle, new Object[]{}); + } + catch (Throwable t) + { + log.closingConnectionThrowable(t); + } + } + catch (NoSuchMethodException nsme) + { + log.closingConnectionNoClose(connectionHandle.getClass().getName()); + } + } + + + /** + * Close synch. class. + */ + private class CloseConnectionSynchronization implements Synchronization + { + /**Connection handles*/ + CopyOnWriteArraySet connections = new CopyOnWriteArraySet(); + + /**Closing flag*/ + AtomicBoolean closing = new AtomicBoolean(false); + + /** + * Creates a new instance. + */ + public CloseConnectionSynchronization() + { + } + + /** + * Add new connection handle. + * @param c connection handle + */ + public void add(Object c) + { + if (!closing.get()) + connections.add(c); + } + + /** + * Removes connection handle. + * @param c connection handle + */ + public void remove(Object c) + { + if (!closing.get()) + connections.remove(c); + } + + /** + * {@inheritDoc} + */ + public void beforeCompletion() + { + // No-action + } + + /** + * {@inheritDoc} + */ + public void afterCompletion(int status) + { + closing.set(true); + + for (Iterator i = connections.iterator(); i.hasNext();) + { + closeConnection(i.next()); + } + + connections.clear(); + } + } + + /** + * Get the currentObjects. + * This method is package protected beacause it is intended only for test case use. + * Please don't use it in your production code. + * + * @return the currentObjects. + */ + final ThreadLocal> getCurrentObjects() + { + return currentObjects; + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("CachedConnectionManagerImpl@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[debug=").append(debug); + sb.append(" error=").append(error); + sb.append(" ignoreConnections=").append(ignoreConnections); + sb.append(" transactionIntegration=").append(transactionIntegration); + sb.append(" currentObjects=").append(currentObjects.get()); + sb.append(" objectToConnectionManagerMap=").append(objectToConnectionManagerMap); + sb.append(" connectionStackTraces=").append(connectionStackTraces); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/KeyConnectionAssociation.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/KeyConnectionAssociation.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/KeyConnectionAssociation.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,108 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.ccm; + +import org.jboss.jca.core.connectionmanager.ConnectionRecord; +import org.jboss.jca.core.connectionmanager.listener.ConnectionCacheListener; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * The class KeyConnectionAssociation wraps objects so they may be used in hashmaps + * based on their object identity rather than equals implementation. Used for keys. + * + * @author Gurkan Erdogdu + * @version $Rev$ + */ +final class KeyConnectionAssociation +{ + //key + private final Object metaAwareObject; + + //map of cm to list of connections for that cm. + private ConcurrentMap> cmToConnectionsMap; + + /** + * Creates a new instance. + * @param metaAwareObject meta aware object + */ + KeyConnectionAssociation(final Object metaAwareObject) + { + this.metaAwareObject = metaAwareObject; + } + + /** + * {@inheritDoc} + */ + public boolean equals(Object other) + { + if (other == this) + return true; + + if (other == null || !(other instanceof KeyConnectionAssociation)) + return false; + + KeyConnectionAssociation kca = (KeyConnectionAssociation)other; + + return metaAwareObject.equals(kca.metaAwareObject); + } + + /** + * {@inheritDoc} + */ + public String toString() + { + return metaAwareObject.getClass().getName() + '@' + Integer.toHexString(System.identityHashCode(metaAwareObject)); + } + + /** + * {@inheritDoc} + */ + public int hashCode() + { + return System.identityHashCode(metaAwareObject); + } + + /** + * Set map instance. + * @param cmToConnectionsMap connection manager to connections + */ + public void setCMToConnectionsMap(ConcurrentMap> cmToConnectionsMap) + { + this.cmToConnectionsMap = cmToConnectionsMap; + } + + /** + * + * @return map instance + */ + public ConcurrentMap> getCMToConnectionsMap() + { + if (cmToConnectionsMap == null) + cmToConnectionsMap = new ConcurrentHashMap>(); + + return cmToConnectionsMap; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,76 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.ccm; + +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Constructor + */ + private SecurityActions() + { + } + + /** + * Get the method + * @param c The class + * @param name The name + * @param params The parameters + * @return The method + * @exception NoSuchMethodException If a matching method is not found. + */ + static Method getMethod(final Class c, final String name, final Class... params) + throws NoSuchMethodException + { + if (System.getSecurityManager() == null) + return c.getMethod(name, params); + + Method result = AccessController.doPrivileged(new PrivilegedAction() + { + public Method run() + { + try + { + return c.getMethod(name, params); + } + catch (NoSuchMethodException e) + { + return null; + } + } + }); + + if (result != null) + return result; + + throw new NoSuchMethodException(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the cached connection manager. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/AbstractConnectionListener.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/AbstractConnectionListener.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/AbstractConnectionListener.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,736 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.listener; + +import org.jboss.jca.common.api.metadata.common.FlushStrategy; +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.connectionmanager.ccm.CachedConnectionManager; +import org.jboss.jca.core.api.connectionmanager.pool.FlushMode; +import org.jboss.jca.core.connectionmanager.ConnectionManager; +import org.jboss.jca.core.connectionmanager.pool.api.Pool; +import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool; +import org.jboss.jca.core.spi.transaction.ConnectableResourceListener; +import org.jboss.jca.core.tracer.Tracer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.resource.ResourceException; +import javax.resource.spi.ConnectionEvent; +import javax.resource.spi.ManagedConnection; +import javax.transaction.SystemException; + +import org.jboss.logging.Messages; + +/** + * Abstract implementation of the {@link ConnectionListener} interface + * contract. + * + * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +public abstract class AbstractConnectionListener implements ConnectionListener, ConnectableResourceListener +{ + private final CoreLogger log; + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** Connection Manager */ + private final ConnectionManager cm; + + /** Managed connection */ + private final ManagedConnection managedConnection; + + /** Pool for this connection */ + private final Pool pool; + + /** Managed connection pool */ + private final ManagedConnectionPool managedConnectionPool; + + /** Flush strategy */ + private FlushStrategy flushStrategy; + + /** Connection State */ + private ConnectionState state = ConnectionState.NORMAL; + + /** Connection handles */ + protected CopyOnWriteArraySet connectionHandles = new CopyOnWriteArraySet(); + + /** Connection traces */ + protected Map connectionTraces; + + /** Track by transaction or not */ + private final AtomicBoolean trackByTx = new AtomicBoolean(false); + + /** Connection last returned */ + private long lastReturned; + + /** Connection last validated time */ + private long lastValidated; + + /** Connection check out time */ + private long lastCheckedOut; + + /** Enlisted */ + private boolean enlisted; + + /** Tracking */ + protected Boolean tracking; + + /** The reported exception */ + private Exception reportedException; + + /** + * Creates a new instance of the listener that is responsible for + * tracking the owned connection instance. + * @param cm connection manager + * @param managedConnection managed connection + * @param pool pool + * @param mcp managed connection pool + * @param flushStrategy flushStrategy + * @param tracking tracking + */ + protected AbstractConnectionListener(ConnectionManager cm, ManagedConnection managedConnection, + Pool pool, ManagedConnectionPool mcp, FlushStrategy flushStrategy, + Boolean tracking) + { + this.cm = cm; + this.managedConnection = managedConnection; + this.pool = pool; + this.managedConnectionPool = mcp; + this.flushStrategy = flushStrategy; + this.log = getLogger(); + this.enlisted = false; + + long createdTime = System.currentTimeMillis(); + this.lastReturned = createdTime; + this.lastValidated = createdTime; + this.lastCheckedOut = createdTime; + + this.tracking = tracking; + + if (tracking != null && tracking.booleanValue()) + this.connectionTraces = new HashMap(); + + this.reportedException = null; + } + + /** + * Gets cached connection manager + * @return cached connection manager + */ + protected CachedConnectionManager getCachedConnectionManager() + { + return cm.getCachedConnectionManager(); + } + + /** + * Gets connection manager. + * @return connection manager + */ + protected ConnectionManager getConnectionManager() + { + return cm; + } + + /** + * Get the logger + * @return The value + */ + protected abstract CoreLogger getLogger(); + + /** + * {@inheritDoc} + */ + public int getNumberOfConnections() + { + return connectionHandles.size(); + } + + /** + * {@inheritDoc} + */ + public boolean isEnlisted() + { + return enlisted; + } + + /** + * Set the enlisted flag + * @param v The value + */ + void setEnlisted(boolean v) + { + enlisted = v; + } + + /** + * {@inheritDoc} + */ + public boolean delist() throws ResourceException + { + return true; + } + + /** + * {@inheritDoc} + */ + public void enlist() throws SystemException + { + } + + /** + * {@inheritDoc} + */ + public ManagedConnectionPool getManagedConnectionPool() + { + return managedConnectionPool; + } + + /** + * {@inheritDoc} + */ + public long getLastValidatedTime() + { + return lastValidated; + } + + /** + * {@inheritDoc} + */ + public long getLastReturnedTime() + { + return lastReturned; + } + + /** + * {@inheritDoc} + */ + public long getLastCheckedOutTime() + { + return lastCheckedOut; + } + + /** + * {@inheritDoc} + */ + public void setLastCheckedOutTime(long v) + { + lastCheckedOut = v; + } + + /** + * {@inheritDoc} + */ + public ManagedConnection getManagedConnection() + { + return managedConnection; + } + + /** + * {@inheritDoc} + */ + public Pool getPool() + { + return pool; + } + + /** + * {@inheritDoc} + */ + public ConnectionState getState() + { + return state; + } + + /** + * {@inheritDoc} + */ + public boolean isManagedConnectionFree() + { + if (log.isTraceEnabled()) + log.tracef("[%s] isManagedConnectionFree: %s", getIdentifier(), connectionHandles.isEmpty()); + + return connectionHandles.isEmpty(); + } + + /** + * {@inheritDoc} + */ + public boolean isTimedOut(long timeout) + { + return lastReturned < timeout; + } + + /** + * {@inheritDoc} + */ + public boolean isTrackByTx() + { + return trackByTx.get(); + } + + /** + * {@inheritDoc} + */ + public void registerConnection(Object handle) + { + if (handle != null) + { + connectionHandles.add(handle); + + if (Tracer.isEnabled()) + Tracer.getConnection(pool != null ? pool.getName() : null, managedConnectionPool, this, handle); + + if (log.isTraceEnabled()) + log.tracef("[%s] registerConnection: %s [size=%s] (%s)", getIdentifier(), handle, + connectionHandles.size(), connectionHandles); + + if (tracking != null && tracking.booleanValue()) + connectionTraces.put(handle, new Exception()); + } + else + { + log.registeredNullHandleManagedConnection(managedConnection); + } + } + + /** + * {@inheritDoc} + */ + public void setLastValidatedTime(long lastValidated) + { + this.lastValidated = lastValidated; + } + + /** + * {@inheritDoc} + */ + public void setState(ConnectionState newState) + { + this.state = newState; + } + + /** + * {@inheritDoc} + */ + public void setTrackByTx(boolean trackByTx) + { + this.trackByTx.set(trackByTx); + } + + /** + * {@inheritDoc} + */ + public void tidyup() throws ResourceException + { + } + + /** + * {@inheritDoc} + */ + public void unregisterConnection(Object handle) + { + if (handle != null) + { + if (!connectionHandles.remove(handle)) + { + log.unregisteredHandleNotRegistered(handle, managedConnection); + } + + if (Tracer.isEnabled()) + Tracer.returnConnection(pool != null ? pool.getName() : null, managedConnectionPool, this, handle); + + if (tracking != null && tracking.booleanValue()) + connectionTraces.remove(handle); + } + else + { + log.unregisteredNullHandleManagedConnection(managedConnection); + } + + if (log.isTraceEnabled()) + log.tracef("[%s] unregisterConnection: " + connectionHandles.size() + " handles left (%s)", + getIdentifier(), connectionHandles); + } + + /** + * Unregister connections. + */ + public void unregisterConnections() + { + if (log.isTraceEnabled()) + log.tracef("[%s] unregisterConnections", getIdentifier()); + + if (getCachedConnectionManager() != null) + { + for (Object handle : connectionHandles) + { + getCachedConnectionManager().unregisterConnection(getConnectionManager(), this, handle); + } + } + + if (Tracer.isEnabled()) + { + for (Object handle : connectionHandles) + { + Tracer.returnConnection(pool != null ? pool.getName() : null, managedConnectionPool, this, handle); + } + } + + connectionHandles.clear(); + + if (tracking != null && tracking.booleanValue()) + connectionTraces.clear(); + } + + + /** + * {@inheritDoc} + */ + public void toPool() + { + lastReturned = System.currentTimeMillis(); + } + + /** + * {@inheritDoc} + */ + public void connectionClosed(ConnectionEvent event) + { + } + + /** + * {@inheritDoc} + */ + public void connectionErrorOccurred(ConnectionEvent event) + { + if (state == ConnectionState.NORMAL) + { + if (event != null) + { + Exception cause = event.getException(); + if (cause == null) + { + cause = new Exception("No exception was reported"); + } + else + { + reportedException = cause; + } + + log.connectionErrorOccured(this, cause); + } + else + { + Exception cause = new Exception("No exception was reported"); + log.unknownConnectionErrorOccured(this, cause); + } + } + + try + { + unregisterConnections(); + } + catch (Throwable t) + { + //ignore, it wasn't checked out. + } + + if (event != null && event.getSource() != getManagedConnection()) + { + log.notifiedErrorDifferentManagedConnection(); + } + + haltCatchFire(); + + getConnectionManager().returnManagedConnection(this, true); + + if (flushStrategy == FlushStrategy.FAILING_CONNECTION_ONLY) + { + managedConnectionPool.prefill(); + } + else if (flushStrategy == FlushStrategy.INVALID_IDLE_CONNECTIONS) + { + Collection toDestroy = new ArrayList(); + managedConnectionPool.flush(FlushMode.INVALID, toDestroy); + for (ConnectionListener connectionListener: toDestroy) + { + connectionListener.destroy(); + } + } + else if (flushStrategy == FlushStrategy.IDLE_CONNECTIONS) + { + Collection toDestroy = new ArrayList(); + managedConnectionPool.flush(FlushMode.IDLE, toDestroy); + for (ConnectionListener connectionListener: toDestroy) + { + connectionListener.destroy(); + } + } + else if (flushStrategy == FlushStrategy.GRACEFULLY) + { + Collection toDestroy = new ArrayList(); + managedConnectionPool.flush(FlushMode.GRACEFULLY, toDestroy); + for (ConnectionListener connectionListener: toDestroy) + { + connectionListener.destroy(); + } + } + else if (flushStrategy == FlushStrategy.ENTIRE_POOL) + { + Collection toDestroy = new ArrayList(); + managedConnectionPool.flush(FlushMode.ALL, toDestroy); + for (ConnectionListener connectionListener: toDestroy) + { + connectionListener.destroy(); + } + } + else if (flushStrategy == FlushStrategy.ALL_INVALID_IDLE_CONNECTIONS) + { + pool.flush(FlushMode.INVALID); + } + else if (flushStrategy == FlushStrategy.ALL_IDLE_CONNECTIONS) + { + pool.flush(FlushMode.IDLE); + } + else if (flushStrategy == FlushStrategy.ALL_GRACEFULLY) + { + pool.flush(FlushMode.GRACEFULLY); + } + else if (flushStrategy == FlushStrategy.ALL_CONNECTIONS) + { + pool.flush(FlushMode.ALL); + } + } + + /** + * {@inheritDoc} + */ + public Exception getException() + { + return reportedException; + } + + /** + * {@inheritDoc} + */ + public boolean controls(ManagedConnection mc, Object connection) + { + if (managedConnection.equals(mc)) + { + if (connection == null || connectionHandles.contains(connection)) + return true; + } + + return false; + } + + /** + * {@inheritDoc} + */ + public void dissociate() throws ResourceException + { + // Nothing by default + } + + /** + * {@inheritDoc} + */ + public boolean supportsLazyAssociation() + { + return managedConnection instanceof javax.resource.spi.DissociatableManagedConnection; + } + + /** + * {@inheritDoc} + */ + public boolean supportsLazyEnlistment() + { + return managedConnection instanceof javax.resource.spi.LazyEnlistableManagedConnection; + } + + /** + * {@inheritDoc} + */ + public void localTransactionCommitted(ConnectionEvent event) + { + } + + /** + * {@inheritDoc} + */ + public void localTransactionRolledback(ConnectionEvent event) + { + } + + /** + * {@inheritDoc} + */ + public void localTransactionStarted(ConnectionEvent event) + { + } + + /** + * {@inheritDoc} + */ + public void handleCreated(Object h) + { + registerConnection(h); + + if (getCachedConnectionManager() != null) + { + getCachedConnectionManager().registerConnection(getConnectionManager(), this, h); + } + } + + /** + * {@inheritDoc} + */ + public void handleClosed(Object h) + { + } + + /** + * {@inheritDoc} + */ + public void destroy() + { + if (getState() == ConnectionState.DESTROYED) + { + log.tracef("ManagedConnection is already destroyed %s", this); + return; + } + + getManagedConnectionPool().connectionListenerDestroyed(this); + + setState(ConnectionState.DESTROYED); + + final ManagedConnection mc = getManagedConnection(); + try + { + mc.destroy(); + } + catch (Throwable t) + { + if (log.isDebugEnabled()) + log.debug("Exception destroying ManagedConnection " + this, t); + } + + mc.removeConnectionEventListener(this); + } + + /** + * Halt and Catch Fire + */ + void haltCatchFire() + { + // Do nothing by default + } + + /** + * Compare + * @param o The other object + * @return 0 if equal; -1 if less than based on lastReturned; otherwise 1 + */ + public int compareTo(Object o) + { + if (this == o) + return 0; + + if (!(o instanceof AbstractConnectionListener)) + throw new ClassCastException(bundle.notCorrectTypeWhenClassCast(o.getClass().getName())); + + final AbstractConnectionListener acl = (AbstractConnectionListener)o; + + if (lastReturned < acl.lastReturned) + return -1; + + return 1; + } + + /** + * Get string identifier + * @return The value + */ + private String getIdentifier() + { + StringBuffer buffer = new StringBuffer(100); + buffer.append(getClass().getSimpleName()).append('@').append(Integer.toHexString(System.identityHashCode(this))); + return buffer.toString(); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() + { + StringBuffer buffer = new StringBuffer(100); + buffer.append(getClass().getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))); + buffer.append("[state="); + + if (state.equals(ConnectionState.NORMAL)) + { + buffer.append("NORMAL"); + } + else if (state.equals(ConnectionState.DESTROY)) + { + buffer.append("DESTROY"); + } + else if (state.equals(ConnectionState.DESTROYED)) + { + buffer.append("DESTROYED"); + } + else + { + buffer.append("UNKNOWN?"); + } + buffer.append(" managed connection=").append(managedConnection); + buffer.append(" connection handles=").append(connectionHandles.size()); + buffer.append(" lastReturned=").append(lastReturned); + buffer.append(" lastValidated=").append(lastValidated); + buffer.append(" lastCheckedOut=").append(lastCheckedOut); + buffer.append(" trackByTx=").append(trackByTx.get()); + buffer.append(" pool=").append(pool); + buffer.append(" mcp=").append(managedConnectionPool); + toString(buffer); + buffer.append(']'); + + return buffer.toString(); + } + + /** + * Add specific properties. + * @param buffer buffer instance + */ + protected void toString(StringBuffer buffer) + { + + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionCacheListener.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionCacheListener.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionCacheListener.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,49 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2006, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.listener; + +import org.jboss.jca.core.connectionmanager.ConnectionRecord; + +import java.util.Collection; + +import javax.transaction.SystemException; + + +/** + * ConnectionCacheListener. + * + * @author David Jencks + * @author Erwin Guib + * @author Adrian Brock + * @author Jesper Pedersen + */ +public interface ConnectionCacheListener + extends org.jboss.jca.core.api.connectionmanager.listener.ConnectionCacheListener +{ + /** + * Notification of transaction started + * + * @param conns the connections + * @throws SystemException for any error + */ + void transactionStarted(Collection conns) throws SystemException; +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionListener.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionListener.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionListener.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,229 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2006, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.listener; + +import org.jboss.jca.core.connectionmanager.pool.api.Pool; +import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool; + +import javax.resource.ResourceException; +import javax.resource.spi.ManagedConnection; +import javax.transaction.SystemException; + +/** + * Connection listener. + * + * @author Gurkan Erdogdu + * @author Adrian Brock + * @author Weston Price + * @author Jesper Pedersen + */ +public interface ConnectionListener extends org.jboss.jca.core.api.connectionmanager.listener.ConnectionListener +{ + /** + * Get number of connection handles + * @return The value + */ + public int getNumberOfConnections(); + + /** + * Retrieve the pool for this listener. + * + * @return the pool + */ + public Pool getPool(); + + /** + * Tidyup + *

+ * Invoked just before returning the connection to the pool when the + * connection is not being destroyed. + * + * @throws ResourceException for any error + */ + public void tidyup() throws ResourceException; + + /** + * Get the managed connection pool + * @return The value + */ + public ManagedConnectionPool getManagedConnectionPool(); + + /** + * Retrieve the state of this connection. + * + * @return the state + */ + public ConnectionState getState(); + + /** + * Set the state of this connection. + * + * @param newState new state + */ + public void setState(ConnectionState newState); + + /** + * Has the connection timed out? + * + * @param timeout the timeout + * @return true for timed out, false otherwise + */ + public boolean isTimedOut(long timeout); + + /** + * Mark the connection as in pool + */ + public void toPool(); + + /** + * Register a new connection + * + * @param handle the connection handle + */ + public void registerConnection(Object handle); + + /** + * Unregister a connection + * + * @param handle the connection handle + */ + public void unregisterConnection(Object handle); + + /** + * Unregister all connections + */ + public void unregisterConnections(); + + /** + * Is the managed connection free? + * + * @return true when it is free + */ + public boolean isManagedConnectionFree(); + + /** + * Is enlisted + * @return True if enlisted, otherwise false + */ + public boolean isEnlisted(); + + /** + * Enlist the managed connection + * + * @throws SystemException for errors + */ + public void enlist() throws SystemException; + + /** + * Delist the managed connection + * @return True if the listener was delisted succesfully, otherwise false + * @throws ResourceException if exception occurs + */ + public boolean delist() throws ResourceException; + + /** + * Get whether the listener is track by transaction + * + * @return true for track by transaction, false otherwise + */ + public boolean isTrackByTx(); + + /** + * Set whether the listener is track by transaction + * + * @param trackByTx true for track by transaction, false otherwise + */ + public void setTrackByTx(boolean trackByTx); + + /** + * Retrieve the last time this connection was validated. + * + * @return the last time the connection was validated + */ + public long getLastValidatedTime(); + + /** + * Set the last time, in milliseconds, that this connection was validated. + * + * @param lastValidated the last time the connection was validated in + * milliseconds. + */ + public void setLastValidatedTime(long lastValidated); + + /** + * Retrieve the last time this connection was returned to the pool + * + * @return the last time the connection was returned to the pool + */ + public long getLastReturnedTime(); + + /** + * Retrieve the last time this connection was obtained from the pool + * + * @return the last time the connection was obtained from the pool + */ + public long getLastCheckedOutTime(); + + /** + * Set the last time this connection was obtained from the pool + * + * @param v The value + */ + public void setLastCheckedOutTime(long v); + + /** + * Get exception + * @return The exception that occured, or null + */ + public Exception getException(); + + /** + * Controls the managed connection / connection pair + * @param mc The managed connection + * @param connection The connection; optional + * @return True if the connection listener controls the pair, otherwise false + */ + public boolean controls(ManagedConnection mc, Object connection); + + /** + * Dissociate the connection listener + * @throws ResourceException if exception occurs + */ + public void dissociate() throws ResourceException; + + /** + * Supports lazy association + * @return True if supported, otherwise false + */ + public boolean supportsLazyAssociation(); + + /** + * Supports lazy enlistment + * @return True if supported, otherwise false + */ + public boolean supportsLazyEnlistment(); + + /** + * Destroys this connection listener and its managed connection. + */ + public void destroy(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionState.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionState.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionState.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,47 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.listener; + +/** + * Connection listener status flag. Connections can be in three state + *

    + *
  • NORMAL
  • + *
  • DESTROY
  • + *
  • DESTROYED
  • + *
+ * + * @version $Rev: $ + * @author Gurkan Erdogdu + */ +public enum ConnectionState +{ + /**Normal state*/ + NORMAL, + + /**Destroy this connection*/ + DESTROY, + + /**Connection is destroyed*/ + DESTROYED; + +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/NoTxConnectionListener.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/NoTxConnectionListener.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/NoTxConnectionListener.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,96 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.listener; + +import org.jboss.jca.common.api.metadata.common.FlushStrategy; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.connectionmanager.ConnectionManager; +import org.jboss.jca.core.connectionmanager.pool.api.Pool; +import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool; + +import javax.resource.spi.ConnectionEvent; +import javax.resource.spi.ManagedConnection; + +import org.jboss.logging.Logger; + +/** + * NoTx Connection Listener. + * + * @author Gurkan Erdogdu + * @author Jesper Pedersen + * @see AbstractConnectionListener + */ +public class NoTxConnectionListener extends AbstractConnectionListener +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + NoTxConnectionListener.class.getName()); + + /** + * Creates a new no-tx listener. + * @param cm connection manager + * @param mc managed connection + * @param pool pool + * @param mcp mcp + * @param flushStrategy flushStrategy + * @param tracking tracking + */ + public NoTxConnectionListener(final ConnectionManager cm, final ManagedConnection mc, + final Pool pool, final ManagedConnectionPool mcp, final FlushStrategy flushStrategy, + final Boolean tracking) + { + super(cm, mc, pool, mcp, flushStrategy, tracking); + } + + /** + * {@inheritDoc} + */ + protected CoreLogger getLogger() + { + return log; + } + + /** + * {@inheritDoc} + */ + public void connectionClosed(ConnectionEvent ce) + { + if (getCachedConnectionManager() != null) + { + try + { + getCachedConnectionManager().unregisterConnection(getConnectionManager(), this, ce.getConnectionHandle()); + } + catch (Throwable t) + { + log.debug("Throwable from unregisterConnection", t); + } + } + + getConnectionManager().unregisterAssociation(this, ce.getConnectionHandle()); + + if (isManagedConnectionFree()) + { + getConnectionManager().returnManagedConnection(this, false); + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,50 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.listener; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Get a system property + * @param name The property name + * @return The property value + */ + static String getSystemProperty(final String name) + { + return AccessController.doPrivileged(new PrivilegedAction() + { + public String run() + { + return System.getProperty(name); + } + }); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/TxConnectionListener.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/TxConnectionListener.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/TxConnectionListener.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,1247 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.listener; + +import org.jboss.jca.common.api.metadata.common.FlushStrategy; +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.connectionmanager.ConnectionManager; +import org.jboss.jca.core.connectionmanager.TxConnectionManager; +import org.jboss.jca.core.connectionmanager.pool.api.Pool; +import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool; +import org.jboss.jca.core.connectionmanager.transaction.LockKey; +import org.jboss.jca.core.connectionmanager.transaction.TransactionSynchronizer; +import org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl; +import org.jboss.jca.core.spi.transaction.ConnectableResource; +import org.jboss.jca.core.spi.transaction.TxUtils; +import org.jboss.jca.core.spi.transaction.local.LocalXAResource; +import org.jboss.jca.core.tracer.Tracer; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.Lock; + +import javax.resource.ResourceException; +import javax.resource.spi.ConnectionEvent; +import javax.resource.spi.LocalTransaction; +import javax.resource.spi.ManagedConnection; +import javax.transaction.Status; +import javax.transaction.Synchronization; +import javax.transaction.SystemException; +import javax.transaction.Transaction; +import javax.transaction.TransactionManager; +import javax.transaction.TransactionSynchronizationRegistry; +import javax.transaction.xa.XAException; +import javax.transaction.xa.XAResource; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * Tx connection listener. + * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +public class TxConnectionListener extends AbstractConnectionListener +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + TxConnectionListener.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** Disable failed to enlist message */ + private static boolean disableFailedtoEnlist = false; + + /**Transaction synch. instance*/ + private TransactionSynchronization transactionSynchronization; + + /**XAResource instance*/ + private final XAResource xaResource; + + /** XAResource timeout */ + private final int xaResourceTimeout; + + /** Whether there is a local transaction */ + private final AtomicBoolean localTransaction = new AtomicBoolean(false); + + /** Delist resource */ + private boolean doDelistResource; + + /** Set rollback */ + private boolean doSetRollbackOnly; + + /** Enlistment trace */ + private Boolean enlistmentTrace; + + static + { + String value = SecurityActions.getSystemProperty("ironjacamar.disable_enlistment_trace"); + + if (value != null && !value.trim().equals("")) + { + try + { + disableFailedtoEnlist = Boolean.valueOf(value); + } + catch (Throwable t) + { + // Assume enable + disableFailedtoEnlist = true; + } + } + } + + /** + * Creates a new tx listener. + * @param cm connection manager + * @param mc managed connection + * @param pool pool + * @param mcp mcp + * @param flushStrategy flushStrategy + * @param tracking tracking + * @param enlistmentTrace enlistmentTrace + * @param xaResource xaresource instance + * @param xaResourceTimeout timeout for the XAResource + * @throws ResourceException if aexception while creating + */ + public TxConnectionListener(final ConnectionManager cm, final ManagedConnection mc, + final Pool pool, final ManagedConnectionPool mcp, final FlushStrategy flushStrategy, + final Boolean tracking, final Boolean enlistmentTrace, + final XAResource xaResource, final int xaResourceTimeout) + throws ResourceException + { + super(cm, mc, pool, mcp, flushStrategy, tracking); + + this.xaResource = xaResource; + this.xaResourceTimeout = xaResourceTimeout; + this.doDelistResource = true; + this.doSetRollbackOnly = true; + this.enlistmentTrace = enlistmentTrace; + + if (xaResource instanceof LocalXAResource) + { + ((LocalXAResource) xaResource).setConnectionListener(this); + } + if (xaResource instanceof ConnectableResource) + { + ((ConnectableResource) xaResource).setConnectableResourceListener(this); + } + + String value = SecurityActions.getSystemProperty("ironjacamar.no_delist_resource"); + if (value != null && !value.trim().equals("")) + { + StringTokenizer st = new StringTokenizer(value, ","); + while (doDelistResource && st.hasMoreTokens()) + { + if (getPool().getName().equals(st.nextToken())) + doDelistResource = false; + } + } + value = SecurityActions.getSystemProperty("ironjacamar.no_delist_resource_all"); + if (value != null && !value.trim().equals("")) + { + doDelistResource = false; + } + + value = SecurityActions.getSystemProperty("ironjacamar.rollback_on_fatal_error"); + if (value != null && !value.trim().equals("")) + { + if ("true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value)) + { + doSetRollbackOnly = Boolean.parseBoolean(value); + } + else + { + StringTokenizer st = new StringTokenizer(value, ","); + while (doSetRollbackOnly && st.hasMoreTokens()) + { + if (getPool().getName().equals(st.nextToken())) + doSetRollbackOnly = false; + } + } + } + } + + /** + * {@inheritDoc} + */ + protected CoreLogger getLogger() + { + return log; + } + + /** + * {@inheritDoc} + */ + @Override + public void toPool() + { + super.toPool(); + + // Do a reset of the underlying XAResource timeout + if (!(xaResource instanceof LocalXAResource) && xaResourceTimeout > 0) + { + try + { + xaResource.setTransactionTimeout(xaResourceTimeout); + } + catch (XAException e) + { + log.debugf(e, "XAException happend during return for: %s", + getPool() != null ? getPool().getName() : "Unknown"); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void enlist() throws SystemException + { + // This method is a bit convulted, but it has to be such because + // there is a race condition in the transaction manager where it + // unlocks during the enlist of the XAResource. It does this + // to avoid distributed deadlocks and to ensure the transaction + // timeout can fail a badly behaving resource during the enlist. + // + // When two threads in the same transaction are trying to enlist + // connections they could be from the same resource manager + // or even the same connection when tracking the connection by transaction. + // + // For the same connection, we only want to do the real enlist once. + // For two connections from the same resource manager we don't + // want the join before the initial start request. + // + // The solution is to build up a list of unenlisted resources + // in the TransactionSynchronizer and then choose one of the + // threads that is contending in the transaction to enlist them + // in order. The actual order doesn't really matter as it is the + // transaction manager that calculates the enlist flags and determines + // whether the XAResource was already enlisted. + // + // Once there are no unenlisted resources the threads are released + // to return the result of the enlistments. + // + // In practice, a thread just takes a snapshot to try to avoid one + // thread having to do all the work. If it did not do them all + // the next waiting thread will do the next snapshot until there + // there is either no snapshot or no waiting threads. + // + // A downside to this design is a thread could have its resource enlisted by + // an earlier thread while it enlists some later thread's resource. + // Since they are all a part of the same transaction, this is probably + // not a real issue. + + // If we are already enlisted there is no reason to check again, as this method + // could be called multiple times during a transaction lifecycle. + // We know that we can only be inside this method if we are allowed to + if (isEnlisted() || getState().equals(ConnectionState.DESTROY) || getState().equals(ConnectionState.DESTROYED)) + return; + + // No transaction associated with the thread + TransactionManager tm = getConnectionManager().getTransactionIntegration().getTransactionManager(); + int status = tm.getStatus(); + + if (status == Status.STATUS_NO_TRANSACTION) + { + if (transactionSynchronization != null && transactionSynchronization.currentTx != null) + { + String error = "Attempt to use connection outside a transaction when already a tx!"; + log.tracef("%s %s", error, this); + + + throw new IllegalStateException(error); + } + log.tracef("No transaction, no need to enlist: %s", this); + + return; + } + + // Inactive transaction + Transaction threadTx = tm.getTransaction(); + if (threadTx == null || status != Status.STATUS_ACTIVE) + { + TxConnectionManager txConnectionManager = (TxConnectionManager)getConnectionManager(); + + if (!txConnectionManager.isAllowMarkedForRollback()) + { + String error = "Transaction " + threadTx + " is not active " + TxUtils.getStatusAsString(status); + log.tracef("%s cl=%s", error, this); + + throw new IllegalStateException(error); + } + } + + log.tracef("Pre-enlist: %s threadTx=%s", this, threadTx); + + // Our synchronization + TransactionSynchronization ourSynchronization = null; + + // Serializes enlistment when two different threads are enlisting + // different connections in the same transaction concurrently + TransactionSynchronizer synchronizer = null; + + try + { + TransactionSynchronizer.lock(threadTx, + getConnectionManager().getTransactionIntegration()); + } + catch (Exception e) + { + setTrackByTx(false); + TxConnectionManagerImpl.rethrowAsSystemException("Exception during lock", threadTx, e); + } + + try + { + // Interleaving should have an unenlisted transaction + // TODO We should be able to do some sharing shouldn't we? + if (!isTrackByTx() && transactionSynchronization != null) + { + String error = "Can't enlist - already a tx!"; + log.tracef("%s %s", error, this); + throw new IllegalStateException(error); + } + + // Check for different transaction + if (transactionSynchronization != null && !transactionSynchronization.currentTx.equals(threadTx)) + { + String error = "Trying to change transaction " + threadTx + " in enlist!"; + log.tracef("%s %s", error, this); + throw new IllegalStateException(error); + } + + // Get the synchronizer + try + { + log.tracef("Get synchronizer %s threadTx=%s", this, threadTx); + + synchronizer = + TransactionSynchronizer.getRegisteredSynchronizer(threadTx, + getConnectionManager().getTransactionIntegration()); + } + catch (Throwable t) + { + setTrackByTx(false); + TxConnectionManagerImpl.rethrowAsSystemException("Cannot register synchronization", threadTx, t); + } + + // First time through, create a transaction synchronization + if (transactionSynchronization == null) + { + TransactionSynchronization synchronization = new TransactionSynchronization(threadTx, isTrackByTx()); + synchronizer.addUnenlisted(synchronization); + transactionSynchronization = synchronization; + } + + ourSynchronization = transactionSynchronization; + } + finally + { + TransactionSynchronizer.unlock(threadTx, getConnectionManager().getTransactionIntegration()); + } + + // Perform the enlistment(s) + List unenlisted = synchronizer.getUnenlisted(); + if (unenlisted != null) + { + try + { + int size = unenlisted.size(); + for (int i = 0; i < size; ++i) + { + TransactionSynchronization sync = (TransactionSynchronization) unenlisted.get(i); + if (sync.enlist()) + { + synchronizer.addEnlisted(sync); + } + } + } + finally + { + synchronizer.enlisted(); + } + } + + // What was the result of our enlistment? + log.tracef("Check enlisted %s threadTx=%s", this, threadTx); + + ourSynchronization.checkEnlisted(); + setEnlisted(true); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean delist() throws ResourceException + { + log.tracef("delisting %s", this); + + boolean success = true; + + try + { + if (!isTrackByTx()) + { + if (transactionSynchronization != null) + { + // SUSPEND + Transaction tx = transactionSynchronization.currentTx; + TransactionSynchronization synchronization = transactionSynchronization; + transactionSynchronization = null; + if (TxUtils.isUncommitted(tx)) + { + if (synchronization.enlisted) + { + TransactionSynchronizer synchronizer = + TransactionSynchronizer.getRegisteredSynchronizer(tx, + getConnectionManager(). + getTransactionIntegration()); + + if (!synchronizer.removeEnlisted(synchronization)) + { + log.tracef("%s not found in %s", synchronization, synchronizer); + } + } + + if (!getState().equals(ConnectionState.DESTROYED)) + { + log.tracef("delistResource(%s, TMSUSPEND)", getXAResource()); + + boolean suspendResult = tx.delistResource(getXAResource(), XAResource.TMSUSPEND); + + if (Tracer.isEnabled()) + Tracer.delistConnectionListener(getPool() != null ? getPool().getName() : null, + getManagedConnectionPool(), + this, tx.toString(), + suspendResult, false, true); + + if (!suspendResult) + { + throw new ResourceException(bundle.failureDelistResource(this)); + } + else + { + log.tracef("delist-suspend: %s", this); + } + } + } + } + else + { + // SUCCESS / FAIL + if (!getState().equals(ConnectionState.DESTROYED) && + isManagedConnectionFree() && + isEnlisted() && + doDelistResource) + { + if (getConnectionManager().getTransactionIntegration() != null && + getConnectionManager().getTransactionIntegration().getTransactionManager() != null) + { + Transaction tx = getConnectionManager().getTransactionIntegration(). + getTransactionManager().getTransaction(); + + if (TxUtils.isUncommitted(tx)) + { + if (TxUtils.isActive(tx)) + { + log.tracef("delistResource(%s, TMSUCCESS)", getXAResource()); + + boolean successResult = tx.delistResource(getXAResource(), XAResource.TMSUCCESS); + + if (Tracer.isEnabled()) + Tracer.delistConnectionListener(getPool() != null ? getPool().getName() : null, + getManagedConnectionPool(), + this, tx.toString(), + true, false, true); + + if (successResult) + { + log.tracef("delist-success: %s", this); + } + else + { + log.debugf("delist-success failed: %s", this); + success = false; + } + } + else + { + log.tracef("delistResource(%s, TMFAIL)", getXAResource()); + + boolean failResult = tx.delistResource(getXAResource(), XAResource.TMFAIL); + + if (Tracer.isEnabled()) + Tracer.delistConnectionListener(getPool() != null ? getPool().getName() : null, + getManagedConnectionPool(), + this, tx.toString(), + false, false, true); + + if (failResult) + { + log.tracef("delist-fail: %s", this); + } + else + { + log.debugf("delist-fail failed: %s", this); + + success = false; + } + } + } + } + } + } + + setEnlisted(false); + } + + log.tracef("delisted %s", this); + + return success; + } + catch (ResourceException re) + { + throw re; + } + catch (Throwable t) + { + throw new ResourceException(bundle.errorInDelist(), t); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void dissociate() throws ResourceException + { + log.tracef("dissociate: %s", this); + + try + { + TransactionManager tm = getConnectionManager().getTransactionIntegration().getTransactionManager(); + int status = tm.getStatus(); + + log.tracef("dissociate: status=%s", TxUtils.getStatusAsString(status)); + + if (status != Status.STATUS_NO_TRANSACTION) + { + if (isEnlisted()) + { + if (doDelistResource) + { + Transaction tx = tm.getTransaction(); + boolean delistResult = tx.delistResource(getXAResource(), XAResource.TMSUCCESS); + + log.tracef("dissociate: delistResult=%s", delistResult); + } + } + else + { + log.tracef("dissociate: not enlisted (%s)", this); + } + + if (isTrackByTx()) + { + ManagedConnectionPool mcp = getManagedConnectionPool(); + TransactionSynchronizationRegistry tsr = + getConnectionManager().getTransactionIntegration().getTransactionSynchronizationRegistry(); + + Lock lock = (Lock)tsr.getResource(LockKey.INSTANCE); + if (lock != null) + { + try + { + lock.lockInterruptibly(); + } + catch (InterruptedException ie) + { + Thread.interrupted(); + + throw new ResourceException(bundle.unableObtainLock(), ie); + } + + try + { + tsr.putResource(mcp, null); + } + finally + { + lock.unlock(); + } + } + } + } + + localTransaction.set(false); + setTrackByTx(false); + + if (transactionSynchronization != null) + { + transactionSynchronization.cancel(); + transactionSynchronization = null; + } + + setEnlisted(false); + } + catch (Throwable t) + { + throw new ResourceException(bundle.errorInDissociate(), t); + } + } + + //local will return this, xa will return one from mc. + /** + * Get XA resource. + * @return xa resource + */ + protected XAResource getXAResource() + { + return xaResource; + } + + /** + * {@inheritDoc} + */ + @Override + public void connectionClosed(ConnectionEvent ce) + { + log.tracef("connectionClosed called mc=%s", this.getManagedConnection()); + if (this.getManagedConnection() != (ManagedConnection)ce.getSource()) + throw new IllegalArgumentException("ConnectionClosed event received from wrong ManagedConnection! Expected: " + + this.getManagedConnection() + ", actual: " + ce.getSource()); + + if (getCachedConnectionManager() != null) + { + try + { + this.getCachedConnectionManager().unregisterConnection(this.getConnectionManager(), this, + ce.getConnectionHandle()); + } + catch (Throwable t) + { + log.throwableFromUnregisterConnection(t); + } + } + + try + { + if (wasFreed(ce.getConnectionHandle())) + { + boolean success = delist(); + + log.tracef("isManagedConnectionFree=true mc=%s", this.getManagedConnection()); + + if (success || (tracking != null && !tracking.booleanValue())) + { + this.getConnectionManager().returnManagedConnection(this, false); + } + else + { + log.delistingFailed(getPool() != null ? getPool().getName() : "Unknown", new Exception()); + this.getConnectionManager().returnManagedConnection(this, true); + } + } + else + { + log.tracef("isManagedConnectionFree=false mc=%s", this.getManagedConnection()); + } + } + catch (Throwable t) + { + log.errorWhileClosingConnectionHandle(t); + this.getConnectionManager().returnManagedConnection(this, true); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void localTransactionStarted(ConnectionEvent ce) + { + localTransaction.set(true); + } + + /** + * {@inheritDoc} + */ + @Override + public void localTransactionCommitted(ConnectionEvent ce) + { + localTransaction.set(false); + } + + /** + * {@inheritDoc} + */ + @Override + public void localTransactionRolledback(ConnectionEvent ce) + { + localTransaction.set(false); + } + + /** + * {@inheritDoc} + */ + @Override + public void tidyup() throws ResourceException + { + // We have a hanging transaction + if (localTransaction.get()) + { + LocalTransaction local = null; + ManagedConnection mc = getManagedConnection(); + try + { + local = mc.getLocalTransaction(); + } + catch (Throwable t) + { + throw new ResourceException(bundle.unfinishedLocalTransaction(this), t); + } + if (local == null) + throw new ResourceException(bundle.unfinishedLocalTransactionNotProvideLocalTransaction(this)); + else + { + local.rollback(); + log.debugf("Unfinished local transaction was rolled back.%s", this); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + void haltCatchFire() + { + if (isEnlisted()) + { + if (transactionSynchronization != null) + transactionSynchronization.cancel(); + + String txId = ""; + + if (getConnectionManager().getTransactionIntegration() != null && + getConnectionManager().getTransactionIntegration().getTransactionManager() != null) + { + Transaction tx = null; + try + { + tx = getConnectionManager().getTransactionIntegration().getTransactionManager().getTransaction(); + + if (Tracer.isEnabled() && tx != null) + txId = tx.toString(); + + if (TxUtils.isUncommitted(tx) && doDelistResource) + { + log.tracef("connectionErrorOccurred: delistResource(%s, TMFAIL)", getXAResource()); + + boolean failResult = tx.delistResource(getXAResource(), XAResource.TMFAIL); + + if (failResult) + { + log.tracef("connectionErrorOccurred: delist-fail: %s", this); + } + else + { + log.debugf("connectionErrorOccurred: delist-fail failed: %s", this); + } + } + } + catch (Exception e) + { + log.debugf(e, "connectionErrorOccurred: Exception during delistResource=%s", e.getMessage()); + } + finally + { + if (TxUtils.isUncommitted(tx) && doSetRollbackOnly) + { + try + { + tx.setRollbackOnly(); + } + catch (Exception e) + { + // Just a hint + } + } + } + } + + if (Tracer.isEnabled()) + { + Tracer.delistConnectionListener(getPool() != null ? getPool().getName() : null, + getManagedConnectionPool(), + this, txId, false, true, false); + } + } + + // Prepare to explode + setEnlisted(false); + transactionSynchronization = null; + } + + /** + * {@inheritDoc} + */ + //Important method!! + @Override + public boolean isManagedConnectionFree() + { + if (isTrackByTx() && transactionSynchronization != null) + return false; + return super.isManagedConnectionFree(); + } + + /** + * This method changes the number of handles or + * the track-by-tx value depending on the parameter passed in + * @param handle The handle; if null track-by-tx is changed + * @return True if the managed connection was freed + */ + boolean wasFreed(Object handle) + { + if (handle != null) + { + // Unregister the handle + unregisterConnection(handle); + } + else + { + if (!isTrackByTx()) + { + // Only change the state once + return false; + } + + // Set track-by-tx to false + setTrackByTx(false); + } + + // Return if the managed connection was just freed + return isManagedConnectionFree(); + } + + /** + * Transaction sync. class. + * Please note this class has public access is for test purposes only. + * Except for test purposes it should be considered private! + * Don't use it outside enclosing class or testcase! + */ + public class TransactionSynchronization implements Synchronization + { + /**Error message*/ + private final Throwable failedToEnlist; + + /** Record enlist */ + private final boolean recordEnlist; + + /** Transaction */ + protected final Transaction currentTx; + + /** This is the status when we were registered */ + private final boolean wasTrackByTx; + + /** Whether we are enlisted */ + private boolean enlisted; + + /** Any error during enlistment */ + private Throwable enlistError; + + /** Cancel */ + private boolean cancel; + + /** + * Create a new TransactionSynchronization.transaction + * @param tx transaction + * + * @param trackByTx whether this is track by connection + */ + public TransactionSynchronization(final Transaction tx, final boolean trackByTx) + { + this.currentTx = tx; + this.wasTrackByTx = trackByTx; + this.enlisted = false; + this.enlistError = null; + this.cancel = false; + + if (TxConnectionListener.this.enlistmentTrace != null) + { + this.recordEnlist = TxConnectionListener.this.enlistmentTrace.booleanValue(); + } + else + { + this.recordEnlist = !disableFailedtoEnlist; + } + + if (this.recordEnlist) + { + this.failedToEnlist = new Throwable("Unabled to enlist resource, see the previous warnings."); + } + else + { + this.failedToEnlist = null; + } + + log.tracef("%s: Constructor", toString()); + } + + /** + * Set the cancel flag + */ + public void cancel() + { + cancel = true; + } + + /** + * Get the result of the enlistment. + * + * @throws SystemException for any error + */ + public void checkEnlisted() throws SystemException + { + if (this.enlistError != null) + { + String error = "Error enlisting resource in transaction=" + this.currentTx; + log.tracef("%s %s", error, TxConnectionListener.this); + + // Wrap the error to give a reasonable stacktrace since the resource + // could have been enlisted by a different thread + if (recordEnlist && enlistError == failedToEnlist) + { + SystemException se = + new SystemException(bundle.systemExceptionWhenFailedToEnlistEqualsCurrentTx( + failedToEnlist, this.currentTx)); + + if (Tracer.isEnabled()) + Tracer.exception(getPool() != null ? getPool().getName() : null, + getManagedConnectionPool(), + TxConnectionListener.this, se); + + throw se; + + } + else + { + SystemException e = new SystemException(error); + e.initCause(enlistError); + + if (Tracer.isEnabled()) + Tracer.exception(getPool() != null ? getPool().getName() : null, + getManagedConnectionPool(), + TxConnectionListener.this, e); + + throw e; + } + } + if (!enlisted) + { + String error = "Resource is not enlisted in transaction=" + currentTx; + log.tracef("%s %s", error, TxConnectionListener.this); + throw new IllegalStateException("Resource was not enlisted."); + } + } + + /** + * Enlist the resource + * + * @return true when enlisted, false otherwise + */ + public boolean enlist() + { + log.tracef("Enlisting resource %s", TxConnectionListener.this); + try + { + XAResource resource = getXAResource(); + if (!currentTx.enlistResource(resource)) + { + if (Tracer.isEnabled()) + Tracer.enlistConnectionListener(getPool() != null ? getPool().getName() : null, + getManagedConnectionPool(), + TxConnectionListener.this, currentTx.toString(), false, + !TxConnectionListener.this.isTrackByTx()); + + if (recordEnlist) + { + enlistError = failedToEnlist; + } + else + { + enlistError = new Throwable("Failed to enlist"); + } + } + else + { + if (Tracer.isEnabled()) + Tracer.enlistConnectionListener(getPool() != null ? getPool().getName() : null, + getManagedConnectionPool(), + TxConnectionListener.this, currentTx.toString(), true, + !TxConnectionListener.this.isTrackByTx()); + } + } + catch (Throwable t) + { + enlistError = t; + + if (Tracer.isEnabled()) + Tracer.enlistConnectionListener(getPool() != null ? getPool().getName() : null, + getManagedConnectionPool(), + TxConnectionListener.this, currentTx.toString(), false, + !TxConnectionListener.this.isTrackByTx()); + } + + synchronized (this) + { + if (enlistError != null) + { + if (log.isTraceEnabled()) + { + log.trace("Failed to enlist resource " + TxConnectionListener.this, enlistError); + } + + setTrackByTx(false); + transactionSynchronization = null; + + return false; + } + + enlisted = true; + + log.tracef("Enlisted resource %s", TxConnectionListener.this); + + return true; + } + } + + /** + * {@inheritDoc} + */ + public void beforeCompletion() + { + if (enlisted && !cancel) + { + try + { + if (this.equals(transactionSynchronization) && wasTrackByTx && doDelistResource) + { + if (TxUtils.isUncommitted(currentTx)) + { + if (TxUtils.isActive(currentTx)) + { + log.tracef("delistResource(%s, TMSUCCESS)", TxConnectionListener.this.getXAResource()); + + currentTx.delistResource(TxConnectionListener.this.getXAResource(), XAResource.TMSUCCESS); + + if (Tracer.isEnabled()) + Tracer.delistConnectionListener(getPool() != null ? getPool().getName() : null, + getManagedConnectionPool(), + TxConnectionListener.this, currentTx.toString(), + true, false, false); + } + else + { + log.tracef("delistResource(%s, TMFAIL)", TxConnectionListener.this.getXAResource()); + + currentTx.delistResource(TxConnectionListener.this.getXAResource(), XAResource.TMFAIL); + + if (Tracer.isEnabled()) + Tracer.delistConnectionListener(getPool() != null ? getPool().getName() : null, + getManagedConnectionPool(), + TxConnectionListener.this, currentTx.toString(), + false, false, false); + } + } + else + { + if (log.isTraceEnabled()) + log.tracef("Non-uncommitted transaction for %s (%s)", TxConnectionListener.this, + currentTx != null ? TxUtils.getStatusAsString(currentTx.getStatus()) : "None"); + } + } + else + { + log.tracef("No delistResource for: %s", TxConnectionListener.this); + } + } + catch (Throwable t) + { + log.beforeCompletionErrorOccured(TxConnectionListener.this, t); + } + } + else + { + log.tracef("Unenlisted resource: %s", TxConnectionListener.this); + } + } + + /** + * {@inheritDoc} + */ + public void afterCompletion(int status) + { + // The connection got destroyed during the transaction + if (getState().equals(ConnectionState.DESTROYED)) + { + return; + } + + if (!cancel) + { + // Are we still in the original transaction? + if (!this.equals(transactionSynchronization)) + { + // If we are interleaving transactions we have nothing to do + if (!wasTrackByTx) + { + TxConnectionListener.this.setEnlisted(false); + return; + } + else + { + // There is something wrong with the pooling + String message = "afterCompletion called with wrong tx! Expected: " + + this + ", actual: " + transactionSynchronization; + IllegalStateException e = new IllegalStateException(message); + log.somethingWrongWithPooling(e); + } + } + // "Delist" + TxConnectionListener.this.setEnlisted(false); + transactionSynchronization = null; + + // This is where we close when doing track by transaction + if (wasTrackByTx) + { + log.tracef("afterCompletion(%d) isTrackByTx=%b for %s" + , status, isTrackByTx(), TxConnectionListener.this); + + if (wasFreed(null)) + { + if (Tracer.isEnabled() && status == Status.STATUS_ROLLEDBACK) + Tracer.delistConnectionListener(getPool() != null ? getPool().getName() : null, + getManagedConnectionPool(), + TxConnectionListener.this, "", true, true, false); + + getConnectionManager().returnManagedConnection(TxConnectionListener.this, false); + } + else + { + if (tracking == null || tracking.booleanValue()) + { + log.activeHandles(getPool() != null ? getPool().getName() : "Unknown", connectionHandles.size()); + + if (tracking != null && tracking.booleanValue()) + { + Iterator> it = connectionTraces.entrySet().iterator(); + while (it.hasNext()) + { + Map.Entry entry = it.next(); + log.activeHandle(entry.getKey(), entry.getValue()); + } + + log.txConnectionListenerBoundary(new Exception()); + } + + if (Tracer.isEnabled()) + { + for (Object c : connectionHandles) + { + Tracer.clearConnection(getPool() != null ? getPool().getName() : null, + getManagedConnectionPool(), + TxConnectionListener.this, c); + } + } + + getConnectionManager().returnManagedConnection(TxConnectionListener.this, true); + } + else + { + if (log.isTraceEnabled()) + log.tracef(new Exception("Connection across boundary"), "ConnectionListener=%s", + TxConnectionListener.this); + } + } + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() + { + StringBuffer buffer = new StringBuffer(); + buffer.append("TransactionSynchronization@").append(System.identityHashCode(this)); + buffer.append("{tx=").append(currentTx); + buffer.append(" wasTrackByTx=").append(wasTrackByTx); + buffer.append(" enlisted=").append(enlisted); + buffer.append(" cancel=").append(cancel); + buffer.append("}"); + return buffer.toString(); + } + } + + /** + * {@inheritDoc} + */ + // For debugging + @Override + protected void toString(StringBuffer buffer) + { + buffer.append(" xaResource=").append(xaResource); + buffer.append(" txSync=").append(transactionSynchronization); + } + + /** + * Get the transactionSynchronization. + * Please note this package protected method is for test purposes only. Don't use it! + * + * @return the transactionSynchronization. + */ + final TransactionSynchronization getTransactionSynchronization() + { + return transactionSynchronization; + } + + /** + * Set the transactionSynchronization. + * Please note this package protected method is for test purposes only. Don't use it! + * + * @param transactionSynchronization The transactionSynchronization to set. + */ + final void setTransactionSynchronization(TransactionSynchronization transactionSynchronization) + { + this.transactionSynchronization = transactionSynchronization; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the connection listener implementation. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/notx/NoTxConnectionManagerImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/notx/NoTxConnectionManagerImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/notx/NoTxConnectionManagerImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,107 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.notx; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.connectionmanager.AbstractConnectionManager; +import org.jboss.jca.core.connectionmanager.ConnectionRecord; +import org.jboss.jca.core.connectionmanager.NoTxConnectionManager; +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.connectionmanager.listener.NoTxConnectionListener; +import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool; +import org.jboss.jca.core.spi.transaction.TransactionIntegration; + +import java.util.Collection; + +import javax.resource.ResourceException; +import javax.resource.spi.ManagedConnection; +import javax.transaction.SystemException; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * Non transactional connection manager implementation. + * + * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +public class NoTxConnectionManagerImpl extends AbstractConnectionManager implements NoTxConnectionManager +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, NoTxConnectionManager.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** Serial version uid */ + private static final long serialVersionUID = 1L; + + /** + * Default constructor. + */ + public NoTxConnectionManagerImpl() + { + } + + /** + * Get the logger. + * @return The value + */ + protected CoreLogger getLogger() + { + return log; + } + + /** + * {@inheritDoc} + */ + public ConnectionListener createConnectionListener(ManagedConnection managedConnection, ManagedConnectionPool mcp) + throws ResourceException + { + ConnectionListener cli = new NoTxConnectionListener(this, managedConnection, getPool(), + mcp, getFlushStrategy(), getTracking()); + managedConnection.addConnectionEventListener(cli); + + return cli; + } + + @Override + public void transactionStarted(Collection conns) throws SystemException + { + // Doing nothing + } + + @Override + public TransactionIntegration getTransactionIntegration() + { + return null; + } + + @Override + public boolean isTransactional() + { + return false; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/notx/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/notx/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/notx/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the non-tx connection manager implementation. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the connection manager implementation. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/AbstractPool.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/AbstractPool.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/AbstractPool.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,1176 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.connectionmanager.pool.FlushMode; +import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration; +import org.jboss.jca.core.api.connectionmanager.pool.PoolStatistics; +import org.jboss.jca.core.connectionmanager.ConnectionManager; +import org.jboss.jca.core.connectionmanager.TxConnectionManager; +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.connectionmanager.pool.api.Capacity; +import org.jboss.jca.core.connectionmanager.pool.api.Pool; +import org.jboss.jca.core.connectionmanager.pool.api.Semaphore; +import org.jboss.jca.core.connectionmanager.pool.capacity.DefaultCapacity; +import org.jboss.jca.core.connectionmanager.pool.capacity.TimedOutDecrementer; +import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool; +import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPoolFactory; +import org.jboss.jca.core.connectionmanager.transaction.LockKey; +import org.jboss.jca.core.spi.transaction.TransactionIntegration; +import org.jboss.jca.core.tracer.Tracer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import javax.resource.ResourceException; +import javax.resource.spi.ConnectionRequestInfo; +import javax.resource.spi.ManagedConnection; +import javax.resource.spi.ManagedConnectionFactory; +import javax.security.auth.Subject; +import javax.transaction.Transaction; +import javax.transaction.TransactionManager; +import javax.transaction.TransactionSynchronizationRegistry; + +import org.jboss.logging.Messages; + +/** + * Abstract pool implementation. + *

+ * It can contains sub-pools according to the semantic of + * the pool. Concrete implementatins override {@link AbstractPool#getKey(Subject, ConnectionRequestInfo, boolean)} + * method to create map key object. + *

+ * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +public abstract class AbstractPool implements Pool +{ + /** New line */ + private static String newLine = SecurityActions.getSystemProperty("line.separator"); + + /** The logger */ + protected final CoreLogger log; + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** The managed connection pools, maps key --> pool */ + private final ConcurrentMap mcpPools = + new ConcurrentHashMap(); + + /** The managed connection factory for this pool */ + private final ManagedConnectionFactory mcf; + + /** The connection manager for this pool*/ + private ConnectionManager cm; + + /** The pool parameters */ + private final PoolConfiguration poolConfiguration; + + /** Whether to use separate pools for transactional and non-transaction use */ + private final boolean noTxSeparatePools; + + /** Shutdown */ + private final AtomicBoolean shutdown = new AtomicBoolean(false); + + /** The poolName */ + private String poolName; + + /** Statistics */ + private PoolStatisticsImpl statistics; + + /** The permits used to control who can checkout a connection */ + private Semaphore permits; + + /** Are the connections sharable */ + private boolean sharable; + + /** MCP class */ + private String mcpClass; + + /** The capacity */ + private Capacity capacity; + + /** Interleaving */ + private boolean interleaving; + + /** No lazy enlistment available */ + private AtomicBoolean noLazyEnlistmentAvailable; + + /** + * Create a new base pool. + * + * @param mcf the managed connection factory + * @param pc the pool configuration + * @param noTxSeparatePools noTxSeparatePool + * @param sharable Are the connections sharable + * @param mcp mcp + */ + protected AbstractPool(final ManagedConnectionFactory mcf, final PoolConfiguration pc, + final boolean noTxSeparatePools, final boolean sharable, + final String mcp) + { + if (mcf == null) + throw new IllegalArgumentException("MCF is null"); + + if (pc == null) + throw new IllegalArgumentException("PoolConfiguration is null"); + + this.mcf = mcf; + this.poolConfiguration = pc; + this.noTxSeparatePools = noTxSeparatePools; + this.sharable = sharable; + this.mcpClass = mcp; + this.log = getLogger(); + this.statistics = new PoolStatisticsImpl(pc.getMaxSize()); + this.permits = new Semaphore(pc.getMaxSize(), pc.isFair(), statistics); + this.capacity = null; + this.interleaving = false; + this.noLazyEnlistmentAvailable = new AtomicBoolean(false); + } + + /** + * Sets pool name. + * @param poolName pool name + */ + public void setName(String poolName) + { + this.poolName = poolName; + } + + /** + * Gets pool name. + * @return pool name + */ + public String getName() + { + return poolName; + } + + /** + * {@inheritDoc} + */ + public Semaphore getLock() + { + return permits; + } + + /** + * Is sharable + * @return The value + */ + public boolean isSharable() + { + return sharable; + } + + /** + * {@inheritDoc} + */ + public Capacity getCapacity() + { + if (capacity == null) + return DefaultCapacity.INSTANCE; + + return capacity; + } + + /** + * {@inheritDoc} + */ + public void setCapacity(Capacity c) + { + capacity = c; + } + + + /** + * {@inheritDoc} + */ + public boolean isFIFO() + { + if (capacity == null || capacity.getDecrementer() == null || + TimedOutDecrementer.class.getName().equals(capacity.getDecrementer().getClass().getName())) + return false; + + return true; + } + + /** + * {@inheritDoc} + */ + public boolean isInterleaving() + { + return interleaving; + } + + /** + * {@inheritDoc} + */ + public void setInterleaving(boolean v) + { + interleaving = v; + } + + /** + * {@inheritDoc} + */ + public boolean isIdle() + { + for (ManagedConnectionPool mcp : mcpPools.values()) + { + if (!mcp.isIdle()) + return false; + } + + return true; + } + + /** + * {@inheritDoc} + */ + public boolean isFull() + { + return permits.availablePermits() == 0; + } + + /** + * Retrieve the key for this request. + * + * @param subject the subject + * @param cri the connection request information + * @param separateNoTx separateNoTx + * @return the key + * @throws ResourceException for any error + */ + protected abstract Object getKey(Subject subject, ConnectionRequestInfo cri, + boolean separateNoTx) throws ResourceException; + + /** + * Determine the correct pool for this request, + * creates a new one when necessary. + * + * @param key the key to the pool + * @param subject the subject of the pool + * @param cri the connection request info + * @return the subpool context + * @throws ResourceException for any error + */ + protected ManagedConnectionPool getManagedConnectionPool(Object key, Subject subject, ConnectionRequestInfo cri) + throws ResourceException + { + try + { + ManagedConnectionPool mcp = mcpPools.get(key); + if (mcp == null) + { + // Let sync, since it is expensive to create connections + synchronized (this) + { + mcp = mcpPools.get(key); + + if (mcp == null) + { + ManagedConnectionPoolFactory mcpf = new ManagedConnectionPoolFactory(); + ManagedConnectionPool newMcp = mcpf.create(mcpClass, mcf, cm, subject, cri, poolConfiguration, this); + + mcp = mcpPools.putIfAbsent(key, newMcp); + if (mcp == null) + { + mcp = newMcp; + + if (Tracer.isEnabled()) + Tracer.createManagedConnectionPool(getName(), mcp); + + try + { + initLock(); + } + catch (Throwable lockThrowable) + { + // Init later then + } + } + else + { + // and shut them down again + newMcp.shutdown(); + } + + log.tracef("%s: mcpPools=%s", getName(), mcpPools); + } + } + } + + return mcp; + } + catch (Throwable t) + { + throw new ResourceException(bundle.unableGetManagedConnectionPool(), t); + } + } + + /** + * Get any transaction integration associated with the pool. + * + * @return the transaction integration + */ + protected TransactionIntegration getTransactionIntegration() + { + if (cm != null) + return cm.getTransactionIntegration(); + + return null; + } + + /** + * Get any transaction manager associated with the pool. + * + * @return the transaction manager + */ + protected TransactionManager getTransactionManager() + { + if (getTransactionIntegration() != null) + return getTransactionIntegration().getTransactionManager(); + + return null; + } + + /** + * Get any transaction synchronization registry associated with the pool. + * @return The value + */ + protected TransactionSynchronizationRegistry getTransactionSynchronizationRegistry() + { + if (getTransactionIntegration() != null) + return getTransactionIntegration().getTransactionSynchronizationRegistry(); + + return null; + } + + /** + * Init lock + * @return The lock + */ + private Lock initLock() + { + TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry(); + + if (tsr != null) + return initLock(tsr); + + return null; + } + + /** + * Init lock + * @param tsr The transaction synchronization registry + * @return The lock + */ + private Lock initLock(TransactionSynchronizationRegistry tsr) + { + if (tsr.getTransactionKey() != null) + { + Lock lock = (Lock)tsr.getResource(LockKey.INSTANCE); + if (lock == null) + { + lock = new ReentrantLock(true); + tsr.putResource(LockKey.INSTANCE, lock); + return lock; + } + else + { + return lock; + } + } + + return null; + } + + /** + * Get TSR lock + * @return The lock; null if TX isn't active + */ + private Lock getTSRLock() + { + Lock result = null; + try + { + TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry(); + + if (tsr != null && tsr.getTransactionKey() != null) + { + result = (Lock)tsr.getResource(LockKey.INSTANCE); + if (result == null) + { + result = initLock(tsr); + } + } + } + catch (Throwable t) + { + // Catch all exceptions + } + + return result; + } + + /** + * {@inheritDoc} + */ + public void emptyManagedConnectionPool(ManagedConnectionPool pool) + { + log.debugf("%s: emptyManagedConnectionPool(%s)", poolName, pool); + + if (pool != null) + { + // We only consider removal if there are more than 1 managed connection pool + if (mcpPools.size() > 1 && pool.isEmpty()) + { + if (mcpPools.values().remove(pool)) + { + try + { + pool.shutdown(); + } + catch (Exception e) + { + // Should not happen + log.trace("MCP.shutdown: " + e.getMessage(), e); + } + + if (Tracer.isEnabled()) + Tracer.destroyManagedConnectionPool(getName(), pool); + + log.tracef("%s: mcpPools=%s", getName(), mcpPools); + } + } + } + } + + /** + * {@inheritDoc} + */ + public void flush() + { + flush(FlushMode.IDLE); + } + + /** + * {@inheritDoc} + */ + public void flush(boolean kill) + { + if (!kill) + { + flush(FlushMode.IDLE); + } + else + { + flush(FlushMode.ALL); + } + } + + /** + * {@inheritDoc} + */ + public void flush(FlushMode mode) + { + final Collection removedConnectionListeners = new ArrayList(); + synchronized (this) + { + log.debugf("%s: flush(%s)", poolName, mode); + + Set clearMcpPools = new HashSet(); + int size = mcpPools.size(); + + Iterator it = mcpPools.values().iterator(); + while (it.hasNext()) + { + ManagedConnectionPool mcp = it.next(); + try + { + mcp.flush(mode, removedConnectionListeners); + } + catch (Exception e) + { + // Should not happen + log.trace("MCP.flush: " + e.getMessage(), e); + } + + if (mcp.isEmpty() && !isPrefill() && size > 1) + clearMcpPools.add(mcp); + } + + if (clearMcpPools.size() > 0) + { + for (ManagedConnectionPool mcp : clearMcpPools) + { + if (mcp.isEmpty()) + { + try + { + mcp.shutdown(); + } + catch (Exception e) + { + // Should not happen + log.trace("MCP.shutdown: " + e.getMessage(), e); + } + + if (Tracer.isEnabled()) + Tracer.destroyManagedConnectionPool(getName(), mcp); + + mcpPools.values().remove(mcp); + } + } + + log.tracef("%s: mcpPools=%s", getName(), mcpPools); + } + } + if (removedConnectionListeners != null) + { + removedConnectionListeners.parallelStream().forEach(cl ->{ + log.tracef("Destroying flushed connection %s", cl); + + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(getName(), cl.getManagedConnectionPool(), cl, false, false, false, true, + false, false, false, Tracer.isRecordCallstacks() ? new Throwable("CALLSTACK") : null); + cl.destroy(); + }); + } + } + + /** + * {@inheritDoc} + */ + public ConnectionListener getConnection(Transaction trackByTransaction, Subject subject, ConnectionRequestInfo cri) + throws ResourceException + { + ConnectionListener cl = null; + boolean separateNoTx = false; + + if (shutdown.get()) + throw new ResourceException(bundle.connectionManagerIsShutdown(poolName)); + + if (noTxSeparatePools) + { + separateNoTx = cm.isTransactional(); + } + + // Get specific managed connection pool key + Object key = getKey(subject, cri, separateNoTx); + + // Get managed connection pool + ManagedConnectionPool mcp = getManagedConnectionPool(key, subject, cri); + + // Are we doing track by transaction ? + TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry(); + Object transactionKey = tsr != null ? tsr.getTransactionKey() : null; + + if (trackByTransaction == null || transactionKey == null) + { + return getSimpleConnection(subject, cri, mcp); + } + + // Transaction old connections + cl = getTransactionOldConnection(trackByTransaction, mcp); + + // Creates a new connection with given transaction + if (cl == null) + { + cl = getTransactionNewConnection(trackByTransaction, mcp, subject, cri); + } + + return cl; + } + + /** + * Gets simple connection listener that wraps connection. + * @param subject Subject instance + * @param cri Connection request info + * @param mcp The managed connection pool + * @return connection listener + * @throws ResourceException ResourceException + */ + private ConnectionListener getSimpleConnection(final Subject subject, final ConnectionRequestInfo cri, + final ManagedConnectionPool mcp) + throws ResourceException + { + // Get connection from the managed connection pool + ConnectionListener cl = mcp.getConnection(subject, cri); + + log.tracef("Got connection from pool: %s", cl); + + if (cm instanceof TxConnectionManager && cm.getCachedConnectionManager() == null && + noLazyEnlistmentAvailable.compareAndSet(false, true)) + log.noLazyEnlistmentAvailable(poolName); + + return cl; + } + + /** + * Gets connection listener instance associated with transaction. + * This method is package protected beacause it is intended only for test case use. + * Please don't use it in your production code. + * @param trackByTransaction transaction instance + * @param mcp the managed connection pool associated with the desired connection listener + * @return connection listener instance + * @throws ResourceException Thrown if an error occurs + */ + ConnectionListener getTransactionOldConnection(Transaction trackByTransaction, ManagedConnectionPool mcp) + throws ResourceException + { + TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry(); + Lock lock = getTSRLock(); + + if (lock == null) + throw new ResourceException(bundle.unableObtainLock()); + + try + { + lock.lockInterruptibly(); + } + catch (InterruptedException ie) + { + Thread.interrupted(); + + throw new ResourceException(bundle.unableObtainLock(), ie); + } + try + { + // Already got one + ConnectionListener cl = (ConnectionListener)tsr.getResource(mcp); + if (cl != null) + { + log.tracef("Previous connection tracked by transaction=%s tx=%s", cl, trackByTransaction); + return cl; + } + + return null; + } + catch (Throwable t) + { + throw new ResourceException(bundle.unableGetConnectionListener(), t); + } + finally + { + lock.unlock(); + } + } + + /** + * Gets new connection listener if necessary instance with transaction. + * This method is package protected beacause it is intended only for test case use. + * Please don't use it in your production code. + * @param trackByTransaction transaction instance + * @param mcp pool instance + * @param subject subject instance + * @param cri connection request info + * @return connection listener instance + * @throws ResourceException ResourceException + */ + ConnectionListener getTransactionNewConnection(Transaction trackByTransaction, ManagedConnectionPool mcp, + Subject subject, ConnectionRequestInfo cri) + throws ResourceException + { + // Need a new one for this transaction + // This must be done outside the tx local lock, otherwise + // the tx timeout won't work and get connection can do a lot of other work + // with many opportunities for deadlocks. + // Instead we do a double check after we got the transaction to see + // whether another thread beat us to the punch. + ConnectionListener cl = mcp.getConnection(subject, cri); + log.tracef("Got connection from pool tracked by transaction=%s tx=%s", cl, trackByTransaction); + + if (cm.isEnlistment() && cl.supportsLazyEnlistment()) + { + log.tracef("Lazy enlistment connection from pool tracked by transaction=%s tx=%s", cl, trackByTransaction); + + return cl; + } + + TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry(); + Lock lock = getTSRLock(); + + if (lock == null) + { + if (cl != null) + { + log.tracef("Killing connection tracked by transaction=%s tx=%s", cl, trackByTransaction); + + returnConnection(cl, true); + } + + throw new ResourceException(bundle.unableObtainLock()); + } + + try + { + lock.lockInterruptibly(); + } + catch (InterruptedException ie) + { + Thread.interrupted(); + + if (cl != null) + { + log.tracef("Killing connection tracked by transaction=%s tx=%s", cl, trackByTransaction); + + returnConnection(cl, true); + } + + throw new ResourceException(bundle.unableObtainLock(), ie); + } + try + { + // Check we weren't racing with another transaction + ConnectionListener other = + (ConnectionListener)tsr.getResource(mcp); + + if (other != null) + { + returnConnection(cl, false); + + log.tracef("Another thread already got a connection tracked by transaction=%s tx=%s", + other, trackByTransaction); + + cl = other; + } + + // This is the connection for this transaction + cl.setTrackByTx(true); + tsr.putResource(mcp, cl); + + log.tracef("Using connection from pool tracked by transaction=%s tx=%s", cl, trackByTransaction); + + return cl; + } + catch (Throwable t) + { + if (cl != null) + { + log.tracef("Killing connection tracked by transaction=%s tx=%s", cl, trackByTransaction); + + returnConnection(cl, true); + } + + throw new ResourceException(bundle.unableGetConnectionListener(), t); + } + finally + { + lock.unlock(); + } + } + + /** + * {@inheritDoc} + */ + public ConnectionListener findConnectionListener(ManagedConnection mc) + { + return findConnectionListener(mc, null); + } + + /** + * {@inheritDoc} + */ + public ConnectionListener findConnectionListener(ManagedConnection mc, Object connection) + { + for (ManagedConnectionPool mcp : mcpPools.values()) + { + ConnectionListener cl = mcp.findConnectionListener(mc, connection); + if (cl != null) + return cl; + } + + return null; + } + + /** + * {@inheritDoc} + */ + public ManagedConnectionFactory getManagedConnectionFactory() + { + return mcf; + } + + /** + * {@inheritDoc} + */ + public void returnConnection(ConnectionListener cl, boolean kill) throws ResourceException + { + cl.setTrackByTx(false); + //Get connection listener pool + ManagedConnectionPool mcp = cl.getManagedConnectionPool(); + + if (Tracer.isEnabled()) + { + if (kill && cl.getException() != null) + Tracer.exception(poolName, cl.getManagedConnectionPool(), cl, cl.getException()); + + Tracer.returnConnectionListener(poolName, cl.getManagedConnectionPool(), cl, kill, interleaving, + Tracer.isRecordCallstacks() ? new Throwable("CALLSTACK") : null); + } + + //Return connection to the pool + mcp.returnConnection(cl, kill); + + log.tracef("Returning connection to pool %s", cl); + } + + /** + * {@inheritDoc} + */ + public boolean hasConnection(Subject subject, ConnectionRequestInfo cri) + { + TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry(); + Lock lock = getTSRLock(); + + if (lock == null) + return false; + + try + { + lock.lockInterruptibly(); + } + catch (InterruptedException ie) + { + Thread.interrupted(); + return false; + } + try + { + boolean separateNoTx = false; + + if (noTxSeparatePools) + { + separateNoTx = cm.isTransactional(); + } + + // Get specific managed connection pool key + Object key = getKey(subject, cri, separateNoTx); + + // Get managed connection pool + ManagedConnectionPool mcp = getManagedConnectionPool(key, subject, cri); + + // Already got one + ConnectionListener cl = (ConnectionListener)tsr.getResource(mcp); + if (cl != null) + { + return true; + } + } + catch (Throwable t) + { + log.debugf(t, "hasConnection error: %s", t.getMessage()); + } + finally + { + lock.unlock(); + } + + return false; + } + + /** + * Get the connection manager + * @return The value + */ + protected ConnectionManager getConnectionManager() + { + return cm; + } + + /** + * {@inheritDoc} + */ + public void setConnectionManager(ConnectionManager cm) + { + this.cm = cm; + } + + /** + * {@inheritDoc} + */ + public boolean isShutdown() + { + return shutdown.get(); + } + + /** + * {@inheritDoc} + */ + public synchronized void shutdown() + { + log.debugf("%s: shutdown", poolName); + shutdown.set(true); + + Iterator it = mcpPools.values().iterator(); + while (it.hasNext()) + { + ManagedConnectionPool mcp = it.next(); + try + { + mcp.shutdown(); + } + catch (Exception e) + { + // Should not happen + log.tracef(e, "MCP.shutdown: %s", e.getMessage()); + } + + if (Tracer.isEnabled()) + Tracer.destroyManagedConnectionPool(getName(), mcp); + } + + mcpPools.clear(); + } + + /** + * {@inheritDoc} + */ + public void prepareShutdown() + { + log.debugf("%s: prepareShutdown", poolName); + shutdown.set(true); + + flush(FlushMode.GRACEFULLY); + } + + /** + * {@inheritDoc} + */ + public boolean cancelShutdown() + { + log.debugf("%s: cancelShutdown", poolName); + + if (shutdown.get()) + { + shutdown.set(false); + + if (isPrefill()) + { + Iterator it = mcpPools.values().iterator(); + while (it.hasNext()) + { + ManagedConnectionPool mcp = it.next(); + try + { + mcp.prefill(); + } + catch (Exception e) + { + // Should not happen + log.trace("MCP.prefill: " + e.getMessage(), e); + } + } + } + + return true; + } + + return false; + } + + /** + * {@inheritDoc} + */ + public PoolStatistics getStatistics() + { + return statistics; + } + + /** + * {@inheritDoc} + */ + public PoolStatisticsImpl getInternalStatistics() + { + return statistics; + } + + /** + * {@inheritDoc} + */ + public abstract boolean testConnection(); + + /** + * {@inheritDoc} + */ + public abstract boolean testConnection(ConnectionRequestInfo cri, Subject subject); + + /** + * Test if a connection can be obtained + * @param subject Optional subject + * @param cri Optional CRI + * @return True if possible; otherwise false + */ + protected boolean internalTestConnection(ConnectionRequestInfo cri, Subject subject) + { + log.debugf("%s: testConnection(%s, %s) (%s)", poolName, cri, subject, + Integer.toHexString(System.identityHashCode(subject))); + + log.debugf("%s: Statistics=%s", poolName, statistics); + + boolean result = false; + boolean kill = false; + ConnectionListener cl = null; + + if (shutdown.get()) + return false; + + if (isFull()) + return false; + + try + { + boolean separateNoTx = false; + + if (noTxSeparatePools) + { + separateNoTx = cm.isTransactional(); + } + + Object key = getKey(subject, cri, separateNoTx); + ManagedConnectionPool mcp = getManagedConnectionPool(key, subject, cri); + + cl = mcp.getConnection(subject, cri); + result = true; + } + catch (Throwable t) + { + kill = true; + } + finally + { + if (cl != null) + { + try + { + returnConnection(cl, kill); + } + catch (ResourceException ire) + { + // Ignore + } + } + } + + return result; + } + + /** + * {@inheritDoc} + */ + public String[] dumpQueuedThreads() + { + List result = new ArrayList(); + + if (permits.hasQueuedThreads()) + { + Collection queuedThreads = new ArrayList(permits.getQueuedThreads()); + for (Thread t : queuedThreads) + { + result.add(dumpQueuedThread(t)); + } + } + + return result.toArray(new String[result.size()]); + } + + /** + * Dump a thread + * @param t The thread + * @return The stack trace + */ + private String dumpQueuedThread(Thread t) + { + StringBuilder sb = new StringBuilder(); + + // Header + sb = sb.append("Queued thread: "); + sb = sb.append(t.getName()); + sb = sb.append(newLine); + + // Body + StackTraceElement[] stes = SecurityActions.getStackTrace(t); + if (stes != null) + { + for (StackTraceElement ste : stes) + { + sb = sb.append(" "); + sb = sb.append(ste.getClassName()); + sb = sb.append(":"); + sb = sb.append(ste.getMethodName()); + sb = sb.append(":"); + sb = sb.append(ste.getLineNumber()); + sb = sb.append(newLine); + } + } + + return sb.toString(); + } + + /** + * Get the managed connection pools. + * @return The managed connection pools + */ + protected ConcurrentMap getManagedConnectionPools() + { + return mcpPools; + } + + /** + * Get the pool configuration + * @return The value + */ + protected PoolConfiguration getPoolConfiguration() + { + return poolConfiguration; + } + + /** + * Is prefill + * @return The value + */ + protected boolean isPrefill() + { + return false; + } + + /** + * Get the logger + * @return The value + */ + public abstract CoreLogger getLogger(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/AbstractPrefillPool.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/AbstractPrefillPool.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/AbstractPrefillPool.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,93 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool; + +import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration; +import org.jboss.jca.core.connectionmanager.pool.api.PrefillPool; + +import javax.resource.spi.ConnectionRequestInfo; +import javax.resource.spi.ManagedConnectionFactory; +import javax.security.auth.Subject; + +/** + * Abstract pool implementation which can be prefilled. + * + * @author Jesper Pedersen + */ +public abstract class AbstractPrefillPool extends AbstractPool implements PrefillPool +{ + /** Should prefill be performed */ + private boolean shouldPrefill = false; + + /** + * Create a new prefill pool. + * + * @param mcf the managed connection factory + * @param pc the pool configuration + * @param noTxSeparatePools noTxSeparatePool + * @param sharable Are the connections sharable + * @param mcp mcp + */ + protected AbstractPrefillPool(final ManagedConnectionFactory mcf, final PoolConfiguration pc, + final boolean noTxSeparatePools, final boolean sharable, final String mcp) + { + super(mcf, pc, noTxSeparatePools, sharable, mcp); + this.shouldPrefill = pc.isPrefill() || pc.isStrictMin(); + } + + /** + * {@inheritDoc} + */ + public void prefill(Subject subject, ConnectionRequestInfo cri, boolean noTxnSeperatePool) + { + if (shouldPrefill) + { + if (log.isDebugEnabled()) + log.debug("Attempting to prefill pool: " + getName()); + + try + { + //Get pool key + Object key = getKey(subject, cri, noTxnSeperatePool); + + //Get pool automatically initializes pool + getManagedConnectionPool(key, subject, cri); + } + catch (Throwable t) + { + //No real need to throw here being that pool remains in the same state as before. + log.error("Unable to prefill pool: " + getName(), t); + } + } + } + + /** + * Is prefill + * @return The value + */ + @Override + protected boolean isPrefill() + { + return getPoolConfiguration().getMinSize() > 0; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/PoolStatisticsImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/PoolStatisticsImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/PoolStatisticsImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,1752 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool; + +import org.jboss.jca.core.api.connectionmanager.pool.PoolStatistics; +import org.jboss.jca.core.spi.transaction.XAResourceStatistics; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +/** + * Pool statistics + * + * @author Jesper Pedersen + */ +public class PoolStatisticsImpl implements PoolStatistics, XAResourceStatistics +{ + /** Serial version uid */ + private static final long serialVersionUID = 9L; + + private static final String ACTIVE_COUNT = "ActiveCount"; + private static final String AVAILABLE_COUNT = "AvailableCount"; + private static final String AVERAGE_BLOCKING_TIME = "AverageBlockingTime"; + private static final String AVERAGE_CREATION_TIME = "AverageCreationTime"; + private static final String AVERAGE_GET_TIME = "AverageGetTime"; + private static final String AVERAGE_POOL_TIME = "AveragePoolTime"; + private static final String AVERAGE_USAGE_TIME = "AverageUsageTime"; + private static final String BLOCKING_FAILURE_COUNT = "BlockingFailureCount"; + private static final String CREATED_COUNT = "CreatedCount"; + private static final String DESTROYED_COUNT = "DestroyedCount"; + private static final String IDLE_COUNT = "IdleCount"; + private static final String IN_USE_COUNT = "InUseCount"; + private static final String MAX_CREATION_TIME = "MaxCreationTime"; + private static final String MAX_GET_TIME = "MaxGetTime"; + private static final String MAX_POOL_TIME = "MaxPoolTime"; + private static final String MAX_USAGE_TIME = "MaxUsageTime"; + private static final String MAX_USED_COUNT = "MaxUsedCount"; + private static final String MAX_WAIT_COUNT = "MaxWaitCount"; + private static final String MAX_WAIT_TIME = "MaxWaitTime"; + private static final String TIMED_OUT = "TimedOut"; + private static final String TOTAL_BLOCKING_TIME = "TotalBlockingTime"; + private static final String TOTAL_CREATION_TIME = "TotalCreationTime"; + private static final String TOTAL_GET_TIME = "TotalGetTime"; + private static final String TOTAL_POOL_TIME = "TotalPoolTime"; + private static final String TOTAL_USAGE_TIME = "TotalUsageTime"; + private static final String WAIT_COUNT = "WaitCount"; + + private static final String XA_COMMIT_COUNT = "XACommitCount"; + private static final String XA_COMMIT_AVERAGE_TIME = "XACommitAverageTime"; + private static final String XA_COMMIT_TOTAL_TIME = "XACommitTotalTime"; + private static final String XA_COMMIT_MAX_TIME = "XACommitMaxTime"; + private static final String XA_END_COUNT = "XAEndCount"; + private static final String XA_END_AVERAGE_TIME = "XAEndAverageTime"; + private static final String XA_END_TOTAL_TIME = "XAEndTotalTime"; + private static final String XA_END_MAX_TIME = "XAEndMaxTime"; + private static final String XA_FORGET_COUNT = "XAForgetCount"; + private static final String XA_FORGET_AVERAGE_TIME = "XAForgetAverageTime"; + private static final String XA_FORGET_TOTAL_TIME = "XAForgetTotalTime"; + private static final String XA_FORGET_MAX_TIME = "XAForgetMaxTime"; + private static final String XA_PREPARE_COUNT = "XAPrepareCount"; + private static final String XA_PREPARE_AVERAGE_TIME = "XAPrepareAverageTime"; + private static final String XA_PREPARE_TOTAL_TIME = "XAPrepareTotalTime"; + private static final String XA_PREPARE_MAX_TIME = "XAPrepareMaxTime"; + private static final String XA_RECOVER_COUNT = "XARecoverCount"; + private static final String XA_RECOVER_AVERAGE_TIME = "XARecoverAverageTime"; + private static final String XA_RECOVER_TOTAL_TIME = "XARecoverTotalTime"; + private static final String XA_RECOVER_MAX_TIME = "XARecoverMaxTime"; + private static final String XA_ROLLBACK_COUNT = "XARollbackCount"; + private static final String XA_ROLLBACK_AVERAGE_TIME = "XARollbackAverageTime"; + private static final String XA_ROLLBACK_TOTAL_TIME = "XARollbackTotalTime"; + private static final String XA_ROLLBACK_MAX_TIME = "XARollbackMaxTime"; + private static final String XA_START_COUNT = "XAStartCount"; + private static final String XA_START_AVERAGE_TIME = "XAStartAverageTime"; + private static final String XA_START_TOTAL_TIME = "XAStartTotalTime"; + private static final String XA_START_MAX_TIME = "XAStartMaxTime"; + + private int maxPoolSize; + private transient SortedSet names; + private transient Map types; + private transient Map rbs; + + private transient AtomicBoolean enabled; + private transient AtomicInteger createdCount; + private transient AtomicInteger destroyedCount; + private transient AtomicInteger maxUsedCount; + private transient AtomicLong maxCreationTime; + private transient AtomicLong maxGetTime; + private transient AtomicLong maxPoolTime; + private transient AtomicLong maxUsageTime; + private transient AtomicInteger maxWaitCount; + private transient AtomicLong maxWaitTime; + private transient AtomicInteger timedOut; + private transient AtomicLong totalBlockingTime; + private transient AtomicLong totalBlockingTimeInvocations; + private transient AtomicLong totalCreationTime; + private transient AtomicLong totalGetTime; + private transient AtomicLong totalGetTimeInvocations; + private transient AtomicLong totalPoolTime; + private transient AtomicLong totalPoolTimeInvocations; + private transient AtomicLong totalUsageTime; + private transient AtomicLong totalUsageTimeInvocations; + private transient AtomicInteger inUseCount; + private transient AtomicInteger blockingFailureCount; + private transient AtomicInteger waitCount; + + + private transient AtomicLong commitCount; + private transient AtomicLong commitTotalTime; + private transient AtomicLong commitMaxTime; + private transient AtomicLong endCount; + private transient AtomicLong endTotalTime; + private transient AtomicLong endMaxTime; + private transient AtomicLong forgetCount; + private transient AtomicLong forgetTotalTime; + private transient AtomicLong forgetMaxTime; + private transient AtomicLong prepareCount; + private transient AtomicLong prepareTotalTime; + private transient AtomicLong prepareMaxTime; + private transient AtomicLong recoverCount; + private transient AtomicLong recoverTotalTime; + private transient AtomicLong recoverMaxTime; + private transient AtomicLong rollbackCount; + private transient AtomicLong rollbackTotalTime; + private transient AtomicLong rollbackMaxTime; + private transient AtomicLong startCount; + private transient AtomicLong startTotalTime; + private transient AtomicLong startMaxTime; + + /** + * Constructor + * @param maxPoolSize The maximum pool size + */ + public PoolStatisticsImpl(int maxPoolSize) + { + init(maxPoolSize); + } + + /** + * Init + * @param maxPoolSize The maximum pool size + */ + private void init(int maxPoolSize) + { + this.maxPoolSize = maxPoolSize; + + this.createdCount = new AtomicInteger(0); + this.destroyedCount = new AtomicInteger(0); + this.maxCreationTime = new AtomicLong(Long.MIN_VALUE); + this.maxGetTime = new AtomicLong(Long.MIN_VALUE); + this.maxPoolTime = new AtomicLong(Long.MIN_VALUE); + this.maxUsageTime = new AtomicLong(Long.MIN_VALUE); + this.maxUsedCount = new AtomicInteger(Integer.MIN_VALUE); + this.maxWaitCount = new AtomicInteger(0); + this.maxWaitTime = new AtomicLong(Long.MIN_VALUE); + this.timedOut = new AtomicInteger(0); + this.totalBlockingTime = new AtomicLong(0); + this.totalBlockingTimeInvocations = new AtomicLong(0); + this.totalCreationTime = new AtomicLong(0); + this.totalGetTime = new AtomicLong(0); + this.totalGetTimeInvocations = new AtomicLong(0); + this.totalPoolTime = new AtomicLong(0); + this.totalPoolTimeInvocations = new AtomicLong(0); + this.totalUsageTime = new AtomicLong(0); + this.totalUsageTimeInvocations = new AtomicLong(0); + this.inUseCount = new AtomicInteger(0); + this.blockingFailureCount = new AtomicInteger(0); + this.waitCount = new AtomicInteger(0); + + this.commitCount = new AtomicLong(0L); + this.commitTotalTime = new AtomicLong(0L); + this.commitMaxTime = new AtomicLong(0L); + this.endCount = new AtomicLong(0L); + this.endTotalTime = new AtomicLong(0L); + this.endMaxTime = new AtomicLong(0L); + this.forgetCount = new AtomicLong(0L); + this.forgetTotalTime = new AtomicLong(0L); + this.forgetMaxTime = new AtomicLong(0L); + this.prepareCount = new AtomicLong(0L); + this.prepareTotalTime = new AtomicLong(0L); + this.prepareMaxTime = new AtomicLong(0L); + this.recoverCount = new AtomicLong(0L); + this.recoverTotalTime = new AtomicLong(0L); + this.recoverMaxTime = new AtomicLong(0L); + this.rollbackCount = new AtomicLong(0L); + this.rollbackTotalTime = new AtomicLong(0L); + this.rollbackMaxTime = new AtomicLong(0L); + this.startCount = new AtomicLong(0L); + this.startTotalTime = new AtomicLong(0L); + this.startMaxTime = new AtomicLong(0L); + + SortedSet n = new TreeSet(); + Map t = new HashMap(); + + n.add(ACTIVE_COUNT); + t.put(ACTIVE_COUNT, int.class); + + n.add(AVAILABLE_COUNT); + t.put(AVAILABLE_COUNT, int.class); + + n.add(AVERAGE_BLOCKING_TIME); + t.put(AVERAGE_BLOCKING_TIME, long.class); + + n.add(AVERAGE_CREATION_TIME); + t.put(AVERAGE_CREATION_TIME, long.class); + + n.add(AVERAGE_GET_TIME); + t.put(AVERAGE_GET_TIME, long.class); + + n.add(AVERAGE_USAGE_TIME); + t.put(AVERAGE_USAGE_TIME, long.class); + + n.add(AVERAGE_POOL_TIME); + t.put(AVERAGE_POOL_TIME, long.class); + + n.add(BLOCKING_FAILURE_COUNT); + t.put(BLOCKING_FAILURE_COUNT, int.class); + + n.add(CREATED_COUNT); + t.put(CREATED_COUNT, int.class); + + n.add(DESTROYED_COUNT); + t.put(DESTROYED_COUNT, int.class); + + n.add(IDLE_COUNT); + t.put(IDLE_COUNT, int.class); + + n.add(IN_USE_COUNT); + t.put(IN_USE_COUNT, int.class); + + n.add(MAX_CREATION_TIME); + t.put(MAX_CREATION_TIME, long.class); + + n.add(MAX_GET_TIME); + t.put(MAX_GET_TIME, long.class); + + n.add(MAX_POOL_TIME); + t.put(MAX_POOL_TIME, long.class); + + n.add(MAX_USAGE_TIME); + t.put(MAX_USAGE_TIME, long.class); + + n.add(MAX_USED_COUNT); + t.put(MAX_USED_COUNT, int.class); + + n.add(MAX_WAIT_COUNT); + t.put(MAX_WAIT_COUNT, int.class); + + n.add(MAX_WAIT_TIME); + t.put(MAX_WAIT_TIME, long.class); + + n.add(TIMED_OUT); + t.put(TIMED_OUT, int.class); + + n.add(TOTAL_BLOCKING_TIME); + t.put(TOTAL_BLOCKING_TIME, long.class); + + n.add(TOTAL_CREATION_TIME); + t.put(TOTAL_CREATION_TIME, long.class); + + n.add(TOTAL_GET_TIME); + t.put(TOTAL_GET_TIME, long.class); + + n.add(TOTAL_POOL_TIME); + t.put(TOTAL_POOL_TIME, long.class); + + n.add(TOTAL_USAGE_TIME); + t.put(TOTAL_USAGE_TIME, long.class); + + n.add(WAIT_COUNT); + t.put(WAIT_COUNT, int.class); + + n.add(XA_COMMIT_COUNT); + t.put(XA_COMMIT_COUNT, long.class); + n.add(XA_COMMIT_AVERAGE_TIME); + t.put(XA_COMMIT_AVERAGE_TIME, long.class); + n.add(XA_COMMIT_TOTAL_TIME); + t.put(XA_COMMIT_TOTAL_TIME, long.class); + n.add(XA_COMMIT_MAX_TIME); + t.put(XA_COMMIT_MAX_TIME, long.class); + + n.add(XA_END_COUNT); + t.put(XA_END_COUNT, long.class); + n.add(XA_END_AVERAGE_TIME); + t.put(XA_END_AVERAGE_TIME, long.class); + n.add(XA_END_TOTAL_TIME); + t.put(XA_END_TOTAL_TIME, long.class); + n.add(XA_END_MAX_TIME); + t.put(XA_END_MAX_TIME, long.class); + + n.add(XA_FORGET_COUNT); + t.put(XA_FORGET_COUNT, long.class); + n.add(XA_FORGET_AVERAGE_TIME); + t.put(XA_FORGET_AVERAGE_TIME, long.class); + n.add(XA_FORGET_TOTAL_TIME); + t.put(XA_FORGET_TOTAL_TIME, long.class); + n.add(XA_FORGET_MAX_TIME); + t.put(XA_FORGET_MAX_TIME, long.class); + + n.add(XA_PREPARE_COUNT); + t.put(XA_PREPARE_COUNT, long.class); + n.add(XA_PREPARE_AVERAGE_TIME); + t.put(XA_PREPARE_AVERAGE_TIME, long.class); + n.add(XA_PREPARE_TOTAL_TIME); + t.put(XA_PREPARE_TOTAL_TIME, long.class); + n.add(XA_PREPARE_MAX_TIME); + t.put(XA_PREPARE_MAX_TIME, long.class); + + n.add(XA_RECOVER_COUNT); + t.put(XA_RECOVER_COUNT, long.class); + n.add(XA_RECOVER_AVERAGE_TIME); + t.put(XA_RECOVER_AVERAGE_TIME, long.class); + n.add(XA_RECOVER_TOTAL_TIME); + t.put(XA_RECOVER_TOTAL_TIME, long.class); + n.add(XA_RECOVER_MAX_TIME); + t.put(XA_RECOVER_MAX_TIME, long.class); + + n.add(XA_ROLLBACK_COUNT); + t.put(XA_ROLLBACK_COUNT, long.class); + n.add(XA_ROLLBACK_AVERAGE_TIME); + t.put(XA_ROLLBACK_AVERAGE_TIME, long.class); + n.add(XA_ROLLBACK_TOTAL_TIME); + t.put(XA_ROLLBACK_TOTAL_TIME, long.class); + n.add(XA_ROLLBACK_MAX_TIME); + t.put(XA_ROLLBACK_MAX_TIME, long.class); + + n.add(XA_START_COUNT); + t.put(XA_START_COUNT, long.class); + n.add(XA_START_AVERAGE_TIME); + t.put(XA_START_AVERAGE_TIME, long.class); + n.add(XA_START_TOTAL_TIME); + t.put(XA_START_TOTAL_TIME, long.class); + n.add(XA_START_MAX_TIME); + t.put(XA_START_MAX_TIME, long.class); + + this.names = Collections.unmodifiableSortedSet(n); + this.types = Collections.unmodifiableMap(t); + this.enabled = new AtomicBoolean(true); + + ResourceBundle defaultResourceBundle = + ResourceBundle.getBundle("poolstatistics", Locale.US, + SecurityActions.getClassLoader(PoolStatisticsImpl.class)); + this.rbs = new HashMap(1); + this.rbs.put(Locale.US, defaultResourceBundle); + + clear(); + } + + + /** + * {@inheritDoc} + */ + public Set getNames() + { + return names; + } + + /** + * {@inheritDoc} + */ + public Class getType(String name) + { + return types.get(name); + } + + /** + * {@inheritDoc} + */ + public String getDescription(String name) + { + return getDescription(name, Locale.US); + } + + /** + * {@inheritDoc} + */ + public String getDescription(String name, Locale locale) + { + ResourceBundle rb = rbs.get(locale); + + if (rb == null) + { + ResourceBundle newResourceBundle = + ResourceBundle.getBundle("poolstatistics", locale, + SecurityActions.getClassLoader(PoolStatisticsImpl.class)); + + if (newResourceBundle != null) + rbs.put(locale, newResourceBundle); + } + + if (rb == null) + rb = rbs.get(Locale.US); + + if (rb != null) + return rb.getString(name); + + return ""; + } + + /** + * {@inheritDoc} + */ + @Override + public Object getValue(String name) + { + if (ACTIVE_COUNT.equals(name)) + { + return getActiveCount(); + } + else if (AVAILABLE_COUNT.equals(name)) + { + return getAvailableCount(); + } + else if (AVERAGE_BLOCKING_TIME.equals(name)) + { + return getAverageBlockingTime(); + } + else if (AVERAGE_CREATION_TIME.equals(name)) + { + return getAverageCreationTime(); + } + else if (AVERAGE_GET_TIME.equals(name)) + { + return getAverageGetTime(); + } + else if (AVERAGE_USAGE_TIME.equals(name)) + { + return getAverageUsageTime(); + } + else if (AVERAGE_POOL_TIME.equals(name)) + { + return getAveragePoolTime(); + } + else if (BLOCKING_FAILURE_COUNT.equals(name)) + { + return getBlockingFailureCount(); + } + else if (CREATED_COUNT.equals(name)) + { + return getCreatedCount(); + } + else if (DESTROYED_COUNT.equals(name)) + { + return getDestroyedCount(); + } + else if (IDLE_COUNT.equals(name)) + { + return getIdleCount(); + } + else if (IN_USE_COUNT.equals(name)) + { + return getInUseCount(); + } + else if (MAX_CREATION_TIME.equals(name)) + { + return getMaxCreationTime(); + } + else if (MAX_GET_TIME.equals(name)) + { + return getMaxGetTime(); + } + else if (MAX_POOL_TIME.equals(name)) + { + return getMaxPoolTime(); + } + else if (MAX_USAGE_TIME.equals(name)) + { + return getMaxUsageTime(); + } + else if (MAX_USED_COUNT.equals(name)) + { + return getMaxUsedCount(); + } + else if (MAX_WAIT_COUNT.equals(name)) + { + return getMaxWaitCount(); + } + else if (MAX_WAIT_TIME.equals(name)) + { + return getMaxWaitTime(); + } + else if (TIMED_OUT.equals(name)) + { + return getTimedOut(); + } + else if (TOTAL_BLOCKING_TIME.equals(name)) + { + return getTotalBlockingTime(); + } + else if (TOTAL_CREATION_TIME.equals(name)) + { + return getTotalCreationTime(); + } + else if (TOTAL_GET_TIME.equals(name)) + { + return getTotalGetTime(); + } + else if (TOTAL_POOL_TIME.equals(name)) + { + return getTotalPoolTime(); + } + else if (TOTAL_USAGE_TIME.equals(name)) + { + return getTotalUsageTime(); + } + else if (WAIT_COUNT.equals(name)) + { + return getWaitCount(); + } + else if (XA_COMMIT_COUNT.equals(name)) + { + return getCommitCount(); + } + else if (XA_COMMIT_AVERAGE_TIME.equals(name)) + { + return getCommitAverageTime(); + } + else if (XA_COMMIT_TOTAL_TIME.equals(name)) + { + return getCommitTotalTime(); + } + else if (XA_COMMIT_MAX_TIME.equals(name)) + { + return getCommitMaxTime(); + } + else if (XA_END_COUNT.equals(name)) + { + return getEndCount(); + } + else if (XA_END_AVERAGE_TIME.equals(name)) + { + return getEndAverageTime(); + } + else if (XA_END_TOTAL_TIME.equals(name)) + { + return getEndTotalTime(); + } + else if (XA_END_MAX_TIME.equals(name)) + { + return getEndMaxTime(); + } + else if (XA_FORGET_COUNT.equals(name)) + { + return getForgetCount(); + } + else if (XA_FORGET_AVERAGE_TIME.equals(name)) + { + return getForgetAverageTime(); + } + else if (XA_FORGET_TOTAL_TIME.equals(name)) + { + return getForgetTotalTime(); + } + else if (XA_FORGET_MAX_TIME.equals(name)) + { + return getForgetMaxTime(); + } + else if (XA_PREPARE_COUNT.equals(name)) + { + return getPrepareCount(); + } + else if (XA_PREPARE_AVERAGE_TIME.equals(name)) + { + return getPrepareAverageTime(); + } + else if (XA_PREPARE_TOTAL_TIME.equals(name)) + { + return getPrepareTotalTime(); + } + else if (XA_PREPARE_MAX_TIME.equals(name)) + { + return getPrepareMaxTime(); + } + else if (XA_RECOVER_COUNT.equals(name)) + { + return getRecoverCount(); + } + else if (XA_RECOVER_AVERAGE_TIME.equals(name)) + { + return getRecoverAverageTime(); + } + else if (XA_RECOVER_TOTAL_TIME.equals(name)) + { + return getRecoverTotalTime(); + } + else if (XA_RECOVER_MAX_TIME.equals(name)) + { + return getRecoverMaxTime(); + } + else if (XA_ROLLBACK_COUNT.equals(name)) + { + return getRollbackCount(); + } + else if (XA_ROLLBACK_AVERAGE_TIME.equals(name)) + { + return getRollbackAverageTime(); + } + else if (XA_ROLLBACK_TOTAL_TIME.equals(name)) + { + return getRollbackTotalTime(); + } + else if (XA_ROLLBACK_MAX_TIME.equals(name)) + { + return getRollbackMaxTime(); + } + else if (XA_START_COUNT.equals(name)) + { + return getStartCount(); + } + else if (XA_START_AVERAGE_TIME.equals(name)) + { + return getStartAverageTime(); + } + else if (XA_START_TOTAL_TIME.equals(name)) + { + return getStartTotalTime(); + } + else if (XA_START_MAX_TIME.equals(name)) + { + return getStartMaxTime(); + } + + return null; + } + + /** + * {@inheritDoc} + */ + public boolean isEnabled() + { + return enabled.get(); + } + + /** + * {@inheritDoc} + */ + public void setEnabled(boolean v) + { + if (enabled.get() != v) + { + enabled.set(v); + clear(); + } + } + + /** + * {@inheritDoc} + */ + public int getActiveCount() + { + if (!enabled.get()) + return 0; + + if (createdCount.get() < destroyedCount.get()) + clear(); + + return createdCount.get() - destroyedCount.get(); + } + + /** + * {@inheritDoc} + */ + public int getAvailableCount() + { + if (!enabled.get()) + return 0; + + return maxPoolSize - inUseCount.get(); + } + + /** + * {@inheritDoc} + */ + public long getAverageBlockingTime() + { + if (!enabled.get()) + return 0L; + + return totalBlockingTimeInvocations.get() != 0 ? totalBlockingTime.get() / totalBlockingTimeInvocations.get() : 0; + } + + /** + * {@inheritDoc} + */ + public long getAverageCreationTime() + { + if (!enabled.get()) + return 0L; + + return createdCount.get() != 0 ? totalCreationTime.get() / createdCount.get() : 0; + } + + /** + * {@inheritDoc} + */ + public long getAverageGetTime() + { + if (!enabled.get()) + return 0L; + + return totalGetTimeInvocations.get() != 0 ? totalGetTime.get() / totalGetTimeInvocations.get() : 0; + } + + /** + * {@inheritDoc} + */ + public long getAverageUsageTime() + { + if (!enabled.get()) + return 0L; + + return totalUsageTimeInvocations.get() != 0 ? totalUsageTime.get() / totalUsageTimeInvocations.get() : 0; + } + + /** + * {@inheritDoc} + */ + public long getAveragePoolTime() + { + if (!enabled.get()) + return 0L; + + return totalPoolTimeInvocations.get() != 0 ? totalPoolTime.get() / totalPoolTimeInvocations.get() : 0; + } + + /** + * {@inheritDoc} + */ + public int getBlockingFailureCount() + { + if (!enabled.get()) + return 0; + + return blockingFailureCount.get(); + } + + /** + * Delta the blocking failure count value + */ + public void deltaBlockingFailureCount() + { + if (enabled.get()) + blockingFailureCount.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getCreatedCount() + { + if (!enabled.get()) + return 0; + + return createdCount.get(); + } + + /** + * Delta the created count value + */ + public void deltaCreatedCount() + { + if (enabled.get()) + createdCount.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getDestroyedCount() + { + if (!enabled.get()) + return 0; + + return destroyedCount.get(); + } + + /** + * Delta the destroyed count value + */ + public void deltaDestroyedCount() + { + if (enabled.get()) + destroyedCount.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getIdleCount() + { + if (!enabled.get()) + return 0; + + return getActiveCount() - getInUseCount(); + } + + /** + * {@inheritDoc} + */ + public int getInUseCount() + { + if (!enabled.get()) + return 0; + + return inUseCount.get(); + } + + /** + * Set in used count + * @param v The value + */ + public void setInUsedCount(int v) + { + inUseCount.set(v); + setMaxUsedCount(v); + } + + /** + * Get max used count + * @return The value + */ + public int getMaxUsedCount() + { + if (!enabled.get()) + return 0; + + return maxUsedCount.get() != Integer.MIN_VALUE ? maxUsedCount.get() : 0; + } + + /** + * Set max used count + * @param v The value + */ + private void setMaxUsedCount(int v) + { + if (v > maxUsedCount.get()) + maxUsedCount.set(v); + } + + /** + * {@inheritDoc} + */ + public long getMaxCreationTime() + { + if (!enabled.get()) + return 0L; + + return maxCreationTime.get() != Long.MIN_VALUE ? maxCreationTime.get() : 0; + } + + /** + * {@inheritDoc} + */ + public long getMaxGetTime() + { + if (!enabled.get()) + return 0L; + + return maxGetTime.get() != Long.MIN_VALUE ? maxGetTime.get() : 0; + } + + /** + * {@inheritDoc} + */ + public long getMaxPoolTime() + { + if (!enabled.get()) + return 0L; + + return maxPoolTime.get() != Long.MIN_VALUE ? maxPoolTime.get() : 0; + } + + /** + * {@inheritDoc} + */ + public long getMaxUsageTime() + { + if (!enabled.get()) + return 0L; + + return maxUsageTime.get() != Long.MIN_VALUE ? maxUsageTime.get() : 0; + } + + /** + * Get max wait count + * @return The value + */ + public int getMaxWaitCount() + { + if (!isEnabled()) + return 0; + + return maxWaitCount.get() != Integer.MIN_VALUE ? maxWaitCount.get() : 0; + } + + /** + * Set max wait count + * @param v The value + */ + public void setMaxWaitCount(int v) + { + if (v > maxWaitCount.get()) + maxWaitCount.set(v); + } + + /** + * {@inheritDoc} + */ + public long getMaxWaitTime() + { + if (!enabled.get()) + return 0L; + + return maxWaitTime.get() != Long.MIN_VALUE ? maxWaitTime.get() : 0; + } + + /** + * {@inheritDoc} + */ + public int getTimedOut() + { + if (!enabled.get()) + return 0; + + return timedOut.get(); + } + + /** + * Delta the timed out value + */ + public void deltaTimedOut() + { + if (enabled.get()) + timedOut.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public long getTotalBlockingTime() + { + if (!enabled.get()) + return 0L; + + return totalBlockingTime.get(); + } + + /** + * Add delta to total blocking timeout + * @param delta The value + */ + public void deltaTotalBlockingTime(long delta) + { + if (enabled.get() && delta > 0) + { + totalBlockingTime.addAndGet(delta); + totalBlockingTimeInvocations.incrementAndGet(); + + if (delta > maxWaitTime.get()) + maxWaitTime.set(delta); + } + } + + /** + * {@inheritDoc} + */ + public long getTotalCreationTime() + { + if (!enabled.get()) + return 0L; + + return totalCreationTime.get(); + } + + /** + * Add delta to total creation time + * @param delta The value + */ + public void deltaTotalCreationTime(long delta) + { + if (enabled.get() && delta > 0) + { + totalCreationTime.addAndGet(delta); + + if (delta > maxCreationTime.get()) + maxCreationTime.set(delta); + } + } + + /** + * {@inheritDoc} + */ + public long getTotalGetTime() + { + if (!enabled.get()) + return 0L; + + return totalGetTime.get(); + } + + /** + * Add delta to total get time + * @param delta The value + */ + public void deltaTotalGetTime(long delta) + { + if (enabled.get() && delta > 0) + { + totalGetTime.addAndGet(delta); + totalGetTimeInvocations.incrementAndGet(); + + if (delta > maxGetTime.get()) + maxGetTime.set(delta); + } + } + + /** + * {@inheritDoc} + */ + public long getTotalPoolTime() + { + if (!enabled.get()) + return 0L; + + return totalPoolTime.get(); + } + + /** + * Add delta to total pool time + * @param delta The value + */ + public void deltaTotalPoolTime(long delta) + { + if (enabled.get() && delta > 0) + { + totalPoolTime.addAndGet(delta); + totalPoolTimeInvocations.incrementAndGet(); + + if (delta > maxPoolTime.get()) + maxPoolTime.set(delta); + } + } + + /** + * {@inheritDoc} + */ + public long getTotalUsageTime() + { + if (!enabled.get()) + return 0L; + + return totalUsageTime.get(); + } + + /** + * Add delta to total usage time + * @param delta The value + */ + public void deltaTotalUsageTime(long delta) + { + if (enabled.get() && delta > 0) + { + totalUsageTime.addAndGet(delta); + totalUsageTimeInvocations.incrementAndGet(); + + if (delta > maxUsageTime.get()) + maxUsageTime.set(delta); + } + } + + /** + * {@inheritDoc} + */ + public int getWaitCount() + { + if (!enabled.get()) + return 0; + + return waitCount.get(); + } + + /** + * Add delta wait count + */ + public void deltaWaitCount() + { + if (enabled.get()) + waitCount.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public long getCommitCount() + { + if (!isEnabled()) + return 0L; + + return commitCount.get(); + } + + /** + * {@inheritDoc} + */ + public long getCommitTotalTime() + { + if (!isEnabled()) + return 0L; + + return commitTotalTime.get(); + } + + /** + * {@inheritDoc} + */ + public long getCommitAverageTime() + { + if (!isEnabled()) + return 0L; + + if (commitCount.get() > 0) + return commitTotalTime.get() / commitCount.get(); + + return 0L; + } + + /** + * {@inheritDoc} + */ + public long getCommitMaxTime() + { + if (!isEnabled()) + return 0L; + + return commitMaxTime.get(); + } + + /** + * {@inheritDoc} + */ + public void deltaCommit(long time) + { + commitCount.incrementAndGet(); + + if (time > 0) + { + commitTotalTime.addAndGet(time); + + if (time > commitMaxTime.get()) + commitMaxTime.set(time); + } + } + + /** + * {@inheritDoc} + */ + public long getEndCount() + { + if (!isEnabled()) + return 0L; + + return endCount.get(); + } + + /** + * {@inheritDoc} + */ + public long getEndTotalTime() + { + if (!isEnabled()) + return 0L; + + return endTotalTime.get(); + } + + /** + * {@inheritDoc} + */ + public long getEndAverageTime() + { + if (!isEnabled()) + return 0L; + + if (endCount.get() > 0) + return endTotalTime.get() / endCount.get(); + + return 0L; + } + + /** + * {@inheritDoc} + */ + public long getEndMaxTime() + { + if (!isEnabled()) + return 0L; + + return endMaxTime.get(); + } + + /** + * {@inheritDoc} + */ + public void deltaEnd(long time) + { + endCount.incrementAndGet(); + + if (time > 0) + { + endTotalTime.addAndGet(time); + + if (time > endMaxTime.get()) + endMaxTime.set(time); + } + } + + /** + * {@inheritDoc} + */ + public long getForgetCount() + { + if (!isEnabled()) + return 0L; + + return forgetCount.get(); + } + + /** + * {@inheritDoc} + */ + public long getForgetTotalTime() + { + if (!isEnabled()) + return 0L; + + return forgetTotalTime.get(); + } + + /** + * {@inheritDoc} + */ + public long getForgetAverageTime() + { + if (!isEnabled()) + return 0L; + + if (forgetCount.get() > 0) + return forgetTotalTime.get() / forgetCount.get(); + + return 0L; + } + + /** + * {@inheritDoc} + */ + public long getForgetMaxTime() + { + if (!isEnabled()) + return 0L; + + return forgetMaxTime.get(); + } + + /** + * {@inheritDoc} + */ + public void deltaForget(long time) + { + forgetCount.incrementAndGet(); + + if (time > 0) + { + forgetTotalTime.addAndGet(time); + + if (time > forgetMaxTime.get()) + forgetMaxTime.set(time); + } + } + + /** + * {@inheritDoc} + */ + public long getPrepareCount() + { + if (!isEnabled()) + return 0L; + + return prepareCount.get(); + } + + /** + * {@inheritDoc} + */ + public long getPrepareTotalTime() + { + if (!isEnabled()) + return 0L; + + return prepareTotalTime.get(); + } + + /** + * {@inheritDoc} + */ + public long getPrepareAverageTime() + { + if (!isEnabled()) + return 0L; + + if (prepareCount.get() > 0) + return prepareTotalTime.get() / prepareCount.get(); + + return 0L; + } + + /** + * {@inheritDoc} + */ + public long getPrepareMaxTime() + { + if (!isEnabled()) + return 0L; + + return prepareMaxTime.get(); + } + + /** + * {@inheritDoc} + */ + public void deltaPrepare(long time) + { + prepareCount.incrementAndGet(); + + if (time > 0) + { + prepareTotalTime.addAndGet(time); + + if (time > prepareMaxTime.get()) + prepareMaxTime.set(time); + } + } + + /** + * {@inheritDoc} + */ + public long getRecoverCount() + { + if (!isEnabled()) + return 0L; + + return recoverCount.get(); + } + + /** + * {@inheritDoc} + */ + public long getRecoverTotalTime() + { + if (!isEnabled()) + return 0L; + + return recoverTotalTime.get(); + } + + /** + * {@inheritDoc} + */ + public long getRecoverAverageTime() + { + if (!isEnabled()) + return 0L; + + if (recoverCount.get() > 0) + return recoverTotalTime.get() / recoverCount.get(); + + return 0L; + } + + /** + * {@inheritDoc} + */ + public long getRecoverMaxTime() + { + if (!isEnabled()) + return 0L; + + return recoverMaxTime.get(); + } + + /** + * {@inheritDoc} + */ + public void deltaRecover(long time) + { + recoverCount.incrementAndGet(); + + if (time > 0) + { + recoverTotalTime.addAndGet(time); + + if (time > recoverMaxTime.get()) + recoverMaxTime.set(time); + } + } + + /** + * {@inheritDoc} + */ + public long getRollbackCount() + { + if (!isEnabled()) + return 0L; + + return rollbackCount.get(); + } + + /** + * {@inheritDoc} + */ + public long getRollbackTotalTime() + { + if (!isEnabled()) + return 0L; + + return rollbackTotalTime.get(); + } + + /** + * {@inheritDoc} + */ + public long getRollbackAverageTime() + { + if (!isEnabled()) + return 0L; + + if (rollbackCount.get() > 0) + return rollbackTotalTime.get() / rollbackCount.get(); + + return 0L; + } + + /** + * {@inheritDoc} + */ + public long getRollbackMaxTime() + { + if (!isEnabled()) + return 0L; + + return rollbackMaxTime.get(); + } + + /** + * {@inheritDoc} + */ + public void deltaRollback(long time) + { + rollbackCount.incrementAndGet(); + + if (time > 0) + { + rollbackTotalTime.addAndGet(time); + + if (time > rollbackMaxTime.get()) + rollbackMaxTime.set(time); + } + } + + /** + * {@inheritDoc} + */ + public long getStartCount() + { + if (!isEnabled()) + return 0L; + + return startCount.get(); + } + + /** + * {@inheritDoc} + */ + public long getStartTotalTime() + { + if (!isEnabled()) + return 0L; + + return startTotalTime.get(); + } + + /** + * {@inheritDoc} + */ + public long getStartAverageTime() + { + if (!isEnabled()) + return 0L; + + if (startCount.get() > 0) + return startTotalTime.get() / startCount.get(); + + return 0L; + } + + /** + * {@inheritDoc} + */ + public long getStartMaxTime() + { + if (!isEnabled()) + return 0L; + + return startMaxTime.get(); + } + + /** + * {@inheritDoc} + */ + public void deltaStart(long time) + { + startCount.incrementAndGet(); + + if (time > 0) + { + startTotalTime.addAndGet(time); + + if (time > startMaxTime.get()) + startMaxTime.set(time); + } + } + + /** + * {@inheritDoc} + */ + public void clear() + { + this.createdCount.set(0); + this.destroyedCount.set(0); + this.maxCreationTime.set(Long.MIN_VALUE); + this.maxGetTime.set(Long.MIN_VALUE); + this.maxPoolTime.set(Long.MIN_VALUE); + this.maxUsageTime.set(Long.MIN_VALUE); + this.maxUsedCount.set(Integer.MIN_VALUE); + this.maxWaitTime.set(Long.MIN_VALUE); + this.timedOut.set(0); + this.totalBlockingTime.set(0L); + this.totalBlockingTimeInvocations.set(0L); + this.totalCreationTime.set(0L); + this.totalGetTime.set(0L); + this.totalGetTimeInvocations.set(0L); + this.totalPoolTime.set(0L); + this.totalPoolTimeInvocations.set(0L); + this.totalUsageTime.set(0L); + this.totalUsageTimeInvocations.set(0L); + this.inUseCount.set(0); + this.blockingFailureCount.set(0); + this.waitCount.set(0); + + this.commitCount = new AtomicLong(0L); + this.commitTotalTime = new AtomicLong(0L); + this.commitMaxTime = new AtomicLong(0L); + this.endCount = new AtomicLong(0L); + this.endTotalTime = new AtomicLong(0L); + this.endMaxTime = new AtomicLong(0L); + this.forgetCount = new AtomicLong(0L); + this.forgetTotalTime = new AtomicLong(0L); + this.forgetMaxTime = new AtomicLong(0L); + this.prepareCount = new AtomicLong(0L); + this.prepareTotalTime = new AtomicLong(0L); + this.prepareMaxTime = new AtomicLong(0L); + this.recoverCount = new AtomicLong(0L); + this.recoverTotalTime = new AtomicLong(0L); + this.recoverMaxTime = new AtomicLong(0L); + this.rollbackCount = new AtomicLong(0L); + this.rollbackTotalTime = new AtomicLong(0L); + this.rollbackMaxTime = new AtomicLong(0L); + this.startCount = new AtomicLong(0L); + this.startTotalTime = new AtomicLong(0L); + this.startMaxTime = new AtomicLong(0L); + } + + private void writeObject(ObjectOutputStream out) throws IOException + { + out.defaultWriteObject(); + out.writeInt(maxPoolSize); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + init(in.readInt()); + } + + /** + * toString + * @return The value + */ + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("PoolStatistics@").append(Integer.toHexString(System.identityHashCode(this))); + + sb.append("["); + + sb.append("Enabled=").append(isEnabled()); + sb.append(","); + sb.append(ACTIVE_COUNT).append("=").append(getActiveCount()); + sb.append(","); + sb.append(AVAILABLE_COUNT).append("=").append(getAvailableCount()); + sb.append(","); + sb.append(AVERAGE_BLOCKING_TIME).append("=").append(getAverageBlockingTime()); + sb.append(","); + sb.append(AVERAGE_CREATION_TIME).append("=").append(getAverageCreationTime()); + sb.append(","); + sb.append(AVERAGE_GET_TIME).append("=").append(getAverageGetTime()); + sb.append(","); + sb.append(AVERAGE_POOL_TIME).append("=").append(getAveragePoolTime()); + sb.append(","); + sb.append(AVERAGE_USAGE_TIME).append("=").append(getAverageUsageTime()); + sb.append(","); + sb.append(BLOCKING_FAILURE_COUNT).append("=").append(getBlockingFailureCount()); + sb.append(","); + sb.append(CREATED_COUNT).append("=").append(getCreatedCount()); + sb.append(","); + sb.append(DESTROYED_COUNT).append("=").append(getDestroyedCount()); + sb.append(","); + sb.append(IDLE_COUNT).append("=").append(getIdleCount()); + sb.append(","); + sb.append(IN_USE_COUNT).append("=").append(getInUseCount()); + sb.append(","); + sb.append(MAX_CREATION_TIME).append("=").append(getMaxCreationTime()); + sb.append(","); + sb.append(MAX_GET_TIME).append("=").append(getMaxGetTime()); + sb.append(","); + sb.append(MAX_POOL_TIME).append("=").append(getMaxPoolTime()); + sb.append(","); + sb.append(MAX_USAGE_TIME).append("=").append(getMaxUsageTime()); + sb.append(","); + sb.append(MAX_USED_COUNT).append("=").append(getMaxUsedCount()); + sb.append(","); + sb.append(MAX_WAIT_COUNT).append("=").append(getMaxWaitCount()); + sb.append(","); + sb.append(MAX_WAIT_TIME).append("=").append(getMaxWaitTime()); + sb.append(","); + sb.append(TIMED_OUT).append("=").append(getTimedOut()); + sb.append(","); + sb.append(TOTAL_BLOCKING_TIME).append("=").append(getTotalBlockingTime()); + sb.append(","); + sb.append(TOTAL_CREATION_TIME).append("=").append(getTotalCreationTime()); + sb.append(","); + sb.append(TOTAL_GET_TIME).append("=").append(getTotalGetTime()); + sb.append(","); + sb.append(TOTAL_POOL_TIME).append("=").append(getTotalPoolTime()); + sb.append(","); + sb.append(TOTAL_USAGE_TIME).append("=").append(getTotalUsageTime()); + sb.append(","); + sb.append(WAIT_COUNT).append("=").append(getWaitCount()); + + sb.append(","); + sb.append(XA_COMMIT_COUNT).append("=").append(getCommitCount()); + sb.append(","); + sb.append(XA_COMMIT_AVERAGE_TIME).append("=").append(getCommitAverageTime()); + sb.append(","); + sb.append(XA_COMMIT_TOTAL_TIME).append("=").append(getCommitTotalTime()); + sb.append(","); + sb.append(XA_COMMIT_MAX_TIME).append("=").append(getCommitMaxTime()); + sb.append(","); + sb.append(XA_END_COUNT).append("=").append(getEndCount()); + sb.append(","); + sb.append(XA_END_AVERAGE_TIME).append("=").append(getEndAverageTime()); + sb.append(","); + sb.append(XA_END_TOTAL_TIME).append("=").append(getEndTotalTime()); + sb.append(","); + sb.append(XA_END_MAX_TIME).append("=").append(getEndMaxTime()); + sb.append(","); + sb.append(XA_FORGET_COUNT).append("=").append(getForgetCount()); + sb.append(","); + sb.append(XA_FORGET_AVERAGE_TIME).append("=").append(getForgetAverageTime()); + sb.append(","); + sb.append(XA_FORGET_TOTAL_TIME).append("=").append(getForgetTotalTime()); + sb.append(","); + sb.append(XA_FORGET_MAX_TIME).append("=").append(getForgetMaxTime()); + sb.append(","); + sb.append(XA_PREPARE_COUNT).append("=").append(getPrepareCount()); + sb.append(","); + sb.append(XA_PREPARE_AVERAGE_TIME).append("=").append(getPrepareAverageTime()); + sb.append(","); + sb.append(XA_PREPARE_TOTAL_TIME).append("=").append(getPrepareTotalTime()); + sb.append(","); + sb.append(XA_PREPARE_MAX_TIME).append("=").append(getPrepareMaxTime()); + sb.append(","); + sb.append(XA_RECOVER_COUNT).append("=").append(getRecoverCount()); + sb.append(","); + sb.append(XA_RECOVER_AVERAGE_TIME).append("=").append(getRecoverAverageTime()); + sb.append(","); + sb.append(XA_RECOVER_TOTAL_TIME).append("=").append(getRecoverTotalTime()); + sb.append(","); + sb.append(XA_RECOVER_MAX_TIME).append("=").append(getRecoverMaxTime()); + sb.append(","); + sb.append(XA_ROLLBACK_COUNT).append("=").append(getRollbackCount()); + sb.append(","); + sb.append(XA_ROLLBACK_AVERAGE_TIME).append("=").append(getRollbackAverageTime()); + sb.append(","); + sb.append(XA_ROLLBACK_TOTAL_TIME).append("=").append(getRollbackTotalTime()); + sb.append(","); + sb.append(XA_ROLLBACK_MAX_TIME).append("=").append(getRollbackMaxTime()); + sb.append(","); + sb.append(XA_START_COUNT).append("=").append(getStartCount()); + sb.append(","); + sb.append(XA_START_AVERAGE_TIME).append("=").append(getStartAverageTime()); + sb.append(","); + sb.append(XA_START_TOTAL_TIME).append("=").append(getStartTotalTime()); + sb.append(","); + sb.append(XA_START_MAX_TIME).append("=").append(getStartMaxTime()); + + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,88 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Get a system property + * @param name The property name + * @return The property value + */ + static String getSystemProperty(final String name) + { + return AccessController.doPrivileged(new PrivilegedAction() + { + public String run() + { + return System.getProperty(name); + } + }); + } + + /** + * Get the classloader. + * @param c The class + * @return The classloader + */ + static ClassLoader getClassLoader(final Class c) + { + if (System.getSecurityManager() == null) + return c.getClassLoader(); + + return AccessController.doPrivileged(new PrivilegedAction() + { + public ClassLoader run() + { + return c.getClassLoader(); + } + }); + } + + /** + * Get stack trace + * @param t The thread + * @return The trace + */ + static StackTraceElement[] getStackTrace(final Thread t) + { + if (System.getSecurityManager() == null) + return t.getStackTrace(); + + return AccessController.doPrivileged(new PrivilegedAction() + { + public StackTraceElement[] run() + { + return t.getStackTrace(); + } + }); + } + +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Capacity.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Capacity.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Capacity.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,42 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.api; + +/** + * The capacity policy + * + * @author Jesper Pedersen + */ +public interface Capacity +{ + /** + * Get the incrementer policy + * @return The policy; can be null for container default policy + */ + public CapacityIncrementer getIncrementer(); + + /** + * Get the decrementer policy + * @return The policy; can be null for container default policy + */ + public CapacityDecrementer getDecrementer(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/CapacityDecrementer.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/CapacityDecrementer.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/CapacityDecrementer.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,43 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.api; + +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; + +/** + * The capacity decrementer policy + * + * @author Jesper Pedersen + */ +public interface CapacityDecrementer +{ + /** + * Should the connection listener be destroyed + * @param cl The connection listener + * @param timeout The timeout watermark + * @param currentSize The current pool size + * @param minPoolSize The minimum pool size + * @param destroyed The number of connection listeners destroyed during this call cycle + * @return True if the connection listener should be destroyed; otherwise false + */ + public boolean shouldDestroy(ConnectionListener cl, long timeout, int currentSize, int minPoolSize, int destroyed); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/CapacityIncrementer.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/CapacityIncrementer.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/CapacityIncrementer.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,39 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.api; + +/** + * The capacity incrementer policy + * + * @author Jesper Pedersen + */ +public interface CapacityIncrementer +{ + /** + * Should the connection listener be created + * @param currentSize The current pool size + * @param maxSize The maximum pool size + * @param created The number of connection listeners created during this call cycle + * @return True if a connection listener should be created; otherwise false + */ + public boolean shouldCreate(int currentSize, int maxSize, int created); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Pool.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Pool.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Pool.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,205 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2006, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.api; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.connectionmanager.ConnectionManager; +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.connectionmanager.pool.PoolStatisticsImpl; +import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool; + +import javax.resource.ResourceException; +import javax.resource.spi.ConnectionRequestInfo; +import javax.resource.spi.ManagedConnection; +import javax.resource.spi.ManagedConnectionFactory; +import javax.security.auth.Subject; +import javax.transaction.Transaction; + +/** + * A pool. + * + * @author Gurkan Erdogdu + * @author David Jencks + * @author Jesper Pedersen + */ +public interface Pool extends org.jboss.jca.core.api.connectionmanager.pool.Pool +{ + /** + * Sets pool name. + * @param poolName pool name + */ + public void setName(String poolName); + + /** + * Is sharable + * @return The value + */ + public boolean isSharable(); + + /** + * Retrieve the managed connection factory for this pool. + * + * @return the managed connection factory + */ + public ManagedConnectionFactory getManagedConnectionFactory(); + + /** + * Set the connection manager + * + * @param cm the connection manager + */ + public void setConnectionManager(ConnectionManager cm); + + /** + * Get the lock + * @return The value + */ + public Semaphore getLock(); + + /** + * Get the capacity policy + * @return The value + */ + public Capacity getCapacity(); + + /** + * Is the pool a FIFO or FILO pool + * @return True if FIFO + */ + public boolean isFIFO(); + + /** + * Set the capacity policy + * @param c The value + */ + public void setCapacity(Capacity c); + + /** + * Get the interleaving flag + * @return The value + */ + public boolean isInterleaving(); + + /** + * Set the interleaving flag + * @param v The value + */ + public void setInterleaving(boolean v); + + /** + * Is the pool idle + * @return True if idle, otherwise false + */ + public boolean isIdle(); + + /** + * Is the pool full + * @return True if full, otherwise false + */ + public boolean isFull(); + + /** + * Get internal statistics + * @return The value + */ + public PoolStatisticsImpl getInternalStatistics(); + + /** + * Get a connection + * + * @param trackByTransaction for transaction stickiness + * @param subject the subject for connection + * @param cri the connection request information + * @return a connection event listener wrapping the connection + * @throws ResourceException for any error + */ + public ConnectionListener getConnection(Transaction trackByTransaction, Subject subject, ConnectionRequestInfo cri) + throws ResourceException; + + /** + * Find a connection listener + * @param mc The managed connection + * @return The connection listener + */ + public ConnectionListener findConnectionListener(ManagedConnection mc); + + /** + * Find a connection listener + * @param mc The managed connection + * @param connection The connection + * @return The connection listener + */ + public ConnectionListener findConnectionListener(ManagedConnection mc, Object connection); + + /** + * Return a connection + * + * @param cl the connection event listener wrapping the connection + * @param kill whether to destroy the managed connection + * @throws ResourceException for any error + */ + public void returnConnection(ConnectionListener cl, boolean kill) + throws ResourceException; + + /** + * Has an existing connection + * + * @param subject the subject for connection + * @param cri the connection request information + * @return true if there is an existing connection enlisted, otherwise false + */ + public boolean hasConnection(Subject subject, ConnectionRequestInfo cri); + + /** + * Is shutdown + * @return The value + */ + public boolean isShutdown(); + + /** + * Shutdown the pool + */ + public void shutdown(); + + /** + * Prepare Shutdown + */ + public void prepareShutdown(); + + /** + * Cancel shutdown + * @return True if the shutdown was canceled; false otherwise + */ + public boolean cancelShutdown(); + + /** + * Remove the matching managed connection pool if the pool is empty + * @param pool The pool + */ + public void emptyManagedConnectionPool(ManagedConnectionPool pool); + + /** + * Get the logger + * @return The value + */ + public CoreLogger getLogger(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PoolFactory.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PoolFactory.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PoolFactory.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,93 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.api; + +import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration; +import org.jboss.jca.core.connectionmanager.pool.strategy.OnePool; +import org.jboss.jca.core.connectionmanager.pool.strategy.PoolByCri; +import org.jboss.jca.core.connectionmanager.pool.strategy.PoolBySubject; +import org.jboss.jca.core.connectionmanager.pool.strategy.PoolBySubjectAndCri; +import org.jboss.jca.core.connectionmanager.pool.strategy.ReauthPool; + +import javax.resource.spi.ManagedConnectionFactory; + +/** + * The pool factory. + * @author Jesper Pedersen + */ +public class PoolFactory +{ + /** + * Constructor + */ + public PoolFactory() + { + } + + /** + * Create a pool + * @param strategy The pool strategy + * @param mcf The managed connection factory + * @param pc The pool configuration + * @param noTxSeparatePools no-tx separate pool + * @param sharable Are the connections sharable + * @param mcp ManagedConnectionPool + * @return The pool instance + */ + public Pool create(final PoolStrategy strategy, + final ManagedConnectionFactory mcf, + final PoolConfiguration pc, + final boolean noTxSeparatePools, + final boolean sharable, + final String mcp) + { + if (strategy == null) + throw new IllegalArgumentException("Strategy is null"); + + if (mcf == null) + throw new IllegalArgumentException("MCF is null"); + + if (pc == null) + throw new IllegalArgumentException("PoolConfiguration is null"); + + switch (strategy) + { + case POOL_BY_CRI: + return new PoolByCri(mcf, pc, noTxSeparatePools, sharable, mcp); + + case POOL_BY_SUBJECT: + return new PoolBySubject(mcf, pc, noTxSeparatePools, sharable, mcp); + + case POOL_BY_SUBJECT_AND_CRI: + return new PoolBySubjectAndCri(mcf, pc, noTxSeparatePools, sharable, mcp); + + case ONE_POOL: + return new OnePool(mcf, pc, noTxSeparatePools, sharable, mcp); + + case REAUTH: + return new ReauthPool(mcf, pc, noTxSeparatePools, sharable, mcp); + } + + throw new IllegalArgumentException("Unknown strategy " + strategy); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PoolStrategy.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PoolStrategy.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PoolStrategy.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,45 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.api; + +/** + * Defines a pool strategy. + * @author Jesper Pedersen + */ +public enum PoolStrategy +{ + /** POOL_BY_CRI */ + POOL_BY_CRI, + + /** POOL_BY_SUBJECT */ + POOL_BY_SUBJECT, + + /** POOL_BY_SUBJECT_AND_CRI */ + POOL_BY_SUBJECT_AND_CRI, + + /** ONE_POOL */ + ONE_POOL, + + /** REAUTH */ + REAUTH +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PrefillPool.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PrefillPool.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PrefillPool.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,44 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2006, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.api; + +import javax.resource.spi.ConnectionRequestInfo; +import javax.security.auth.Subject; + +/** + * Prefill pool allows for prefilling connection pools. + * + * @author Weston Price + * @author Jesper Pedersen + */ +public interface PrefillPool extends Pool +{ + /** + * Prefill the connection pool + * + * @param subject the subject the subject + * @param cri the connection request info + * @param noTxnSeperatePool whether or not we are seperating non transaction and transaction pools + * + */ + public void prefill(Subject subject, ConnectionRequestInfo cri, boolean noTxnSeperatePool); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Semaphore.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Semaphore.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Semaphore.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,100 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.api; + +import org.jboss.jca.core.connectionmanager.pool.PoolStatisticsImpl; + +import java.util.Collection; +import java.util.concurrent.TimeUnit; + +/** + * A semaphore implementation that supports statistics + * + * @author Jesper Pedersen + */ +public class Semaphore extends java.util.concurrent.Semaphore +{ + /** Serial version uid */ + private static final long serialVersionUID = 4L; + + /** Max size */ + private int maxSize; + + /** Statistics */ + private PoolStatisticsImpl statistics; + + /** + * Constructor + * @param maxSize The maxumum size + * @param fairness The fairness + * @param statistics The statistics module + */ + public Semaphore(int maxSize, boolean fairness, PoolStatisticsImpl statistics) + { + super(maxSize, fairness); + this.maxSize = maxSize; + this.statistics = statistics; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException + { + if (statistics.isEnabled()) + statistics.setMaxWaitCount(getQueueLength()); + + boolean result = super.tryAcquire(timeout, unit); + + if (result && statistics.isEnabled()) + { + statistics.setInUsedCount(maxSize - availablePermits()); + } + + return result; + } + + /** + * {@inheritDoc} + */ + @Override + public void release() + { + super.release(); + + if (statistics.isEnabled()) + { + statistics.setInUsedCount(maxSize - availablePermits()); + } + } + + /** + * {@inheritDoc} + */ + @Override + public Collection getQueuedThreads() + { + return super.getQueuedThreads(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the connection pool api. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/CapacityFactory.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/CapacityFactory.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/CapacityFactory.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,243 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.capacity; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer; +import org.jboss.jca.core.connectionmanager.pool.api.CapacityIncrementer; +import org.jboss.jca.core.util.Injection; + +import java.util.Map; + +import org.jboss.logging.Logger; + +/** + * The capacity factory + * + * @author Jesper Pedersen + */ +public class CapacityFactory +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, CapacityFactory.class.getName()); + + /** + * Constructor + */ + private CapacityFactory() + { + } + + /** + * Create a capacity instance based on the metadata + * @param metadata The metadata + * @param isCRI Is the pool CRI based + * @return The instance + */ + public static org.jboss.jca.core.connectionmanager.pool.api.Capacity + create(org.jboss.jca.common.api.metadata.common.Capacity metadata, + boolean isCRI) + { + if (metadata == null) + return DefaultCapacity.INSTANCE; + + CapacityIncrementer incrementer = null; + CapacityDecrementer decrementer = null; + + // Incrementer + if (metadata.getIncrementer() != null && metadata.getIncrementer().getClassName() != null) + { + incrementer = loadIncrementer(metadata.getIncrementer().getClassName()); + + if (incrementer != null) + { + if (metadata.getIncrementer().getConfigPropertiesMap().size() > 0) + { + Injection injector = new Injection(); + + Map properties = metadata.getIncrementer().getConfigPropertiesMap(); + for (Map.Entry property : properties.entrySet()) + { + try + { + injector.inject(incrementer, property.getKey(), property.getValue()); + } + catch (Throwable t) + { + log.invalidCapacityOption(property.getKey(), + property.getValue(), incrementer.getClass().getName()); + } + } + } + } + else + { + log.invalidCapacityIncrementer(metadata.getIncrementer().getClassName()); + } + } + + if (incrementer == null) + incrementer = DefaultCapacity.DEFAULT_INCREMENTER; + + // Decrementer + if (metadata.getDecrementer() != null && metadata.getDecrementer().getClassName() != null) + { + if (!isCRI) + { + decrementer = loadDecrementer(metadata.getDecrementer().getClassName()); + + if (decrementer != null) + { + if (metadata.getDecrementer().getConfigPropertiesMap().size() > 0) + { + Injection injector = new Injection(); + + Map properties = metadata.getDecrementer().getConfigPropertiesMap(); + for (Map.Entry property : properties.entrySet()) + { + try + { + injector.inject(decrementer, property.getKey(), property.getValue()); + } + catch (Throwable t) + { + log.invalidCapacityOption(property.getKey(), + property.getValue(), decrementer.getClass().getName()); + } + } + } + } + else + { + log.invalidCapacityDecrementer(metadata.getDecrementer().getClassName()); + } + } + else + { + // Explicit allow TimedOutDecrementer, MinPoolSizeDecrementer and SizeDecrementer for CRI based pools + if (TimedOutDecrementer.class.getName().equals(metadata.getDecrementer().getClassName()) || + TimedOutFIFODecrementer.class.getName().equals(metadata.getDecrementer().getClassName()) || + MinPoolSizeDecrementer.class.getName().equals(metadata.getDecrementer().getClassName()) || + SizeDecrementer.class.getName().equals(metadata.getDecrementer().getClassName())) + { + decrementer = loadDecrementer(metadata.getDecrementer().getClassName()); + + if (metadata.getDecrementer().getConfigPropertiesMap().size() > 0) + { + Injection injector = new Injection(); + + Map properties = metadata.getDecrementer().getConfigPropertiesMap(); + for (Map.Entry property : properties.entrySet()) + { + try + { + injector.inject(decrementer, property.getKey(), property.getValue()); + } + catch (Throwable t) + { + log.invalidCapacityOption(property.getKey(), + property.getValue(), decrementer.getClass().getName()); + } + } + } + } + else + { + log.invalidCapacityDecrementer(metadata.getDecrementer().getClassName()); + } + } + } + + if (decrementer == null) + decrementer = DefaultCapacity.DEFAULT_DECREMENTER; + + return new ExplicitCapacity(incrementer, decrementer); + } + + /** + * Load the incrementer + * @param clz The incrementer class name + * @return The incrementer + */ + private static CapacityIncrementer loadIncrementer(String clz) + { + Object result = loadClass(clz); + + if (result != null && result instanceof CapacityIncrementer) + { + return (CapacityIncrementer)result; + } + + log.debugf("%s wasn't a CapacityIncrementer", clz); + + return null; + } + + /** + * Load the decrementer + * @param clz The decrementer class name + * @return The decrementer + */ + private static CapacityDecrementer loadDecrementer(String clz) + { + Object result = loadClass(clz); + + if (result != null && result instanceof CapacityDecrementer) + { + return (CapacityDecrementer)result; + } + + log.debugf("%s wasn't a CapacityDecrementer", clz); + + return null; + } + + /** + * Load the class + * @param clz The class name + * @return The object + */ + private static Object loadClass(String clz) + { + try + { + Class c = Class.forName(clz, true, SecurityActions.getClassLoader(CapacityFactory.class)); + return c.newInstance(); + } + catch (Throwable t) + { + log.tracef("Throwable while loading %s using own classloader: %s", clz, t.getMessage()); + } + + try + { + Class c = Class.forName(clz, true, SecurityActions.getThreadContextClassLoader()); + return c.newInstance(); + } + catch (Throwable t) + { + log.tracef("Throwable while loading %s using TCCL: %s", clz, t.getMessage()); + } + + return null; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/DefaultCapacity.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/DefaultCapacity.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/DefaultCapacity.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,66 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.capacity; + +import org.jboss.jca.core.connectionmanager.pool.api.Capacity; +import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer; +import org.jboss.jca.core.connectionmanager.pool.api.CapacityIncrementer; + +/** + * The default capacity policy + * + * @author Jesper Pedersen + */ +public class DefaultCapacity implements Capacity +{ + /** The instance */ + public static final Capacity INSTANCE = new DefaultCapacity(); + + /** The default incrementer */ + public static final CapacityIncrementer DEFAULT_INCREMENTER = null; + + /** The default decrementer */ + public static final CapacityDecrementer DEFAULT_DECREMENTER = new TimedOutDecrementer(); + + /** + * Constructor + */ + private DefaultCapacity() + { + } + + /** + * {@inheritDoc} + */ + public CapacityIncrementer getIncrementer() + { + return DEFAULT_INCREMENTER; + } + + /** + * {@inheritDoc} + */ + public CapacityDecrementer getDecrementer() + { + return DEFAULT_DECREMENTER; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/ExplicitCapacity.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/ExplicitCapacity.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/ExplicitCapacity.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,67 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.capacity; + +import org.jboss.jca.core.connectionmanager.pool.api.Capacity; +import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer; +import org.jboss.jca.core.connectionmanager.pool.api.CapacityIncrementer; + +/** + * Explicit capacity policy + * + * @author Jesper Pedersen + */ +public class ExplicitCapacity implements Capacity +{ + /** The incrementer */ + private CapacityIncrementer incrementer; + + /** The decrementer */ + private CapacityDecrementer decrementer; + + /** + * Constructor + * @param incrementer The incrementer + * @param decrementer The decrementer + */ + public ExplicitCapacity(CapacityIncrementer incrementer, CapacityDecrementer decrementer) + { + this.incrementer = incrementer; + this.decrementer = decrementer; + } + + /** + * {@inheritDoc} + */ + public CapacityIncrementer getIncrementer() + { + return incrementer; + } + + /** + * {@inheritDoc} + */ + public CapacityDecrementer getDecrementer() + { + return decrementer; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/MaxPoolSizeIncrementer.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/MaxPoolSizeIncrementer.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/MaxPoolSizeIncrementer.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,55 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.capacity; + +import org.jboss.jca.core.connectionmanager.pool.api.CapacityIncrementer; + +/** + * Keep incrementing until max-pool-size is reached + * + * @author Jesper Pedersen + */ +public class MaxPoolSizeIncrementer implements CapacityIncrementer +{ + /** + * Constructor + */ + public MaxPoolSizeIncrementer() + { + } + + /** + * {@inheritDoc} + */ + public boolean shouldCreate(int currentSize, int maxSize, int created) + { + return currentSize < maxSize; + } + + /** + * {@inheritDoc} + */ + public String toString() + { + return getClass().getName(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/MinPoolSizeDecrementer.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/MinPoolSizeDecrementer.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/MinPoolSizeDecrementer.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,56 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.capacity; + +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer; + +/** + * Keep destroying connection listeners until min-pool-size is reached + * + * @author Jesper Pedersen + */ +public class MinPoolSizeDecrementer implements CapacityDecrementer +{ + /** + * Constructor + */ + public MinPoolSizeDecrementer() + { + } + + /** + * {@inheritDoc} + */ + public boolean shouldDestroy(ConnectionListener cl, long timeout, int currentSize, int minPoolSize, int destroyed) + { + return currentSize > minPoolSize; + } + + /** + * {@inheritDoc} + */ + public String toString() + { + return getClass().getName(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,74 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.capacity; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Get the classloader. + * @param c The class + * @return The classloader + */ + static ClassLoader getClassLoader(final Class c) + { + if (System.getSecurityManager() == null) + return c.getClassLoader(); + + return AccessController.doPrivileged(new PrivilegedAction() + { + public ClassLoader run() + { + return c.getClassLoader(); + } + }); + } + + /** + * Get the context classloader. + * @return The classloader + */ + public static ClassLoader getThreadContextClassLoader() + { + if (System.getSecurityManager() == null) + { + return Thread.currentThread().getContextClassLoader(); + } + else + { + return AccessController.doPrivileged(new PrivilegedAction() + { + public ClassLoader run() + { + return Thread.currentThread().getContextClassLoader(); + } + }); + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SizeDecrementer.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SizeDecrementer.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SizeDecrementer.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,71 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.capacity; + +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer; + +/** + * Decrement until the defined number of connection has been destroyed. + * + * Default value is 1 + * @author Jesper Pedersen + */ +public class SizeDecrementer implements CapacityDecrementer +{ + /** Size */ + private int size; + + /** + * Constructor + */ + public SizeDecrementer() + { + this.size = 1; + } + + /** + * Set the size + * @param v The value + */ + public void setSize(int v) + { + if (v > 0) + size = v; + } + + /** + * {@inheritDoc} + */ + public boolean shouldDestroy(ConnectionListener cl, long timeout, int currentSize, int minPoolSize, int destroyed) + { + return size > destroyed; + } + + /** + * {@inheritDoc} + */ + public String toString() + { + return getClass().getName() + "(" + size + ")"; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SizeIncrementer.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SizeIncrementer.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SizeIncrementer.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,70 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.capacity; + +import org.jboss.jca.core.connectionmanager.pool.api.CapacityIncrementer; + +/** + * Increment until the defined number of connection has been created. + * + * Default value is 1 + * @author Jesper Pedersen + */ +public class SizeIncrementer implements CapacityIncrementer +{ + /** Size */ + private int size; + + /** + * Constructor + */ + public SizeIncrementer() + { + this.size = 1; + } + + /** + * Set the size + * @param v The value + */ + public void setSize(int v) + { + if (v > 0) + size = v; + } + + /** + * {@inheritDoc} + */ + public boolean shouldCreate(int currentSize, int maxSize, int created) + { + return size > created; + } + + /** + * {@inheritDoc} + */ + public String toString() + { + return getClass().getName() + "(" + size + ")"; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/TimedOutDecrementer.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/TimedOutDecrementer.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/TimedOutDecrementer.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,56 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.capacity; + +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer; + +/** + * Decrement all timed out connection listeners + * + * @author Jesper Pedersen + */ +public class TimedOutDecrementer implements CapacityDecrementer +{ + /** + * Constructor + */ + public TimedOutDecrementer() + { + } + + /** + * {@inheritDoc} + */ + public boolean shouldDestroy(ConnectionListener cl, long timeout, int currentSize, int minPoolSize, int destroyed) + { + return cl.isTimedOut(timeout); + } + + /** + * {@inheritDoc} + */ + public String toString() + { + return getClass().getName(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/TimedOutFIFODecrementer.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/TimedOutFIFODecrementer.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/TimedOutFIFODecrementer.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,37 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2015, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.capacity; + +/** + * Decrement all timed out connection listeners (FIFO marker) + * + * @author Jesper Pedersen + */ +public class TimedOutFIFODecrementer extends TimedOutDecrementer +{ + /** + * Constructor + */ + public TimedOutFIFODecrementer() + { + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/WatermarkDecrementer.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/WatermarkDecrementer.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/WatermarkDecrementer.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,73 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.capacity; + +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer; + +/** + * Decrement until the defined pool size is reached. + * + * Default value is min-pool-size + * @author Jesper Pedersen + */ +public class WatermarkDecrementer implements CapacityDecrementer +{ + /** Watermark */ + private int watermark; + + /** + * Constructor + */ + public WatermarkDecrementer() + { + this.watermark = -1; + } + + /** + * Set the watermark + * @param v The value + */ + public void setWatermark(int v) + { + watermark = v; + } + + /** + * {@inheritDoc} + */ + public boolean shouldDestroy(ConnectionListener cl, long timeout, int currentSize, int minPoolSize, int destroyed) + { + if (watermark < 0) + return currentSize > minPoolSize; + + return watermark < currentSize; + } + + /** + * {@inheritDoc} + */ + public String toString() + { + return getClass().getName() + "(" + watermark + ")"; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/WatermarkIncrementer.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/WatermarkIncrementer.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/WatermarkIncrementer.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,72 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.capacity; + +import org.jboss.jca.core.connectionmanager.pool.api.CapacityIncrementer; + +/** + * Increment until the defined pool size is reached. + * + * Default value is max-pool-size + * @author Jesper Pedersen + */ +public class WatermarkIncrementer implements CapacityIncrementer +{ + /** Watermark */ + private int watermark; + + /** + * Constructor + */ + public WatermarkIncrementer() + { + this.watermark = -1; + } + + /** + * Set the watermark + * @param v The value + */ + public void setWatermark(int v) + { + watermark = v; + } + + /** + * {@inheritDoc} + */ + public boolean shouldCreate(int currentSize, int maxSize, int created) + { + if (watermark < 0) + return currentSize < maxSize; + + return watermark > currentSize; + } + + /** + * {@inheritDoc} + */ + public String toString() + { + return getClass().getName() + "(" + watermark + ")"; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the capacity policy implementations + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/IdleConnectionRemovalSupport.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/IdleConnectionRemovalSupport.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/IdleConnectionRemovalSupport.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,39 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.idle; + +/** + * A IdleConnectionRemovalSupport specified contract for a pool that is able + * to remove an idle connection. + * + * @author gurkanerdogdu + * @author Weston Price + * @version $Revision$ + */ +public interface IdleConnectionRemovalSupport +{ + /** + * Pool removes idle connections. + */ + public void removeIdleConnections(); + +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/IdleRemover.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/IdleRemover.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/IdleRemover.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,306 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.idle; + +import org.jboss.jca.core.CoreLogger; + +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.jboss.logging.Logger; + +/** + * Idle remover + * + * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +public class IdleRemover +{ + /** Logger instance */ + private static CoreLogger logger = Logger.getMessageLogger(CoreLogger.class, IdleRemover.class.getName()); + + /** Thread name */ + private static final String THREAD_NAME = "IdleRemover"; + + /** Singleton instance */ + private static IdleRemover instance = new IdleRemover(); + + /** Registered pool instances */ + private CopyOnWriteArrayList registeredPools = + new CopyOnWriteArrayList(); + + /** Executor service */ + private ExecutorService executorService; + + /** Is the executor external */ + private boolean isExternal; + + /** The interval */ + private long interval; + + /** The next scan */ + private long next; + + /** Shutdown */ + private AtomicBoolean shutdown; + + /** Lock */ + private Lock lock; + + /** Condition */ + private Condition condition; + + /** + * Private constructor. + */ + private IdleRemover() + { + this.executorService = null; + this.isExternal = false; + this.interval = Long.MAX_VALUE; + this.next = Long.MAX_VALUE; + this.shutdown = new AtomicBoolean(false); + this.lock = new ReentrantLock(true); + this.condition = lock.newCondition(); + } + + /** + * Get the instance + * @return The value + */ + public static IdleRemover getInstance() + { + return instance; + } + + /** + * Set the executor service + * @param v The value + */ + public void setExecutorService(ExecutorService v) + { + if (v != null) + { + this.executorService = v; + this.isExternal = true; + } + else + { + this.executorService = null; + this.isExternal = false; + } + } + + /** + * Start + * @exception Throwable Thrown if an error occurs + */ + public void start() throws Throwable + { + if (!isExternal) + { + this.executorService = Executors.newSingleThreadExecutor(new IdleRemoverThreadFactory()); + } + + this.shutdown.set(false); + this.interval = Long.MAX_VALUE; + this.next = Long.MAX_VALUE; + + this.executorService.execute(new IdleRemoverRunner()); + } + + /** + * Stop + * @exception Throwable Thrown if an error occurs + */ + public void stop() throws Throwable + { + instance.shutdown.set(true); + + if (!isExternal) + { + instance.executorService.shutdownNow(); + instance.executorService = null; + } + + instance.registeredPools.clear(); + } + + /** + * Register pool for connection validation. + * @param mcp managed connection pool + * @param interval validation interval + */ + public void registerPool(IdleConnectionRemovalSupport mcp, long interval) + { + logger.debugf("Register pool: %s (interval=%s)", mcp, interval); + + instance.internalRegisterPool(mcp, interval); + } + + /** + * Unregister pool instance for connection validation. + * @param mcp pool instance + */ + public void unregisterPool(IdleConnectionRemovalSupport mcp) + { + logger.debugf("Unregister pool: %s", mcp); + + instance.internalUnregisterPool(mcp); + } + + private void internalRegisterPool(IdleConnectionRemovalSupport mcp, long interval) + { + try + { + this.lock.lock(); + + this.registeredPools.addIfAbsent(mcp); + + if (interval > 1 && interval / 2 < this.interval) + { + this.interval = interval / 2; + long maybeNext = System.currentTimeMillis() + this.interval; + if (next > maybeNext && maybeNext > 0) + { + next = maybeNext; + if (logger.isDebugEnabled()) + { + logger.debug("About to notify thread: old next: " + next + ", new next: " + maybeNext); + } + + this.condition.signal(); + } + } + } + finally + { + this.lock.unlock(); + } + } + + private void internalUnregisterPool(IdleConnectionRemovalSupport mcp) + { + this.registeredPools.remove(mcp); + + if (this.registeredPools.size() == 0) + { + if (logger.isDebugEnabled()) + { + logger.debug("Setting interval to Long.MAX_VALUE"); + } + + interval = Long.MAX_VALUE; + } + } + + /** + * Thread factory. + */ + private static class IdleRemoverThreadFactory implements ThreadFactory + { + /** + * {@inheritDoc} + */ + public Thread newThread(Runnable r) + { + Thread thread = new Thread(r, IdleRemover.THREAD_NAME); + thread.setDaemon(true); + + return thread; + } + } + + /** + * IdleRemoverRunner + */ + private class IdleRemoverRunner implements Runnable + { + /** + * {@inheritDoc} + */ + public void run() + { + final ClassLoader oldTccl = SecurityActions.getThreadContextClassLoader(); + SecurityActions.setThreadContextClassLoader(IdleRemover.class.getClassLoader()); + + try + { + lock.lock(); + + while (!shutdown.get()) + { + boolean result = instance.condition.await(instance.interval, TimeUnit.MILLISECONDS); + + if (logger.isTraceEnabled()) + { + logger.trace("Result of await: " + result); + } + + if (logger.isDebugEnabled()) + { + logger.debug("Notifying pools, interval: " + interval); + } + + for (IdleConnectionRemovalSupport mcp : registeredPools) + { + mcp.removeIdleConnections(); + } + + next = System.currentTimeMillis() + interval; + + if (next < 0) + { + next = Long.MAX_VALUE; + } + } + } + catch (InterruptedException e) + { + if (!shutdown.get()) + logger.returningConnectionValidatorInterrupted(); + } + catch (RuntimeException e) + { + logger.connectionValidatorIgnoredUnexpectedRuntimeException(e); + } + catch (Exception e) + { + logger.connectionValidatorIgnoredUnexpectedError(e); + } + finally + { + lock.unlock(); + SecurityActions.setThreadContextClassLoader(oldTccl); + } + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,83 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.idle; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Get the context classloader. + * @return The classloader + */ + public static ClassLoader getThreadContextClassLoader() + { + if (System.getSecurityManager() == null) + { + return Thread.currentThread().getContextClassLoader(); + } + else + { + return AccessController.doPrivileged(new PrivilegedAction() + { + public ClassLoader run() + { + return Thread.currentThread().getContextClassLoader(); + } + }); + } + } + + /** + * Set the context classloader. + * @param cl classloader + */ + public static void setThreadContextClassLoader(final ClassLoader cl) + { + if (cl == null) + return; + + if (System.getSecurityManager() == null) + { + Thread.currentThread().setContextClassLoader(cl); + } + else + { + AccessController.doPrivileged(new PrivilegedAction() + { + public Object run() + { + Thread.currentThread().setContextClassLoader(cl); + + return null; + } + }); + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the infrastructure for removing idle connections. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/CapacityFiller.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/CapacityFiller.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/CapacityFiller.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,132 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.mcp; + +import java.util.LinkedList; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Capacity filler + * + * @author Jesper Pedersen + */ +class CapacityFiller implements Runnable +{ + /** Singleton instance */ + private static final CapacityFiller INSTANCE = new CapacityFiller(); + + /** Managed connection pool list */ + private final LinkedList crs = new LinkedList(); + + /** Filler thread */ + private final Thread fillerThread; + + /** Thread name */ + private static final String THREAD_FILLER_NAME = "JCA CapacityFiller"; + + /**Thread is configured or not*/ + private AtomicBoolean threadStarted = new AtomicBoolean(false); + + /** + * Schedule capacity request + * @param cr The value + */ + static void schedule(CapacityRequest cr) + { + INSTANCE.internalSchedule(cr); + } + + /** + * Constructor + */ + CapacityFiller() + { + fillerThread = new Thread(this, THREAD_FILLER_NAME); + fillerThread.setDaemon(true); + } + + /** + * {@inheritDoc} + */ + public void run() + { + final ClassLoader myClassLoader = SecurityActions.getClassLoader(getClass()); + SecurityActions.setThreadContextClassLoader(myClassLoader); + + while (true) + { + boolean empty = false; + + while (!empty) + { + CapacityRequest cr = null; + + synchronized (crs) + { + empty = crs.isEmpty(); + if (!empty) + cr = crs.removeFirst(); + } + + if (!empty) + { + cr.getManagedConnectionPool().increaseCapacity(cr.getSubject(), cr.getConnectionRequestInfo()); + } + } + + try + { + synchronized (crs) + { + while (crs.isEmpty()) + { + crs.wait(); + } + } + } + catch (InterruptedException ie) + { + Thread.currentThread().interrupt(); + return; + } + } + } + + /** + * Internal: Schedule + * @param cr The value + */ + private void internalSchedule(CapacityRequest cr) + { + if (this.threadStarted.compareAndSet(false, true)) + { + this.fillerThread.start(); + } + + // Multiple instances of the same ManagedConnectionPool is allowed + synchronized (crs) + { + crs.addLast(cr); + crs.notifyAll(); + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/CapacityRequest.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/CapacityRequest.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/CapacityRequest.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,138 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.mcp; + +import javax.resource.spi.ConnectionRequestInfo; +import javax.security.auth.Subject; + +/** + * Represents a capacity request for a managed connection pool + * + * @author Jesper Pedersen + */ +class CapacityRequest +{ + /** Managed connection pool */ + private ManagedConnectionPool mcp; + + /** Subject */ + private Subject subject; + + /** ConnectionRequestInfo */ + private ConnectionRequestInfo cri; + + /** + * Constructor + * @param mcp The managed connection pool + * @param subject The subject + * @param cri The connection request info object + */ + CapacityRequest(ManagedConnectionPool mcp, Subject subject, ConnectionRequestInfo cri) + { + this.mcp = mcp; + this.subject = subject; + this.cri = cri; + } + + /** + * Get the managed connection pool + * @return The value + */ + ManagedConnectionPool getManagedConnectionPool() + { + return mcp; + } + + /** + * Get the subject + * @return The value + */ + Subject getSubject() + { + return subject; + } + + /** + * Get the connection request info object + * @return The value + */ + ConnectionRequestInfo getConnectionRequestInfo() + { + return cri; + } + + /** + * {@inheritDoc} + */ + public int hashCode() + { + int result = 31; + result += 7 * mcp.hashCode(); + result += subject != null ? 7 * SecurityActions.hashCode(subject) : 7; + result += cri != null ? 7 * cri.hashCode() : 7; + return result; + } + + /** + * {@inheritDoc} + */ + public boolean equals(Object obj) + { + if (this == obj) + return true; + + if (obj == null) + return false; + + if (!(obj instanceof CapacityRequest)) + return false; + + CapacityRequest other = (CapacityRequest) obj; + + if (mcp == null) + { + if (other.mcp != null) + return false; + } + else if (System.identityHashCode(mcp) != System.identityHashCode(other.mcp)) + return false; + + if (subject == null) + { + if (other.subject != null) + return false; + } + else if (!SecurityActions.equals(subject, other.subject)) + return false; + + if (cri == null) + { + if (other.cri != null) + return false; + } + else if (!cri.equals(other.cri)) + return false; + + return true; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/FillRequest.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/FillRequest.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/FillRequest.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,107 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.mcp; + +/** + * Represents a fill request for a managed connection pool + * + * @author Jesper Pedersen + */ +class FillRequest +{ + /** Managed connection pool */ + private ManagedConnectionPool mcp; + + /** Fill size */ + private int fillSize; + + /** + * Constructor + * @param mcp The managed connection pool + * @param fillSize The fill size + */ + FillRequest(ManagedConnectionPool mcp, int fillSize) + { + this.mcp = mcp; + this.fillSize = fillSize; + } + + /** + * Get the managed connection pool + * @return The value + */ + ManagedConnectionPool getManagedConnectionPool() + { + return mcp; + } + + /** + * Get the fill size + * @return The value + */ + int getFillSize() + { + return fillSize; + } + + /** + * {@inheritDoc} + */ + public int hashCode() + { + int result = 31; + result += 7 * mcp.hashCode(); + result += 7 * fillSize; + return result; + } + + /** + * {@inheritDoc} + */ + public boolean equals(Object obj) + { + if (this == obj) + return true; + + if (obj == null) + return false; + + if (!(obj instanceof FillRequest)) + return false; + + FillRequest other = (FillRequest) obj; + + if (mcp == null) + { + if (other.mcp != null) + return false; + } + else if (System.identityHashCode(mcp) != System.identityHashCode(other.mcp)) + return false; + + if (fillSize != other.fillSize) + return false; + + return true; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/LeakDumperManagedConnectionPool.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/LeakDumperManagedConnectionPool.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/LeakDumperManagedConnectionPool.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,225 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.mcp; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import javax.resource.ResourceException; +import javax.resource.spi.ConnectionRequestInfo; +import javax.security.auth.Subject; + +import org.jboss.logging.Logger; + +/** + * A managed connection pool which dumps any leaks at shutdown + * + * @author Jesper Pedersen + */ +public class LeakDumperManagedConnectionPool extends SemaphoreArrayListManagedConnectionPool +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + LeakDumperManagedConnectionPool.class.getName()); + + /** Dump to special file too */ + private static boolean useFile = false; + + /** Special file name */ + private static String leakFileName = null; + + /** Leak lock */ + private static Object leakLock = new Object(); + + /** The tracker map of connection listeners */ + private final ConcurrentMap tracker = + new ConcurrentHashMap(); + + /** The time map of connection listeners */ + private final ConcurrentMap times = + new ConcurrentHashMap(); + + static + { + String f = SecurityActions.getSystemProperty("ironjacamar.leaklog"); + if (f != null && !f.trim().equals("")) + { + useFile = true; + leakFileName = f; + } + } + + /** + * Constructor + */ + public LeakDumperManagedConnectionPool() + { + } + + /** + * {@inheritDoc} + */ + @Override + public ConnectionListener getConnection(Subject subject, ConnectionRequestInfo cri) throws ResourceException + { + ConnectionListener cl = super.getConnection(subject, cri); + + tracker.put(cl, new Throwable("ALLOCATION LEAK")); + times.put(cl, Long.valueOf(System.currentTimeMillis())); + + return cl; + } + + /** + * {@inheritDoc} + */ + @Override + public void returnConnection(ConnectionListener cl, boolean kill, boolean cleanup) + { + tracker.remove(cl); + times.remove(cl); + super.returnConnection(cl, kill, cleanup); + } + + /** + * {@inheritDoc} + */ + public void connectionListenerDestroyed(ConnectionListener cl) + { + if (tracker.containsKey(cl)) + { + Throwable t = tracker.get(cl); + Long l = times.get(cl); + log.connectionLeak(getPoolName(), Integer.toHexString(System.identityHashCode(cl)), l.longValue(), t); + + if (useFile) + dump(cl, t, l.longValue()); + + tracker.remove(cl); + times.remove(cl); + } + super.connectionListenerDestroyed(cl); + } + + /** + * {@inheritDoc} + */ + @Override + public void shutdown() + { + if (tracker.size() > 0) + { + Iterator> it = tracker.entrySet().iterator(); + while (it.hasNext()) + { + Map.Entry entry = it.next(); + Long l = times.get(entry.getKey()); + + log.connectionLeak(getPoolName(), Integer.toHexString(System.identityHashCode(entry.getKey())), + l.longValue(), entry.getValue()); + + if (useFile) + dump(entry.getKey(), entry.getValue(), l.longValue()); + } + + tracker.clear(); + times.clear(); + } + + super.shutdown(); + } + + private void dump(ConnectionListener cl, Throwable t, long time) + { + synchronized (leakLock) + { + OutputStream os = null; + try + { + os = new FileOutputStream(leakFileName, true); + + PrintStream ps = new PrintStream(os, true); + + ps.print("Leak detected in pool: "); + ps.println(getPoolName()); + + ps.print(" ConnectionListener: "); + ps.println(Integer.toHexString(System.identityHashCode(cl))); + + ps.print(" Allocation timestamp: "); + ps.println(time); + + ps.println(" Allocation stacktrack:"); + + t.printStackTrace(ps); + + ps.println(); + + ps.flush(); + } + catch (Exception e) + { + log.debug(e.getMessage(), e); + } + finally + { + if (os != null) + { + try + { + os.close(); + } + catch (IOException ioe) + { + // Ignore + } + } + } + } + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("LeakDumperManagedConnectionPool@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[super=").append(super.toString()); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPool.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPool.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPool.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,173 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.mcp; + +import org.jboss.jca.core.api.connectionmanager.pool.FlushMode; +import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration; +import org.jboss.jca.core.connectionmanager.ConnectionManager; +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.connectionmanager.pool.api.Pool; +import org.jboss.jca.core.connectionmanager.pool.idle.IdleConnectionRemovalSupport; + +import java.util.Collection; + +import javax.resource.ResourceException; +import javax.resource.spi.ConnectionRequestInfo; +import javax.resource.spi.ManagedConnection; +import javax.resource.spi.ManagedConnectionFactory; +import javax.security.auth.Subject; + +/** + * Represents a managed connection pool, which manages all connection listeners + * + * @author Jesper Pedersen + */ +public interface ManagedConnectionPool extends IdleConnectionRemovalSupport +{ + /** + * Get the last used timestamp + * @return The value + */ + public long getLastUsed(); + + /** + * Initialize the managed connection pool + * + * @param mcf The managed connection factory + * @param cm The connection manager + * @param subject The subject + * @param cri The connection request info + * @param pc The pool configuration + * @param p The pool + */ + public void initialize(ManagedConnectionFactory mcf, ConnectionManager cm, Subject subject, + ConnectionRequestInfo cri, PoolConfiguration pc, Pool p); + + /** + * Returns a connection listener that wraps managed connection. + * @param subject subject + * @param cri connection request info + * @return connection listener wrapped managed connection + * @throws ResourceException exception + */ + public ConnectionListener getConnection(Subject subject, ConnectionRequestInfo cri) throws ResourceException; + + /** + * Find a connection listener + * @param mc The managed connection + * @return The connection listener; null if the connection listener doesn't belong + */ + public ConnectionListener findConnectionListener(ManagedConnection mc); + + /** + * Find a connection listener + * @param mc The managed connection + * @param connection The connection + * @return The connection listener; null if the connection listener doesn't belong + */ + public ConnectionListener findConnectionListener(ManagedConnection mc, Object connection); + + /** + * Return connection to the pool. + * @param cl connection listener + * @param kill kill connection + */ + public void returnConnection(ConnectionListener cl, boolean kill); + + /** + * Checks if the pool is empty or not + * @return True if is emtpy; otherwise false + */ + public boolean isEmpty(); + + /** + * Is the pool idle ? + * @return True if idle, otherwise false + */ + public boolean isIdle(); + + /** + * Checks if the pool is running or not + * @return True if is running; otherwise false + */ + public boolean isRunning(); + + /** + * Get number of active connections + * @return The value + */ + public int getActive(); + + /** + * Prefill + */ + public void prefill(); + + /** + * Flush + * @param mode The flush mode + * @param toDestroy list of connection listeners to be destroyed + */ + public void flush(FlushMode mode, Collection toDestroy); + + /** + * Shutdown + */ + public void shutdown(); + + /** + * Fill to + * @param size The size + */ + public void fillTo(int size); + + /** + * Validate connecitons. + * @throws Exception for exception + */ + public void validateConnections() throws Exception; + + /** + * Increase capacity + * @param subject The subject + * @param cri The connection request information object + */ + public void increaseCapacity(Subject subject, ConnectionRequestInfo cri); + + /** + * Add a connection to the pool + * @param cl The connection listener + */ + public void addConnectionListener(ConnectionListener cl); + + /** + * Remove an idle connection from the pool + * @return A connection listener; null if no connection listener was available + */ + public ConnectionListener removeConnectionListener(); + + /** + * Notify that a connection listener belonging to this pool was destroyed. + */ + public void connectionListenerDestroyed(ConnectionListener cl); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPoolFactory.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPoolFactory.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPoolFactory.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,195 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.mcp; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration; +import org.jboss.jca.core.connectionmanager.ConnectionManager; +import org.jboss.jca.core.connectionmanager.pool.api.Pool; + +import javax.resource.spi.ConnectionRequestInfo; +import javax.resource.spi.ManagedConnectionFactory; +import javax.security.auth.Subject; + +import org.jboss.logging.Logger; + +/** + * Factory to create a managed connection pool + * + * @author Jesper Pedersen + */ +public class ManagedConnectionPoolFactory +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + ManagedConnectionPoolFactory.class.getName()); + + /** Default implementation */ + public static final String DEFAULT_IMPLEMENTATION = + "org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreArrayListManagedConnectionPool"; + + /** Experimental implementation */ + public static final String EXPERIMENTAL_IMPLEMENTATION = + "org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreConcurrentLinkedDequeManagedConnectionPool"; + + /** Deprecated implementations */ + private static final String[] DEPRECATED_IMPLEMENTATIONS = new String[] { + "org.jboss.jca.core.connectionmanager.pool.mcp.ArrayBlockingQueueManagedConnectionPool", + "org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreConcurrentLinkedQueueManagedConnectionPool" + }; + + /** Default class definition */ + private static Class defaultImplementation; + + /** Override */ + private static boolean override; + + static + { + String clz = SecurityActions.getSystemProperty("ironjacamar.mcp"); + + if (clz != null && !clz.trim().equals("")) + { + clz = clz.trim(); + for (String impl : DEPRECATED_IMPLEMENTATIONS) + { + if (clz.equals(impl)) + { + log.deprecatedPool(clz, EXPERIMENTAL_IMPLEMENTATION); + clz = EXPERIMENTAL_IMPLEMENTATION; + } + } + + override = true; + } + else + { + clz = DEFAULT_IMPLEMENTATION; + override = false; + } + + try + { + defaultImplementation = Class.forName(clz, + true, + SecurityActions.getClassLoader(ManagedConnectionPoolFactory.class)); + } + catch (Throwable t) + { + throw new RuntimeException("Unable to load default managed connection pool implementation: " + clz); + } + } + + /** + * Constructor + */ + public ManagedConnectionPoolFactory() + { + } + + /** + * Get the default implementation + * @return The value + */ + public String getDefaultImplementation() + { + return defaultImplementation.getName(); + } + + /** + * Is override + * @return The value + */ + public boolean isOverride() + { + return override; + } + + /** + * Create a managed connection pool using the default implementation strategy + * + * @param mcf the managed connection factory + * @param cm the connection manager + * @param subject the subject + * @param cri the connection request info + * @param pc the pool configuration + * @param p The pool + * @return The initialized managed connection pool + * @exception Throwable Thrown in case of an error + */ + public ManagedConnectionPool create(ManagedConnectionFactory mcf, ConnectionManager cm, Subject subject, + ConnectionRequestInfo cri, PoolConfiguration pc, Pool p) + throws Throwable + { + ManagedConnectionPool mcp = (ManagedConnectionPool)defaultImplementation.newInstance(); + + return init(mcp, mcf, cm, subject, cri, pc, p); + } + + /** + * Create a managed connection pool using a specific implementation strategy + * + * @param strategy Fullt qualified class name for the managed connection pool strategy + * @param mcf the managed connection factory + * @param cm the connection manager + * @param subject the subject + * @param cri the connection request info + * @param pc the pool configuration + * @param p The pool + * @return The initialized managed connection pool + * @exception Throwable Thrown in case of an error + */ + public ManagedConnectionPool create(String strategy, + ManagedConnectionFactory mcf, ConnectionManager cm, Subject subject, + ConnectionRequestInfo cri, PoolConfiguration pc, Pool p) + throws Throwable + { + Class clz = Class.forName(strategy, + true, + SecurityActions.getClassLoader(ManagedConnectionPoolFactory.class)); + + ManagedConnectionPool mcp = (ManagedConnectionPool)clz.newInstance(); + + return init(mcp, mcf, cm, subject, cri, pc, p); + } + + /** + * Initialize + * @param mcp The managed connection pool + * @param mcf the managed connection factory + * @param cm the connection manager + * @param subject the subject + * @param cri the connection request info + * @param pc the pool configuration + * @param p The pool + * @return The initialized managed connection pool + */ + private ManagedConnectionPool init(ManagedConnectionPool mcp, + ManagedConnectionFactory mcf, ConnectionManager cm, Subject subject, + ConnectionRequestInfo cri, PoolConfiguration pc, Pool p) + { + mcp.initialize(mcf, cm, subject, cri, pc, p); + + return mcp; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPoolUtility.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPoolUtility.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPoolUtility.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,219 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.mcp; + +import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration; +import org.jboss.jca.core.connectionmanager.ConnectionManager; +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.connectionmanager.pool.PoolStatisticsImpl; +import org.jboss.jca.core.connectionmanager.pool.api.Pool; + +import java.util.Collection; + +import javax.resource.spi.ConnectionRequestInfo; +import javax.resource.spi.ManagedConnectionFactory; +import javax.security.auth.Subject; + +/** + * Managed connection pool utility class + * + * @author Jesper Pedersen + */ +class ManagedConnectionPoolUtility +{ + private static String newLine = SecurityActions.getSystemProperty("line.separator"); + + /** + * Get the full details of a managed connection pool state + * @param method The method identifier + * @param poolName The pool name + * @param inUse The in use count + * @param max The max + * @return The state + */ + static String details(String method, String poolName, int inUse, int max) + { + StringBuilder sb = new StringBuilder(1024); + + sb.append(poolName).append(": "); + sb.append(method).append(" "); + sb.append("["); + sb.append(Integer.toString(inUse)); + sb.append("/"); + sb.append(Integer.toString(max)); + sb.append("]"); + + return sb.toString(); + } + + /** + * Get the full details of a managed connection pool state + * @param mcp The managed connection pool + * @param method The method identifier + * @param mcf The managed connection factory + * @param cm The connection manager + * @param pool The pool + * @param pc The pool configuration + * @param available The available connection listeners + * @param inUse The in-use connection listeners + * @param ps The statistics + * @param subject The subject + * @param cri The ConnectionRequestInfo + * @return The state + */ + static String fullDetails(ManagedConnectionPool mcp, String method, ManagedConnectionFactory mcf, + ConnectionManager cm, Pool pool, PoolConfiguration pc, + Collection available, Collection inUse, + PoolStatisticsImpl ps, Subject subject, ConnectionRequestInfo cri) + { + StringBuilder sb = new StringBuilder(1024); + long now = System.currentTimeMillis(); + + sb.append(method).append(newLine); + sb.append("Method: ").append(method).append(newLine); + sb.append(" Subject: ").append(subject == null ? "null" : + Integer.toHexString(System.identityHashCode(subject))).append(newLine); + sb.append(" CRI: ").append(cri == null ? "null" : + Integer.toHexString(System.identityHashCode(cri))).append(newLine); + sb.append("ManagedConnectionPool:").append(newLine); + sb.append(" Class: ").append(mcp.getClass().getName()).append(newLine); + sb.append(" Object: ").append(Integer.toHexString(System.identityHashCode(mcp))).append(newLine); + sb.append("ManagedConnectionFactory:").append(newLine); + sb.append(" Class: ").append(mcf.getClass().getName()).append(newLine); + sb.append(" Object: ").append(Integer.toHexString(System.identityHashCode(mcf))).append(newLine); + sb.append("ConnectionManager:").append(newLine); + sb.append(" Class: ").append(cm.getClass().getName()).append(newLine); + sb.append(" Object: ").append(Integer.toHexString(System.identityHashCode(cm))).append(newLine); + sb.append("Pool:").append(newLine); + sb.append(" Name: ").append(pool.getName()).append(newLine); + sb.append(" Class: ").append(pool.getClass().getName()).append(newLine); + sb.append(" Object: ").append(Integer.toHexString(System.identityHashCode(pool))).append(newLine); + sb.append(" FIFO: ").append(pool.isFIFO()).append(newLine); + sb.append("PoolConfiguration:").append(newLine); + sb.append(" MinSize: ").append(pc.getMinSize()).append(newLine); + sb.append(" InitialSize: ").append(pc.getInitialSize()).append(newLine); + sb.append(" MaxSize: ").append(pc.getMaxSize()).append(newLine); + sb.append(" BlockingTimeout: ").append(pc.getBlockingTimeout()).append(newLine); + sb.append(" IdleTimeoutMinutes: ").append(pc.getIdleTimeoutMinutes()).append(newLine); + sb.append(" ValidateOnMatch: ").append(pc.isValidateOnMatch()).append(newLine); + sb.append(" BackgroundValidation: ").append(pc.isBackgroundValidation()).append(newLine); + sb.append(" BackgroundValidationMillis: ").append(pc.getBackgroundValidationMillis()).append(newLine); + sb.append(" StrictMin: ").append(pc.isStrictMin()).append(newLine); + sb.append(" UseFastFail: ").append(pc.isUseFastFail()).append(newLine); + if (pool.getCapacity() != null) + { + if (pool.getCapacity().getIncrementer() != null) + sb.append(" Incrementer: ").append(pool.getCapacity().getIncrementer()).append(newLine); + + if (pool.getCapacity().getDecrementer() != null) + sb.append(" Decrementer: ").append(pool.getCapacity().getDecrementer()).append(newLine); + } + + int availableSize = (available != null ? available.size() : 0); + sb.append("Available (").append(availableSize).append("):").append(newLine); + if (available != null) + { + for (ConnectionListener cl : available) + { + sb.append(" ").append(Integer.toHexString(System.identityHashCode(cl))); + sb.append(" (").append(cl.getState()).append(")"); + sb.append(" (Returned: ").append(cl.getLastReturnedTime()).append(")"); + sb.append(" (Validated: ").append(cl.getLastValidatedTime()).append(")"); + sb.append(" (Pool: ").append(now - cl.getLastReturnedTime()).append(")").append(newLine); + } + } + + int inUseSize = (inUse != null ? inUse.size() : 0); + sb.append("InUse (").append(inUseSize).append("):").append(newLine); + if (inUse != null) + { + for (ConnectionListener cl : inUse) + { + sb.append(" ").append(Integer.toHexString(System.identityHashCode(cl))); + sb.append(" (").append(cl.getState()).append(")"); + sb.append(" (CheckedOut: ").append(cl.getLastCheckedOutTime()).append(")"); + sb.append(" (Validated: ").append(cl.getLastValidatedTime()).append(")"); + sb.append(" (Usage: ").append(now - cl.getLastCheckedOutTime()).append(")").append(newLine); + } + } + + sb.append("Statistics:").append(newLine); + sb.append(" ActiveCount: ").append(ps.getActiveCount()).append(newLine); + sb.append(" AvailableCount: ").append(ps.getAvailableCount()).append(newLine); + sb.append(" AverageBlockingTime: ").append(ps.getAverageBlockingTime()).append(newLine); + sb.append(" AverageCreationTime: ").append(ps.getAverageCreationTime()).append(newLine); + sb.append(" AverageGetTime: ").append(ps.getAverageGetTime()).append(newLine); + sb.append(" AveragePoolTime: ").append(ps.getAveragePoolTime()).append(newLine); + sb.append(" AverageUsageTime: ").append(ps.getAverageUsageTime()).append(newLine); + sb.append(" BlockingFailureCount: ").append(ps.getBlockingFailureCount()).append(newLine); + sb.append(" CreatedCount: ").append(ps.getCreatedCount()).append(newLine); + sb.append(" DestroyedCount: ").append(ps.getDestroyedCount()).append(newLine); + sb.append(" IdleCount: ").append(ps.getIdleCount()).append(newLine); + sb.append(" InUseCount: ").append(ps.getInUseCount()).append(newLine); + sb.append(" MaxCreationTime: ").append(ps.getMaxCreationTime()).append(newLine); + sb.append(" MaxGetTime: ").append(ps.getMaxGetTime()).append(newLine); + sb.append(" MaxPoolTime: ").append(ps.getMaxPoolTime()).append(newLine); + sb.append(" MaxUsageTime: ").append(ps.getMaxUsageTime()).append(newLine); + sb.append(" MaxUsedCount: ").append(ps.getMaxUsedCount()).append(newLine); + sb.append(" MaxWaitTime: ").append(ps.getMaxWaitTime()).append(newLine); + sb.append(" TimedOut: ").append(ps.getTimedOut()).append(newLine); + sb.append(" TotalBlockingTime: ").append(ps.getTotalBlockingTime()).append(newLine); + sb.append(" TotalCreationTime: ").append(ps.getTotalCreationTime()).append(newLine); + sb.append(" TotalGetTime: ").append(ps.getTotalGetTime()).append(newLine); + sb.append(" TotalPoolTime: ").append(ps.getTotalPoolTime()).append(newLine); + sb.append(" TotalUsageTime: ").append(ps.getTotalUsageTime()).append(newLine); + sb.append(" WaitCount: ").append(ps.getWaitCount()).append(newLine); + + sb.append("XAResource:").append(newLine); + sb.append(" CommitCount: ").append(ps.getCommitCount()).append(newLine); + sb.append(" CommitTotalTime: ").append(ps.getCommitTotalTime()).append(newLine); + sb.append(" CommitAverageTime: ").append(ps.getCommitAverageTime()).append(newLine); + sb.append(" CommitMaxTime: ").append(ps.getCommitMaxTime()).append(newLine); + sb.append(" EndCount: ").append(ps.getEndCount()).append(newLine); + sb.append(" EndTotalTime: ").append(ps.getEndTotalTime()).append(newLine); + sb.append(" EndAverageTime: ").append(ps.getEndAverageTime()).append(newLine); + sb.append(" EndMaxTime: ").append(ps.getEndMaxTime()).append(newLine); + sb.append(" ForgetCount: ").append(ps.getForgetCount()).append(newLine); + sb.append(" ForgetTotalTime: ").append(ps.getForgetTotalTime()).append(newLine); + sb.append(" ForgetAverageTime: ").append(ps.getForgetAverageTime()).append(newLine); + sb.append(" ForgetMaxTime: ").append(ps.getForgetMaxTime()).append(newLine); + sb.append(" PrepareCount: ").append(ps.getPrepareCount()).append(newLine); + sb.append(" PrepareTotalTime: ").append(ps.getPrepareTotalTime()).append(newLine); + sb.append(" PrepareAverageTime: ").append(ps.getPrepareAverageTime()).append(newLine); + sb.append(" PrepareMaxTime: ").append(ps.getPrepareMaxTime()).append(newLine); + sb.append(" RecoverCount: ").append(ps.getRecoverCount()).append(newLine); + sb.append(" RecoverTotalTime: ").append(ps.getRecoverTotalTime()).append(newLine); + sb.append(" RecoverAverageTime: ").append(ps.getRecoverAverageTime()).append(newLine); + sb.append(" RecoverMaxTime: ").append(ps.getRecoverMaxTime()).append(newLine); + sb.append(" RollbackCount: ").append(ps.getRollbackCount()).append(newLine); + sb.append(" RollbackTotalTime: ").append(ps.getRollbackTotalTime()).append(newLine); + sb.append(" RollbackAverageTime: ").append(ps.getRollbackAverageTime()).append(newLine); + sb.append(" RollbackMaxTime: ").append(ps.getRollbackMaxTime()).append(newLine); + sb.append(" StartCount: ").append(ps.getStartCount()).append(newLine); + sb.append(" StartTotalTime: ").append(ps.getStartTotalTime()).append(newLine); + sb.append(" StartAverageTime: ").append(ps.getStartAverageTime()).append(newLine); + sb.append(" StartMaxTime: ").append(ps.getStartMaxTime()); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/PoolFiller.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/PoolFiller.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/PoolFiller.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,139 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2006, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.pool.mcp; + +import java.util.LinkedList; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * PoolFiller + * + * @author David Jencks + * @author Scott Stark + * @author Adrian Brock + * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +class PoolFiller implements Runnable +{ + + /** Singleton instance */ + private static final PoolFiller FILLER = new PoolFiller(); + + /** Pools list */ + private final LinkedList pools = new LinkedList(); + + /** Filler thread */ + private final Thread fillerThread; + + /** Thread name */ + private static final String THREAD_FILLER_NAME = "JCA PoolFiller"; + + /**Thread is configured or not*/ + private AtomicBoolean threadStarted = new AtomicBoolean(false); + + /** + * Fill given pool + * @param fr The fill request + */ + static void fillPool(FillRequest fr) + { + FILLER.internalFillPool(fr); + } + + /** + * Creates a new pool filler instance. + */ + PoolFiller() + { + fillerThread = new Thread(this, THREAD_FILLER_NAME); + fillerThread.setDaemon(true); + } + + /** + * {@inheritDoc} + */ + public void run() + { + final ClassLoader myClassLoader = SecurityActions.getClassLoader(getClass()); + SecurityActions.setThreadContextClassLoader(myClassLoader); + + while (true) + { + boolean empty = false; + + while (!empty) + { + FillRequest fr = null; + + synchronized (pools) + { + empty = pools.isEmpty(); + if (!empty) + fr = pools.removeFirst(); + } + + if (!empty) + { + fr.getManagedConnectionPool().fillTo(fr.getFillSize()); + } + } + + try + { + synchronized (pools) + { + while (pools.isEmpty()) + { + pools.wait(); + } + } + } + catch (InterruptedException ie) + { + Thread.currentThread().interrupt(); + return; + } + } + } + + /** + * Fill pool + * @param fr The fill request + */ + private void internalFillPool(FillRequest fr) + { + if (this.threadStarted.compareAndSet(false, true)) + { + this.fillerThread.start(); + } + + synchronized (pools) + { + if (!pools.contains(fr)) + { + pools.addLast(fr); + pools.notifyAll(); + } + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,138 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.mcp; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +import javax.security.auth.Subject; + +/** + * Privileged Blocks + * + * @author Gurkan Erdogdu + */ +class SecurityActions +{ + /** + * Get the classloader. + * @param c The class + * @return The classloader + */ + static ClassLoader getClassLoader(final Class c) + { + if (System.getSecurityManager() == null) + return c.getClassLoader(); + + return AccessController.doPrivileged(new PrivilegedAction() + { + public ClassLoader run() + { + return c.getClassLoader(); + } + }); + } + + /** + * Set the context classloader. + * @param cl classloader + */ + public static void setThreadContextClassLoader(final ClassLoader cl) + { + if (System.getSecurityManager() == null) + { + Thread.currentThread().setContextClassLoader(cl); + } + else + { + AccessController.doPrivileged(new PrivilegedAction() + { + public Object run() + { + Thread.currentThread().setContextClassLoader(cl); + + return null; + } + }); + } + } + + /** + * Get a system property + * @param name The property name + * @return The property value + */ + static String getSystemProperty(final String name) + { + return AccessController.doPrivileged(new PrivilegedAction() + { + public String run() + { + return System.getProperty(name); + } + }); + } + + /** + * Get the hash code for a Subject + * @param subject The Subject + * @return The hash code + */ + static int hashCode(final Subject subject) + { + if (System.getSecurityManager() == null) + return subject.hashCode(); + + Integer hashCode = AccessController.doPrivileged(new PrivilegedAction() + { + public Integer run() + { + return subject.hashCode(); + } + }); + + return hashCode.intValue(); + } + + /** + * Verify if two Subject's are equal + * @param s1 The first Subject + * @param s2 The second Subject + * @return True if equal; otherwise false + */ + static boolean equals(final Subject s1, final Subject s2) + { + if (System.getSecurityManager() == null) + return s1 != null ? s1.equals(s2) : s2 == null; + + Boolean equals = AccessController.doPrivileged(new PrivilegedAction() + { + public Boolean run() + { + return s1 != null ? s1.equals(s2) : s2 == null; + } + }); + + return equals.booleanValue(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SemaphoreArrayListManagedConnectionPool.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SemaphoreArrayListManagedConnectionPool.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SemaphoreArrayListManagedConnectionPool.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,1602 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.mcp; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.connectionmanager.pool.FlushMode; +import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration; +import org.jboss.jca.core.connectionmanager.ConnectionManager; +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.connectionmanager.listener.ConnectionState; +import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer; +import org.jboss.jca.core.connectionmanager.pool.api.Pool; +import org.jboss.jca.core.connectionmanager.pool.api.PrefillPool; +import org.jboss.jca.core.connectionmanager.pool.capacity.DefaultCapacity; +import org.jboss.jca.core.connectionmanager.pool.capacity.TimedOutDecrementer; +import org.jboss.jca.core.connectionmanager.pool.capacity.TimedOutFIFODecrementer; +import org.jboss.jca.core.connectionmanager.pool.idle.IdleRemover; +import org.jboss.jca.core.connectionmanager.pool.validator.ConnectionValidator; +import org.jboss.jca.core.tracer.Tracer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.TimeUnit; + +import javax.resource.ResourceException; +import javax.resource.cci.Connection; +import javax.resource.spi.ConnectionRequestInfo; +import javax.resource.spi.DissociatableManagedConnection; +import javax.resource.spi.ManagedConnection; +import javax.resource.spi.ManagedConnectionFactory; +import javax.resource.spi.RetryableException; +import javax.resource.spi.ValidatingManagedConnectionFactory; +import javax.security.auth.Subject; + +import org.jboss.logging.Messages; + +/** + * The internal pool implementation + * + * @author David Jencks + * @author Adrian Brock + * @author Weston Price + * @author Jesper Pedersen + */ +public class SemaphoreArrayListManagedConnectionPool implements ManagedConnectionPool +{ + /** The log */ + private CoreLogger log; + + /** Whether debug is enabled */ + private boolean debug; + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** The managed connection factory */ + private ManagedConnectionFactory mcf; + + /** The connection manager */ + private ConnectionManager cm; + + /** The default subject */ + private Subject defaultSubject; + + /** The default connection request information */ + private ConnectionRequestInfo defaultCri; + + /** The pool configuration */ + private PoolConfiguration poolConfiguration; + + /** The pool */ + private Pool pool; + + /** FIFO / FILO */ + private boolean fifo; + + /** + * Copy of the maximum size from the pooling parameters. + * Dynamic changes to this value are not compatible with + * the semaphore which cannot change be dynamically changed. + */ + private int maxSize; + + /** The available connection event listeners */ + private ArrayList cls; + + /** The map of connection listeners which has a permit */ + private final ConcurrentMap clPermits = + new ConcurrentHashMap(); + + /** The checked out connections */ + private final ArrayList checkedOut = new ArrayList(); + + /** Supports lazy association */ + private Boolean supportsLazyAssociation; + + /** Last idle check */ + private long lastIdleCheck; + + /** Last used */ + private long lastUsed; + + /** + * Constructor + */ + public SemaphoreArrayListManagedConnectionPool() + { + } + + /** + * {@inheritDoc} + */ + public void initialize(ManagedConnectionFactory mcf, ConnectionManager cm, Subject subject, + ConnectionRequestInfo cri, PoolConfiguration pc, Pool p) + { + if (mcf == null) + throw new IllegalArgumentException("ManagedConnectionFactory is null"); + + if (cm == null) + throw new IllegalArgumentException("ConnectionManager is null"); + + if (pc == null) + throw new IllegalArgumentException("PoolConfiguration is null"); + + if (p == null) + throw new IllegalArgumentException("Pool is null"); + + this.mcf = mcf; + this.cm = cm; + this.defaultSubject = subject; + this.defaultCri = cri; + this.poolConfiguration = pc; + this.maxSize = pc.getMaxSize(); + this.pool = p; + this.fifo = p.isFIFO(); + this.log = pool.getLogger(); + this.debug = log.isDebugEnabled(); + this.cls = new ArrayList(this.maxSize); + this.supportsLazyAssociation = null; + this.lastIdleCheck = System.currentTimeMillis(); + this.lastUsed = Long.MAX_VALUE; + + // Schedule managed connection pool for prefill + if ((pc.isPrefill() || pc.isStrictMin()) && p instanceof PrefillPool && pc.getInitialSize() > 0) + { + PoolFiller.fillPool(new FillRequest(this, pc.getInitialSize())); + } + + if (poolConfiguration.getIdleTimeoutMinutes() > 0) + { + //Register removal support + IdleRemover.getInstance().registerPool(this, poolConfiguration.getIdleTimeoutMinutes() * 1000L * 60); + } + + if (poolConfiguration.isBackgroundValidation() && poolConfiguration.getBackgroundValidationMillis() > 0) + { + if (debug) + log.debug("Registering for background validation at interval " + + poolConfiguration.getBackgroundValidationMillis()); + + //Register validation + ConnectionValidator.getInstance().registerPool(this, poolConfiguration.getBackgroundValidationMillis()); + } + } + + /** + * {@inheritDoc} + */ + public long getLastUsed() + { + return lastUsed; + } + + /** + * {@inheritDoc} + */ + public boolean isRunning() + { + return !pool.isShutdown(); + } + + /** + * {@inheritDoc} + */ + public boolean isEmpty() + { + synchronized (cls) + { + return cls.size() == 0 && checkedOut.size() == 0; + } + } + + /** + * {@inheritDoc} + */ + public boolean isIdle() + { + synchronized (cls) + { + return checkedOut.size() == 0; + } + } + + /** + * {@inheritDoc} + */ + public int getActive() + { + synchronized (cls) + { + return cls.size() + checkedOut.size(); + } + } + + /** + * Check if the pool has reached a certain size + * @param size The size + * @return True if reached; otherwise false + */ + private boolean isSize(int size) + { + synchronized (cls) + { + return (cls.size() + checkedOut.size()) >= size; + } + } + + /** + * {@inheritDoc} + */ + public void prefill() + { + if (isRunning() && + (poolConfiguration.isPrefill() || poolConfiguration.isStrictMin()) && + pool instanceof PrefillPool && + poolConfiguration.getMinSize() > 0) + PoolFiller.fillPool(new FillRequest(this, poolConfiguration.getMinSize())); + } + + /** + * {@inheritDoc} + */ + public ConnectionListener getConnection(Subject subject, ConnectionRequestInfo cri) throws ResourceException + { + + if (log.isTraceEnabled()) + { + synchronized (cls) + { + String method = "getConnection(" + subject + ", " + cri + ")"; + log.trace(ManagedConnectionPoolUtility.fullDetails(this, method, + mcf, cm, pool, poolConfiguration, + cls, checkedOut, pool.getInternalStatistics(), + subject, cri)); + } + } + else if (debug) + { + String method = "getConnection(" + subject + ", " + cri + ")"; + log.debug(ManagedConnectionPoolUtility.details(method, pool.getName(), + pool.getInternalStatistics().getInUseCount(), maxSize)); + } + + subject = (subject == null) ? defaultSubject : subject; + cri = (cri == null) ? defaultCri : cri; + + if (pool.isFull()) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaWaitCount(); + + if (pool.isSharable() && (supportsLazyAssociation == null || supportsLazyAssociation.booleanValue())) + { + if (supportsLazyAssociation == null) + checkLazyAssociation(); + + if (supportsLazyAssociation != null && supportsLazyAssociation.booleanValue()) + { + if (log.isTraceEnabled()) + log.tracef("Trying to detach - Pool: %s MCP: %s", pool.getName(), + Integer.toHexString(System.identityHashCode(this))); + + if (!detachConnectionListener()) + { + log.tracef("Detaching didn't succeed - Pool: %s MCP: %s", pool.getName(), + Integer.toHexString(System.identityHashCode(this))); + } + } + } + } + + long startWait = pool.getInternalStatistics().isEnabled() ? System.currentTimeMillis() : 0L; + try + { + if (pool.getLock().tryAcquire(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS)) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalBlockingTime(System.currentTimeMillis() - startWait); + + //We have a permit to get a connection. Is there one in the pool already? + ConnectionListener cl = null; + do + { + if (!isRunning()) + { + pool.getLock().release(); + throw new ResourceException( + bundle.thePoolHasBeenShutdown(pool.getName(), + Integer.toHexString(System.identityHashCode(this)))); + } + + synchronized (cls) + { + if (cls.size() > 0) + { + if (fifo) + { + cl = cls.remove(0); + } + else + { + cl = cls.remove(cls.size() - 1); + } + checkedOut.add(cl); + } + } + + if (cl != null) + { + //Yes, we retrieved a ManagedConnection from the pool. Does it match? + try + { + Object matchedMC = mcf.matchManagedConnections(Collections.singleton(cl.getManagedConnection()), + subject, cri); + + boolean valid = true; + if (matchedMC != null) + { + if (poolConfiguration.isValidateOnMatch()) + { + if (mcf instanceof ValidatingManagedConnectionFactory) + { + try + { + ValidatingManagedConnectionFactory vcf = (ValidatingManagedConnectionFactory) mcf; + Set candidateSet = Collections.singleton(cl.getManagedConnection()); + candidateSet = vcf.getInvalidConnections(candidateSet); + + if (candidateSet != null && candidateSet.size() > 0) + { + valid = false; + } + } + catch (Throwable t) + { + valid = false; + if (log.isTraceEnabled()) + log.trace("Exception while ValidateOnMatch: " + t.getMessage(), t); + } + } + else + { + log.validateOnMatchNonCompliantManagedConnectionFactory(mcf.getClass().getName()); + } + } + + if (valid) + { + log.tracef("supplying ManagedConnection from pool: %s", cl); + + clPermits.put(cl, cl); + + lastUsed = System.currentTimeMillis(); + cl.setLastCheckedOutTime(lastUsed); + + if (pool.getInternalStatistics().isEnabled()) + { + pool.getInternalStatistics().deltaTotalGetTime(lastUsed - startWait); + pool.getInternalStatistics().deltaTotalPoolTime(lastUsed - cl.getLastReturnedTime()); + } + + if (Tracer.isEnabled()) + Tracer.getConnectionListener(pool.getName(), this, cl, true, pool.isInterleaving(), + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + return cl; + } + } + + // Match did not succeed but no exception was thrown. + // Either we have the matching strategy wrong or the + // connection died while being checked. We need to + // distinguish these cases, but for now we always + // destroy the connection. + if (valid) + { + log.destroyingConnectionNotSuccessfullyMatched(cl); + } + else + { + log.destroyingConnectionNotValidated(cl); + } + + synchronized (cls) + { + checkedOut.remove(cl); + } + + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() - + cl.getLastReturnedTime()); + + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, true, false, false, + false, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + cl.destroy(); + cl = null; + } + catch (Throwable t) + { + log.throwableWhileTryingMatchManagedConnectionThenDestroyingConnection(cl, t); + + synchronized (cls) + { + checkedOut.remove(cl); + } + + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() - + cl.getLastReturnedTime()); + + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, false, false, true, + false, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + cl.destroy(); + cl = null; + } + + // We made it here, something went wrong and we should validate + // if we should continue attempting to acquire a connection + if (poolConfiguration.isUseFastFail()) + { + if (log.isTraceEnabled()) + log.trace("Fast failing for connection attempt. No more attempts will be made to " + + "acquire connection from pool and a new connection will be created immeadiately"); + break; + } + + } + } + while (cls.size() > 0); + + // OK, we couldnt find a working connection from the pool. Make a new one. + try + { + // No, the pool was empty, so we have to make a new one. + cl = createConnectionEventListener(subject, cri); + + if (Tracer.isEnabled()) + Tracer.createConnectionListener(pool.getName(), this, cl, cl.getManagedConnection(), + true, false, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + synchronized (cls) + { + checkedOut.add(cl); + } + + log.tracef("supplying new ManagedConnection: %s", cl); + + clPermits.put(cl, cl); + + lastUsed = System.currentTimeMillis(); + + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalGetTime(lastUsed - startWait); + + // Trigger prefill + prefill(); + + // Trigger capacity increase + if (pool.getCapacity().getIncrementer() != null) + CapacityFiller.schedule(new CapacityRequest(this, subject, cri)); + + if (Tracer.isEnabled()) + Tracer.getConnectionListener(pool.getName(), this, cl, false, pool.isInterleaving(), + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + return cl; + } + catch (Throwable t) + { + if (cl != null || !(t instanceof RetryableException)) + log.throwableWhileAttemptingGetNewGonnection(cl, t); + + if (cl != null) + { + // Return permit and rethrow + synchronized (cls) + { + checkedOut.remove(cl); + } + + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, false, false, true, + false, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + cl.destroy(); + } + + pool.getLock().release(); + + if (t instanceof ResourceException) + { + throw (ResourceException)t; + } + else + { + throw new ResourceException(bundle.unexpectedThrowableWhileTryingCreateConnection(cl), t); + } + } + } + else + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaBlockingFailureCount(); + + // We timed out + throw new ResourceException(bundle.noMManagedConnectionsAvailableWithinConfiguredBlockingTimeout( + poolConfiguration.getBlockingTimeout())); + } + + } + catch (InterruptedException ie) + { + Thread.interrupted(); + + long end = pool.getInternalStatistics().isEnabled() ? (System.currentTimeMillis() - startWait) : 0L; + pool.getInternalStatistics().deltaTotalBlockingTime(end); + throw new ResourceException(bundle.interruptedWhileRequestingPermit(end)); + } + } + + /** + * {@inheritDoc} + */ + public ConnectionListener findConnectionListener(ManagedConnection mc) + { + return findConnectionListener(mc, null); + } + + /** + * {@inheritDoc} + */ + public ConnectionListener findConnectionListener(ManagedConnection mc, Object connection) + { + synchronized (cls) + { + for (ConnectionListener cl : checkedOut) + { + if (cl.controls(mc, connection)) + return cl; + } + } + + return null; + } + + /** + * {@inheritDoc} + */ + public void addConnectionListener(ConnectionListener cl) + { + synchronized (cls) + { + cls.add(cl); + } + + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaCreatedCount(); + } + + /** + * {@inheritDoc} + */ + public ConnectionListener removeConnectionListener() + { + synchronized (cls) + { + if (cls.size() > 0) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaDestroyedCount(); + return cls.remove(0); + } + } + + return null; + } + + /** + * {@inheritDoc} + */ + public void returnConnection(ConnectionListener cl, boolean kill) + { + returnConnection(cl, kill, true); + } + + /** + * {@inheritDoc} + */ + public void returnConnection(ConnectionListener cl, boolean kill, boolean cleanup) + { + if (pool.getInternalStatistics().isEnabled() && cl.getState() != ConnectionState.DESTROYED) + pool.getInternalStatistics().deltaTotalUsageTime(System.currentTimeMillis() - cl.getLastCheckedOutTime()); + + if (log.isTraceEnabled()) + { + synchronized (cls) + { + String method = "returnConnection(" + Integer.toHexString(System.identityHashCode(cl)) + ", " + kill + ")"; + log.trace(ManagedConnectionPoolUtility.fullDetails(this, method, + mcf, cm, pool, poolConfiguration, + cls, checkedOut, pool.getInternalStatistics(), + defaultSubject, defaultCri)); + } + } + else if (debug) + { + String method = "returnConnection(" + Integer.toHexString(System.identityHashCode(cl)) + ", " + kill + ")"; + log.debug(ManagedConnectionPoolUtility.details(method, pool.getName(), + pool.getInternalStatistics().getInUseCount(), maxSize)); + } + + if (cl.getState() == ConnectionState.DESTROYED) + { + log.tracef("ManagedConnection is being returned after it was destroyed: %s", cl); + + ConnectionListener present = clPermits.remove(cl); + if (present != null) + { + pool.getLock().release(); + } + + return; + } + + if (cleanup) + { + try + { + cl.getManagedConnection().cleanup(); + } + catch (ResourceException re) + { + log.resourceExceptionCleaningUpManagedConnection(cl, re); + kill = true; + } + } + + // We need to destroy this one + if (cl.getState() == ConnectionState.DESTROY || cl.getState() == ConnectionState.DESTROYED) + kill = true; + + // This is really an error + if (!kill && isSize(poolConfiguration.getMaxSize() + 1)) + { + log.destroyingReturnedConnectionMaximumPoolSizeExceeded(cl); + kill = true; + } + + // If we are destroying, check the connection is not in the pool + if (kill) + { + synchronized (cls) + { + // Adrian Brock: A resource adapter can asynchronously notify us that + // a connection error occurred. + // This could happen while the connection is not checked out. + // e.g. JMS can do this via an ExceptionListener on the connection. + // I have twice had to reinstate this line of code, PLEASE DO NOT REMOVE IT! + checkedOut.remove(cl); + cls.remove(cl); + + if (clPermits.remove(cl) != null) + { + pool.getLock().release(); + } + } + } + // return to the pool + else + { + cl.toPool(); + synchronized (cls) + { + checkedOut.remove(cl); + if (!cls.contains(cl)) + { + cls.add(cl); + } + else + { + log.attemptReturnConnectionTwice(cl, new Throwable("STACKTRACE")); + } + + if (clPermits.remove(cl) != null) + { + pool.getLock().release(); + } + } + } + + if (kill) + { + log.tracef("Destroying returned connection %s", cl); + + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, cl, true, false, false, false, false, + false, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + cl.destroy(); + cl = null; + } + } + + /** + * {@inheritDoc} + */ + public void flush(FlushMode mode, Collection toDestroy) + { + ArrayList keep = null; + + synchronized (cls) + { + if (FlushMode.ALL == mode) + { + log.tracef("Flushing pool checkedOut=%s inPool=%s", checkedOut, cls); + + // Mark checked out connections as requiring destruction + while (checkedOut.size() > 0) + { + ConnectionListener cl = checkedOut.remove(0); + + log.tracef("Flush marking checked out connection for destruction %s", cl); + + cl.setState(ConnectionState.DESTROY); + + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalUsageTime(System.currentTimeMillis() - + cl.getLastCheckedOutTime()); + + toDestroy.add(cl); + + ConnectionListener present = clPermits.remove(cl); + if (present != null) + { + pool.getLock().release(); + } + } + } + else if (FlushMode.GRACEFULLY == mode) + { + log.tracef("Gracefully flushing pool checkedOut=%s inPool=%s", checkedOut , cls); + + // Mark checked out connections as requiring destruction upon return + for (ConnectionListener cl : checkedOut) + { + log.tracef("Graceful flush marking checked out connection for destruction %s", cl); + + cl.setState(ConnectionState.DESTROY); + } + } + + // Destroy connections in the pool + while (cls.size() > 0) + { + ConnectionListener cl = cls.remove(0); + boolean kill = true; + + if (FlushMode.INVALID == mode && cl.getState().equals(ConnectionState.NORMAL)) + { + if (mcf instanceof ValidatingManagedConnectionFactory) + { + try + { + ValidatingManagedConnectionFactory vcf = (ValidatingManagedConnectionFactory) mcf; + Set candidateSet = Collections.singleton(cl.getManagedConnection()); + candidateSet = vcf.getInvalidConnections(candidateSet); + + if (candidateSet == null || candidateSet.size() == 0) + { + kill = false; + } + } + catch (Throwable t) + { + log.trace("Exception during invalid flush", t); + } + } + } + + if (kill) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() - + cl.getLastReturnedTime()); + + cl.setState(ConnectionState.DESTROY); + toDestroy.add(cl); + } + else + { + if (keep == null) + keep = new ArrayList(1); + + keep.add(cl); + } + } + + if (keep != null) + cls.addAll(keep); + } + + // Trigger prefill + prefill(); + } + + /** + * {@inheritDoc} + */ + public void removeIdleConnections() + { + long now = System.currentTimeMillis(); + long timeoutSetting = poolConfiguration.getIdleTimeoutMinutes() * 1000L * 60; + + CapacityDecrementer decrementer = pool.getCapacity().getDecrementer(); + + if (decrementer == null) + decrementer = DefaultCapacity.DEFAULT_DECREMENTER; + + if (TimedOutDecrementer.class.getName().equals(decrementer.getClass().getName()) || + TimedOutFIFODecrementer.class.getName().equals(decrementer.getClass().getName())) + { + // Allow through each minute + if (now < (lastIdleCheck + 60000L)) + return; + } + else + { + // Otherwise, strict check + if (now < (lastIdleCheck + timeoutSetting)) + return; + } + + lastIdleCheck = now; + + ArrayList destroyConnections = new ArrayList(); + long timeout = now - timeoutSetting; + + boolean destroy = true; + int destroyed = 0; + + if (log.isTraceEnabled()) + { + synchronized (cls) + { + String method = "removeIdleConnections(" + timeout + ")"; + log.trace(ManagedConnectionPoolUtility.fullDetails(this, method, + mcf, cm, pool, poolConfiguration, + cls, checkedOut, pool.getInternalStatistics(), + defaultSubject, defaultCri)); + } + } + else if (debug) + { + String method = "removeIdleConnections(" + timeout + ")"; + log.debug(ManagedConnectionPoolUtility.details(method, pool.getName(), + pool.getInternalStatistics().getInUseCount(), maxSize)); + } + + while (destroy) + { + synchronized (cls) + { + // No free connection listeners + if (cls.size() == 0) + break; + + // We always check the first connection listener, since it is the oldest + ConnectionListener cl = cls.get(0); + + destroy = decrementer.shouldDestroy(cl, timeout, + cls.size() + checkedOut.size(), + poolConfiguration.getMinSize(), + destroyed); + + if (destroy) + { + if (shouldRemove() || !isRunning()) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTimedOut(); + + log.tracef("Idle connection cl=%s", cl); + + // We need to destroy this one + cls.remove(0); + destroyConnections.add(cl); + destroyed++; + } + else + { + destroy = false; + } + } + } + } + + // We found some connections to destroy + if (destroyConnections.size() > 0 || isEmpty()) + { + for (ConnectionListener cl : destroyConnections) + { + log.tracef("Destroying connection %s", cl); + + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() - + cl.getLastReturnedTime()); + + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, cl, false, true, false, false, false, + false, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + cl.destroy(); + cl = null; + } + + if (isRunning()) + { + // Let prefill and use-strict-min be the same + boolean emptyManagedConnectionPool = false; + + if ((poolConfiguration.isPrefill() || poolConfiguration.isStrictMin()) && pool instanceof PrefillPool) + { + if (poolConfiguration.getMinSize() > 0) + { + prefill(); + } + else + { + emptyManagedConnectionPool = true; + } + } + else + { + emptyManagedConnectionPool = true; + } + + // Empty pool + if (emptyManagedConnectionPool && isEmpty()) + pool.emptyManagedConnectionPool(this); + } + } + } + + /** + * {@inheritDoc} + */ + public void shutdown() + { + final Collection toDestroy; + synchronized (this) + { + if (log.isTraceEnabled()) + log.tracef("Shutdown - Pool: %s MCP: %s", pool.getName(), Integer.toHexString(System.identityHashCode( + this))); + + IdleRemover.getInstance().unregisterPool(this); + ConnectionValidator.getInstance().unregisterPool(this); + + if (checkedOut.size() > 0) + { + for (ConnectionListener cl : checkedOut) + { + log.destroyingActiveConnection(pool.getName(), cl.getManagedConnection()); + + if (Tracer.isEnabled()) + Tracer.clearConnectionListener(pool.getName(), this, cl); + } + } + + toDestroy = new ArrayList(); + flush(FlushMode.ALL, toDestroy); + } + for (ConnectionListener cl : toDestroy) + { + cl.destroy(); + } + } + + /** + * {@inheritDoc} + */ + public void fillTo(int size) + { + if (size <= 0) + return; + + if (!(poolConfiguration.isPrefill() || poolConfiguration.isStrictMin())) + return; + + if (!(pool instanceof PrefillPool)) + return; + + if (log.isTraceEnabled()) + { + synchronized (cls) + { + String method = "fillTo(" + size + ")"; + log.trace(ManagedConnectionPoolUtility.fullDetails(this, method, + mcf, cm, pool, poolConfiguration, + cls, checkedOut, pool.getInternalStatistics(), + defaultSubject, defaultCri)); + } + } + else if (debug) + { + String method = "fillTo(" + size + ")"; + log.debug(ManagedConnectionPoolUtility.details(method, pool.getName(), + pool.getInternalStatistics().getInUseCount(), maxSize)); + } + + while (!pool.isFull()) + { + // Get a permit - avoids a race when the pool is nearly full + // Also avoids unnessary fill checking when all connections are checked out + try + { + long startWait = pool.getInternalStatistics().isEnabled() ? System.currentTimeMillis() : 0L; + if (pool.getLock().tryAcquire(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS)) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalBlockingTime(System.currentTimeMillis() - startWait); + try + { + if (!isRunning()) + { + return; + } + + // We already have enough connections + if (isSize(size)) + { + return; + } + + // Create a connection to fill the pool + try + { + ConnectionListener cl = createConnectionEventListener(defaultSubject, defaultCri); + + if (Tracer.isEnabled()) + Tracer.createConnectionListener(pool.getName(), this, cl, cl.getManagedConnection(), + false, true, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + boolean added = false; + synchronized (cls) + { + if (!isSize(size)) + { + log.tracef("Filling pool cl=%s", cl); + + cls.add(cl); + added = true; + } + } + + if (!added) + { + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, false, false, + false, true, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + cl.destroy(); + return; + } + } + catch (ResourceException re) + { + log.unableFillPool(re, cm.getJndiName()); + return; + } + } + finally + { + pool.getLock().release(); + } + } + } + catch (InterruptedException ignored) + { + Thread.interrupted(); + + log.trace("Interrupted while requesting permit in fillTo"); + } + } + } + + /** + * {@inheritDoc} + */ + public void increaseCapacity(Subject subject, ConnectionRequestInfo cri) + { + // We have already created one connection when this method is scheduled + int created = 1; + boolean create = true; + + while (create && !pool.isFull()) + { + try + { + long startWait = pool.getInternalStatistics().isEnabled() ? System.currentTimeMillis() : 0L; + if (pool.getLock().tryAcquire(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS)) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalBlockingTime(System.currentTimeMillis() - startWait); + try + { + if (!isRunning()) + { + return; + } + + int currentSize = 0; + synchronized (cls) + { + currentSize = cls.size() + checkedOut.size(); + } + + create = pool.getCapacity().getIncrementer().shouldCreate(currentSize, + poolConfiguration.getMaxSize(), created); + + if (create) + { + try + { + ConnectionListener cl = createConnectionEventListener(subject, cri); + + if (Tracer.isEnabled()) + Tracer.createConnectionListener(pool.getName(), this, cl, cl.getManagedConnection(), + false, false, true, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + boolean added = false; + synchronized (cls) + { + if (!isSize(poolConfiguration.getMaxSize())) + { + log.tracef("Capacity fill: cl=%s", cl); + + cls.add(cl); + created++; + added = true; + } + } + + if (!added) + { + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, true, false, + false, false, true, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + cl.destroy(); + return; + } + } + catch (ResourceException re) + { + log.unableFillPool(re, cm.getJndiName()); + return; + } + } + } + finally + { + pool.getLock().release(); + } + } + } + catch (InterruptedException ignored) + { + Thread.interrupted(); + + log.trace("Interrupted while requesting permit in increaseCapacity"); + } + } + } + + /** + * Create a connection event listener + * + * @param subject the subject + * @param cri the connection request information + * @return the new listener + * @throws ResourceException for any error + */ + private ConnectionListener createConnectionEventListener(Subject subject, ConnectionRequestInfo cri) + throws ResourceException + { + long start = pool.getInternalStatistics().isEnabled() ? System.currentTimeMillis() : 0L; + + ManagedConnection mc = mcf.createManagedConnection(subject, cri); + + if (pool.getInternalStatistics().isEnabled()) + { + pool.getInternalStatistics().deltaTotalCreationTime(System.currentTimeMillis() - start); + pool.getInternalStatistics().deltaCreatedCount(); + } + try + { + return cm.createConnectionListener(mc, this); + } + catch (ResourceException re) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaDestroyedCount(); + mc.destroy(); + throw re; + } + } + + /** + * {@inheritDoc} + */ + public void connectionListenerDestroyed(ConnectionListener cl) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaDestroyedCount(); + } + + /** + * Should any connections be removed from the pool + * @return True if connections should be removed; otherwise false + */ + private boolean shouldRemove() + { + boolean remove = true; + + if (poolConfiguration.isStrictMin() && pool instanceof PrefillPool) + { + // Add 1 to min-pool-size since it is strict + remove = isSize(poolConfiguration.getMinSize() + 1); + + log.tracef("StrictMin is active. Current connection will be removed is %b", remove); + } + + return remove; + } + + /** + * {@inheritDoc} + */ + public void validateConnections() throws Exception + { + + if (log.isTraceEnabled()) + { + log.tracef("Attempting to validate connections for pool %s", this); + synchronized (cls) + { + String method = "validateConnections()"; + log.trace(ManagedConnectionPoolUtility.fullDetails(this, method, + mcf, cm, pool, poolConfiguration, + cls, checkedOut, pool.getInternalStatistics(), + defaultSubject, defaultCri)); + } + } + else if (debug) + { + String method = "validateConnections()"; + log.debug(ManagedConnectionPoolUtility.details(method, pool.getName(), + pool.getInternalStatistics().getInUseCount(), maxSize)); + } + + if (pool.getLock().tryAcquire(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS)) + { + boolean anyDestroyed = false; + + try + { + while (true) + { + ConnectionListener cl = null; + boolean destroyed = false; + + synchronized (cls) + { + if (cls.size() == 0) + { + break; + } + + cl = removeForFrequencyCheck(); + } + + if (cl == null) + { + break; + } + + try + { + Set candidateSet = Collections.singleton(cl.getManagedConnection()); + + if (mcf instanceof ValidatingManagedConnectionFactory) + { + ValidatingManagedConnectionFactory vcf = (ValidatingManagedConnectionFactory) mcf; + candidateSet = vcf.getInvalidConnections(candidateSet); + + if ((candidateSet != null && candidateSet.size() > 0) || !isRunning()) + { + if (cl.getState() != ConnectionState.DESTROY) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() - + cl.getLastReturnedTime()); + + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, true, + false, false, false, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + cl.destroy(); + cl = null; + destroyed = true; + anyDestroyed = true; + } + } + } + else + { + log.backgroundValidationNonCompliantManagedConnectionFactory(); + } + } + catch (ResourceException re) + { + if (cl != null) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() - + cl.getLastReturnedTime()); + + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, false, + false, true, false, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + cl.destroy(); + cl = null; + destroyed = true; + anyDestroyed = true; + } + + log.connectionValidatorIgnoredUnexpectedError(re); + } + finally + { + if (!destroyed) + { + synchronized (cls) + { + returnForFrequencyCheck(cl); + } + } + } + } + } + finally + { + pool.getLock().release(); + + if (anyDestroyed) + prefill(); + } + } + } + + /** + * Get the pool name + * @return The value + */ + String getPoolName() + { + if (pool == null) + return ""; + + return pool.getName(); + } + + /** + * Returns the connection listener that should be removed due to background validation + * @return The listener; otherwise null if none should be removed + */ + private ConnectionListener removeForFrequencyCheck() + { + ConnectionListener cl = null; + + for (Iterator iter = cls.iterator(); iter.hasNext();) + { + cl = iter.next(); + long lastCheck = cl.getLastValidatedTime(); + + if ((System.currentTimeMillis() - lastCheck) >= poolConfiguration.getBackgroundValidationMillis()) + { + cls.remove(cl); + break; + } + else + { + cl = null; + } + } + + if (debug) + log.debugf("Checking for connection within frequency: %s", cl); + + return cl; + } + + /** + * Return a connection listener to the pool and update its validation timestamp + * @param cl The listener + */ + private void returnForFrequencyCheck(ConnectionListener cl) + { + if (debug) + log.debugf("Returning for connection within frequency: %s", cl); + + cl.setLastValidatedTime(System.currentTimeMillis()); + cls.add(cl); + } + + /** + * Check if the resource adapter supports lazy association + */ + private void checkLazyAssociation() + { + synchronized (cls) + { + ConnectionListener cl = null; + + if (checkedOut.size() > 0) + cl = checkedOut.get(0); + + if (cl == null && cls.size() > 0) + cl = cls.get(0); + + if (cl != null) + { + if (cl.supportsLazyAssociation()) + { + if (debug) + log.debug("Enable lazy association support for: " + pool.getName()); + + supportsLazyAssociation = Boolean.TRUE; + } + else + { + if (debug) + log.debug("Disable lazy association support for: " + pool.getName()); + + supportsLazyAssociation = Boolean.FALSE; + } + } + } + } + + /** + * Detach connection listener + * @return The outcome + */ + private boolean detachConnectionListener() + { + synchronized (cls) + { + ConnectionListener cl = null; + try + { + Iterator it = checkedOut.iterator(); + while (it.hasNext()) + { + cl = it.next(); + if (!cl.isEnlisted() && cl.getManagedConnection() instanceof DissociatableManagedConnection) + { + log.tracef("Detach: %s", cl); + + DissociatableManagedConnection dmc = (DissociatableManagedConnection)cl.getManagedConnection(); + dmc.dissociateConnections(); + + cl.unregisterConnections(); + + if (Tracer.isEnabled()) + Tracer.returnConnectionListener(pool.getName(), this, cl, false, pool.isInterleaving(), + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + returnConnection(cl, false, false); + + return true; + } + } + } + catch (Throwable t) + { + // Ok - didn't work; nuke it and disable + if (debug) + log.debug("Exception during detach for: " + pool.getName(), t); + + supportsLazyAssociation = Boolean.FALSE; + + if (cl != null) + { + if (Tracer.isEnabled()) + Tracer.returnConnectionListener(pool.getName(), this, cl, true, pool.isInterleaving(), + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + returnConnection(cl, true, true); + } + } + } + + return false; + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("SemaphoreArrayListManagedConnectionPool@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[pool=").append(pool.getName()); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SemaphoreConcurrentLinkedDequeManagedConnectionPool.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SemaphoreConcurrentLinkedDequeManagedConnectionPool.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SemaphoreConcurrentLinkedDequeManagedConnectionPool.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,1788 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2015, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.mcp; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.connectionmanager.pool.FlushMode; +import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration; +import org.jboss.jca.core.connectionmanager.ConnectionManager; +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.connectionmanager.listener.ConnectionState; +import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer; +import org.jboss.jca.core.connectionmanager.pool.api.Pool; +import org.jboss.jca.core.connectionmanager.pool.api.PrefillPool; +import org.jboss.jca.core.connectionmanager.pool.capacity.DefaultCapacity; +import org.jboss.jca.core.connectionmanager.pool.capacity.TimedOutDecrementer; +import org.jboss.jca.core.connectionmanager.pool.capacity.TimedOutFIFODecrementer; +import org.jboss.jca.core.connectionmanager.pool.idle.IdleRemover; +import org.jboss.jca.core.connectionmanager.pool.validator.ConnectionValidator; +import org.jboss.jca.core.tracer.Tracer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.resource.ResourceException; +import javax.resource.spi.ConnectionRequestInfo; +import javax.resource.spi.DissociatableManagedConnection; +import javax.resource.spi.ManagedConnection; +import javax.resource.spi.ManagedConnectionFactory; +import javax.resource.spi.RetryableException; +import javax.resource.spi.ValidatingManagedConnectionFactory; +import javax.security.auth.Subject; + +import org.jboss.logging.Messages; + +/** + * ManagedConnectionPool implementation based on a semaphore and ConcurrentLinkedDeque + * + * @author John O'Hara + * @author Jesper Pedersen + */ +public class SemaphoreConcurrentLinkedDequeManagedConnectionPool implements ManagedConnectionPool +{ + /** The log */ + private CoreLogger log; + + /** Whether debug is enabled */ + private boolean debug; + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** The managed connection factory */ + private ManagedConnectionFactory mcf; + + /** The connection manager */ + private ConnectionManager cm; + + /** The default subject */ + private Subject defaultSubject; + + /** The default connection request information */ + private ConnectionRequestInfo defaultCri; + + /** The pool configuration */ + private PoolConfiguration poolConfiguration; + + /** The pool */ + private Pool pool; + + /** FIFO / FILO */ + private boolean fifo; + + /** + * Copy of the maximum size from the pooling parameters. Dynamic changes to + * this value are not compatible with the semaphore which cannot change be + * dynamically changed. + */ + private int maxSize; + + /** The available connection event listeners */ + private ConcurrentLinkedDeque clq; + + /** all connection event listeners */ + private Map cls; + + /** Current pool size **/ + private AtomicInteger poolSize = new AtomicInteger(); + + /** Current checked out connections **/ + private AtomicInteger checkedOutSize = new AtomicInteger(); + + /** Supports lazy association */ + private Boolean supportsLazyAssociation; + + /** Last idle check */ + private long lastIdleCheck; + + /** Last used */ + private long lastUsed; + + /** + * Constructor + */ + public SemaphoreConcurrentLinkedDequeManagedConnectionPool() + { + } + + /** + * {@inheritDoc} + */ + public void initialize(ManagedConnectionFactory mcf, ConnectionManager cm, Subject subject, + ConnectionRequestInfo cri, PoolConfiguration pc, Pool p) + { + if (mcf == null) + throw new IllegalArgumentException("ManagedConnectionFactory is null"); + + if (cm == null) + throw new IllegalArgumentException("ConnectionManager is null"); + + if (pc == null) + throw new IllegalArgumentException("PoolConfiguration is null"); + + if (p == null) + throw new IllegalArgumentException("Pool is null"); + + this.mcf = mcf; + this.cm = cm; + this.defaultSubject = subject; + this.defaultCri = cri; + this.poolConfiguration = pc; + this.maxSize = pc.getMaxSize(); + this.pool = p; + this.fifo = p.isFIFO(); + this.log = pool.getLogger(); + this.debug = log.isDebugEnabled(); + this.clq = new ConcurrentLinkedDeque(); + this.cls = new ConcurrentHashMap(); + this.poolSize.set(0); + this.checkedOutSize.set(0); + this.supportsLazyAssociation = null; + this.lastIdleCheck = System.currentTimeMillis(); + this.lastUsed = Long.MAX_VALUE; + + // Schedule managed connection pool for prefill + if ((pc.isPrefill() || pc.isStrictMin()) && p instanceof PrefillPool && pc.getInitialSize() > 0) + { + PoolFiller.fillPool(new FillRequest(this, pc.getInitialSize())); + } + + if (poolConfiguration.getIdleTimeoutMinutes() > 0) + { + // Register removal support + IdleRemover.getInstance().registerPool(this, + poolConfiguration.getIdleTimeoutMinutes() * 1000L * 60); + } + + if (poolConfiguration.isBackgroundValidation() && poolConfiguration.getBackgroundValidationMillis() > 0) + { + if (debug) + log.debug("Registering for background validation at interval " + + poolConfiguration.getBackgroundValidationMillis()); + + // Register validation + ConnectionValidator.getInstance().registerPool(this, + poolConfiguration.getBackgroundValidationMillis()); + } + } + + /** + * {@inheritDoc} + */ + public long getLastUsed() + { + return lastUsed; + } + + /** + * {@inheritDoc} + */ + public boolean isRunning() + { + return !pool.isShutdown(); + } + + /** + * {@inheritDoc} + */ + public boolean isEmpty() + { + return poolSize.get() == 0; + } + + /** + * {@inheritDoc} + */ + public boolean isIdle() + { + return checkedOutSize.get() == 0; + } + + /** + * {@inheritDoc} + */ + public int getActive() + { + return poolSize.get(); + } + + /** + * Check if the pool has reached a certain size + * + * @param size The size + * @return True if reached; otherwise false + */ + private boolean isSize(int size) + { + return poolSize.get() >= size; + } + + /** + * {@inheritDoc} + */ + public void prefill() + { + if (isRunning() && + (poolConfiguration.isPrefill() || poolConfiguration.isStrictMin()) && + pool instanceof PrefillPool && + poolConfiguration.getMinSize() > 0) + PoolFiller.fillPool(new FillRequest(this, poolConfiguration.getMinSize())); + } + + /** + * {@inheritDoc} + */ + public ConnectionListener getConnection(Subject subject, ConnectionRequestInfo cri) throws ResourceException + { + if (log.isTraceEnabled()) + { + synchronized (cls) + { + String method = "getConnection(" + subject + ", " + cri + ")"; + SortedSet checkedOut = new TreeSet(); + SortedSet available = new TreeSet(); + for (Entry entry : cls.entrySet()) + { + if (entry.getValue().isCheckedOut()) + checkedOut.add(entry.getKey()); + else + available.add(entry.getKey()); + } + log.trace(ManagedConnectionPoolUtility.fullDetails(this, method, mcf, cm, pool, + poolConfiguration, available, checkedOut, + pool.getInternalStatistics(), subject, cri)); + } + } + else if (debug) + { + String method = "getConnection(" + subject + ", " + cri + ")"; + log.debug(ManagedConnectionPoolUtility.details(method, pool.getName(), + pool.getInternalStatistics().getInUseCount(), maxSize)); + } + + subject = (subject == null) ? defaultSubject : subject; + cri = (cri == null) ? defaultCri : cri; + + if (pool.isFull()) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaWaitCount(); + + if (pool.isSharable() && (supportsLazyAssociation == null || supportsLazyAssociation.booleanValue())) + { + if (supportsLazyAssociation == null) + checkLazyAssociation(); + + if (supportsLazyAssociation != null && supportsLazyAssociation.booleanValue()) + { + if (log.isTraceEnabled()) + log.tracef("Trying to detach - Pool: %s MCP: %s", pool.getName(), + Integer.toHexString(System.identityHashCode(this))); + + if (!detachConnectionListener()) + { + if (log.isTraceEnabled()) + log.tracef("Detaching didn't succeed - Pool: %s MCP: %s", pool.getName(), + Integer.toHexString(System.identityHashCode(this))); + } + } + } + } + + long startWait = pool.getInternalStatistics().isEnabled() ? System.currentTimeMillis() : 0L; + try + { + if (pool.getLock().tryAcquire(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS)) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalBlockingTime(System.currentTimeMillis() - startWait); + + // We have a permit to get a connection. Is there one in the pool already? + ConnectionListenerWrapper clw = null; + do + { + if (!isRunning()) + { + pool.getLock().release(); + + throw new ResourceException( + bundle.thePoolHasBeenShutdown(pool.getName(), + Integer.toHexString(System.identityHashCode(this)))); + } + + if (fifo) + { + clw = clq.pollFirst(); + } + else + { + clw = clq.pollLast(); + } + + if (clw != null) + { + clw.setCheckedOut(true); + checkedOutSize.incrementAndGet(); + + // Yes, we retrieved a ManagedConnection from the pool. + // Does it match? + try + { + Object matchedMC = mcf.matchManagedConnections(Collections.singleton( + clw.getConnectionListener().getManagedConnection()), subject, cri); + + boolean valid = true; + + if (matchedMC != null) + { + if (poolConfiguration.isValidateOnMatch()) + { + if (mcf instanceof ValidatingManagedConnectionFactory) + { + try + { + ValidatingManagedConnectionFactory vcf = (ValidatingManagedConnectionFactory) mcf; + Set candidateSet = + Collections.singleton(clw.getConnectionListener().getManagedConnection()); + candidateSet = vcf.getInvalidConnections(candidateSet); + + if (candidateSet != null && candidateSet.size() > 0) + { + valid = false; + } + } + catch (Throwable t) + { + valid = false; + if (log.isTraceEnabled()) + log.trace("Exception while ValidateOnMatch: " + t.getMessage(), t); + } + } + else + { + log.validateOnMatchNonCompliantManagedConnectionFactory(mcf.getClass().getName()); + } + } + + if (valid) + { + log.tracef("supplying ManagedConnection from pool: %s", clw.getConnectionListener()); + + lastUsed = System.currentTimeMillis(); + clw.getConnectionListener().setLastCheckedOutTime(lastUsed); + + if (pool.getInternalStatistics().isEnabled()) + { + pool.getInternalStatistics().deltaTotalGetTime(lastUsed - startWait); + pool.getInternalStatistics().deltaTotalPoolTime(lastUsed - + clw.getConnectionListener().getLastReturnedTime()); + } + + if (Tracer.isEnabled()) + Tracer.getConnectionListener(pool.getName(), this, clw.getConnectionListener(), + true, pool.isInterleaving(), + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + clw.setHasPermit(true); + + return clw.getConnectionListener(); + } + } + + // Match did not succeed but no exception was + // thrown. + // Either we have the matching strategy wrong or the + // connection died while being checked. We need to + // distinguish these cases, but for now we always + // destroy the connection. + if (valid) + { + log.destroyingConnectionNotSuccessfullyMatched(clw.getConnectionListener()); + } + else + { + log.destroyingConnectionNotValidated(clw.getConnectionListener()); + } + + if (pool.getInternalStatistics().isEnabled()) + { + pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() - + clw.getConnectionListener().getLastReturnedTime()); + } + + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, clw.getConnectionListener(), + false, false, true, false, false, false, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + removeConnectionListenerFromPool(clw); + clw.getConnectionListener().destroy(); + clw = null; + } + catch (Throwable t) + { + log.throwableWhileTryingMatchManagedConnectionThenDestroyingConnection( + clw.getConnectionListener(), t); + + if (pool.getInternalStatistics().isEnabled()) + { + pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() - + clw.getConnectionListener().getLastReturnedTime()); + } + + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, clw.getConnectionListener(), + false, false, false, false, true, false, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + removeConnectionListenerFromPool(clw); + clw.getConnectionListener().destroy(); + clw = null; + } + + // We made it here, something went wrong and we should + // validate + // if we should continue attempting to acquire a + // connection + if (poolConfiguration.isUseFastFail()) + { + if (log.isTraceEnabled()) + log.trace("Fast failing for connection attempt. No more attempts will be made to " + + "acquire connection from pool and a new connection will be created immeadiately"); + break; + } + + } + } + while (clq.size() > 0); + + // OK, we couldnt find a working connection from the pool. Make + // a new one. + try + { + // No, the pool was empty, so we have to make a new one. + clw = new ConnectionListenerWrapper(createConnectionEventListener(subject, cri), true, true); + + if (Tracer.isEnabled()) + Tracer.createConnectionListener(pool.getName(), this, clw.getConnectionListener(), + clw.getConnectionListener().getManagedConnection(), + true, false, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + clw.setCheckedOut(true); + checkedOutSize.incrementAndGet(); + + cls.put(clw.getConnectionListener(), clw); + + log.tracef("supplying new ManagedConnection: %s", clw.getConnectionListener()); + + lastUsed = System.currentTimeMillis(); + + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalGetTime(lastUsed - startWait); + + prefill(); + + // Trigger capacity increase + if (pool.getCapacity().getIncrementer() != null) + CapacityFiller.schedule(new CapacityRequest(this, subject, cri)); + + if (Tracer.isEnabled()) + Tracer.getConnectionListener(pool.getName(), this, clw.getConnectionListener(), false, + pool.isInterleaving(), + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + return clw.getConnectionListener(); + } + catch (Throwable t) + { + if (clw != null || !(t instanceof RetryableException)) + log.throwableWhileAttemptingGetNewGonnection(clw != null ? clw.getConnectionListener() : null, t); + + // Return permit and rethrow + if (clw != null) + { + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, clw.getConnectionListener(), + false, false, false, false, true, false, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + removeConnectionListenerFromPool(clw); + clw.getConnectionListener().destroy(); + } + + pool.getLock().release(); + + if (t instanceof ResourceException) + { + throw (ResourceException)t; + } + else + { + throw new ResourceException( + bundle.unexpectedThrowableWhileTryingCreateConnection( + clw != null ? clw.getConnectionListener() : null), t); + } + } + } + else + { + // We timed out + throw new ResourceException( + bundle.noMManagedConnectionsAvailableWithinConfiguredBlockingTimeout( + poolConfiguration.getBlockingTimeout())); + } + + } + catch (InterruptedException ie) + { + Thread.interrupted(); + + long end = pool.getInternalStatistics().isEnabled() ? (System.currentTimeMillis() - startWait) : 0L; + pool.getInternalStatistics().deltaTotalBlockingTime(end); + throw new ResourceException(bundle.interruptedWhileRequestingPermit(end)); + } + } + + /** + * {@inheritDoc} + */ + public ConnectionListener findConnectionListener(ManagedConnection mc) + { + return findConnectionListener(mc, null); + } + + /** + * {@inheritDoc} + */ + public ConnectionListener findConnectionListener(ManagedConnection mc, Object connection) + { + for (Entry entry : cls.entrySet()) + { + if (entry.getValue().isCheckedOut() && entry.getKey().controls(mc, connection)) + return entry.getKey(); + } + return null; + } + + /** + * {@inheritDoc} + */ + public void returnConnection(ConnectionListener cl, boolean kill) + { + returnConnection(cl, kill, true); + } + + /** + * {@inheritDoc} + */ + public void returnConnection(ConnectionListener cl, boolean kill, boolean cleanup) + { + if (pool.getInternalStatistics().isEnabled() && cl.getState() != ConnectionState.DESTROYED) + pool.getInternalStatistics().deltaTotalUsageTime(System.currentTimeMillis() - cl.getLastCheckedOutTime()); + + if (log.isTraceEnabled()) + { + synchronized (cls) + { + String method = "returnConnection(" + Integer.toHexString(System.identityHashCode(cl)) + ", " + kill + ")"; + SortedSet checkedOut = new TreeSet(); + SortedSet available = new TreeSet(); + for (Entry entry : cls.entrySet()) + { + if (entry.getValue().isCheckedOut()) + checkedOut.add(entry.getKey()); + else + available.add(entry.getKey()); + } + log.trace(ManagedConnectionPoolUtility.fullDetails( + this, method, mcf, cm, pool, + poolConfiguration, available, checkedOut, pool.getInternalStatistics(), defaultSubject, defaultCri)); + } + } + else if (debug) + { + String method = "returnConnection(" + Integer.toHexString(System.identityHashCode(cl)) + ", " + kill + ")"; + log.debug(ManagedConnectionPoolUtility.details(method, + pool.getName(), pool.getInternalStatistics().getInUseCount(), maxSize)); + } + + ConnectionListenerWrapper clw = cls.get(cl); + if (cl.getState() == ConnectionState.DESTROYED) + { + log.tracef("ManagedConnection is being returned after it was destroyed: %s", cl); + + if (clw != null && clw.hasPermit()) + { + clw.setHasPermit(false); + pool.getLock().release(); + } + + return; + } + + if (cleanup) + { + try + { + cl.getManagedConnection().cleanup(); + } + catch (ResourceException re) + { + log.resourceExceptionCleaningUpManagedConnection(cl, re); + kill = true; + } + } + + // We need to destroy this one + if (clw == null || cl.getState() == ConnectionState.DESTROY || cl.getState() == ConnectionState.DESTROYED) + kill = true; + + // This is really an error + if (!kill && isSize(poolConfiguration.getMaxSize() + 1)) + { + log.destroyingReturnedConnectionMaximumPoolSizeExceeded(cl); + kill = true; + } + + boolean releasePermit = false; + if (clw != null) + { + if (clw.hasPermit()) + { + clw.setHasPermit(false); + releasePermit = true; + } + if (clw.isCheckedOut()) + { + clw.setCheckedOut(false); + checkedOutSize.decrementAndGet(); + } + } + + // If we are destroying, check the connection is not in the pool + if (kill) + { + // Adrian Brock: A resource adapter can asynchronously notify us + // that a connection error occurred. + // This could happen while the connection is not checked out. + // e.g. JMS can do this via an ExceptionListener on the connection. + // I have twice had to reinstate this line of code, PLEASE DO NOT + // REMOVE IT! + cls.remove(cl); + } + // return to the pool + else + { + cl.toPool(); + if (!clq.contains(clw)) + { + clq.addLast(clw); + } + else + { + log.attemptReturnConnectionTwice(cl, new Throwable("STACKTRACE")); + } + } + + if (kill) + { + log.tracef("Destroying returned connection %s", cl); + + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, cl, + true, false, false, false, false, false, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + removeConnectionListenerFromPool(clw); + cl.destroy(); + } + + if (releasePermit) + { + pool.getLock().release(); + } + } + + /** + * {@inheritDoc} + */ + public void flush(FlushMode mode, Collection toDestroy) + { + ArrayList destroy = null; + + synchronized (cls) + { + if (FlushMode.ALL == mode) + { + if (log.isTraceEnabled()) + { + SortedSet checkedOut = new TreeSet(); + for (Entry entry : cls.entrySet()) + { + if (entry.getValue().isCheckedOut()) + checkedOut.add(entry.getKey()); + } + log.tracef("Flushing pool checkedOut=%s inPool=%s", checkedOut , cls); + } + + // Mark checked out connections as requiring destruction + for (Entry entry : cls.entrySet()) + { + if (entry.getValue().isCheckedOut()) + { + log.tracef("Flush marking checked out connection for destruction %s", entry.getKey()); + + entry.getValue().setCheckedOut(false); + checkedOutSize.decrementAndGet(); + + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalUsageTime(System.currentTimeMillis() - + entry.getKey().getLastCheckedOutTime()); + + if (entry.getValue().hasPermit()) + { + entry.getValue().setHasPermit(false); + pool.getLock().release(); + } + + entry.getKey().setState(ConnectionState.DESTROY); + + if (destroy == null) + destroy = new ArrayList(1); + + destroy.add(entry.getValue()); + + clq.remove(entry.getValue()); + cls.remove(entry.getKey()); + } + } + } + else if (FlushMode.GRACEFULLY == mode) + { + if (log.isTraceEnabled()) + { + SortedSet checkedOut = new TreeSet(); + for (Entry entry : cls.entrySet()) + { + if (entry.getValue().isCheckedOut()) + checkedOut.add(entry.getKey()); + } + log.tracef("Gracefully flushing pool checkedOut=%s inPool=%s", checkedOut , cls); + } + + for (Entry entry : cls.entrySet()) + { + if (entry.getValue().isCheckedOut()) + { + log.tracef("Graceful flush marking checked out connection for destruction %s", entry.getKey()); + + entry.getKey().setState(ConnectionState.DESTROY); + } + } + + } + + // Destroy connections in the pool + Iterator clqIter = clq.iterator(); + while (clqIter.hasNext()) + { + ConnectionListenerWrapper clw = clqIter.next(); + boolean kill = true; + + if (FlushMode.INVALID == mode && clw.getConnectionListener().getState().equals(ConnectionState.NORMAL)) + { + if (mcf instanceof ValidatingManagedConnectionFactory) + { + try + { + ValidatingManagedConnectionFactory vcf = (ValidatingManagedConnectionFactory) mcf; + Set candidateSet = Collections.singleton(clw.getConnectionListener().getManagedConnection()); + candidateSet = vcf.getInvalidConnections(candidateSet); + + if (candidateSet == null || candidateSet.size() == 0) + { + kill = false; + } + } + catch (Throwable t) + { + log.trace("Exception during invalid flush", t); + } + } + } + + if (kill) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() - + clw.getConnectionListener().getLastReturnedTime()); + + clq.remove(clw); + cls.remove(clw.getConnectionListener()); + + if (destroy == null) + destroy = new ArrayList(1); + + clw.getConnectionListener().setState(ConnectionState.DESTROY); + destroy.add(clw); + } + + } + } + + // We need to destroy some connections + if (destroy != null) + { + for (ConnectionListenerWrapper clw : destroy) + { + removeConnectionListenerFromPool(clw); + toDestroy.add(clw.getConnectionListener()); + clw = null; + } + } + + // Trigger prefill + prefill(); + } + + /** + * {@inheritDoc} + */ + public void removeIdleConnections() + { + long now = System.currentTimeMillis(); + long timeoutSetting = poolConfiguration.getIdleTimeoutMinutes() * 1000L * 60; + + CapacityDecrementer decrementer = pool.getCapacity().getDecrementer(); + + if (decrementer == null) + decrementer = DefaultCapacity.DEFAULT_DECREMENTER; + + if (TimedOutDecrementer.class.getName().equals(decrementer.getClass().getName()) || + TimedOutFIFODecrementer.class.getName().equals(decrementer.getClass().getName())) + { + // Allow through each minute + if (now < (lastIdleCheck + 60000L)) + return; + } + else + { + // Otherwise, strict check + if (now < (lastIdleCheck + timeoutSetting)) + return; + } + + lastIdleCheck = now; + + ArrayList destroyConnections = new ArrayList(); + long timeout = now - timeoutSetting; + + boolean destroy = true; + int destroyed = 0; + + if (log.isTraceEnabled()) + { + synchronized (cls) + { + String method = "removeIdleConnections(" + timeout + ")"; + SortedSet checkedOut = new TreeSet(); + SortedSet available = new TreeSet(); + for (Entry entry : cls.entrySet()) + { + if (entry.getValue().isCheckedOut()) + checkedOut.add(entry.getKey()); + else + available.add(entry.getKey()); + } + log.trace(ManagedConnectionPoolUtility.fullDetails( + this, method, mcf, cm, pool, + poolConfiguration, available, checkedOut, pool.getInternalStatistics(), defaultSubject, defaultCri)); + } + } + else if (debug) + { + String method = "removeIdleConnections(" + timeout + ")"; + log.debug(ManagedConnectionPoolUtility.details(method, pool.getName(), + pool.getInternalStatistics().getInUseCount(), maxSize)); + } + + Iterator clwIter = clq.iterator(); + while (clwIter.hasNext() && destroy) + { + // Nothing left to destroy + if (clq.size() == 0) + break; + + ConnectionListenerWrapper clw = clwIter.next(); + + destroy = decrementer.shouldDestroy(clw.getConnectionListener(), + timeout, poolSize.get() - destroyed, + poolConfiguration.getMinSize(), destroyed); + + if (destroy) + { + if (shouldRemove() || !isRunning()) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTimedOut(); + + log.tracef("Idle connection cl=%s", clw.getConnectionListener()); + + // We need to destroy this one, so deregister now + if (cls.remove(clw.getConnectionListener()) == null) + log.tracef("Connection Pool did not contain: %s", clw.getConnectionListener()); + + if (!clq.remove(clw)) + log.tracef("Available connection queue did not contain: %s", clw.getConnectionListener()); + + destroyConnections.add(clw); + destroyed++; + } + else + { + destroy = false; + } + } + } + + // We found some connections to destroy + if (destroyConnections.size() > 0 || isEmpty()) + { + for (ConnectionListenerWrapper clw : destroyConnections) + { + log.tracef("Destroying connection %s", clw.getConnectionListener()); + + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() - + clw.getConnectionListener().getLastReturnedTime()); + + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, clw.getConnectionListener(), + false, true, false, false, false, false, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + removeConnectionListenerFromPool(clw); + clw.getConnectionListener().destroy(); + clw = null; + } + + if (isRunning()) + { + // Let prefill and use-strict-min be the same + boolean emptyManagedConnectionPool = false; + + if ((poolConfiguration.isPrefill() || poolConfiguration.isStrictMin()) && pool instanceof PrefillPool) + { + if (poolConfiguration.getMinSize() > 0) + { + prefill(); + } + else + { + emptyManagedConnectionPool = true; + } + } + else + { + emptyManagedConnectionPool = true; + } + + // Empty pool + if (emptyManagedConnectionPool && isEmpty()) + pool.emptyManagedConnectionPool(this); + } + } + } + + /** + * {@inheritDoc} + */ + public void shutdown() + { + if (log.isTraceEnabled()) + log.tracef("Shutdown - Pool: %s MCP: %s", pool.getName(), Integer.toHexString(System.identityHashCode(this))); + + IdleRemover.getInstance().unregisterPool(this); + ConnectionValidator.getInstance().unregisterPool(this); + + if (checkedOutSize.get() > 0) + { + for (Entry entry : cls.entrySet()) + { + if (entry.getValue().isCheckedOut()) + log.destroyingActiveConnection(pool.getName(), entry.getKey().getManagedConnection()); + + if (Tracer.isEnabled()) + Tracer.clearConnectionListener(pool.getName(), this, entry.getKey()); + + } + } + + final Collection toDestroy = new ArrayList(); + flush(FlushMode.ALL, toDestroy); + for (ConnectionListener cl : toDestroy) + { + cl.destroy(); + } + } + + /** + * {@inheritDoc} + */ + public void fillTo(int size) + { + if (size <= 0) + return; + + if (!(poolConfiguration.isPrefill() || poolConfiguration.isStrictMin())) + return; + + if (!(pool instanceof PrefillPool)) + return; + + if (log.isTraceEnabled()) + { + synchronized (cls) + { + String method = "fillTo(" + size + ")"; + SortedSet checkedOut = new TreeSet(); + SortedSet available = new TreeSet(); + for (Entry entry : cls.entrySet()) + { + if (entry.getValue().isCheckedOut()) + checkedOut.add(entry.getKey()); + else + available.add(entry.getKey()); + } + log.trace(ManagedConnectionPoolUtility.fullDetails( + this, method, mcf, cm, pool, + poolConfiguration, available, checkedOut, pool.getInternalStatistics(), defaultSubject, defaultCri)); + } + } + else if (debug) + { + String method = "fillTo(" + size + ")"; + log.debug(ManagedConnectionPoolUtility.details(method, pool.getName(), + pool.getInternalStatistics().getInUseCount(), maxSize)); + } + + while (!pool.isFull()) + { + // Get a permit - avoids a race when the pool is nearly full + // Also avoids unnessary fill checking when all connections are + // checked out + try + { + long startWait = pool.getInternalStatistics().isEnabled() ? System.currentTimeMillis() : 0L; + if (pool.getLock().tryAcquire(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS)) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalBlockingTime(System.currentTimeMillis() - startWait); + try + { + if (!isRunning()) + { + return; + } + + // We already have enough connections + if (isSize(size)) + { + return; + } + + // Create a connection to fill the pool + try + { + ConnectionListener cl = createConnectionEventListener(defaultSubject, defaultCri); + + if (Tracer.isEnabled()) + Tracer.createConnectionListener(pool.getName(), this, cl, cl.getManagedConnection(), + false, true, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + boolean added = false; + // We have to add 1, since poolSize is already incremented + if (!isSize(size + 1)) + { + log.tracef("Filling pool cl=%s", cl); + + cls.put(cl, new ConnectionListenerWrapper(cl, false, false)); + clq.addLast(cls.get(cl)); + added = true; + } + + if (!added) + { + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, false, false, + false, true, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + ConnectionListenerWrapper clw = new ConnectionListenerWrapper(cl, false, false); + removeConnectionListenerFromPool(clw); + clw.getConnectionListener().destroy(); + return; + } + } + catch (ResourceException re) + { + log.unableFillPool(re, cm.getJndiName()); + return; + } + } + finally + { + pool.getLock().release(); + } + } + } + catch (InterruptedException ignored) + { + Thread.interrupted(); + + log.trace("Interrupted while requesting permit in fillTo"); + } + } + } + + @Override + public void increaseCapacity(Subject subject, ConnectionRequestInfo cri) + { + // We have already created one connection when this method is scheduled + int created = 1; + boolean create = true; + + while (create && !pool.isFull()) + { + try + { + long startWait = pool.getInternalStatistics().isEnabled() ? System.currentTimeMillis() : 0L; + if (pool.getLock().tryAcquire(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS)) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalBlockingTime(System.currentTimeMillis() - startWait); + try + { + if (!isRunning()) + { + return; + } + + create = pool.getCapacity().getIncrementer().shouldCreate(poolSize.get(), + poolConfiguration.getMaxSize(), created); + + if (create) + { + try + { + ConnectionListener cl = createConnectionEventListener(subject, cri); + + if (Tracer.isEnabled()) + Tracer.createConnectionListener(pool.getName(), this, cl, cl.getManagedConnection(), + false, false, true, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + boolean added = false; + // We have to add 1, since poolSize is already incremented + if (!isSize(poolConfiguration.getMaxSize() + 1)) + { + log.tracef("Capacity fill: cl=%s", cl); + + cls.put(cl, new ConnectionListenerWrapper(cl, false, false)); + clq.addLast(cls.get(cl)); + + created++; + added = true; + } + + if (!added) + { + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, true, false, + false, false, true, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + ConnectionListenerWrapper clw = new ConnectionListenerWrapper(cl, false, false); + removeConnectionListenerFromPool(clw); + clw.getConnectionListener().destroy(); + return; + } + } + catch (ResourceException re) + { + log.unableFillPool(re, cm.getJndiName()); + return; + } + } + } + finally + { + pool.getLock().release(); + } + } + } + catch (InterruptedException ignored) + { + Thread.interrupted(); + + log.trace("Interrupted while requesting permit in increaseCapacity"); + } + } + } + + /** + * {@inheritDoc} + */ + public void addConnectionListener(ConnectionListener cl) + { + cls.put(cl, new ConnectionListenerWrapper(cl, false, false)); + clq.addLast(cls.get(cl)); + poolSize.incrementAndGet(); + + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaCreatedCount(); + } + + /** + * {@inheritDoc} + */ + public ConnectionListener removeConnectionListener() + { + if (cls.size() > 0) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaDestroyedCount(); + ConnectionListenerWrapper clw = clq.removeFirst(); + if (cls.remove(clw.getConnectionListener()) != null) + poolSize.decrementAndGet(); + return clw.getConnectionListener(); + } + + return null; + } + + /** + * Create a connection event listener + * + * @param subject + * the subject + * @param cri + * the connection request information + * @return the new listener + * @throws ResourceException + * for any error + */ + private ConnectionListener createConnectionEventListener(Subject subject, ConnectionRequestInfo cri) + throws ResourceException + { + long start = pool.getInternalStatistics().isEnabled() ? System.currentTimeMillis() : 0L; + + ManagedConnection mc = mcf.createManagedConnection(subject, cri); + + if (pool.getInternalStatistics().isEnabled()) + { + pool.getInternalStatistics().deltaTotalCreationTime(System.currentTimeMillis() - start); + pool.getInternalStatistics().deltaCreatedCount(); + } + try + { + ConnectionListener cl = cm.createConnectionListener(mc, this); + poolSize.incrementAndGet(); + return cl; + } + catch (ResourceException re) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaDestroyedCount(); + mc.destroy(); + throw re; + } + } + + /** + * {@inheritDoc} + */ + public void connectionListenerDestroyed(ConnectionListener cl) + { + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaDestroyedCount(); + } + + /** + * Remove Connection Listener from pool and update counters and statistics + * + * Note, that the ConnectionListenerWrapper may already have been removed + * @param clw The wrapper + */ + private void removeConnectionListenerFromPool(ConnectionListenerWrapper clw) + { + if (clw != null) + { + clq.remove(clw); + cls.remove(clw.getConnectionListener()); + + //update counter and statistics + if (clw.isCheckedOut()) + { + clw.setCheckedOut(false); + checkedOutSize.decrementAndGet(); + } + // update pool size + poolSize.decrementAndGet(); + } + } + + /** + * Should any connections be removed from the pool + * + * @return True if connections should be removed; otherwise false + */ + private boolean shouldRemove() + { + boolean remove = true; + + if (poolConfiguration.isStrictMin() && pool instanceof PrefillPool) + { + // Add 1 to min-pool-size since it is strict + remove = isSize(poolConfiguration.getMinSize() + 1); + + log.tracef("StrictMin is active. Current connection will be removed is %b", remove); + } + + return remove; + } + + /** + * {@inheritDoc} + */ + public void validateConnections() throws Exception + { + + log.tracef("Attempting to validate connections for pool %s", this); + + if (pool.getLock().tryAcquire(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS)) + { + boolean anyDestroyed = false; + + try + { + while (true) + { + ConnectionListener cl = null; + boolean destroyed = false; + + synchronized (cls) + { + if (clq.size() == 0) + { + break; + } + + cl = removeForFrequencyCheck(); + } + + if (cl == null) + { + break; + } + + try + { + Set candidateSet = Collections.singleton(cl.getManagedConnection()); + + if (mcf instanceof ValidatingManagedConnectionFactory) + { + ValidatingManagedConnectionFactory vcf = (ValidatingManagedConnectionFactory) mcf; + candidateSet = vcf.getInvalidConnections(candidateSet); + + if ((candidateSet != null && candidateSet.size() > 0) || !isRunning()) + { + if (cl.getState() != ConnectionState.DESTROY) + { + ConnectionListenerWrapper clw = cls.remove(cl); + + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() - + clw.getConnectionListener().getLastReturnedTime()); + + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, clw.getConnectionListener(), + false, false, true, false, false, false, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + removeConnectionListenerFromPool(clw); + clw.getConnectionListener().destroy(); + clw = null; + destroyed = true; + anyDestroyed = true; + } + } + } + else + { + log.backgroundValidationNonCompliantManagedConnectionFactory(); + } + } + catch (ResourceException re) + { + if (cl != null) + { + ConnectionListenerWrapper clw = cls.remove(cl); + + if (pool.getInternalStatistics().isEnabled()) + pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() - + clw.getConnectionListener().getLastReturnedTime()); + + if (Tracer.isEnabled()) + Tracer.destroyConnectionListener(pool.getName(), this, clw.getConnectionListener(), + false, false, false, false, true, false, false, + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + removeConnectionListenerFromPool(clw); + clw.getConnectionListener().destroy(); + clw = null; + destroyed = true; + anyDestroyed = true; + } + + log.connectionValidatorIgnoredUnexpectedError(re); + } + finally + { + if (!destroyed) + { + synchronized (cls) + { + returnForFrequencyCheck(cl); + } + } + } + } + } + finally + { + pool.getLock().release(); + + if (anyDestroyed) + prefill(); + } + } + } + + /** + * Get the pool name + * @return The value + */ + String getPoolName() + { + if (pool == null) + return ""; + + return pool.getName(); + } + + /** + * Returns the connection listener that should be removed due to background + * validation + * + * @return The listener; otherwise null if none should be removed + */ + private ConnectionListener removeForFrequencyCheck() + { + log.debug("Checking for connection within frequency"); + + ConnectionListenerWrapper clw = null; + + for (Iterator iter = clq.iterator(); iter.hasNext();) + { + clw = iter.next(); + long lastCheck = clw.getConnectionListener().getLastValidatedTime(); + + if ((System.currentTimeMillis() - lastCheck) >= poolConfiguration.getBackgroundValidationMillis()) + { + clq.remove(clw); + break; + } + else + { + clw = null; + } + } + + if (clw != null) + return clw.getConnectionListener(); + else + return null; + } + + /** + * Return a connection listener to the pool and update its validation + * timestamp + * + * @param cl + * The listener + */ + private void returnForFrequencyCheck(ConnectionListener cl) + { + log.debug("Returning for connection within frequency"); + + cl.setLastValidatedTime(System.currentTimeMillis()); + clq.addLast(cls.get(cl)); + } + + /** + * Check if the resource adapter supports lazy association + */ + private void checkLazyAssociation() + { + ConnectionListener cl = null; + + if (cls.size() > 0) + cl = cls.keySet().iterator().next(); + + if (cl != null) + { + if (cl.supportsLazyAssociation()) + { + if (debug) + log.debug("Enable lazy association support for: " + pool.getName()); + + supportsLazyAssociation = Boolean.TRUE; + } + else + { + if (debug) + log.debug("Disable lazy association support for: " + pool.getName()); + + supportsLazyAssociation = Boolean.FALSE; + } + } + } + + /** + * Detach connection listener + * + * @return The outcome + */ + private boolean detachConnectionListener() + { + synchronized (cls) + { + ConnectionListener cl = null; + try + { + for (Entry entry : cls.entrySet()) + { + cl = entry.getKey(); + + if (entry.getValue().isCheckedOut()) + { + if (!cl.isEnlisted() && cl.getManagedConnection() instanceof DissociatableManagedConnection) + { + log.tracef("Detach: %s", cl); + + DissociatableManagedConnection dmc = (DissociatableManagedConnection) cl.getManagedConnection(); + dmc.dissociateConnections(); + + cl.unregisterConnections(); + + if (Tracer.isEnabled()) + Tracer.returnConnectionListener(pool.getName(), this, cl, false, pool.isInterleaving(), + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + returnConnection(cl, false, false); + + return true; + } + } + } + } + catch (Throwable t) + { + // Ok - didn't work; nuke it and disable + if (debug) + log.debug("Exception during detach for: " + pool.getName(), + t); + + supportsLazyAssociation = Boolean.FALSE; + + if (cl != null) + { + if (Tracer.isEnabled()) + Tracer.returnConnectionListener(pool.getName(), this, cl, true, pool.isInterleaving(), + Tracer.isRecordCallstacks() ? + new Throwable("CALLSTACK") : null); + + returnConnection(cl, true, true); + } + } + } + + return false; + } + + /** + * String representation + * + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("SemaphoreConcurrentLinkedQueueManagedConnectionPool@"); + sb.append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[pool=").append(pool.getName()); + sb.append("]"); + + return sb.toString(); + } + + /** + * Connection Listener wrapper to retain connection listener pool state + * + * @author John O'Hara + * @author Jesper Pedersen + */ + static class ConnectionListenerWrapper + { + private volatile ConnectionListener cl; + private volatile boolean checkedOut; + private volatile boolean hasPermit; + + /** + * Constructor + * + * @param connectionListener wrapped Connection Listener + */ + public ConnectionListenerWrapper(ConnectionListener connectionListener) + { + this(connectionListener, false, false); + } + + /** + * Constructor + * + * @param connectionListener wrapped Connection Listener + * @param checkedOut is connection listener checked out + */ + public ConnectionListenerWrapper(ConnectionListener connectionListener, boolean checkedOut) + { + this(connectionListener, checkedOut, false); + } + + /** + * Constructor + * + * @param connectionListener wrapped Connection Listener + * @param checkedOut is connection listener checked out + * @param hasPermit does connection listener have a permit + */ + public ConnectionListenerWrapper(ConnectionListener connectionListener, boolean checkedOut, boolean hasPermit) + { + this.cl = connectionListener; + this.checkedOut = checkedOut; + this.hasPermit = hasPermit; + } + + /** + * Get wrapped Connection Listener + * + * @return Wrapped Connection Listener + */ + public ConnectionListener getConnectionListener() + { + return cl; + } + + /** + * Is Connection Listener checked out + * + * @return Connection Listener is checked out + */ + public boolean isCheckedOut() + { + return checkedOut; + } + + /** + * Set whether Connection Listener is checkout out + * + * @param checkedOut is connection listener checked out + */ + public void setCheckedOut(boolean checkedOut) + { + this.checkedOut = checkedOut; + } + + /** + * Does Connection Listener have a permit + * + * @return Connection Listener has a permit + */ + public boolean hasPermit() + { + return hasPermit; + } + + /** + * Set whether Connection Listener has permit + * + * @param hasPermit does connection listener have a permit + */ + public void setHasPermit(boolean hasPermit) + { + this.hasPermit = hasPermit; + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,4 @@ + +This package contains the managed connection pool implementations and the +factory to create one with. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the connection pool implementation. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/CriKey.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/CriKey.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/CriKey.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,86 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.strategy; + +import javax.resource.spi.ConnectionRequestInfo; + +/** + * Pool by {@link ConnectionRequestInfo} key. + * + * @author Gurkan Erdogdu + * @version $Rev: $ + */ +class CriKey +{ + /** Identifies no connection request information */ + private static final Object NOCRI = new Object(); + + /** The connection request information */ + private final Object cri; + + /** Separate no tx */ + private boolean separateNoTx; + + /** The cached hashCode */ + private int hashCode = Integer.MAX_VALUE; + + /** + * Creates a new instance. + * @param cri connection request info + * @param separateNoTx separateNoTx + */ + CriKey(ConnectionRequestInfo cri, boolean separateNoTx) + { + this.cri = (cri == null) ? NOCRI : cri; + this.separateNoTx = separateNoTx; + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() + { + if (hashCode == Integer.MAX_VALUE) + hashCode = cri.hashCode(); + + return hashCode; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + + if (obj == null || !(obj instanceof CriKey)) + return false; + + CriKey other = (CriKey) obj; + + return cri.equals(other.cri) && separateNoTx == other.separateNoTx; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/OnePool.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/OnePool.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/OnePool.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,111 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.strategy; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration; +import org.jboss.jca.core.connectionmanager.pool.AbstractPrefillPool; +import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool; + +import javax.resource.spi.ConnectionRequestInfo; +import javax.resource.spi.ManagedConnectionFactory; +import javax.security.auth.Subject; + +import org.jboss.logging.Logger; + +/** + * Single pool implementation. + * + * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +public class OnePool extends AbstractPrefillPool +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, OnePool.class.getName()); + + /** + * Creates a new instance. + * + * @param mcf managed connection factory + * @param pc pool configuration + * @param noTxSeparatePools notx seperate pool + * @param sharable Are the connections sharable + * @param mcp mcp + */ + public OnePool(final ManagedConnectionFactory mcf, final PoolConfiguration pc, + final boolean noTxSeparatePools, final boolean sharable, + final String mcp) + { + super(mcf, pc, noTxSeparatePools, sharable, mcp); + } + + /** + * {@inheritDoc} + */ + @Override + protected Object getKey(final Subject subject, final ConnectionRequestInfo cri, boolean separateNoTx) + { + if (separateNoTx) + { + return Boolean.TRUE; + } + else + { + return Boolean.FALSE; + } + } + + /** + * {@inheritDoc} + */ + @Override + public void emptyManagedConnectionPool(ManagedConnectionPool pool) + { + // No-operation + } + + /** + * {@inheritDoc} + */ + public boolean testConnection() + { + return internalTestConnection(null, null); + } + + /** + * {@inheritDoc} + */ + public boolean testConnection(ConnectionRequestInfo cri, Subject subject) + { + return internalTestConnection(null, null); + } + + /** + * {@inheritDoc} + */ + public CoreLogger getLogger() + { + return log; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolByCri.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolByCri.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolByCri.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,94 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.strategy; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration; +import org.jboss.jca.core.connectionmanager.pool.AbstractPool; + +import javax.resource.ResourceException; +import javax.resource.spi.ConnectionRequestInfo; +import javax.resource.spi.ManagedConnectionFactory; +import javax.security.auth.Subject; + +import org.jboss.logging.Logger; + +/** + * Pool implementation that uses subject. + * + * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +public class PoolByCri extends AbstractPool +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, PoolByCri.class.getName()); + + /** + * Creates a new instance. + * @param mcf managed connection factory + * @param pc pool configuration + * @param noTxSeparatePools notx seperate pool + * @param sharable Are the connections sharable + * @param mcp mcp + */ + public PoolByCri(final ManagedConnectionFactory mcf, final PoolConfiguration pc, + final boolean noTxSeparatePools, final boolean sharable, + final String mcp) + { + super(mcf, pc, noTxSeparatePools, sharable, mcp); + } + + /** + * {@inheritDoc} + */ + @Override + protected Object getKey(Subject subject, ConnectionRequestInfo cri, boolean separateNoTx) throws ResourceException + { + return new CriKey(cri, separateNoTx); + } + + /** + * {@inheritDoc} + */ + public boolean testConnection() + { + return false; + } + + /** + * {@inheritDoc} + */ + public boolean testConnection(ConnectionRequestInfo cri, Subject subject) + { + return internalTestConnection(cri, null); + } + + /** + * {@inheritDoc} + */ + public CoreLogger getLogger() + { + return log; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolBySubject.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolBySubject.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolBySubject.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,164 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.strategy; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration; +import org.jboss.jca.core.connectionmanager.ConnectionManager; +import org.jboss.jca.core.connectionmanager.pool.AbstractPrefillPool; +import org.jboss.jca.core.spi.security.SubjectFactory; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Set; + +import javax.resource.ResourceException; +import javax.resource.spi.ConnectionRequestInfo; +import javax.resource.spi.ManagedConnectionFactory; +import javax.resource.spi.security.PasswordCredential; +import javax.security.auth.Subject; + +import org.jboss.logging.Logger; + +/** + * Pool implementation that uses subject. + * + * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +public class PoolBySubject extends AbstractPrefillPool +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, PoolBySubject.class.getName()); + + /** + * Creates a new instance. + * @param mcf managed connection factory + * @param pc pool configuration + * @param noTxSeparatePools notx seperate pool + * @param sharable Are the connections sharable + * @param mcp mcp + */ + public PoolBySubject(final ManagedConnectionFactory mcf, final PoolConfiguration pc, + final boolean noTxSeparatePools, final boolean sharable, + final String mcp) + { + super(mcf, pc, noTxSeparatePools, sharable, mcp); + } + + /** + * {@inheritDoc} + */ + @Override + protected Object getKey(Subject subject, ConnectionRequestInfo cri, boolean separateNoTx) throws ResourceException + { + return new SubjectKey(subject, separateNoTx); + } + + /** + * {@inheritDoc} + */ + public boolean testConnection() + { + try + { + ConnectionManager cm = getConnectionManager(); + ManagedConnectionFactory mcf = getManagedConnectionFactory(); + + Subject subject = createSubject(cm.getSubjectFactory(), cm.getSecurityDomain(), mcf, cm.getJndiName()); + + if (subject != null) + return internalTestConnection(null, subject); + } + catch (Throwable t) + { + log.debugf(t, "Error during testConnection: %s", t.getMessage()); + } + + return false; + } + + /** + * {@inheritDoc} + */ + public boolean testConnection(ConnectionRequestInfo cri, Subject subject) + { + return internalTestConnection(null, subject); + } + + /** + * Create a subject + * @param subjectFactory The subject factory + * @param securityDomain The security domain + * @param mcf The managed connection factory + * @param jndiName The jndi-name + * @return The subject; null in case of an error + */ + protected Subject createSubject(final SubjectFactory subjectFactory, + final String securityDomain, + final ManagedConnectionFactory mcf, + final String jndiName) + { + if (subjectFactory == null) + throw new IllegalArgumentException("SubjectFactory is null"); + + if (securityDomain == null) + throw new IllegalArgumentException("SecurityDomain is null"); + + return AccessController.doPrivileged(new PrivilegedAction() + { + public Subject run() + { + try + { + Subject subject = subjectFactory.createSubject(securityDomain); + + Set pcs = subject.getPrivateCredentials(PasswordCredential.class); + if (pcs.size() > 0) + { + for (PasswordCredential pc : pcs) + { + pc.setManagedConnectionFactory(mcf); + } + } + + return subject; + } + catch (Throwable t) + { + log.exceptionDuringCreateSubject(jndiName, t.getMessage(), t); + } + + return null; + } + }); + } + + /** + * {@inheritDoc} + */ + public CoreLogger getLogger() + { + return log; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolBySubjectAndCri.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolBySubjectAndCri.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolBySubjectAndCri.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,95 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.strategy; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration; +import org.jboss.jca.core.connectionmanager.pool.AbstractPool; + +import javax.resource.ResourceException; +import javax.resource.spi.ConnectionRequestInfo; +import javax.resource.spi.ManagedConnectionFactory; +import javax.security.auth.Subject; + +import org.jboss.logging.Logger; + +/** + * Pool implementation that uses subject and connection + * request info for its pool partition. + * + * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +public class PoolBySubjectAndCri extends AbstractPool +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, PoolBySubjectAndCri.class.getName()); + + /** + * Creates a new instance. + * @param mcf managed connection factory + * @param pc pool configuration + * @param noTxSeparatePools notx seperate pool + * @param sharable Are the connections sharable + * @param mcp mcp + */ + public PoolBySubjectAndCri(final ManagedConnectionFactory mcf, final PoolConfiguration pc, + final boolean noTxSeparatePools, final boolean sharable, + final String mcp) + { + super(mcf, pc, noTxSeparatePools, sharable, mcp); + } + + /** + * {@inheritDoc} + */ + @Override + protected Object getKey(Subject subject, ConnectionRequestInfo cri, boolean separateNoTx) throws ResourceException + { + return new SubjectCriKey(subject, cri, separateNoTx); + } + + /** + * {@inheritDoc} + */ + public boolean testConnection() + { + return false; + } + + /** + * {@inheritDoc} + */ + public boolean testConnection(ConnectionRequestInfo cri, Subject subject) + { + return internalTestConnection(cri, subject); + } + + /** + * {@inheritDoc} + */ + public CoreLogger getLogger() + { + return log; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/ReauthKey.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/ReauthKey.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/ReauthKey.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,76 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.strategy; + +import javax.resource.spi.ConnectionRequestInfo; +import javax.security.auth.Subject; + +/** + * Simple reauth pool with same properties as an OnePool + * @author Jesper Pedersen + */ +class ReauthKey +{ + /** The cached hashCode */ + private int hashCode = Integer.MAX_VALUE; + + /** + * Constructor + * @param subject subject instance + * @param cri connection request info + * @param separateNoTx seperateNoTx + */ + ReauthKey(Subject subject, ConnectionRequestInfo cri, boolean separateNoTx) + { + this.hashCode = separateNoTx ? Boolean.TRUE.hashCode() : Boolean.FALSE.hashCode(); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() + { + return hashCode; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + + if (obj == null || !(obj instanceof ReauthKey)) + { + return false; + } + + ReauthKey other = (ReauthKey)obj; + return hashCode == other.hashCode; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/ReauthPool.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/ReauthPool.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/ReauthPool.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,110 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.strategy; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration; +import org.jboss.jca.core.connectionmanager.pool.AbstractPool; +import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool; + +import javax.resource.ResourceException; +import javax.resource.spi.ConnectionRequestInfo; +import javax.resource.spi.ManagedConnectionFactory; +import javax.security.auth.Subject; + +import org.jboss.logging.Logger; + +/** + * Pool implementation that supports reauthentication + * + * @author Jesper Pedersen + */ +public class ReauthPool extends AbstractPool +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, ReauthPool.class.getName()); + + /** + * Creates a new instance. + * @param mcf managed connection factory + * @param pc pool configuration + * @param noTxSeparatePools notx seperate pool + * @param sharable Are the connections sharable + * @param mcp mcp + */ + public ReauthPool(final ManagedConnectionFactory mcf, + final PoolConfiguration pc, + final boolean noTxSeparatePools, + final boolean sharable, + final String mcp) + { + super(mcf, pc, noTxSeparatePools, sharable, mcp); + } + + /** + * {@inheritDoc} + */ + @Override + protected synchronized Object getKey(Subject subject, ConnectionRequestInfo cri, boolean separateNoTx) + throws ResourceException + { + return new ReauthKey(subject, cri, separateNoTx); + } + + /** + * There is no reason to empty the managed connection pool for reauth enabled + * resource adapters, since all managed connections can change + * its credentials + * + * @param pool the managed connection pool + */ + @Override + public void emptyManagedConnectionPool(ManagedConnectionPool pool) + { + // No-operation + } + + /** + * {@inheritDoc} + */ + public boolean testConnection() + { + return false; + } + + /** + * {@inheritDoc} + */ + public boolean testConnection(ConnectionRequestInfo cri, Subject subject) + { + return internalTestConnection(cri, subject); + } + + /** + * {@inheritDoc} + */ + public CoreLogger getLogger() + { + return log; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,85 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.strategy; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +import javax.security.auth.Subject; + +/** + * Privileged Blocks + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Constructor + */ + private SecurityActions() + { + } + + /** + * Get the hash code for a Subject + * @param subject The Subject + * @return The hash code + */ + static int hashCode(final Subject subject) + { + if (System.getSecurityManager() == null) + return subject.hashCode(); + + Integer hashCode = AccessController.doPrivileged(new PrivilegedAction() + { + public Integer run() + { + return subject.hashCode(); + } + }); + + return hashCode.intValue(); + } + + /** + * Verify if two Subject's are equal + * @param s1 The first Subject + * @param s2 The second Subject + * @return True if equal; otherwise false + */ + static boolean equals(final Subject s1, final Subject s2) + { + if (System.getSecurityManager() == null) + return s1 != null ? s1.equals(s2) : s2 == null; + + Boolean equals = AccessController.doPrivileged(new PrivilegedAction() + { + public Boolean run() + { + return s1 != null ? s1.equals(s2) : s2 == null; + } + }); + + return equals.booleanValue(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SubjectCriKey.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SubjectCriKey.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SubjectCriKey.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,108 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.strategy; + +import javax.resource.spi.ConnectionRequestInfo; +import javax.security.auth.Subject; + +/** + * Pool key based on {@link Subject} and {@link ConnectionRequestInfo}. + * + * @author Gurkan Erdogdu + * @author David Jencks + * @author Adrian Brock + * @author Weston Price + * @author Jesper Pedersen + * @version $Rev: $ + */ +class SubjectCriKey +{ + /** Identifies no subject */ + private static final Subject NOSUBJECT = new Subject(); + + /** Identifies no connection request information */ + private static final Object NOCRI = new Object(); + + /** The subject */ + private final Subject subject; + + /** The connection request information */ + private final Object cri; + + /** The cached hashCode */ + private int hashCode = Integer.MAX_VALUE; + + /** Separate no tx */ + private boolean separateNoTx; + + /** + * + * @param subject subject instance + * @param cri connection request info + * @param separateNoTx seperateNoTx + */ + SubjectCriKey(Subject subject, ConnectionRequestInfo cri, boolean separateNoTx) + { + this.subject = (subject == null) ? NOSUBJECT : subject; + this.cri = (cri == null) ? NOCRI : cri; + this.separateNoTx = separateNoTx; + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() + { + if (hashCode == Integer.MAX_VALUE) + { + hashCode = SecurityActions.hashCode(subject) ^ cri.hashCode(); + } + + return hashCode; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + + if (obj == null || !(obj instanceof SubjectCriKey)) + { + return false; + } + + SubjectCriKey other = (SubjectCriKey) obj; + + return SecurityActions.equals(subject, other.subject) + && cri.equals(other.cri) + && separateNoTx == other.separateNoTx; + } + +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SubjectKey.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SubjectKey.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SubjectKey.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,90 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.strategy; + +import javax.security.auth.Subject; + +/** + * Pool by {@link Subject} key. + * + * @author Gurkan Erdogdu + * @version $Rev: $ + */ +class SubjectKey +{ + /** Identifies no subject */ + private static final Subject NOSUBJECT = new Subject(); + + /** The subject */ + private final Subject subject; + + /** Separate no tx */ + private boolean separateNoTx; + + /** The cached hashCode */ + private int hashCode = Integer.MAX_VALUE; + + /** + * Creates a new instance. + * @param subject subject + * @param separateNoTx separateNoTx + */ + SubjectKey(Subject subject, boolean separateNoTx) + { + this.subject = (subject == null) ? NOSUBJECT : subject; + this.separateNoTx = separateNoTx; + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() + { + if (hashCode == Integer.MAX_VALUE) + hashCode = SecurityActions.hashCode(subject); + + return hashCode; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null || !(obj instanceof SubjectKey)) + { + return false; + } + SubjectKey other = (SubjectKey) obj; + + return SecurityActions.equals(subject, other.subject) + && separateNoTx == other.separateNoTx; + } + +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the connection pool strategies. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/ConnectionValidator.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/ConnectionValidator.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/ConnectionValidator.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,308 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.validator; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool; + +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.jboss.logging.Logger; + +/** + * Connection validator + * + * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +public class ConnectionValidator +{ + /** Logger instance */ + private static CoreLogger logger = Logger.getMessageLogger(CoreLogger.class, ConnectionValidator.class.getName()); + + /** Thread name */ + private static final String THREAD_NAME = "ConnectionValidator"; + + /** Singleton instance */ + private static ConnectionValidator instance = new ConnectionValidator(); + + /** Registered pool instances */ + private CopyOnWriteArrayList registeredPools = + new CopyOnWriteArrayList(); + + /** Executor service */ + private ExecutorService executorService; + + /** Is the executor external */ + private boolean isExternal; + + /** The interval */ + private long interval; + + /** The next scan */ + private long next; + + /** Shutdown */ + private AtomicBoolean shutdown; + + /** Lock */ + private Lock lock; + + /** Condition */ + private Condition condition; + + /** + * Private constructor. + */ + private ConnectionValidator() + { + this.executorService = null; + this.isExternal = false; + this.interval = Long.MAX_VALUE; + this.next = Long.MAX_VALUE; + this.shutdown = new AtomicBoolean(false); + this.lock = new ReentrantLock(true); + this.condition = lock.newCondition(); + } + + /** + * Get the instance + * @return The value + */ + public static ConnectionValidator getInstance() + { + return instance; + } + + /** + * Set the executor service + * @param v The value + */ + public void setExecutorService(ExecutorService v) + { + if (v != null) + { + this.executorService = v; + this.isExternal = true; + } + else + { + this.executorService = null; + this.isExternal = false; + } + } + + /** + * Start + * @exception Throwable Thrown if an error occurs + */ + public void start() throws Throwable + { + if (!isExternal) + { + this.executorService = Executors.newSingleThreadExecutor(new ValidatorThreadFactory()); + } + + this.shutdown.set(false); + this.interval = Long.MAX_VALUE; + this.next = Long.MAX_VALUE; + + this.executorService.execute(new ConnectionValidatorRunner()); + } + + /** + * Stop + * @exception Throwable Thrown if an error occurs + */ + public void stop() throws Throwable + { + instance.shutdown.set(true); + + if (!isExternal) + { + instance.executorService.shutdownNow(); + instance.executorService = null; + } + + instance.registeredPools.clear(); + } + + /** + * Register pool for connection validation. + * @param mcp managed connection pool + * @param interval validation interval + */ + public void registerPool(ManagedConnectionPool mcp, long interval) + { + logger.debugf("Register pool: %s (interval=%s)", mcp, interval); + + instance.internalRegisterPool(mcp, interval); + } + + /** + * Unregister pool instance for connection validation. + * @param mcp pool instance + */ + public void unregisterPool(ManagedConnectionPool mcp) + { + logger.debugf("Unregister pool: %s", mcp); + + instance.internalUnregisterPool(mcp); + } + + private void internalRegisterPool(ManagedConnectionPool mcp, long interval) + { + try + { + this.lock.lock(); + + this.registeredPools.addIfAbsent(mcp); + + if (interval > 1 && interval / 2 < this.interval) + { + this.interval = interval / 2; + long maybeNext = System.currentTimeMillis() + this.interval; + if (next > maybeNext && maybeNext > 0) + { + next = maybeNext; + if (logger.isDebugEnabled()) + { + logger.debug("About to notify thread: old next: " + next + ", new next: " + maybeNext); + } + + this.condition.signal(); + } + } + } + finally + { + this.lock.unlock(); + } + } + + private void internalUnregisterPool(ManagedConnectionPool mcp) + { + this.registeredPools.remove(mcp); + + if (this.registeredPools.size() == 0) + { + if (logger.isDebugEnabled()) + { + logger.debug("Setting interval to Long.MAX_VALUE"); + } + + interval = Long.MAX_VALUE; + } + } + + /** + * Thread factory. + */ + private static class ValidatorThreadFactory implements ThreadFactory + { + /** + * {@inheritDoc} + */ + public Thread newThread(Runnable r) + { + Thread thread = new Thread(r, ConnectionValidator.THREAD_NAME); + thread.setDaemon(true); + + return thread; + } + } + + /** + * ConnectionValidatorRunner. + * + */ + private class ConnectionValidatorRunner implements Runnable + { + /** + * {@inheritDoc} + */ + public void run() + { + final ClassLoader oldTccl = SecurityActions.getThreadContextClassLoader(); + SecurityActions.setThreadContextClassLoader(ConnectionValidator.class.getClassLoader()); + + try + { + lock.lock(); + + while (!shutdown.get()) + { + boolean result = instance.condition.await(instance.interval, TimeUnit.MILLISECONDS); + + if (logger.isTraceEnabled()) + { + logger.trace("Result of await: " + result); + } + + if (logger.isDebugEnabled()) + { + logger.debug("Notifying pools, interval: " + interval); + } + + for (ManagedConnectionPool mcp : registeredPools) + { + mcp.validateConnections(); + } + + next = System.currentTimeMillis() + interval; + + if (next < 0) + { + next = Long.MAX_VALUE; + } + } + } + catch (InterruptedException e) + { + if (!shutdown.get()) + logger.returningConnectionValidatorInterrupted(); + } + catch (RuntimeException e) + { + logger.connectionValidatorIgnoredUnexpectedRuntimeException(e); + } + catch (Exception e) + { + logger.connectionValidatorIgnoredUnexpectedError(e); + } + finally + { + lock.unlock(); + SecurityActions.setThreadContextClassLoader(oldTccl); + } + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,83 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.pool.validator; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Get the context classloader. + * @return The classloader + */ + public static ClassLoader getThreadContextClassLoader() + { + if (System.getSecurityManager() == null) + { + return Thread.currentThread().getContextClassLoader(); + } + else + { + return AccessController.doPrivileged(new PrivilegedAction() + { + public ClassLoader run() + { + return Thread.currentThread().getContextClassLoader(); + } + }); + } + } + + /** + * Set the context classloader. + * @param cl classloader + */ + public static void setThreadContextClassLoader(final ClassLoader cl) + { + if (cl == null) + return; + + if (System.getSecurityManager() == null) + { + Thread.currentThread().setContextClassLoader(cl); + } + else + { + AccessController.doPrivileged(new PrivilegedAction() + { + public Object run() + { + Thread.currentThread().setContextClassLoader(cl); + + return null; + } + }); + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the connection validator logic. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/transaction/LockKey.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/transaction/LockKey.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/transaction/LockKey.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,65 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.transaction; + +/** + * Defines the lock key + * + * @author Jesper Pedersen + */ +public class LockKey +{ + /** Instance */ + public static final LockKey INSTANCE = new LockKey(); + + /** + * Constructor + */ + private LockKey() + { + } + + /** + * Equals + * @param other The other object + * @return True if equal; otherwise false + */ + public boolean equals(Object other) + { + if (this == other) + return true; + + if (other == null || !(other instanceof LockKey)) + return false; + + return true; + } + + /** + * Hash code + * @return The value + */ + public int hashCode() + { + return 42; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/transaction/TransactionSynchronizer.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/transaction/TransactionSynchronizer.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/transaction/TransactionSynchronizer.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,501 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2006, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.transaction; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.transaction.TransactionIntegration; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import javax.transaction.RollbackException; +import javax.transaction.Synchronization; +import javax.transaction.SystemException; +import javax.transaction.Transaction; + +import org.jboss.logging.Logger; + +/** + * Organizes transaction synchronization done by JCA. + * + *

+ * This class exists to make sure all Tx synchronizations + * are invoked before the cached connection manager closes any + * closed connections. + * + * @author Adrian Brock + * @author gurkanerdogdu + * @version $Rev$ + */ +public class TransactionSynchronizer implements Synchronization +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, TransactionSynchronizer.class.getName()); + + /** The records */ + private static ConcurrentMap records = + new ConcurrentHashMap(512, 0.75f, 512); + + /** The transaction */ + private Transaction tx; + + /** The identifier */ + private Object identifier; + + /** The enlisting thread */ + private Thread enlistingThread; + + /** Unenlisted */ + private List unenlisted; + + /** Enlisted */ + private List enlisted; + + /** The cached connection manager synchronization */ + private Synchronization ccmSynch; + + /** + * Create a new transaction synchronizer + * + * @param tx the transaction to synchronize with + * @param id the identifier for the transaction + */ + private TransactionSynchronizer(Transaction tx, Object id) + { + this.tx = tx; + this.identifier = id; + this.enlistingThread = null; + this.unenlisted = new ArrayList(1); + this.enlisted = new ArrayList(1); + } + + /** + * Add a new Tx synchronization that has not been enlisted + * + * @param synch the synchronization + */ + public synchronized void addUnenlisted(Synchronization synch) + { + if (unenlisted == null) + unenlisted = new ArrayList(1); + + unenlisted.add(synch); + } + + /** + * Get the unenlisted synchronizations + * and say we are enlisting if some are returned. + * + * @return the unenlisted synchronizations + */ + public synchronized List getUnenlisted() + { + Thread currentThread = Thread.currentThread(); + + while (enlistingThread != null && enlistingThread != currentThread) + { + boolean interrupted = false; + try + { + wait(); + } + catch (InterruptedException e) + { + interrupted = true; + } + if (interrupted) + currentThread.interrupt(); + } + + List result = unenlisted; + unenlisted = null; + + if (result != null) + { + enlistingThread = currentThread; + } + + return result; + } + + /** + * The synchronization is now enlisted + * + * @param synch the synchronization + */ + public synchronized void addEnlisted(Synchronization synch) + { + enlisted.add(synch); + } + + /** + * Remove an enlisted synchronization + * + * @param synch the synchronization + * @return true when the synchronization was enlisted + */ + public synchronized boolean removeEnlisted(Synchronization synch) + { + return enlisted.remove(synch); + } + + /** + * This thread has finished enlisting. + */ + public synchronized void enlisted() + { + Thread currentThread = Thread.currentThread(); + + if (enlistingThread == null || enlistingThread != currentThread) + { + log.threadIsnotEnlistingThread(currentThread, enlistingThread, + new Exception("STACKTRACE")); + return; + } + + enlistingThread = null; + notifyAll(); + } + + /** + * Get a registered transaction synchronizer. + * + * @param tx the transaction + * @param ti the transaction integration + * @throws SystemException sys. exception + * @throws RollbackException rollback exception + * @return the registered transaction synchronizer for this transaction + */ + public static TransactionSynchronizer getRegisteredSynchronizer(Transaction tx, + TransactionIntegration ti) + throws SystemException, RollbackException + { + Object id = ti.getIdentifier(tx); + Record record = records.get(id); + if (record == null) + { + Record newRecord = new Record(new ReentrantLock(true), new TransactionSynchronizer(tx, id)); + record = records.putIfAbsent(id, newRecord); + if (record == null) + { + record = newRecord; + + if (log.isTraceEnabled()) + log.tracef("Adding: %s [%s]", System.identityHashCode(id), id.toString()); + + try + { + if (ti.getTransactionSynchronizationRegistry() != null) + { + ti.getTransactionSynchronizationRegistry(). + registerInterposedSynchronization(record.getTransactionSynchronizer()); + } + else + { + tx.registerSynchronization(record.getTransactionSynchronizer()); + } + } + catch (Throwable t) + { + records.remove(id); + + if (t instanceof SystemException) + { + throw (SystemException)t; + } + else if (t instanceof RollbackException) + { + throw (RollbackException)t; + } + else + { + SystemException se = new SystemException(t.getMessage()); + se.initCause(t); + throw se; + } + } + } + } + return record.getTransactionSynchronizer(); + } + + /** + * Check whether we have a CCM synchronization + * + * @param tx the transaction + * @param ti the transaction integration + * @return synch + */ + public static Synchronization getCCMSynchronization(Transaction tx, TransactionIntegration ti) + { + Record record = records.get(ti.getIdentifier(tx)); + if (record != null) + return record.getTransactionSynchronizer().ccmSynch; + + return null; + } + + /** + * Register a new CCM synchronization + * + * @param tx the transaction + * @param synch the synchronization + * @param ti the transaction integration + * @throws Exception e + */ + public static void registerCCMSynchronization(Transaction tx, + Synchronization synch, + TransactionIntegration ti) + throws Exception + { + TransactionSynchronizer ts = getRegisteredSynchronizer(tx, ti); + ts.ccmSynch = synch; + } + + /** + * Lock for the given transaction + * + * @param tx the transaction + * @param ti the transaction integration + * @throws SystemException sys. exception + * @throws RollbackException rollback exception + */ + public static void lock(Transaction tx, TransactionIntegration ti) + throws SystemException, RollbackException + { + Object id = ti.getIdentifier(tx); + Record record = records.get(id); + if (record == null) + { + Record newRecord = new Record(new ReentrantLock(true), new TransactionSynchronizer(tx, id)); + record = records.putIfAbsent(id, newRecord); + if (record == null) + { + record = newRecord; + + if (log.isTraceEnabled()) + log.tracef("Adding: %s [%s]", System.identityHashCode(id), id.toString()); + + try + { + if (ti.getTransactionSynchronizationRegistry() != null) + { + ti.getTransactionSynchronizationRegistry(). + registerInterposedSynchronization(record.getTransactionSynchronizer()); + } + else + { + tx.registerSynchronization(record.getTransactionSynchronizer()); + } + } + catch (Throwable t) + { + records.remove(id); + + if (t instanceof SystemException) + { + throw (SystemException)t; + } + else if (t instanceof RollbackException) + { + throw (RollbackException)t; + } + else + { + SystemException se = new SystemException(t.getMessage()); + se.initCause(t); + throw se; + } + } + } + } + + Lock lock = record.getLock(); + + try + { + lock.lockInterruptibly(); + } + catch (InterruptedException e) + { + throw new RuntimeException("Unable to get synchronization", e); + } + } + + /** + * Unlock for the given transaction + * + * @param tx the transaction + * @param ti the transaction integration + */ + public static void unlock(Transaction tx, TransactionIntegration ti) + { + Record record = records.get(ti.getIdentifier(tx)); + + if (record != null) + record.getLock().unlock(); + } + + /** + * {@inheritDoc} + */ + public void beforeCompletion() + { + if (ccmSynch != null) + { + invokeBefore(ccmSynch); + } + + for (Synchronization synch : enlisted) + { + invokeBefore(synch); + } + } + + /** + * {@inheritDoc} + */ + public void afterCompletion(int status) + { + if (ccmSynch != null) + { + invokeAfter(ccmSynch, status); + } + + for (Synchronization synch : enlisted) + { + invokeAfter(synch, status); + } + + // Cleanup the maps + if (records.remove(identifier) == null) + { + // The identifier wasn't stable - scan for it + Object altKey = null; + Iterator> iterator = records.entrySet().iterator(); + while (altKey == null && iterator.hasNext()) + { + Map.Entry next = iterator.next(); + if (next.getValue().getTransactionSynchronizer().equals(this)) + { + altKey = next.getKey(); + } + } + + if (altKey != null) + { + records.remove(altKey); + + if (log.isTraceEnabled()) + log.tracef("Removed: %s [%s]", System.identityHashCode(identifier), identifier.toString()); + } + else + { + log.transactionNotFound(identifier); + } + } + else + { + if (log.isTraceEnabled()) + log.tracef("Removed: %s [%s]", System.identityHashCode(identifier), identifier.toString()); + } + } + + /** + * Invoke a beforeCompletion + * + * @param synch the synchronization + */ + protected void invokeBefore(Synchronization synch) + { + try + { + synch.beforeCompletion(); + } + catch (Throwable t) + { + log.transactionErrorInBeforeCompletion(tx, synch, t); + } + } + + /** + * Invoke an afterCompletion + * + * @param synch the synchronization + * @param status the status of the transaction + */ + protected void invokeAfter(Synchronization synch, int status) + { + try + { + synch.afterCompletion(status); + } + catch (Throwable t) + { + log.transactionErrorInAfterCompletion(tx, synch, t); + } + } + + /** + * A record for a transaction + */ + static class Record + { + private Lock lock; + private TransactionSynchronizer txSync; + + /** + * Constructor + * @param lock The lock + * @param txSync The transaction synchronizer + */ + Record(Lock lock, TransactionSynchronizer txSync) + { + this.lock = lock; + this.txSync = txSync; + } + + /** + * Get the lock + * @return The value + */ + Lock getLock() + { + return lock; + } + + /** + * Get the transaction synchronizer + * @return The synchronizer + */ + TransactionSynchronizer getTransactionSynchronizer() + { + return txSync; + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/transaction/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/transaction/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/transaction/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the transaction related utility implementation. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/tx/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/tx/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/tx/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,50 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.connectionmanager.tx; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Get a system property + * @param name The property name + * @return The property value + */ + static String getSystemProperty(final String name) + { + return AccessController.doPrivileged(new PrivilegedAction() + { + public String run() + { + return System.getProperty(name); + } + }); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/tx/TxConnectionManagerImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/tx/TxConnectionManagerImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/tx/TxConnectionManagerImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,991 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2006, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.connectionmanager.tx; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.connectionmanager.AbstractConnectionManager; +import org.jboss.jca.core.connectionmanager.ConnectionRecord; +import org.jboss.jca.core.connectionmanager.TxConnectionManager; +import org.jboss.jca.core.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.connectionmanager.listener.TxConnectionListener; +import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool; +import org.jboss.jca.core.connectionmanager.transaction.LockKey; +import org.jboss.jca.core.spi.transaction.TransactionIntegration; +import org.jboss.jca.core.spi.transaction.TransactionTimeoutConfiguration; +import org.jboss.jca.core.spi.transaction.TxUtils; +import org.jboss.jca.core.spi.transaction.XAResourceStatistics; +import org.jboss.jca.core.tx.jbossts.XAResourceWrapperStatImpl; +import org.wildfly.transaction.client.AbstractTransaction; +import org.wildfly.transaction.client.ContextTransactionManager; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import javax.resource.ResourceException; +import javax.resource.spi.ConnectionRequestInfo; +import javax.resource.spi.DissociatableManagedConnection; +import javax.resource.spi.LazyEnlistableManagedConnection; +import javax.resource.spi.ManagedConnection; +import javax.security.auth.Subject; +import javax.transaction.RollbackException; +import javax.transaction.SystemException; +import javax.transaction.Transaction; +import javax.transaction.TransactionManager; +import javax.transaction.TransactionSynchronizationRegistry; +import javax.transaction.xa.XAException; +import javax.transaction.xa.XAResource; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * The TxConnectionManager is a JBoss ConnectionManager + * implementation for JCA adapters implementing LocalTransaction and XAResource support. + * + * It implements a ConnectionEventListener that implements XAResource to + * manage transactions through the Transaction Manager. To assure that all + * work in a local transaction occurs over the same ManagedConnection, it + * includes a xid to ManagedConnection map. When a Connection is requested + * or a transaction started with a connection handle in use, it checks to + * see if a ManagedConnection already exists enrolled in the global + * transaction and uses it if found. Otherwise a free ManagedConnection + * has its LocalTransaction started and is used. From the + * BaseConnectionManager2, it includes functionality to obtain managed + * connections from + * a ManagedConnectionPool mbean, find the Subject from a SubjectSecurityDomain, + * and interact with the CachedConnectionManager for connections held over + * transaction and method boundaries. Important mbean references are to a + * ManagedConnectionPool supplier (typically a JBossManagedConnectionPool), and a + * RARDeployment representing the ManagedConnectionFactory. + * + * This connection manager has to perform the following operations: + * + * 1. When an application component requests a new ConnectionHandle, + * it must find a ManagedConnection, and make sure a + * ConnectionEventListener is registered. It must inform the + * CachedConnectionManager that a connection handle has been given + * out. It needs to count the number of handles for each + * ManagedConnection. If there is a current transaction, it must + * enlist the ManagedConnection's LocalTransaction in the transaction + * using the ConnectionEventListeners XAResource XAResource implementation. + * Entry point: ConnectionManager.allocateConnection. + * written. + * + * 2. When a ConnectionClosed event is received from the + * ConnectionEventListener, it must reduce the handle count. If + * the handle count is zero, the XAResource should be delisted from + * the Transaction, if any. The CachedConnectionManager must be + * notified that the connection is closed. + * Entry point: ConnectionEventListener.ConnectionClosed. + * written + * + *3. When a transaction begun notification is received from the + * UserTransaction (via the CachedConnectionManager, all + * managedConnections associated with the current object must be + * enlisted in the transaction. + * Entry point: (from + * CachedConnectionManager) + * ConnectionCacheListener.transactionStarted(Transaction, + * Collection). The collection is of ConnectionRecord objects. + * written. + * + * @author David Jencks + * @author Adrian Brock + * @author Weston Price + * @author Jesper Pedersen + */ +public class TxConnectionManagerImpl extends AbstractConnectionManager implements TxConnectionManager +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, TxConnectionManager.class.getName()); + + /** Serial version uid */ + private static final long serialVersionUID = 1L; + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** Allow marked for rollback */ + private static boolean allowMarkedForRollback = false; + + /** Allow marked for rollback fast fail */ + private static boolean allowMarkedForRollbackFastFail = false; + + /** Transaction manager instance */ + private transient TransactionManager transactionManager; + + /** Transaction synchronization registry */ + private transient TransactionSynchronizationRegistry transactionSynchronizationRegistry; + + /** Transaction integration */ + private TransactionIntegration txIntegration; + + /** Interleaving or not */ + private boolean interleaving; + + /** Local tx or not */ + private boolean localTransactions; + + /** XA resource timeout */ + private int xaResourceTimeout = 0; + + /** Xid pad */ + private boolean padXid; + + /** XA resource wrapped or not */ + private boolean wrapXAResource = true; + + /** Same RM override */ + private Boolean isSameRMOverride; + + static + { + String value = SecurityActions.getSystemProperty("ironjacamar.allow_marked_for_rollback"); + if (value != null && !value.trim().equals("")) + { + try + { + allowMarkedForRollback = Boolean.valueOf(value); + } + catch (Throwable t) + { + // Assume enable + allowMarkedForRollback = true; + } + } + + value = SecurityActions.getSystemProperty("ironjacamar.allow_marked_for_rollback_fast_fail"); + if (value != null && !value.trim().equals("")) + { + try + { + allowMarkedForRollbackFastFail = Boolean.valueOf(value); + } + catch (Throwable t) + { + // Assume enable + allowMarkedForRollbackFastFail = true; + } + } + } + + /** + * Constructor + * @param txIntegration The transaction integration layer + * @param localTransactions Is local transactions enabled + */ + public TxConnectionManagerImpl(final TransactionIntegration txIntegration, + final boolean localTransactions) + { + if (txIntegration == null) + throw new IllegalArgumentException("TransactionIntegration is null"); + + this.transactionManager = txIntegration.getTransactionManager(); + this.transactionSynchronizationRegistry = txIntegration.getTransactionSynchronizationRegistry(); + this.txIntegration = txIntegration; + + setLocalTransactions(localTransactions); + } + + /** + * Get the logger. + * @return The value + */ + protected CoreLogger getLogger() + { + return log; + } + + /** + * Get the transaction integration instance + * @return The transaction integration + */ + public TransactionIntegration getTransactionIntegration() + { + return txIntegration; + } + + /** + * Gets interleaving flag. + * @return interleaving flag + */ + public boolean isInterleaving() + { + return interleaving; + } + + /** + * Sets interleaving flag. + * @param value interleaving + */ + public void setInterleaving(boolean value) + { + interleaving = value; + + if (interleaving) + setSharable(false); + } + + /** + * Returns local tx or not. + * @return local tx or not + */ + public boolean isLocalTransactions() + { + return localTransactions; + } + + /** + * Set the local transaction + * @param v The value + */ + void setLocalTransactions(boolean v) + { + localTransactions = v; + + if (v) + { + setInterleaving(false); + } + } + + /** + * Gets XA resource transaction time out. + * @return xa resource transaction timeout + */ + public int getXAResourceTimeout() + { + return xaResourceTimeout; + } + + /** + * Sets XA resource transaction timeout. + * @param timeout xa resource transaction timeout + */ + public void setXAResourceTimeout(int timeout) + { + xaResourceTimeout = timeout; + } + + /** + * Get the IsSameRMOverride value + * @return The value + */ + public Boolean getIsSameRMOverride() + { + return isSameRMOverride; + } + + /** + * Set the IsSameRMOverride value. + * @param v The value + */ + public void setIsSameRMOverride(Boolean v) + { + isSameRMOverride = v; + } + + /** + * Returns true if wrap xa resource. + * @return true if wrap xa resource + */ + public boolean getWrapXAResource() + { + return wrapXAResource; + } + + /** + * Set if the XAResource should be wrapped + * @param v The value + */ + public void setWrapXAResource(boolean v) + { + wrapXAResource = v; + } + + /** + * Get PadXis status + * @return The value + */ + public boolean getPadXid() + { + return padXid; + } + + /** + * Set if the Xid should be padded + * @param v The value + */ + public void setPadXid(boolean v) + { + padXid = v; + } + + /** + * {@inheritDoc} + */ + public boolean isAllowMarkedForRollback() + { + return allowMarkedForRollback; + } + + /** + * Get the XAResource statistics instance, if supported + * @return The value + */ + private XAResourceStatistics getXAResourceStatistics() + { + if (getPool() != null && getPool().getStatistics() != null && + getPool().getStatistics() instanceof XAResourceStatistics) + { + return (XAResourceStatistics)getPool().getStatistics(); + } + + return null; + } + + /** + * Gets time left. + * @param errorRollback error rollback + * @return time left in ms + * @throws RollbackException if exception + */ + public long getTimeLeftBeforeTransactionTimeout(boolean errorRollback) throws RollbackException + { + if (transactionManager == null) + { + throw new IllegalStateException("No transaction manager: " + getCachedConnectionManager()); + } + + if (transactionManager instanceof TransactionTimeoutConfiguration) + { + return ((TransactionTimeoutConfiguration)transactionManager). + getTimeLeftBeforeTransactionTimeout(errorRollback); + } + + if (transactionManager instanceof ContextTransactionManager) + { + AbstractTransaction transaction = ((ContextTransactionManager) transactionManager).getTransaction(); + if (transaction != null) { + return transaction.getEstimatedRemainingTime() * 1000; + } + } + + return -1; + } + + /** + * {@inheritDoc} + */ + public ConnectionListener getManagedConnection(Subject subject, ConnectionRequestInfo cri) + throws ResourceException + { + Transaction trackByTransaction = null; + try + { + Transaction tx = transactionManager.getTransaction(); + if (tx != null) + { + if (!allowMarkedForRollback) + { + if (!TxUtils.isActive(tx)) + if (!getPool().hasConnection(subject, cri) || allowMarkedForRollbackFastFail) + throw new ResourceException(bundle.transactionNotActive(tx)); + } + else + { + if (!TxUtils.isUncommitted(tx)) + throw new ResourceException(bundle.transactionNotActive(tx)); + } + } + + if (!interleaving) + { + trackByTransaction = tx; + } + } + catch (Throwable t) + { + throw new ResourceException(bundle.errorCheckingForTransaction(), t); + } + + log.tracef("getManagedConnection interleaving=%s , tx=%s", interleaving, trackByTransaction); + + return super.getManagedConnection(trackByTransaction, subject, cri); + } + + /** + * {@inheritDoc} + */ + public void transactionStarted(Collection crs) throws SystemException + { + Set cls = new HashSet(crs.size()); + for (ConnectionRecord cr : crs) + { + ConnectionListener cl = cr.getConnectionListener(); + if (!cls.contains(cl)) + { + cls.add(cl); + if (shouldEnlist(cl.getManagedConnection())) + { + if (!isInterleaving()) + cl.setTrackByTx(true); + + cl.enlist(); + } + + if (!isInterleaving()) + { + cl.setTrackByTx(true); + + ManagedConnectionPool mcp = cl.getManagedConnectionPool(); + Transaction tx = transactionManager.getTransaction(); + + // The lock may need to be initialized if we are in the first lazy enlistment + Lock lock = getLock(); + + if (lock == null) + rethrowAsSystemException("Unable to obtain lock with JCA lazy enlistment scenario", tx, + new SystemException( + "Unable to obtain lock with JCA lazy enlistment scenario")); + + try + { + lock.lockInterruptibly(); + } + catch (Throwable t) + { + rethrowAsSystemException("Unable to begin transaction with JCA lazy enlistment scenario", + tx, t); + } + + try + { + transactionSynchronizationRegistry.putResource(mcp, cl); + } + catch (Throwable t) + { + rethrowAsSystemException("Unable to register JCA lazy enlistment scenario", + tx, new SystemException("Unable to register JCA lazy enlistment scenario")); + } + finally + { + lock.unlock(); + } + } + } + } + } + + /** + * Init lock + * @return The lock + */ + private synchronized Lock initLock() + { + if (transactionSynchronizationRegistry != null && transactionSynchronizationRegistry.getTransactionKey() != null) + { + if (transactionSynchronizationRegistry.getResource(LockKey.INSTANCE) == null) + { + Lock lock = new ReentrantLock(true); + transactionSynchronizationRegistry.putResource(LockKey.INSTANCE, lock); + return lock; + } + else + { + return (Lock)transactionSynchronizationRegistry.getResource(LockKey.INSTANCE); + } + } + + return null; + } + + /** + * Get lock + * @return The lock; null if TX isn't active + */ + private Lock getLock() + { + Lock result = null; + try + { + if (transactionSynchronizationRegistry != null && + transactionSynchronizationRegistry.getTransactionKey() != null) + { + result = (Lock)transactionSynchronizationRegistry.getResource(LockKey.INSTANCE); + if (result == null) + { + result = initLock(); + } + } + } + catch (Throwable t) + { + // Catch all exceptions + } + + return result; + } + + /** + * {@inheritDoc} + */ + protected void managedConnectionReconnected(ConnectionListener cl) throws ResourceException + { + try + { + if (shouldEnlist(cl.getManagedConnection())) + cl.enlist(); + } + catch (Throwable t) + { + if (log.isTraceEnabled()) + log.trace("Could not enlist in transaction on entering meta-aware object! " + cl, t); + + throw new ResourceException(bundle.notEnlistInTransactionOnEnteringMetaAwareObject(), t); + } + } + + /** + * {@inheritDoc} + */ + protected void managedConnectionDisconnected(ConnectionListener cl) throws ResourceException + { + Throwable throwable = null; + try + { + cl.delist(); + } + catch (Throwable t) + { + throwable = t; + } + + //if there are no more handles and tx is complete, we can return to pool. + if (cl.isManagedConnectionFree()) + { + log.tracef("Disconnected isManagedConnectionFree=true cl=%s", cl); + + returnManagedConnection(cl, false); + } + else + { + log.tracef("Disconnected isManagedConnectionFree=false cl=%s", cl); + } + + // Rethrow the error + if (throwable != null) + { + throw new ResourceException(bundle.couldNotDelistResourceThenTransactionRollback(), throwable); + } + } + + /** + * {@inheritDoc} + */ + public ConnectionListener createConnectionListener(ManagedConnection mc, ManagedConnectionPool mcp) + throws ResourceException + { + XAResource xaResource = null; + int explicitXAResourceTimeout = 0; + + if (localTransactions) + { + String eisProductName = null; + String eisProductVersion = null; + + try + { + if (mc.getMetaData() != null) + { + eisProductName = mc.getMetaData().getEISProductName(); + eisProductVersion = mc.getMetaData().getEISProductVersion(); + } + } + catch (ResourceException re) + { + // Ignore + } + + if (eisProductName == null) + eisProductName = getJndiName(); + + if (eisProductVersion == null) + eisProductVersion = getJndiName(); + + if (isConnectable()) + { + if (mc instanceof org.jboss.jca.core.spi.transaction.ConnectableResource) + { + org.jboss.jca.core.spi.transaction.ConnectableResource cr = + (org.jboss.jca.core.spi.transaction.ConnectableResource)mc; + + xaResource = txIntegration.createConnectableLocalXAResource(this, eisProductName, eisProductVersion, + getJndiName(), cr, + getXAResourceStatistics()); + } + else if (txIntegration.isConnectableResource(mc)) + { + xaResource = txIntegration.createConnectableLocalXAResource(this, eisProductName, eisProductVersion, + getJndiName(), mc, + getXAResourceStatistics()); + } + } + + if (xaResource == null) + xaResource = txIntegration.createLocalXAResource(this, eisProductName, eisProductVersion, getJndiName(), + getXAResourceStatistics()); + + if (xaResourceTimeout != 0) + { + log.debugf("XAResource transaction timeout cannot be set for local transactions: %s", getJndiName()); + } + } + else + { + if (wrapXAResource) + { + String eisProductName = null; + String eisProductVersion = null; + + try + { + if (mc.getMetaData() != null) + { + eisProductName = mc.getMetaData().getEISProductName(); + eisProductVersion = mc.getMetaData().getEISProductVersion(); + } + } + catch (ResourceException re) + { + // Ignore + } + + if (eisProductName == null) + eisProductName = getJndiName(); + + if (eisProductVersion == null) + eisProductVersion = getJndiName(); + + if (isConnectable()) + { + if (mc instanceof org.jboss.jca.core.spi.transaction.ConnectableResource) + { + org.jboss.jca.core.spi.transaction.ConnectableResource cr = + (org.jboss.jca.core.spi.transaction.ConnectableResource)mc; + + xaResource = txIntegration.createConnectableXAResourceWrapper(mc.getXAResource(), padXid, + isSameRMOverride, + eisProductName, eisProductVersion, + getJndiName(), + cr, + getXAResourceStatistics()); + } + else if (txIntegration.isConnectableResource(mc)) + { + xaResource = txIntegration.createConnectableXAResourceWrapper(mc.getXAResource(), padXid, + isSameRMOverride, + eisProductName, eisProductVersion, + getJndiName(), + mc, + getXAResourceStatistics()); + } + } + + if (xaResource == null) + { + XAResource xar = mc.getXAResource(); + + if (!(xar instanceof org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper) || + (getXAResourceStatistics() != null && + getXAResourceStatistics().isEnabled() && + !(xar instanceof XAResourceWrapperStatImpl))) + { + if (!(xar instanceof org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper)) + { + xaResource = txIntegration + .createXAResourceWrapper(xar, padXid, isSameRMOverride, eisProductName, eisProductVersion, + getJndiName(), txIntegration.isFirstResource(mc), getXAResourceStatistics()); + } + else + { + xaResource = txIntegration + .createXAResourceWrapper(xar, padXid, isSameRMOverride, eisProductName, eisProductVersion, + ((org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper) xar).getJndiName(), + txIntegration.isFirstResource(mc), getXAResourceStatistics()); + } + } + else + { + xaResource = xar; + } + } + + log.tracef("Generating XAResourceWrapper for TxConnectionManager (%s)", this); + } + else + { + log.trace("Not wrapping XAResource."); + + xaResource = mc.getXAResource(); + } + + if (xaResourceTimeout != 0) + { + try + { + if (xaResource.setTransactionTimeout(xaResourceTimeout)) + { + explicitXAResourceTimeout = xaResourceTimeout; + } + else + { + log.debugf("XAResource does not support transaction timeout configuration: %s", getJndiName()); + } + } + catch (XAException e) + { + throw new ResourceException(bundle.unableSetXAResourceTransactionTimeout(getJndiName()), e); + } + } + } + + ConnectionListener cli = new TxConnectionListener(this, mc, getPool(), mcp, + getFlushStrategy(), getTracking(), + getEnlistmentTrace() == null ? null : getEnlistmentTrace().getEnlistmentTrace(), + xaResource, explicitXAResourceTimeout); + mc.addConnectionEventListener(cli); + return cli; + } + + /** + * {@inheritDoc} + */ + public boolean isTransactional() + { + try + { + return !TxUtils.isCompleted(transactionManager.getTransaction()); + } + catch (SystemException se) + { + throw new RuntimeException("Error during isTransactional()", se); + } + } + + /** + * {@inheritDoc} + */ + public int getTransactionTimeout() throws SystemException + { + throw new RuntimeException("NYI: getTransactionTimeout()"); + } + + /** + * {@inheritDoc} + */ + @Override + public void lazyEnlist(ManagedConnection mc) throws ResourceException + { + if (!isEnlistment()) + throw new ResourceException(bundle.enlistmentNotEnabled()); + + if (mc == null || !(mc instanceof LazyEnlistableManagedConnection)) + throw new ResourceException(bundle.managedConnectionNotLazyEnlistable(mc)); + + ConnectionListener cl = getPool().findConnectionListener(mc); + if (cl != null) + { + if (cl.isEnlisted()) + throw new ResourceException(bundle.connectionListenerAlreadyEnlisted(cl)); + + try + { + if (!isInterleaving()) + { + Lock lock = getLock(); + + if (lock == null) + { + if (!isTransactional()) + { + log.tracef("No transaction, no need to lazy enlist: %s", this); + return; + } + if (cl != null) + { + log.tracef("Killing connection tracked by transaction=%s", cl); + + getPool().returnConnection(cl, true); + } + + throw new ResourceException(bundle.unableObtainLock()); + } + + try + { + lock.lockInterruptibly(); + } + catch (InterruptedException ie) + { + Thread.interrupted(); + + if (cl != null) + { + log.tracef("Killing connection tracked by transaction=%s", cl); + + getPool().returnConnection(cl, true); + } + + throw new ResourceException(bundle.unableObtainLock(), ie); + } + try + { + ConnectionListener existing = + (ConnectionListener)transactionSynchronizationRegistry.getResource(cl.getManagedConnectionPool()); + + if (existing == null) + { + // We are the first ManagedConnection to enlist in this transaction + log.tracef("New connection tracked by transaction=%s", cl); + + // We need to set track-by-transaction before we enlist + cl.setTrackByTx(true); + cl.enlist(); + + transactionSynchronizationRegistry.putResource(cl.getManagedConnectionPool(), cl); + } + else + { + log.tracef("Already an enlisted connection in the pool tracked by transaction=%s (new=%s)", + existing, cl); + + if (cl.supportsLazyAssociation()) + { + // Dissociate if possible, as the reconnect will pick up the track-by-transaction cl + // and we can return this cl to the pool + DissociatableManagedConnection dmc = (DissociatableManagedConnection)cl.getManagedConnection(); + dmc.dissociateConnections(); + + getPool().returnConnection(cl, false); + } + else + { + if (isLocalTransactions()) + log.multipleLocalTransactionConnectionListenerEnlisted(getPool().getName(), cl); + + // Ok, lets enlist and roll the dice + cl.setTrackByTx(true); + cl.enlist(); + } + } + } + catch (Throwable t) + { + if (cl != null) + { + log.tracef("Killing connection tracked by transaction=%s", cl); + + getPool().returnConnection(cl, true); + } + + throw new ResourceException(bundle.unableGetConnectionListener(), t); + } + finally + { + lock.unlock(); + } + } + else + { + // We always enlist interleaved connection listeners + cl.enlist(); + } + } + catch (Throwable t) + { + throw new ResourceException(bundle.errorDuringEnlistment(), t); + } + } + else + { + throw new ResourceException(bundle.unableToFindConnectionListener()); + } + } + + /** + * Should the managed connection be enlisted + * @param mc The managed connection + * @return True if enlist, otherwise false + */ + private boolean shouldEnlist(ManagedConnection mc) + { + if (isEnlistment() && mc instanceof LazyEnlistableManagedConnection) + return false; + + return true; + } + + /** + * RethrowAsSystemException. + * @param context context + * @param tx transaction + * @param t throwable + * @throws SystemException system exception + */ + public static void rethrowAsSystemException(String context, Transaction tx, Throwable t) + throws SystemException + { + if (t instanceof SystemException) + throw (SystemException) t; + + if (t instanceof RuntimeException) + throw (RuntimeException) t; + + if (t instanceof Error) + throw (Error) t; + + if (t instanceof RollbackException) + throw new IllegalStateException(context + " tx=" + tx + " marked for rollback."); + + throw new RuntimeException(context + " tx=" + tx + " got unexpected error ", t); + } + + + private void writeObject(ObjectOutputStream out) + throws IOException + { + } + + + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException + { + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/tx/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/tx/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/tx/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the tx connection manager implementation. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/mdr/SimpleMetadataRepository.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/mdr/SimpleMetadataRepository.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/mdr/SimpleMetadataRepository.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,348 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.mdr; + +import org.jboss.jca.common.api.metadata.resourceadapter.Activation; +import org.jboss.jca.common.api.metadata.spec.Connector; +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.spi.mdr.AlreadyExistsException; +import org.jboss.jca.core.spi.mdr.MetadataRepository; +import org.jboss.jca.core.spi.mdr.NotFoundException; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.jboss.logging.Messages; + +/** + * A simple implementation of the metadata repository + * + * @author Jesper Pedersen + */ +public class SimpleMetadataRepository implements MetadataRepository +{ + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** Resource adapter templates */ + private ConcurrentMap raTemplates; + + /** Resource adapter roots */ + private ConcurrentMap raRoots; + + /** Activation metadata */ + private Map activations; + + /** JNDI mappings */ + private ConcurrentMap>> jndiMappings; + + /** + * Constructor + */ + public SimpleMetadataRepository() + { + this.raTemplates = new ConcurrentHashMap(); + this.raRoots = new ConcurrentHashMap(); + this.activations = Collections.synchronizedMap(new HashMap()); + this.jndiMappings = new ConcurrentHashMap>>(); + } + + /** + * {@inheritDoc} + */ + public void registerResourceAdapter(String uniqueId, File root, Connector md, Activation a) + throws AlreadyExistsException + { + if (uniqueId == null) + throw new IllegalArgumentException("UniqueId is null"); + + if (uniqueId.trim().equals("")) + throw new IllegalArgumentException("UniqueId is empty"); + + if (root == null) + throw new IllegalArgumentException("Root is null"); + + if (md == null) + throw new IllegalArgumentException("Connector is null"); + + // The Activation metadata object can be null + + if (raTemplates.containsKey(uniqueId)) + throw new AlreadyExistsException(bundle.keyNotRegistered(uniqueId)); + + raTemplates.put(uniqueId, md); + raRoots.put(uniqueId, root); + activations.put(uniqueId, a); + } + + /** + * {@inheritDoc} + */ + public void unregisterResourceAdapter(String uniqueId) throws NotFoundException + { + if (uniqueId == null) + throw new IllegalArgumentException("UniqueId is null"); + + if (uniqueId.trim().equals("")) + throw new IllegalArgumentException("UniqueId is empty"); + + if (!raTemplates.containsKey(uniqueId)) + throw new NotFoundException(bundle.keyNotRegistered(uniqueId)); + + raTemplates.remove(uniqueId); + raRoots.remove(uniqueId); + activations.remove(uniqueId); + } + + /** + * {@inheritDoc} + */ + public boolean hasResourceAdapter(String uniqueId) + { + if (uniqueId == null) + throw new IllegalArgumentException("UniqueId is null"); + + if (uniqueId.trim().equals("")) + throw new IllegalArgumentException("UniqueId is empty"); + + return raTemplates.containsKey(uniqueId); + } + + /** + * {@inheritDoc} + */ + public Connector getResourceAdapter(String uniqueId) throws NotFoundException + { + if (uniqueId == null) + throw new IllegalArgumentException("UniqueId is null"); + + if (uniqueId.trim().equals("")) + throw new IllegalArgumentException("UniqueId is empty"); + + if (!raTemplates.containsKey(uniqueId)) + throw new NotFoundException(bundle.keyNotRegistered(uniqueId)); + + Connector md = raTemplates.get(uniqueId); + + // Always return a copy as the caller may make changes to it + return (Connector)md.copy(); + } + + /** + * {@inheritDoc} + */ + public Set getResourceAdapters() + { + return Collections.unmodifiableSet(raTemplates.keySet()); + } + + /** + * {@inheritDoc} + */ + public File getRoot(String uniqueId) throws NotFoundException + { + if (uniqueId == null) + throw new IllegalArgumentException("UniqueId is null"); + + if (uniqueId.trim().equals("")) + throw new IllegalArgumentException("UniqueId is empty"); + + if (!raRoots.containsKey(uniqueId)) + throw new NotFoundException(bundle.keyNotRegistered(uniqueId)); + + return raRoots.get(uniqueId); + } + + /** + * {@inheritDoc} + */ + public Activation getActivation(String uniqueId) throws NotFoundException + { + if (uniqueId == null) + throw new IllegalArgumentException("UniqueId is null"); + + if (uniqueId.trim().equals("")) + throw new IllegalArgumentException("UniqueId is empty"); + + if (!activations.containsKey(uniqueId)) + throw new NotFoundException(bundle.keyNotRegistered(uniqueId)); + + return activations.get(uniqueId); + } + + /** + * {@inheritDoc} + */ + public void registerJndiMapping(String uniqueId, String clz, String jndi) + { + if (uniqueId == null) + throw new IllegalArgumentException("UniqueId is null"); + + if (uniqueId.trim().equals("")) + throw new IllegalArgumentException("UniqueId is empty"); + + if (clz == null) + throw new IllegalArgumentException("Clz is null"); + + if (clz.trim().equals("")) + throw new IllegalArgumentException("Clz is empty"); + + if (jndi == null) + throw new IllegalArgumentException("Jndi is null"); + + if (jndi.trim().equals("")) + throw new IllegalArgumentException("Jndi is empty"); + + Map> mappings = jndiMappings.get(uniqueId); + if (mappings == null) + { + Map> newMappings = Collections.synchronizedMap(new HashMap>(1)); + mappings = jndiMappings.putIfAbsent(uniqueId, newMappings); + + if (mappings == null) + { + mappings = newMappings; + } + } + + List l = mappings.get(clz); + + if (l == null) + l = Collections.synchronizedList(new ArrayList(1)); + + l.add(jndi); + mappings.put(clz, l); + } + + /** + * {@inheritDoc} + */ + public void unregisterJndiMapping(String uniqueId, String clz, String jndi) throws NotFoundException + { + if (uniqueId == null) + throw new IllegalArgumentException("UniqueId is null"); + + if (uniqueId.trim().equals("")) + throw new IllegalArgumentException("Uniqueid is empty"); + + if (clz == null) + throw new IllegalArgumentException("Clz is null"); + + if (clz.trim().equals("")) + throw new IllegalArgumentException("Clz is empty"); + + if (jndi == null) + throw new IllegalArgumentException("Jndi is null"); + + if (jndi.trim().equals("")) + throw new IllegalArgumentException("Jndi is empty"); + + if (!jndiMappings.containsKey(uniqueId)) + throw new NotFoundException(bundle.keyNotRegistered(uniqueId)); + + Map> mappings = jndiMappings.get(uniqueId); + + if (mappings != null) + { + List l = mappings.get(clz); + + if (l != null) + { + l.remove(jndi); + + if (l.size() == 0) + { + mappings.remove(clz); + } + } + + if (mappings.size() == 0) + { + jndiMappings.remove(uniqueId); + } + } + } + + /** + * {@inheritDoc} + */ + public boolean hasJndiMappings(String uniqueId) + { + if (uniqueId == null) + throw new IllegalArgumentException("UniqueId is null"); + + if (uniqueId.trim().equals("")) + throw new IllegalArgumentException("UniqueId is empty"); + + return jndiMappings.containsKey(uniqueId); + } + + /** + * {@inheritDoc} + */ + public Map> getJndiMappings(String uniqueId) throws NotFoundException + { + if (uniqueId == null) + throw new IllegalArgumentException("UniqueId is null"); + + if (uniqueId.trim().equals("")) + throw new IllegalArgumentException("UniqueId is empty"); + + if (!jndiMappings.containsKey(uniqueId)) + throw new NotFoundException(bundle.keyNotRegistered(uniqueId)); + + Map> mappings = jndiMappings.get(uniqueId); + + if (mappings == null) + return Collections.unmodifiableMap(new HashMap>(0)); + + return Collections.unmodifiableMap(mappings); + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("SimpleMetadataRepository@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("["); + sb.append(" raTemplates=").append(raTemplates); + sb.append(" raRoots=").append(raRoots); + sb.append(" activations=").append(activations); + sb.append(" jndiMappings=").append(jndiMappings); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/mdr/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/mdr/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/mdr/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the metadata repository implementation. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/ExplicitJndiStrategy.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/ExplicitJndiStrategy.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/ExplicitJndiStrategy.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,425 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.naming; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.naming.JndiStrategy; + +import java.util.Hashtable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.Name; +import javax.naming.NamingException; +import javax.naming.Reference; +import javax.naming.StringRefAddr; +import javax.resource.Referenceable; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * An explicit JNDI strategy that requires a JNDI for each connection factory + * + * @author Jesper Pedersen + */ +public class ExplicitJndiStrategy implements JndiStrategy +{ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, ExplicitJndiStrategy.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + private static ConcurrentMap objs = new ConcurrentHashMap(); + + /** + * Constructor + */ + public ExplicitJndiStrategy() + { + } + + /** + * Obtain the connection factory + * {@inheritDoc} + */ + public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) + throws Exception + { + Reference ref = (Reference)obj; + String className = (String)ref.get("class").getContent(); + String cfname = (String)ref.get("name").getContent(); + + return objs.get(qualifiedName(cfname, className)); + } + + /** + * {@inheritDoc} + */ + public String[] bindConnectionFactories(String deployment, Object[] cfs) throws Throwable + { + throw new IllegalStateException("JNDI names are required"); + } + + /** + * {@inheritDoc} + */ + public String[] bindConnectionFactories(String deployment, Object[] cfs, String[] jndis) throws Throwable + { + if (deployment == null) + throw new IllegalArgumentException("Deployment is null"); + + if (deployment.trim().equals("")) + throw new IllegalArgumentException("Deployment is empty"); + + if (cfs == null) + throw new IllegalArgumentException("CFS is null"); + + if (cfs.length == 0) + throw new IllegalArgumentException("CFS is empty"); + + if (jndis == null) + throw new IllegalArgumentException("JNDIs is null"); + + if (jndis.length == 0) + throw new IllegalArgumentException("JNDIs is empty"); + + if (cfs.length != jndis.length) + throw new IllegalArgumentException("Number of connection factories doesn't match number of JNDI names"); + + Context context = new InitialContext(); + try + { + for (int i = 0; i < cfs.length; i++) + { + String jndiName = jndis[i]; + Object cf = cfs[i]; + + if (log.isTraceEnabled()) + log.tracef("Binding %s under %s", cf.getClass().getName(), jndiName); + + if (cf == null) + throw new IllegalArgumentException("Connection factory is null"); + + if (jndiName == null) + throw new IllegalArgumentException("JNDI name is null"); + + String className = cf.getClass().getName(); + Reference ref = new Reference(className, + new StringRefAddr("class", className), + ExplicitJndiStrategy.class.getName(), + null); + ref.add(new StringRefAddr("name", jndiName)); + + if (objs.putIfAbsent(qualifiedName(jndiName, className), cf) != null) + throw new Exception(bundle.deploymentFailedSinceJndiNameHasDeployed(className, jndiName)); + + Referenceable referenceable = (Referenceable)cf; + referenceable.setReference(ref); + + Util.bind(context, jndiName, cf); + + if (log.isDebugEnabled()) + log.debug("Bound " + cf.getClass().getName() + " under " + jndiName); + } + } + finally + { + if (context != null) + { + try + { + context.close(); + } + catch (NamingException ne) + { + // Ignore + } + } + } + + return jndis; + } + + /** + * {@inheritDoc} + */ + public void unbindConnectionFactories(String deployment, Object[] cfs) throws Throwable + { + throw new IllegalStateException("JNDI names are required"); + } + + /** + * {@inheritDoc} + */ + public void unbindConnectionFactories(String deployment, Object[] cfs, String[] jndis) throws Throwable + { + if (cfs == null) + throw new IllegalArgumentException("CFS is null"); + + if (cfs.length == 0) + throw new IllegalArgumentException("CFS is empty"); + + if (jndis == null) + throw new IllegalArgumentException("JNDIs is null"); + + if (jndis.length == 0) + throw new IllegalArgumentException("JNDIs is empty"); + + if (cfs.length != jndis.length) + throw new IllegalArgumentException("Number of connection factories doesn't match number of JNDI names"); + + Context context = null; + try + { + context = new InitialContext(); + + for (int i = 0; i < cfs.length; i++) + { + String jndiName = jndis[i]; + Object cf = cfs[i]; + + if (cf == null) + throw new IllegalArgumentException("Connection factory is null"); + + if (jndiName == null) + throw new IllegalArgumentException("JNDI name is null"); + + String className = cf.getClass().getName(); + + log.tracef("Unbinding %s under %s", className, jndiName); + + Util.unbind(context, jndiName); + + objs.remove(qualifiedName(jndiName, className)); + + if (log.isDebugEnabled()) + log.debug("Unbound " + className + " under " + jndiName); + } + } + catch (Throwable t) + { + log.exceptionDuringUnbind(t); + } + finally + { + if (context != null) + { + try + { + context.close(); + } + catch (NamingException ne) + { + // Ignore + } + } + } + } + + /** + * {@inheritDoc} + */ + public String[] bindAdminObjects(String deployment, Object[] aos) throws Throwable + { + throw new IllegalStateException("JNDI names are required"); + } + + /** + * {@inheritDoc} + */ + public String[] bindAdminObjects(String deployment, Object[] aos, String[] jndis) throws Throwable + { + if (deployment == null) + throw new IllegalArgumentException("Deployment is null"); + + if (deployment.trim().equals("")) + throw new IllegalArgumentException("Deployment is empty"); + + if (aos == null) + throw new IllegalArgumentException("AOS is null"); + + if (aos.length == 0) + throw new IllegalArgumentException("AOS is empty"); + + if (jndis == null) + throw new IllegalArgumentException("JNDIs is null"); + + if (jndis.length == 0) + throw new IllegalArgumentException("JNDIs is empty"); + + if (aos.length != jndis.length) + throw new IllegalArgumentException("Number of admin objects doesn't match number of JNDI names"); + + Context context = new InitialContext(); + try + { + for (int i = 0; i < aos.length; i++) + { + String jndiName = jndis[i]; + Object ao = aos[i]; + + if (log.isTraceEnabled()) + log.tracef("Binding %s under %s", ao.getClass().getName(), jndiName); + + if (ao == null) + throw new IllegalArgumentException("Admin object is null"); + + if (jndiName == null) + throw new IllegalArgumentException("JNDI name is null"); + + if (ao instanceof Referenceable) + { + String className = ao.getClass().getName(); + Reference ref = new Reference(className, + new StringRefAddr("class", className), + ExplicitJndiStrategy.class.getName(), + null); + ref.add(new StringRefAddr("name", jndiName)); + + if (objs.putIfAbsent(qualifiedName(jndiName, className), ao) != null) + throw new Exception(bundle.deploymentFailedSinceJndiNameHasDeployed(className, jndiName)); + + Referenceable referenceable = (Referenceable)ao; + referenceable.setReference(ref); + } + + Util.bind(context, jndiName, ao); + + if (log.isDebugEnabled()) + log.debug("Bound " + ao.getClass().getName() + " under " + jndiName); + } + } + finally + { + if (context != null) + { + try + { + context.close(); + } + catch (NamingException ne) + { + // Ignore + } + } + } + + return jndis; + } + + /** + * {@inheritDoc} + */ + public void unbindAdminObjects(String deployment, Object[] aos) throws Throwable + { + throw new IllegalStateException("JNDI names are required"); + } + + /** + * {@inheritDoc} + */ + public void unbindAdminObjects(String deployment, Object[] aos, String[] jndis) throws Throwable + { + if (aos == null) + throw new IllegalArgumentException("AOS is null"); + + if (aos.length == 0) + throw new IllegalArgumentException("AOS is empty"); + + if (jndis == null) + throw new IllegalArgumentException("JNDIs is null"); + + if (jndis.length == 0) + throw new IllegalArgumentException("JNDIs is empty"); + + if (aos.length != jndis.length) + throw new IllegalArgumentException("Number of admin objects doesn't match number of JNDI names"); + + Context context = null; + try + { + context = new InitialContext(); + + for (int i = 0; i < aos.length; i++) + { + String jndiName = jndis[i]; + Object ao = aos[i]; + + if (ao == null) + throw new IllegalArgumentException("Admin object is null"); + + if (jndiName == null) + throw new IllegalArgumentException("JNDI name is null"); + + String className = ao.getClass().getName(); + + log.tracef("Unbinding %s under %s", className, jndiName); + + Util.unbind(context, jndiName); + + objs.remove(qualifiedName(jndiName, className)); + + if (log.isDebugEnabled()) + log.debug("Unbound " + className + " under " + jndiName); + } + } + catch (Throwable t) + { + log.exceptionDuringUnbind(t); + } + finally + { + if (context != null) + { + try + { + context.close(); + } + catch (NamingException ne) + { + // Ignore + } + } + } + } + + /** + * Clone the JNDI strategy implementation + * @return A copy of the implementation + * @exception CloneNotSupportedException Thrown if the copy operation isn't supported + * + */ + public JndiStrategy clone() throws CloneNotSupportedException + { + return (JndiStrategy)super.clone(); + } + + private static String qualifiedName(String name, String className) + { + return className + "#" + name; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/JndiBinder.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/JndiBinder.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/JndiBinder.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,182 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.naming; + +import org.jboss.jca.core.CoreLogger; + +import java.util.Hashtable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.Name; +import javax.naming.NamingException; +import javax.naming.Reference; +import javax.naming.StringRefAddr; +import javax.naming.spi.ObjectFactory; + +import org.jboss.logging.Logger; + +/** + * Helper class to create JNDI bindings + * @author Jesper Pedersen + */ +public class JndiBinder implements ObjectFactory +{ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, JndiBinder.class.getName()); + + private static ConcurrentMap objs = new ConcurrentHashMap(); + + private String name; + private Object obj; + + /** + * Constructor + */ + public JndiBinder() + { + } + + /** + * Set the name + * @param v The value + */ + public void setName(String v) + { + this.name = v; + } + + /** + * Set the object + * @param v The value + */ + public void setObject(Object v) + { + this.obj = v; + } + + /** + * Obtain the connection factory + * {@inheritDoc} + */ + public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) + throws Exception + { + Reference ref = (Reference)obj; + String objName = (String)ref.get("name").getContent(); + + return objs.get(objName); + } + + /** + * Bind + * @exception Throwable Thrown in case of an error + */ + public void bind() throws Throwable + { + if (name == null) + throw new IllegalArgumentException("Name is null"); + + if (obj == null) + throw new IllegalArgumentException("Obj is null"); + + if (log.isTraceEnabled()) + log.tracef("Binding %s under %s", obj.getClass().getName(), name); + + Context context = new InitialContext(); + try + { + String className = obj.getClass().getName(); + Reference ref = new Reference(className, + new StringRefAddr("class", className), + JndiBinder.class.getName(), + null); + ref.add(new StringRefAddr("name", name)); + + objs.put(name, obj); + + Util.bind(context, name, ref); + + if (log.isDebugEnabled()) + log.debug("Bound " + obj.getClass().getName() + " under " + name); + } + finally + { + if (context != null) + { + try + { + context.close(); + } + catch (NamingException ne) + { + // Ignore + } + } + } + } + + /** + * Unbind + * @exception Throwable Thrown in case of an error + */ + public void unbind() throws Throwable + { + if (name == null) + throw new IllegalArgumentException("Name is null"); + + log.tracef("Unbinding %s", name); + + Context context = null; + try + { + context = new InitialContext(); + + Util.unbind(context, name); + + objs.remove(name); + + if (log.isDebugEnabled()) + log.debug("Unbound " + name); + } + catch (Throwable t) + { + log.exceptionDuringUnbind(t); + } + finally + { + if (context != null) + { + try + { + context.close(); + } + catch (NamingException ne) + { + // Ignore + } + } + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/NoopJndiStrategy.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/NoopJndiStrategy.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/NoopJndiStrategy.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,126 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.naming; + +import org.jboss.jca.core.spi.naming.JndiStrategy; + +import java.util.Hashtable; + +import javax.naming.Context; +import javax.naming.Name; + +/** + * A noop JNDI strategy + * + * @author Jesper Pedersen + */ +public class NoopJndiStrategy implements JndiStrategy +{ + /** + * Constructor + */ + public NoopJndiStrategy() + { + } + + /** + * Obtain the connection factory + * {@inheritDoc} + */ + public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) + throws Exception + { + return null; + } + + /** + * {@inheritDoc} + */ + public String[] bindConnectionFactories(String deployment, Object[] cfs) throws Throwable + { + return new String[0]; + } + + /** + * {@inheritDoc} + */ + public String[] bindConnectionFactories(String deployment, Object[] cfs, String[] jndis) throws Throwable + { + return new String[0]; + } + + /** + * {@inheritDoc} + */ + public void unbindConnectionFactories(String deployment, Object[] cfs) throws Throwable + { + } + + /** + * {@inheritDoc} + */ + public void unbindConnectionFactories(String deployment, Object[] cfs, String[] jndis) throws Throwable + { + } + + /** + * {@inheritDoc} + */ + public String[] bindAdminObjects(String deployment, Object[] aos) throws Throwable + { + return new String[0]; + } + + /** + * {@inheritDoc} + */ + public String[] bindAdminObjects(String deployment, Object[] aos, String[] jndis) throws Throwable + { + return new String[0]; + } + + /** + * {@inheritDoc} + */ + public void unbindAdminObjects(String deployment, Object[] aos) throws Throwable + { + } + + /** + * {@inheritDoc} + */ + public void unbindAdminObjects(String deployment, Object[] aos, String[] jndis) throws Throwable + { + } + + /** + * Clone the JNDI strategy implementation + * @return A copy of the implementation + * @exception CloneNotSupportedException Thrown if the copy operation isn't supported + * + */ + public JndiStrategy clone() throws CloneNotSupportedException + { + return (JndiStrategy)super.clone(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/SimpleJndiStrategy.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/SimpleJndiStrategy.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/SimpleJndiStrategy.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,448 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.naming; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.naming.JndiStrategy; + +import java.util.Hashtable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.Name; +import javax.naming.NamingException; +import javax.naming.Reference; +import javax.naming.StringRefAddr; +import javax.resource.Referenceable; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * A simple JNDI strategy that bind a single connection factory under the + * name of "java:/eis/<deployment>" by default. + * + * A single admin object is bound under "java:/eis/ao/<deployment>" by default. + * + * @author Jesper Pedersen + */ +public class SimpleJndiStrategy implements JndiStrategy +{ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, SimpleJndiStrategy.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** JNDI prefix for connection factories */ + private static final String CF_JNDI_PREFIX = "java:/eis/"; + + /** JNDI prefix for admin objects */ + private static final String AO_JNDI_PREFIX = "java:/eis/ao/"; + + private static ConcurrentMap objs = new ConcurrentHashMap(); + + /** + * Constructor + */ + public SimpleJndiStrategy() + { + } + + /** + * Obtain the connection factory + * {@inheritDoc} + */ + public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) + throws Exception + { + Reference ref = (Reference)obj; + String className = (String)ref.get("class").getContent(); + String cfname = (String)ref.get("name").getContent(); + + return objs.get(qualifiedName(cfname, className)); + } + + /** + * {@inheritDoc} + */ + public String[] bindConnectionFactories(String deployment, Object[] cfs) throws Throwable + { + String jndiName = CF_JNDI_PREFIX + deployment; + + return bindConnectionFactories(deployment, cfs, new String[] {jndiName}); + } + + /** + * {@inheritDoc} + */ + public String[] bindConnectionFactories(String deployment, Object[] cfs, String[] jndis) throws Throwable + { + if (deployment == null) + throw new IllegalArgumentException("Deployment is null"); + + if (deployment.trim().equals("")) + throw new IllegalArgumentException("Deployment is empty"); + + if (cfs == null) + throw new IllegalArgumentException("CFS is null"); + + if (cfs.length == 0) + throw new IllegalArgumentException("CFS is empty"); + + if (cfs.length > 1) + throw new IllegalArgumentException("SimpleJndiStrategy only support " + + "a single connection factory per deployment"); + if (jndis == null) + throw new IllegalArgumentException("JNDIs is null"); + + if (jndis.length == 0) + throw new IllegalArgumentException("JNDIs is empty"); + + if (jndis.length > 1) + throw new IllegalArgumentException("SimpleJndiStrategy only support " + + "a single JNDI name per deployment"); + + String jndiName = jndis[0]; + Object cf = cfs[0]; + + if (log.isTraceEnabled()) + log.tracef("Binding %s under %s", cf.getClass().getName(), jndiName); + + if (cf == null) + throw new IllegalArgumentException("Connection factory is null"); + + if (jndiName == null) + throw new IllegalArgumentException("JNDI name is null"); + + Context context = new InitialContext(); + try + { + String className = cf.getClass().getName(); + Reference ref = new Reference(className, + new StringRefAddr("class", className), + SimpleJndiStrategy.class.getName(), + null); + ref.add(new StringRefAddr("name", jndiName)); + + if (objs.putIfAbsent(qualifiedName(jndiName, className), cf) != null) + throw new Exception(bundle.deploymentFailedSinceJndiNameHasDeployed(className, jndiName)); + + Referenceable referenceable = (Referenceable)cf; + referenceable.setReference(ref); + + Util.bind(context, jndiName, cf); + + if (log.isDebugEnabled()) + log.debug("Bound " + cf.getClass().getName() + " under " + jndiName); + } + finally + { + if (context != null) + { + try + { + context.close(); + } + catch (NamingException ne) + { + // Ignore + } + } + } + + return new String[] {jndiName}; + } + + /** + * {@inheritDoc} + */ + public void unbindConnectionFactories(String deployment, Object[] cfs) throws Throwable + { + String jndiName = CF_JNDI_PREFIX + deployment; + + unbindConnectionFactories(deployment, cfs, new String[] {jndiName}); + } + + /** + * {@inheritDoc} + */ + public void unbindConnectionFactories(String deployment, Object[] cfs, String[] jndis) throws Throwable + { + if (cfs == null) + throw new IllegalArgumentException("CFS is null"); + + if (cfs.length == 0) + throw new IllegalArgumentException("CFS is empty"); + + if (cfs.length > 1) + throw new IllegalArgumentException("SimpleJndiStrategy only support " + + "a single connection factory per deployment"); + + if (jndis == null) + throw new IllegalArgumentException("JNDIs is null"); + + if (jndis.length == 0) + throw new IllegalArgumentException("JNDIs is empty"); + + if (jndis.length > 1) + throw new IllegalArgumentException("SimpleJndiStrategy only support " + + "a single JNDI name per deployment"); + + String jndiName = jndis[0]; + Object cf = cfs[0]; + + if (cf == null) + throw new IllegalArgumentException("Connection factory is null"); + + if (jndiName == null) + throw new IllegalArgumentException("JNDI name is null"); + + String className = cf.getClass().getName(); + + log.tracef("Unbinding %s under %s", className, jndiName); + + Context context = null; + try + { + context = new InitialContext(); + + Util.unbind(context, jndiName); + + objs.remove(qualifiedName(jndiName, className)); + + if (log.isDebugEnabled()) + log.debug("Unbound " + className + " under " + jndiName); + } + catch (Throwable t) + { + log.exceptionDuringUnbind(t); + } + finally + { + if (context != null) + { + try + { + context.close(); + } + catch (NamingException ne) + { + // Ignore + } + } + } + } + + /** + * {@inheritDoc} + */ + public String[] bindAdminObjects(String deployment, Object[] aos) throws Throwable + { + String jndiName = AO_JNDI_PREFIX + deployment; + + return bindAdminObjects(deployment, aos, new String[] {jndiName}); + } + + /** + * {@inheritDoc} + */ + public String[] bindAdminObjects(String deployment, Object[] aos, String[] jndis) throws Throwable + { + if (deployment == null) + throw new IllegalArgumentException("Deployment is null"); + + if (deployment.trim().equals("")) + throw new IllegalArgumentException("Deployment is empty"); + + if (aos == null) + throw new IllegalArgumentException("AOS is null"); + + if (aos.length == 0) + throw new IllegalArgumentException("AOS is empty"); + + if (aos.length > 1) + throw new IllegalArgumentException("SimpleJndiStrategy only support " + + "a single admin object per deployment"); + if (jndis == null) + throw new IllegalArgumentException("JNDIs is null"); + + if (jndis.length == 0) + throw new IllegalArgumentException("JNDIs is empty"); + + if (jndis.length > 1) + throw new IllegalArgumentException("SimpleJndiStrategy only support " + + "a single JNDI name per deployment"); + + String jndiName = jndis[0]; + Object ao = aos[0]; + + if (log.isTraceEnabled()) + log.tracef("Binding %s under %s", ao.getClass().getName(), jndiName); + + if (ao == null) + throw new IllegalArgumentException("Admin object is null"); + + if (jndiName == null) + throw new IllegalArgumentException("JNDI name is null"); + + Context context = new InitialContext(); + try + { + if (ao instanceof Referenceable) + { + String className = ao.getClass().getName(); + Reference ref = new Reference(className, + new StringRefAddr("class", className), + SimpleJndiStrategy.class.getName(), + null); + ref.add(new StringRefAddr("name", jndiName)); + + if (objs.putIfAbsent(qualifiedName(jndiName, className), ao) != null) + throw new Exception(bundle.deploymentFailedSinceJndiNameHasDeployed(className, jndiName)); + + Referenceable referenceable = (Referenceable)ao; + referenceable.setReference(ref); + } + + Util.bind(context, jndiName, ao); + + if (log.isDebugEnabled()) + log.debug("Bound " + ao.getClass().getName() + " under " + jndiName); + } + finally + { + if (context != null) + { + try + { + context.close(); + } + catch (NamingException ne) + { + // Ignore + } + } + } + + return new String[] {jndiName}; + } + + /** + * {@inheritDoc} + */ + public void unbindAdminObjects(String deployment, Object[] aos) throws Throwable + { + String jndiName = AO_JNDI_PREFIX + deployment; + + unbindAdminObjects(deployment, aos, new String[] {jndiName}); + } + + /** + * {@inheritDoc} + */ + public void unbindAdminObjects(String deployment, Object[] aos, String[] jndis) throws Throwable + { + if (aos == null) + throw new IllegalArgumentException("AOS is null"); + + if (aos.length == 0) + throw new IllegalArgumentException("AOS is empty"); + + if (aos.length > 1) + throw new IllegalArgumentException("SimpleJndiStrategy only support " + + "a single admin object per deployment"); + + if (jndis == null) + throw new IllegalArgumentException("JNDIs is null"); + + if (jndis.length == 0) + throw new IllegalArgumentException("JNDIs is empty"); + + if (jndis.length > 1) + throw new IllegalArgumentException("SimpleJndiStrategy only support " + + "a single JNDI name per deployment"); + + String jndiName = jndis[0]; + Object ao = aos[0]; + + if (ao == null) + throw new IllegalArgumentException("Admin object is null"); + + if (jndiName == null) + throw new IllegalArgumentException("JNDI name is null"); + + String className = ao.getClass().getName(); + + log.tracef("Unbinding %s under %s", className, jndiName); + + Context context = null; + try + { + context = new InitialContext(); + + Util.unbind(context, jndiName); + + objs.remove(qualifiedName(jndiName, className)); + + if (log.isDebugEnabled()) + log.debug("Unbound " + className + " under " + jndiName); + } + catch (Throwable t) + { + log.exceptionDuringUnbind(t); + } + finally + { + if (context != null) + { + try + { + context.close(); + } + catch (NamingException ne) + { + // Ignore + } + } + } + } + + /** + * Clone the JNDI strategy implementation + * @return A copy of the implementation + * @exception CloneNotSupportedException Thrown if the copy operation isn't supported + * + */ + public JndiStrategy clone() throws CloneNotSupportedException + { + return (JndiStrategy)super.clone(); + } + + private static String qualifiedName(String name, String className) + { + return className + "#" + name; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/Util.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/Util.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/Util.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,134 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.naming; + +import javax.naming.Context; +import javax.naming.Name; +import javax.naming.NameNotFoundException; +import javax.naming.NamingException; + +import org.jboss.logging.Logger; + +/** + * A static utility class for common JNDI operations. + * + * @author sstark@redhat.com + * @author abrock@redhat.com + */ +@SuppressWarnings("unchecked") +class Util +{ + private static final Logger log = Logger.getLogger(Util.class); + + /** + * Create a subcontext including any intermediate contexts. + * @param ctx the parent JNDI Context under which value will be bound + * @param name the name relative to ctx of the subcontext. + * @return The new or existing JNDI subcontext + * @throws NamingException on any JNDI failure + */ + private static Context createSubcontext(Context ctx, Name name) throws NamingException + { + Context subctx = ctx; + for (int pos = 0; pos < name.size(); pos++) + { + String ctxName = name.get(pos); + try + { + subctx = (Context) ctx.lookup(ctxName); + } + catch (NameNotFoundException e) + { + subctx = ctx.createSubcontext(ctxName); + } + // The current subctx will be the ctx for the next name component + ctx = subctx; + } + return subctx; + } + + /** + * Bind val to name in ctx, and make sure that all intermediate contexts exist + * @param ctx the parent JNDI Context under which value will be bound + * @param name the name relative to ctx where value will be bound + * @param value the value to bind. + * @throws NamingException for any error + */ + public static void bind(Context ctx, String name, Object value) throws NamingException + { + Name n = ctx.getNameParser("").parse(name); + bind(ctx, n, value); + } + + /** + * Bind val to name in ctx, and make sure that all intermediate contexts exist + * @param ctx the parent JNDI Context under which value will be bound + * @param name the name relative to ctx where value will be bound + * @param value the value to bind. + * @throws NamingException for any error + */ + private static void bind(Context ctx, Name name, Object value) throws NamingException + { + int size = name.size(); + String atom = name.get(size - 1); + Context parentCtx = createSubcontext(ctx, name.getPrefix(size - 1)); + parentCtx.bind(atom, value); + } + + /** + * Unbinds a name from ctx, and removes parents if they are empty + * @param ctx the parent JNDI Context under which the name will be unbound + * @param name The name to unbind + * @throws NamingException for any error + */ + public static void unbind(Context ctx, String name) throws NamingException + { + unbind(ctx, ctx.getNameParser("").parse(name)); + } + + /** + * Unbinds a name from ctx, and removes parents if they are empty + * @param ctx the parent JNDI Context under which the name will be unbound + * @param name The name to unbind + * @throws NamingException for any error + */ + private static void unbind(Context ctx, Name name) throws NamingException + { + ctx.unbind(name); //unbind the end node in the name + int sz = name.size(); + // walk the tree backwards, stopping at the domain + while (--sz > 0) + { + Name pname = name.getPrefix(sz); + try + { + ctx.destroySubcontext(pname); + } + catch (NamingException e) + { + log.tracef("Unable to remove context: %s (%s)", pname, e); + break; + } + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/naming/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains implementation of naming strategies for connection factory binding. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +Top level classes for the core module. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/ActivationImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/ActivationImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/ActivationImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,174 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.rar; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.rar.Activation; +import org.jboss.jca.core.spi.rar.NotFoundException; +import org.jboss.jca.core.util.Injection; + +import java.lang.ref.WeakReference; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import javax.resource.ResourceException; +import javax.resource.spi.ActivationSpec; +import javax.resource.spi.ResourceAdapter; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * An activation implementation + * + * @author Jesper Pedersen + */ +public class ActivationImpl implements Activation +{ + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + ActivationImpl.class.getName()); + + /** Resource adapter */ + private WeakReference rar; + + /** ActivationSpec class */ + private WeakReference> activationSpecClass; + + /** Config properties */ + private Map> configProperties; + + /** Required config properties */ + private Set requiredConfigProperties; + + /** Value properties */ + private Map valueProperties; + + /** + * Constructor + * @param rar The resource adapter + * @param activationSpecClass The activation spec class + * @param configProperties The config properties + * @param requiredConfigProperties The required config properties + * @param valueProperties The value properties + */ + ActivationImpl(ResourceAdapter rar, + Class activationSpecClass, + Map> configProperties, + Set requiredConfigProperties, + Map valueProperties) + { + this.rar = new WeakReference(rar); + this.activationSpecClass = new WeakReference>(activationSpecClass); + this.configProperties = configProperties; + this.requiredConfigProperties = requiredConfigProperties; + this.valueProperties = valueProperties; + } + + /** + * {@inheritDoc} + */ + public Map> getConfigProperties() + { + return configProperties; + } + + /** + * {@inheritDoc} + */ + public Set getRequiredConfigProperties() + { + return requiredConfigProperties; + } + + /** + * {@inheritDoc} + */ + public ActivationSpec createInstance() + throws NotFoundException, InstantiationException, IllegalAccessException, ResourceException + { + Class clz = activationSpecClass.get(); + + if (clz == null) + throw new NotFoundException(bundle.activationSpecClassNotAvailable()); + + ResourceAdapter ra = rar.get(); + + if (ra == null) + throw new NotFoundException(bundle.resourceAdapterNotAvailable()); + + ActivationSpec instance = ActivationSpec.class.cast(clz.newInstance()); + instance.setResourceAdapter(ra); + + if (valueProperties != null && valueProperties.size() > 0) + { + Injection injector = new Injection(); + Iterator> it = valueProperties.entrySet().iterator(); + while (it.hasNext()) + { + String propertyName = null; + String propertyValue = null; + try + { + Map.Entry entry = it.next(); + + propertyName = entry.getKey(); + propertyValue = entry.getValue(); + + injector.inject(instance, propertyName, propertyValue); + } + catch (Throwable t) + { + log.debugf(t, "Ignoring: %s (%s)", propertyName, propertyValue); + } + } + } + + return instance; + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("ActivationImpl@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[rar=").append(rar != null ? rar.get() : "null"); + sb.append(" activationSpecClass=").append(activationSpecClass != null ? activationSpecClass.get() : "null"); + sb.append(" configProperties=").append(configProperties); + sb.append(" requiredConfigProperties=").append(requiredConfigProperties); + sb.append(" valueProperties=").append(valueProperties); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/EndpointImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/EndpointImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/EndpointImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,257 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.rar; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.bv.BeanValidationUtil; +import org.jboss.jca.core.spi.rar.Endpoint; +import org.jboss.jca.core.spi.transaction.TransactionIntegration; +import org.jboss.jca.core.spi.transaction.recovery.XAResourceRecovery; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.resource.ResourceException; +import javax.resource.spi.ActivationSpec; +import javax.resource.spi.ResourceAdapter; +import javax.resource.spi.endpoint.MessageEndpointFactory; +import javax.validation.ConstraintViolationException; +import javax.validation.Validator; +import javax.validation.groups.Default; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * An endpoint representation + * + * @author Jesper Pedersen + */ +public class EndpointImpl implements Endpoint +{ + /** The reference to the resource adapter instance */ + private WeakReference ra; + + /** Is the resource adapter a 1.6 archive */ + private boolean is16; + + /** Bean validation groups */ + private Set beanValidationGroups; + + /** The product name */ + private String productName; + + /** The product version */ + private String productVersion; + + /** Transaction integration */ + private TransactionIntegration transactionIntegration; + + /** XA capable */ + private boolean xa; + + /** The active recovery modules */ + private Map recovery; + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, Endpoint.class.getName()); + + /** Is bean validation for inflow enabled */ + private static boolean bvEnabled; + + static + { + bvEnabled = Boolean.valueOf(SecurityActions.getSystemProperty("ironjacamar.bv.inflow", "true")); + } + + /** + * Constructor + * @param ra The resource adapter reference + * @param is16 Is the resource adapter a 1.6 archive + * @param bvg The bean validation groups + * @param productName The product name + * @param productVersion The product version + * @param ti The transaction integration + * @param xa XA capable + */ + EndpointImpl(WeakReference ra, boolean is16, Set bvg, + String productName, String productVersion, TransactionIntegration ti, + boolean xa) + { + this.ra = ra; + this.is16 = is16; + this.beanValidationGroups = bvg; + this.productName = productName; + this.productVersion = productVersion; + this.transactionIntegration = ti; + this.xa = xa; + this.recovery = new HashMap(); + } + + /** + * {@inheritDoc} + */ + @SuppressWarnings("unchecked") + public void activate(MessageEndpointFactory endpointFactory, + ActivationSpec spec) throws ResourceException + { + if (endpointFactory == null) + throw new IllegalArgumentException("MessageEndpointFactory is null"); + + if (spec == null) + throw new IllegalArgumentException("ActivationSpec is null"); + + ResourceAdapter rar = ra.get(); + + if (rar == null) + throw new ResourceException(bundle.resourceAdapterInstanceNotActive()); + + if (is16 && bvEnabled) + { + ClassLoader oldTCCL = SecurityActions.getThreadContextClassLoader(); + try + { + SecurityActions.setThreadContextClassLoader(SecurityActions.getClassLoader(rar.getClass())); + + List> groups = new ArrayList>(1); + + if (beanValidationGroups != null) + { + for (String group : beanValidationGroups) + { + try + { + Class clz = Class.forName(group, true, SecurityActions.getClassLoader(rar.getClass())); + groups.add(clz); + } + catch (Throwable t) + { + log.debugf(t, "Unable to load bean validation group: %s", group); + } + } + } + + if (groups.isEmpty()) + groups.add(Default.class); + + Validator validator = BeanValidationUtil.createValidator(); + Class[] vargs = groups.toArray(new Class[groups.size()]); + + Set errors = validator.validate(spec, vargs); + + if (errors != null && errors.size() > 0) + { + throw new ResourceException(bundle.validationException(), new ConstraintViolationException(errors)); + } + } + catch (RuntimeException re) + { + throw new ResourceException(bundle.validationException(), re); + } + finally + { + SecurityActions.setThreadContextClassLoader(oldTCCL); + } + } + + try + { + spec.validate(); + } + catch (UnsupportedOperationException uoe) + { + // Ignore + } + + rar.endpointActivation(endpointFactory, spec); + + if (transactionIntegration != null && transactionIntegration.getRecoveryRegistry() != null && xa) + { + XAResourceRecovery xrr = transactionIntegration.createXAResourceRecovery(rar, spec, + productName, productVersion); + + log.tracef("Adding %s for recovery", xrr); + + try + { + xrr.initialize(); + transactionIntegration.getRecoveryRegistry().addXAResourceRecovery(xrr); + recovery.put(spec, xrr); + } + catch (Exception e) + { + throw new ResourceException(bundle.errorDuringRecoveryInitialization(), e); + } + } + } + + /** + * {@inheritDoc} + */ + public void deactivate(MessageEndpointFactory endpointFactory, + ActivationSpec spec) throws ResourceException + { + if (endpointFactory == null) + throw new IllegalArgumentException("MessageEndpointFactory is null"); + + if (spec == null) + throw new IllegalArgumentException("ActivationSpec is null"); + + ResourceAdapter rar = ra.get(); + + if (rar == null) + throw new ResourceException(bundle.resourceAdapterInstanceNotActive()); + + if (transactionIntegration != null && transactionIntegration.getRecoveryRegistry() != null && xa) + { + XAResourceRecovery xrr = recovery.remove(spec); + if (xrr != null) + { + log.tracef("Removing %s for recovery", xrr); + + try + { + xrr.shutdown(); + } + catch (Exception e) + { + throw new ResourceException(bundle.errorDuringRecoveryShutdown(), e); + } + finally + { + transactionIntegration.getRecoveryRegistry().removeXAResourceRecovery(xrr); + } + } + } + + rar.endpointDeactivation(endpointFactory, spec); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/MessageListenerImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/MessageListenerImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/MessageListenerImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,67 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.rar; + +import org.jboss.jca.core.spi.rar.Activation; +import org.jboss.jca.core.spi.rar.MessageListener; + +/** + * A message listener implementation + * + * @author Jesper Pedersen + */ +public class MessageListenerImpl implements MessageListener +{ + /** The message listener type */ + private Class type; + + /** The activation */ + private Activation activation; + + /** + * Constructor + * @param type The type + * @param activation The activation + */ + MessageListenerImpl(Class type, Activation activation) + { + this.type = type; + this.activation = activation; + } + + /** + * {@inheritDoc} + */ + public Class getType() + { + return type; + } + + /** + * {@inheritDoc} + */ + public Activation getActivation() + { + return activation; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,137 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.rar; + +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Get the classloader. + * @param c The class + * @return The classloader + */ + static ClassLoader getClassLoader(final Class c) + { + if (System.getSecurityManager() == null) + return c.getClassLoader(); + + return AccessController.doPrivileged(new PrivilegedAction() + { + public ClassLoader run() + { + return c.getClassLoader(); + } + }); + } + + /** + * Set the context classloader. + * @param cl classloader + */ + static void setThreadContextClassLoader(final ClassLoader cl) + { + if (System.getSecurityManager() == null) + { + Thread.currentThread().setContextClassLoader(cl); + } + else + { + AccessController.doPrivileged(new PrivilegedAction() + { + public Object run() + { + Thread.currentThread().setContextClassLoader(cl); + + return null; + } + }); + } + } + + /** + * Get the context classloader. + * @return The classloader + */ + static ClassLoader getThreadContextClassLoader() + { + if (System.getSecurityManager() == null) + { + return Thread.currentThread().getContextClassLoader(); + } + else + { + return AccessController.doPrivileged(new PrivilegedAction() + { + public ClassLoader run() + { + return Thread.currentThread().getContextClassLoader(); + } + }); + } + } + + /** + * Get a system property + * @param name The property name + * @param value The default property value + * @return The property value + */ + static String getSystemProperty(final String name, final String value) + { + return AccessController.doPrivileged(new PrivilegedAction() + { + public String run() + { + return System.getProperty(name, value); + } + }); + } + + /** + * Get the methods + * @param c The class + * @return The methods + */ + static Method[] getMethods(final Class c) + { + if (System.getSecurityManager() == null) + return c.getMethods(); + + return AccessController.doPrivileged(new PrivilegedAction() + { + public Method[] run() + { + return c.getMethods(); + } + }); + } + +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/SimpleResourceAdapterRepository.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/SimpleResourceAdapterRepository.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/SimpleResourceAdapterRepository.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,699 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.rar; + +import org.jboss.jca.common.api.metadata.resourceadapter.Activation; +import org.jboss.jca.common.api.metadata.spec.Activationspec; +import org.jboss.jca.common.api.metadata.spec.ConfigProperty; +import org.jboss.jca.common.api.metadata.spec.Connector; +import org.jboss.jca.common.api.metadata.spec.Connector.Version; +import org.jboss.jca.common.api.metadata.spec.RequiredConfigProperty; +import org.jboss.jca.common.api.metadata.spec.XsdString; +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.mdr.MetadataRepository; +import org.jboss.jca.core.spi.rar.Endpoint; +import org.jboss.jca.core.spi.rar.NotFoundException; +import org.jboss.jca.core.spi.rar.ResourceAdapterRepository; +import org.jboss.jca.core.spi.transaction.TransactionIntegration; + +import java.lang.ref.WeakReference; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * A simple implementation of the resource adapter repository + * + * @author Jesper Pedersen + */ +public class SimpleResourceAdapterRepository implements ResourceAdapterRepository +{ + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + SimpleResourceAdapterRepository.class.getName()); + + /** The approved types */ + private static Set> approvedTypes; + + /** Resource adapters */ + private Map> rars; + + /** Ids */ + private Map ids; + + /** Recovery */ + private Map recovery; + + /** The metadata repository */ + private MetadataRepository mdr; + + /** The transaction integration */ + private TransactionIntegration transactionIntegration; + + // We include the primitive types because we can handle those + static + { + approvedTypes = new HashSet>(); + approvedTypes.add(boolean.class); + approvedTypes.add(Boolean.class); + approvedTypes.add(byte.class); + approvedTypes.add(Byte.class); + approvedTypes.add(short.class); + approvedTypes.add(Short.class); + approvedTypes.add(int.class); + approvedTypes.add(Integer.class); + approvedTypes.add(long.class); + approvedTypes.add(Long.class); + approvedTypes.add(float.class); + approvedTypes.add(Float.class); + approvedTypes.add(double.class); + approvedTypes.add(Double.class); + approvedTypes.add(char.class); + approvedTypes.add(Character.class); + approvedTypes.add(String.class); + } + + /** + * Constructor + */ + public SimpleResourceAdapterRepository() + { + this.rars = new HashMap>(); + this.ids = new HashMap(); + this.recovery = new HashMap(); + this.mdr = null; + this.transactionIntegration = null; + } + + /** + * Set the metadata repository + * @param v The value + */ + public synchronized void setMetadataRepository(MetadataRepository v) + { + this.mdr = v; + } + + /** + * Set the transaction integration + * @param v The value + */ + public synchronized void setTransactionIntegration(TransactionIntegration v) + { + this.transactionIntegration = v; + } + + /** + * {@inheritDoc} + */ + public synchronized String registerResourceAdapter(javax.resource.spi.ResourceAdapter ra) + { + if (ra == null) + throw new IllegalArgumentException("ResourceAdapter is null"); + + String clzName = ra.getClass().getName(); + + AtomicInteger id = ids.get(clzName); + if (id == null) + { + id = new AtomicInteger(0); + ids.put(clzName, id); + } + + String key = clzName + "#" + id.incrementAndGet(); + + rars.put(key, new WeakReference(ra)); + + return key; + } + + /** + * {@inheritDoc} + */ + public synchronized void unregisterResourceAdapter(String key) throws NotFoundException + { + if (key == null) + throw new IllegalArgumentException("Key is null"); + + if (!rars.keySet().contains(key)) + throw new NotFoundException(bundle.keyNotRegistered(key)); + + rars.remove(key); + recovery.remove(key); + } + + /** + * {@inheritDoc} + */ + public synchronized javax.resource.spi.ResourceAdapter getResourceAdapter(String uniqueId) throws NotFoundException + { + if (uniqueId == null) + throw new IllegalArgumentException("UniqueId is null"); + + if (uniqueId.trim().equals("")) + throw new IllegalArgumentException("UniqueId is empty"); + + if (!rars.containsKey(uniqueId)) + throw new NotFoundException(bundle.keyNotRegistered(uniqueId)); + + WeakReference ra = rars.get(uniqueId); + + if (ra.get() == null) + throw new NotFoundException(bundle.keyNotRegistered(uniqueId)); + + return ra.get(); + } + + /** + * {@inheritDoc} + */ + public synchronized Set getResourceAdapters() + { + return Collections.unmodifiableSet(rars.keySet()); + } + + /** + * {@inheritDoc} + */ + public synchronized Set getResourceAdapters(Class messageListenerType) + { + if (messageListenerType == null) + throw new IllegalArgumentException("MessageListenerType is null"); + + if (mdr == null) + throw new IllegalStateException("MDR is null"); + + Set result = new HashSet(); + + Iterator>> it = rars.entrySet().iterator(); + while (it.hasNext()) + { + Map.Entry> entry = it.next(); + + String raKey = entry.getKey(); + WeakReference ra = entry.getValue(); + + if (ra.get() != null) + { + javax.resource.spi.ResourceAdapter rar = ra.get(); + Connector md = null; + + Set mdrKeys = mdr.getResourceAdapters(); + Iterator mdrIt = mdrKeys.iterator(); + + while (md == null && mdrIt.hasNext()) + { + String mdrId = mdrIt.next(); + try + { + Connector c = mdr.getResourceAdapter(mdrId); + + if (c.getResourceadapter() != null) + { + String clz = c.getResourceadapter().getResourceadapterClass(); + + if (rar.getClass().getName().equals(clz)) + md = c; + } + } + catch (Throwable t) + { + // We will ignore + log.debugf("Resource adapter %s is ignored", rar.getClass().getName()); + } + } + + if (md != null && md.getResourceadapter() != null) + { + org.jboss.jca.common.api.metadata.spec.ResourceAdapter raSpec = md.getResourceadapter(); + + if (raSpec.getInboundResourceadapter() != null && + raSpec.getInboundResourceadapter().getMessageadapter() != null && + raSpec.getInboundResourceadapter().getMessageadapter().getMessagelisteners() != null && + raSpec.getInboundResourceadapter().getMessageadapter().getMessagelisteners().size() > 0) + { + List listeners = + raSpec.getInboundResourceadapter().getMessageadapter().getMessagelisteners(); + + for (org.jboss.jca.common.api.metadata.spec.MessageListener ml : listeners) + { + try + { + ClassLoader cl = SecurityActions.getClassLoader(rar.getClass()); + Class mlType = Class.forName(ml.getMessagelistenerType().getValue(), true, cl); + + if (mlType.isAssignableFrom(messageListenerType)) + result.add(raKey); + } + catch (Throwable t) + { + // We will ignore + } + } + } + } + } + } + + return Collections.unmodifiableSet(result); + } + + /** + * {@inheritDoc} + */ + public synchronized Endpoint getEndpoint(String uniqueId) throws NotFoundException + { + if (uniqueId == null) + throw new IllegalArgumentException("UniqueId is null"); + + if (uniqueId.trim().equals("")) + throw new IllegalArgumentException("UniqueId is empty"); + + if (!rars.containsKey(uniqueId)) + throw new NotFoundException(bundle.keyNotRegistered(uniqueId)); + + WeakReference ra = rars.get(uniqueId); + + if (ra.get() == null) + throw new NotFoundException(bundle.keyNotRegistered(uniqueId)); + + String mdrIdentifier = getMDRIdentifier(ra.get()); + boolean is16 = is16(mdrIdentifier); + Set beanValidationGroups = getBeanValidationGroups(mdrIdentifier); + String productName = getProductName(mdrIdentifier); + String productVersion = getProductVersion(mdrIdentifier); + Boolean isXA = recovery.get(uniqueId); + + if (isXA == null) + isXA = Boolean.TRUE; + + return new EndpointImpl(ra, is16, beanValidationGroups, + productName, productVersion, transactionIntegration, isXA.booleanValue()); + } + + /** + * {@inheritDoc} + */ + public synchronized List getMessageListeners(String uniqueId) + throws NotFoundException, InstantiationException, IllegalAccessException + { + if (uniqueId == null) + throw new IllegalArgumentException("UniqueId is null"); + + if (uniqueId.trim().equals("")) + throw new IllegalArgumentException("UniqueId is empty"); + + if (!rars.containsKey(uniqueId)) + throw new NotFoundException(bundle.keyNotRegistered(uniqueId)); + + WeakReference ra = rars.get(uniqueId); + + if (ra.get() == null) + throw new NotFoundException(bundle.keyNotRegistered(uniqueId)); + + if (mdr == null) + throw new IllegalStateException("MDR is null"); + + javax.resource.spi.ResourceAdapter rar = ra.get(); + Connector md = null; + + Set mdrKeys = mdr.getResourceAdapters(); + Iterator mdrIt = mdrKeys.iterator(); + + while (md == null && mdrIt.hasNext()) + { + String mdrId = mdrIt.next(); + try + { + Connector c = mdr.getResourceAdapter(mdrId); + + if (c.getResourceadapter() != null) + { + String clz = c.getResourceadapter().getResourceadapterClass(); + + if (rar.getClass().getName().equals(clz)) + md = c; + } + } + catch (Throwable t) + { + throw new NotFoundException(bundle.unableLookupResourceAdapterInMDR(uniqueId), t); + } + } + + if (md == null) + throw new NotFoundException(bundle.unableLookupResourceAdapterInMDR(uniqueId)); + + if (md.getResourceadapter() != null) + { + org.jboss.jca.common.api.metadata.spec.ResourceAdapter raSpec = md.getResourceadapter(); + + if (raSpec.getInboundResourceadapter() != null && + raSpec.getInboundResourceadapter().getMessageadapter() != null && + raSpec.getInboundResourceadapter().getMessageadapter().getMessagelisteners() != null && + raSpec.getInboundResourceadapter().getMessageadapter().getMessagelisteners().size() > 0) + { + List listeners = + raSpec.getInboundResourceadapter().getMessageadapter().getMessagelisteners(); + + List result = + new ArrayList(listeners.size()); + + for (org.jboss.jca.common.api.metadata.spec.MessageListener ml : listeners) + { + result.add(createMessageListener(rar, ml)); + } + + return result; + } + } + + return Collections.emptyList(); + } + + + /** + * {@inheritDoc} + */ + public void setRecoveryForResourceAdapter(String uniqueId, boolean isXA) throws NotFoundException + { + if (uniqueId == null) + throw new IllegalArgumentException("UniqueId is null"); + + if (uniqueId.trim().equals("")) + throw new IllegalArgumentException("UniqueId is empty"); + + if (!rars.containsKey(uniqueId)) + throw new NotFoundException(bundle.keyNotRegistered(uniqueId)); + + recovery.put(uniqueId, isXA ? Boolean.TRUE : Boolean.FALSE); + } + + /** + * Create a message listener instance + * @param rar The resource adapter + * @param ml The metadata for the message listener + * @return The instance + * @exception InstantiationException Thrown if an object couldn't created + * @exception IllegalAccessException Thrown if object access is inaccessible + */ + private org.jboss.jca.core.spi.rar.MessageListener + createMessageListener(javax.resource.spi.ResourceAdapter rar, + org.jboss.jca.common.api.metadata.spec.MessageListener ml) + throws InstantiationException, IllegalAccessException + { + try + { + ClassLoader cl = SecurityActions.getClassLoader(rar.getClass()); + + Class type = Class.forName(ml.getMessagelistenerType().getValue(), true, cl); + + Map> configProperties = new HashMap>(); + Set requiredConfigProperties = new HashSet(); + Map valueProperties = new HashMap(); + + Activationspec as = ml.getActivationspec(); + Class asClz = Class.forName(as.getActivationspecClass().getValue(), true, cl); + + if (as.getConfigProperties() != null && as.getConfigProperties().size() > 0) + { + for (ConfigProperty cp : as.getConfigProperties()) + { + String name = cp.getConfigPropertyName().getValue(); + Class ct = Class.forName(cp.getConfigPropertyType().getValue(), true, cl); + + configProperties.put(name, ct); + + if (cp.getConfigPropertyValue() != null && cp.getConfigPropertyValue().getValue() != null) + valueProperties.put(name, cp.getConfigPropertyValue().getValue()); + } + } + + configProperties.putAll(introspectActivationSpec(asClz)); + + List rcps = as.getRequiredConfigProperties(); + if (rcps != null && rcps.size() > 0) + { + for (RequiredConfigProperty rcp : rcps) + { + String name = rcp.getConfigPropertyName().getValue(); + + requiredConfigProperties.add(name); + } + } + + ActivationImpl a = new ActivationImpl(rar, + asClz, + Collections.unmodifiableMap(configProperties), + Collections.unmodifiableSet(requiredConfigProperties), + Collections.unmodifiableMap(valueProperties)); + + return new MessageListenerImpl(type, a); + } + catch (ClassNotFoundException cnfe) + { + InstantiationException ie = new InstantiationException("Unable to create representation"); + ie.initCause(cnfe); + throw ie; + } + } + + /** + * Introspect an activation spec class for config-property's + * @param clz The class + * @return The introspected map + */ + private Map> introspectActivationSpec(Class clz) + { + Map> result = new HashMap>(); + + if (clz != null) + { + Method[] methods = SecurityActions.getMethods(clz); + if (methods.length > 0) + { + for (int i = 0; i < methods.length; i++) + { + Method m = methods[i]; + + if (m.getName().startsWith("set") && m.getParameterTypes().length == 1) + { + Class parameterType = m.getParameterTypes()[0]; + + if (approvedTypes.contains(parameterType)) + { + String n = m.getName().substring(3); + String name = n.substring(0, 1).toLowerCase(Locale.US); + + if (n.length() > 1) + name = name.concat(n.substring(1)); + + result.put(name, parameterType); + } + } + } + } + } + + return result; + } + + /** + * Get MDR identifier + * @param ra The resource adapter + * @return The identifier + */ + private String getMDRIdentifier(javax.resource.spi.ResourceAdapter ra) + { + for (String id : mdr.getResourceAdapters()) + { + try + { + Connector raXml = mdr.getResourceAdapter(id); + if (raXml != null) + { + if (raXml.getResourceadapter() != null) + { + org.jboss.jca.common.api.metadata.spec.ResourceAdapter raSpec = raXml.getResourceadapter(); + if (raSpec.getResourceadapterClass() != null && !raSpec.getResourceadapterClass().equals("")) + { + if (ra.getClass().getName().equals(raSpec.getResourceadapterClass())) + return id; + } + } + } + } + catch (Throwable t) + { + log.debugf(t, "Exception while loading id: %s", id); + } + } + + return null; + } + + /** + * Is the resource adapter a 1.6 archive + * @param id The MDR identifier + * @return True if 1.6; otherwise false + */ + private boolean is16(String id) + { + if (id == null || id.equals("")) + return false; + + try + { + Connector raXml = mdr.getResourceAdapter(id); + if (raXml != null) + { + return (raXml.getVersion() == Version.V_16 || raXml.getVersion() == Version.V_17); + } + } + catch (Throwable t) + { + log.debugf(t, "Exception while loading ra.xml: %s", id); + } + + return false; + } + + /** + * Get the bean validation groups + * @param id The MDR identifier + * @return The groups; null if none were found + */ + private Set getBeanValidationGroups(String id) + { + if (id == null || id.equals("")) + return null; + + try + { + Activation a = mdr.getActivation(id); + if (a != null && a.getBeanValidationGroups() != null && a.getBeanValidationGroups().size() > 0) + { + Set groups = new HashSet(); + for (String group : a.getBeanValidationGroups()) + { + groups.add(group); + } + return groups; + } + } + catch (Throwable t) + { + log.debugf(t, "Exception while loading ironjacamar.xml: %s", id); + } + + return null; + } + + /** + * Get the product name for the resource adapter + * @param id The MDR identifier + * @return The value + */ + private String getProductName(String id) + { + if (id == null || id.equals("")) + return ""; + + try + { + Connector raXml = mdr.getResourceAdapter(id); + if (raXml != null && !XsdString.isNull(raXml.getEisType())) + { + return raXml.getEisType().getValue(); + } + } + catch (Throwable t) + { + log.debugf(t, "Exception while loading ra.xml: %s", id); + } + + return ""; + } + + /** + * Get the product version for the resource adapter + * @param id The MDR identifier + * @return The value + */ + private String getProductVersion(String id) + { + if (id == null || id.equals("")) + return ""; + + try + { + Connector raXml = mdr.getResourceAdapter(id); + if (raXml != null) + { + if (!XsdString.isNull(raXml.getResourceadapterVersion())) + return raXml.getResourceadapterVersion().getValue(); + } + } + catch (Throwable t) + { + log.debugf(t, "Exception while loading ra.xml: %s", id); + } + + return ""; + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("SimpleResourceAdapterRepository@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("["); + sb.append(" rars=").append(rars); + sb.append(" ids=").append(ids); + sb.append(" mdr=").append(mdr); + sb.append(" ti=").append(transactionIntegration); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/rar/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains an implementation of the resource adapter repository. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/recovery/ConfigurableRecoveryPlugin.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/recovery/ConfigurableRecoveryPlugin.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/recovery/ConfigurableRecoveryPlugin.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,191 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.recovery; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.recovery.RecoveryPlugin; + +import java.lang.reflect.Method; + +import javax.resource.ResourceException; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * Configurable implementation of a recovery plugin. + * + * @author Jesper Pedersen + */ +public class ConfigurableRecoveryPlugin implements RecoveryPlugin +{ + /** Log instance */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, DefaultRecoveryPlugin.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** Enable isValid */ + private boolean enableIsValid; + + /** isValid override */ + private boolean isValidOverride; + + /* isValid value */ + private int isValidValue; + + /** Enable close */ + private boolean enableClose; + + /* Close method */ + private String closeMethod; + + /** + * Constructor + */ + public ConfigurableRecoveryPlugin() + { + this.enableIsValid = true; + this.isValidValue = 5; + this.isValidOverride = false; + this.enableClose = true; + this.closeMethod = "close"; + } + + /** + * Enable isValid method call + * @param v The value + */ + public void setEnableIsValid(boolean v) + { + enableIsValid = v; + } + + /** + * Set isValid method parameter + * @param v The value + */ + public void setIsValidValue(int v) + { + isValidValue = v; + } + + /** + * Override value for isValid method call if not enabled + * @param v The value + */ + public void setIsValidOverride(boolean v) + { + isValidOverride = v; + } + + /** + * Enable close method call + * @param v The value + */ + public void setEnableClose(boolean v) + { + enableClose = v; + } + + /** + * Set close method name + * @param v The value + */ + public void setCloseMethod(String v) + { + closeMethod = v; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValid(Object c) throws ResourceException + { + if (enableIsValid) + { + if (c != null) + { + try + { + Method method = SecurityActions.getMethod(c.getClass(), "isValid", new Class[] {int.class}); + SecurityActions.setAccessible(method, true); + Boolean b = (Boolean)method.invoke(c, new Object[] {Integer.valueOf(isValidValue)}); + return b.booleanValue(); + } + catch (Throwable t) + { + log.debugf("No isValid(int) method defined on connection interface (%s)", c.getClass().getName()); + } + } + } + else + { + return isValidOverride; + } + + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public void close(Object c) throws ResourceException + { + if (enableClose) + { + if (c != null) + { + if (c instanceof javax.resource.cci.Connection) + { + try + { + javax.resource.cci.Connection cci = (javax.resource.cci.Connection)c; + cci.close(); + } + catch (ResourceException re) + { + log.exceptionDuringConnectionClose(re); + throw new ResourceException(bundle.errorDuringConnectionClose(), re); + } + } + else + { + try + { + Method method = SecurityActions.getMethod(c.getClass(), closeMethod, (Class[])null); + SecurityActions.setAccessible(method, true); + method.invoke(c, (Object[])null); + } + catch (Throwable t) + { + log.debugf(t, "Error during connection %s()", closeMethod); + throw new ResourceException(bundle.errorDuringConnectionClose(), t); + } + } + } + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/recovery/DefaultRecoveryPlugin.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/recovery/DefaultRecoveryPlugin.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/recovery/DefaultRecoveryPlugin.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,117 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.recovery; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.recovery.RecoveryPlugin; + +import java.lang.reflect.Method; + +import javax.resource.ResourceException; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * Default implementation of a recovery plugin. + * + * @author Stefano Maestri + * @author Jesper Pedersen + */ +public class DefaultRecoveryPlugin implements RecoveryPlugin +{ + /** Log instance */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, DefaultRecoveryPlugin.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** + * Constructor + */ + public DefaultRecoveryPlugin() + { + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValid(Object c) throws ResourceException + { + if (c != null) + { + try + { + Method method = SecurityActions.getMethod(c.getClass(), "isValid", new Class[] {int.class}); + SecurityActions.setAccessible(method, true); + Boolean b = (Boolean)method.invoke(c, new Object[] {Integer.valueOf(5)}); + return b.booleanValue(); + } + catch (Throwable t) + { + log.debugf("No isValid(int) method defined on connection interface (%s)", c.getClass().getName()); + } + } + + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public void close(Object c) throws ResourceException + { + if (c != null) + { + if (c instanceof javax.resource.cci.Connection) + { + try + { + javax.resource.cci.Connection cci = (javax.resource.cci.Connection)c; + cci.close(); + } + catch (ResourceException re) + { + log.exceptionDuringConnectionClose(re); + throw new ResourceException(bundle.errorDuringConnectionClose(), re); + } + } + else + { + try + { + Method method = SecurityActions.getMethod(c.getClass(), "close", (Class[])null); + SecurityActions.setAccessible(method, true); + method.invoke(c, (Object[])null); + } + catch (Throwable t) + { + log.debug("Error during connection close()", t); + throw new ResourceException(bundle.errorDuringConnectionClose(), t); + } + } + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/recovery/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/recovery/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/recovery/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,93 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008-2009, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.recovery; + +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Constructor + */ + private SecurityActions() + { + } + + /** + * Invoke setAccessible on a method + * @param m The method + * @param value The value + */ + static void setAccessible(final Method m, final boolean value) + { + AccessController.doPrivileged(new PrivilegedAction() + { + public Object run() + { + m.setAccessible(value); + return null; + } + }); + } + + /** + * Get the method + * @param c The class + * @param name The name + * @param params The parameters + * @return The method + * @exception NoSuchMethodException If a matching method is not found. + */ + static Method getMethod(final Class c, final String name, final Class... params) + throws NoSuchMethodException + { + if (System.getSecurityManager() == null) + return c.getMethod(name, params); + + Method result = AccessController.doPrivileged(new PrivilegedAction() + { + public Method run() + { + try + { + return c.getMethod(name, params); + } + catch (NoSuchMethodException e) + { + return null; + } + } + }); + + if (result != null) + return result; + + throw new NoSuchMethodException(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/recovery/ValidatingManagedConnectionFactoryRecoveryPlugin.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/recovery/ValidatingManagedConnectionFactoryRecoveryPlugin.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/recovery/ValidatingManagedConnectionFactoryRecoveryPlugin.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,59 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.recovery; + +import org.jboss.jca.core.spi.recovery.RecoveryPlugin; + +import javax.resource.ResourceException; + +/** + * Marker recovery plugin to let the recovery subsystem know that the ValidatingManagedConnectionFactory + * interface should be used for verifying the managed connection + * + * @author Jesper Pedersen + */ +public class ValidatingManagedConnectionFactoryRecoveryPlugin implements RecoveryPlugin +{ + /** + * Constructor + */ + public ValidatingManagedConnectionFactoryRecoveryPlugin() + { + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isValid(Object c) throws ResourceException + { + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public void close(Object c) throws ResourceException + { + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/recovery/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/recovery/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/recovery/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This packages contains the classes for the recovery infrastructure. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/AbstractCallback.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/AbstractCallback.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/AbstractCallback.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,116 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2017, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.security; + +import org.jboss.jca.core.spi.security.Callback; + +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; + +import javax.security.auth.message.callback.CallerPrincipalCallback; +import javax.security.auth.message.callback.GroupPrincipalCallback; + + +/** + * Abstract callback class. + * + * + * @author Flavia Rainone + */ +public abstract class AbstractCallback implements Callback +{ + @Override + public javax.security.auth.callback.Callback[] mapCallbacks(javax.security.auth.callback.Callback[] callbacks) + { + List l = + new ArrayList(callbacks.length); + + for (int i = 0; i < callbacks.length; i++) + { + javax.security.auth.callback.Callback callback = callbacks[i]; + + if (callback instanceof CallerPrincipalCallback) + { + CallerPrincipalCallback callerPrincipalCallback = (CallerPrincipalCallback)callback; + String name = null; + Principal p = null; + + Principal callerPrincipal = callerPrincipalCallback.getPrincipal(); + if (callerPrincipal != null) + name = callerPrincipal.getName(); + + if (name == null && callerPrincipalCallback.getName() != null) + name = callerPrincipalCallback.getName(); + + if (name != null) + p = this.mapPrincipal(name); + + if (p != null) + { + l.add(new CallerPrincipalCallback(callerPrincipalCallback.getSubject(), p)); + } + else + { + l.add(callback); + } + } + else if (callback instanceof GroupPrincipalCallback) + { + GroupPrincipalCallback groupPrincipalCallback = (GroupPrincipalCallback)callback; + + if (groupPrincipalCallback.getGroups() != null && groupPrincipalCallback.getGroups().length > 0) + { + List gs = new ArrayList(groupPrincipalCallback.getGroups().length); + + for (String g : groupPrincipalCallback.getGroups()) + { + String s = this.mapGroup(g); + + if (s != null) + { + gs.add(s); + } + else + { + gs.add(g); + } + } + + l.add(new GroupPrincipalCallback(groupPrincipalCallback.getSubject(), + gs.toArray(new String[gs.size()]))); + } + else + { + l.add(callback); + } + } + else + { + l.add(callback); + } + } + + return l.toArray(new javax.security.auth.callback.Callback[l.size()]); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/CallbackImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/CallbackImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/CallbackImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,313 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.security; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.security.Callback; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.security.Principal; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.jboss.logging.Logger; + +/** + * An implementation of the callback SPI for explicit security settings + * + * @author Jesper Pedersen + */ +public class CallbackImpl extends AbstractCallback implements Callback +{ + /** Serial version uid */ + private static final long serialVersionUID = 1L; + + /** Log instance */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, CallbackImpl.class.getName()); + + /** Is mapping required */ + private boolean mappingRequired; + + /** The domain */ + private String domain; + + /** The default principal */ + private Principal defaultPrincipal; + + /** The default groups */ + private String[] defaultGroups; + + /** The principal map */ + private Map principals; + + /** The groups map */ + private Map groups; + + /** + * Constructor + */ + CallbackImpl() + { + } + + /** + * Constructor + * @param mappingRequired Is a mapping required + * @param domain The domain + * @param defaultPrincipal The default principal + * @param defaultGroups The default groups + * @param principals The principal mappings + * @param groups The group mappings + */ + public CallbackImpl(boolean mappingRequired, String domain, + String defaultPrincipal, String[] defaultGroups, + Map principals, Map groups) + { + this.mappingRequired = mappingRequired; + this.domain = domain; + + if (defaultPrincipal != null) + { + this.defaultPrincipal = new SimplePrincipal(defaultPrincipal); + } + else + { + this.defaultPrincipal = null; + } + + if (defaultGroups != null) + { + this.defaultGroups = Arrays.copyOf(defaultGroups, defaultGroups.length); + } + else + { + this.defaultGroups = null; + } + + if (principals != null) + { + this.principals = Collections.synchronizedMap(new HashMap(principals)); + } + else + { + this.principals = null; + } + + if (groups != null) + { + this.groups = Collections.synchronizedMap(new HashMap(groups));; + } + else + { + this.groups = null; + } + } + + /** + * {@inheritDoc} + */ + public boolean isMappingRequired() + { + return mappingRequired; + } + + /** + * {@inheritDoc} + */ + public String getDomain() + { + return domain; + } + + /** + * {@inheritDoc} + */ + public Principal getDefaultPrincipal() + { + return defaultPrincipal; + } + + /** + * {@inheritDoc} + */ + public String[] getDefaultGroups() + { + if (defaultGroups == null) + return null; + + return Arrays.copyOf(defaultGroups, defaultGroups.length); + } + + /** + * {@inheritDoc} + */ + public Principal mapPrincipal(String name) + { + if (principals != null) + { + String mapping = principals.get(name); + + if (mapping != null) + { + return new SimplePrincipal(mapping); + } + } + + return null; + } + + /** + * {@inheritDoc} + */ + public String mapGroup(String name) + { + if (groups == null) + return null; + + return groups.get(name); + } + + /** + * {@inheritDoc} + */ + public void start() throws Throwable + { + } + + /** + * {@inheritDoc} + */ + public void stop() throws Throwable + { + } + + private void writeObject(ObjectOutputStream out) throws IOException + { + out.writeBoolean(mappingRequired); + out.writeUTF(domain); + + if (defaultPrincipal != null) + { + out.writeBoolean(true); + out.writeUTF(defaultPrincipal.getName()); + } + else + { + out.writeBoolean(false); + } + + out.writeObject(defaultGroups); + + if (principals != null && principals.size() > 0) + { + out.writeInt(principals.size()); + Iterator> it = principals.entrySet().iterator(); + while (it.hasNext()) + { + Map.Entry entry = it.next(); + out.writeUTF(entry.getKey()); + out.writeUTF(entry.getValue()); + } + } + else + { + out.writeInt(0); + } + + if (groups != null && groups.size() > 0) + { + out.writeInt(groups.size()); + Iterator> it = groups.entrySet().iterator(); + while (it.hasNext()) + { + Map.Entry entry = it.next(); + out.writeUTF(entry.getKey()); + out.writeUTF(entry.getValue()); + } + } + else + { + out.writeInt(0); + } + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException + { + mappingRequired = in.readBoolean(); + domain = in.readUTF(); + + if (in.readBoolean()) + defaultPrincipal = new SimplePrincipal(in.readUTF()); + + defaultGroups = (String[])in.readObject(); + + int i = in.readInt(); + if (i > 0) + { + for (int j = 1; j <= i; j++) + { + String from = in.readUTF(); + String to = in.readUTF(); + + principals.put(from, to); + } + } + + i = in.readInt(); + if (i > 0) + { + for (int j = 1; j <= i; j++) + { + String from = in.readUTF(); + String to = in.readUTF(); + + groups.put(from, to); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("CallbackImpl@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[mappingRequired=").append(mappingRequired); + sb.append(" domain=").append(domain); + sb.append(" defaultPrincipal=").append(defaultPrincipal); + sb.append(" defaultGroups=").append(defaultGroups == null ? "null" : Arrays.toString(defaultGroups)); + sb.append(" principals=").append(principals); + sb.append(" groups=").append(groups); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/DefaultCallback.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/DefaultCallback.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/DefaultCallback.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,467 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.security; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.security.Callback; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.StringTokenizer; + +import org.jboss.logging.Logger; + +/** + * A default implementation of the callback security SPI. + * + * @author Jesper Pedersen + */ +public class DefaultCallback extends AbstractCallback implements Callback +{ + /** Serial version uid */ + private static final long serialVersionUID = 1L; + + /** Log instance */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, DefaultCallback.class.getName()); + + /** Default callback.properties file name */ + private static final String DEFAULT_CALLBACK_PROPERTIES = "callback.properties"; + + /** Is mapping required */ + private boolean mappingRequired; + + /** The domain */ + private String domain; + + /** The default principal */ + private Principal defaultPrincipal; + + /** The default groups */ + private String[] defaultGroups; + + /** The principal map */ + private Map principals; + + /** The groups map */ + private Map groups; + + /** The configuration file */ + private String file; + + /** + * Constructor + */ + public DefaultCallback() + { + this(null); + } + + /** + * Constructor + * @param file The file + */ + public DefaultCallback(String file) + { + this.mappingRequired = false; + this.domain = null; + this.defaultPrincipal = null; + this.defaultGroups = null; + this.principals = new HashMap(); + this.groups = new HashMap(); + this.file = file; + } + + /** + * {@inheritDoc} + */ + public String getDomain() + { + return domain; + } + + /** + * Set the domain + * @param v The value + */ + public void setDomain(String v) + { + this.domain = v; + } + + /** + * {@inheritDoc} + */ + public boolean isMappingRequired() + { + return mappingRequired; + } + + /** + * Set the user mapping required + * @param value The value + */ + public void setMappingRequired(boolean value) + { + mappingRequired = value; + } + + /** + * {@inheritDoc} + */ + public Principal getDefaultPrincipal() + { + return defaultPrincipal; + } + + /** + * Set the default principal + * @param value The value + */ + public void setDefaultPrincipal(Principal value) + { + defaultPrincipal = value; + } + + /** + * {@inheritDoc} + */ + public String[] getDefaultGroups() + { + if (defaultGroups == null) + return null; + + return Arrays.copyOf(defaultGroups, defaultGroups.length); + } + + /** + * Set the default groups + * @param value The value + */ + public void setDefaultGroups(String[] value) + { + if (value != null) + { + defaultGroups = Arrays.copyOf(value, value.length); + } + else + { + defaultGroups = null; + } + } + + /** + * {@inheritDoc} + */ + public Principal mapPrincipal(String name) + { + String mapping = principals.get(name); + + if (mapping != null) + { + return new SimplePrincipal(mapping); + } + + return null; + } + + /** + * Add a principal mapping + * @param from The from name + * @param to The to name + */ + public void addPrincipalMapping(String from, String to) + { + principals.put(from, to); + } + + /** + * {@inheritDoc} + */ + public String mapGroup(String name) + { + return groups.get(name); + } + + /** + * Add a group mapping + * @param from The from name + * @param to The to name + */ + public void addGroupMapping(String from, String to) + { + groups.put(from, to); + } + + /** + * Set the file name + * @param value The value + */ + public void setFile(String value) + { + file = value; + } + + /** + * {@inheritDoc} + */ + public void start() throws Throwable + { + InputStream is = null; + + try + { + if (file != null) + { + File f = new File(file); + + if (f.exists()) + { + log.tracef("callback.properties: Using file: %s", file); + + is = new FileInputStream(f); + } + } + + if (is == null) + { + log.trace("callback.properties: Using classloader"); + + is = SecurityActions.getResourceAsStream(DEFAULT_CALLBACK_PROPERTIES); + } + + if (is != null) + { + Properties p = new Properties(); + p.load(is); + + if (p.size() > 0) + { + Iterator> entries = p.entrySet().iterator(); + while (entries.hasNext()) + { + Map.Entry entry = entries.next(); + String key = (String)entry.getKey(); + String value = (String)entry.getValue(); + + if ("mapping-required".equals(key)) + { + mappingRequired = Boolean.valueOf(value); + } + else if ("domain".equals(key)) + { + domain = value; + } + else if ("default-principal".equals(key)) + { + if (value != null && !value.trim().equals("")) + defaultPrincipal = new SimplePrincipal(value); + } + else if ("default-groups".equals(key)) + { + if (value != null && !value.trim().equals("")) + { + StringTokenizer st = new StringTokenizer(","); + List groups = new ArrayList(); + while (st.hasMoreTokens()) + { + groups.add(st.nextToken().trim()); + } + defaultGroups = groups.toArray(new String[groups.size()]); + } + } + else if (key.startsWith("map.user")) + { + if (value != null && value.contains("=>")) + { + int index = value.indexOf("=>"); + String from = value.substring(0, index); + String to = value.substring(index + 2); + addPrincipalMapping(from, to); + } + } + else if (key.startsWith("map.group")) + { + if (value != null && value.contains("=>")) + { + int index = value.indexOf("=>"); + String from = value.substring(0, index); + String to = value.substring(index + 2); + addGroupMapping(from, to); + } + } + } + } + else + { + if (log.isDebugEnabled()) + log.debug("Empty callback.properties file"); + } + } + else + { + log.noCallbackPropertiesFound(); + } + } + catch (IOException ioe) + { + log.errorWhileLoadingCallbackProperties(ioe); + } + finally + { + if (is != null) + { + try + { + is.close(); + } + catch (IOException ignore) + { + // Ignore + } + } + } + } + + /** + * {@inheritDoc} + */ + public void stop() throws Throwable + { + principals.clear(); + groups.clear(); + } + + private void writeObject(ObjectOutputStream out) throws IOException + { + out.writeBoolean(mappingRequired); + out.writeUTF(domain); + + if (defaultPrincipal != null) + { + out.writeBoolean(true); + out.writeUTF(defaultPrincipal.getName()); + } + else + { + out.writeBoolean(false); + } + + out.writeObject(defaultGroups); + + out.writeInt(principals.size()); + if (principals.size() > 0) + { + Iterator> it = principals.entrySet().iterator(); + while (it.hasNext()) + { + Map.Entry entry = it.next(); + out.writeUTF(entry.getKey()); + out.writeUTF(entry.getValue()); + } + } + + out.writeInt(groups.size()); + if (groups.size() > 0) + { + Iterator> it = groups.entrySet().iterator(); + while (it.hasNext()) + { + Map.Entry entry = it.next(); + out.writeUTF(entry.getKey()); + out.writeUTF(entry.getValue()); + } + } + + out.writeUTF(file); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException + { + mappingRequired = in.readBoolean(); + domain = in.readUTF(); + + if (in.readBoolean()) + defaultPrincipal = new SimplePrincipal(in.readUTF()); + + defaultGroups = (String[])in.readObject(); + + int i = in.readInt(); + if (i > 0) + { + for (int j = 1; j <= i; j++) + { + String from = in.readUTF(); + String to = in.readUTF(); + + principals.put(from, to); + } + } + + i = in.readInt(); + if (i > 0) + { + for (int j = 1; j <= i; j++) + { + String from = in.readUTF(); + String to = in.readUTF(); + + groups.put(from, to); + } + } + + file = in.readUTF(); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("DefaultCallback@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[mappingRequired=").append(mappingRequired); + sb.append(" domain=").append(domain); + sb.append(" defaultPrincipal=").append(defaultPrincipal); + sb.append(" defaultGroups=").append(defaultGroups == null ? "null" : Arrays.toString(defaultGroups)); + sb.append(" principals=").append(principals); + sb.append(" groups=").append(groups); + sb.append(" file=").append(file); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/DefaultSubjectFactory.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/DefaultSubjectFactory.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/DefaultSubjectFactory.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,181 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.security; + +import org.jboss.jca.core.spi.security.SubjectFactory; + +import java.security.Principal; + +import javax.resource.spi.security.PasswordCredential; +import javax.security.auth.Subject; + +/** + * Implements a basic subject factory + */ +public class DefaultSubjectFactory implements SubjectFactory +{ + /** The security domain name */ + private String securityDomain; + + /** The user name */ + private String userName; + + /** The password */ + private String password; + + /** + * Create a new DefaultSubjectFactory. + */ + public DefaultSubjectFactory() + { + this(null, null, null); + } + + /** + * Create a new DefaultSubjectFactory. + * + * @param securityDomain securityDomain + * @param userName userName + * @param password password + */ + public DefaultSubjectFactory(String securityDomain, String userName, String password) + { + this.securityDomain = securityDomain; + this.userName = userName; + this.password = password; + } + + /** + * Set the security domain + * @param v The value + */ + public void setSecurityDomain(String v) + { + this.securityDomain = v; + } + + /** + * Set the user name + * @param v The value + */ + public void setUserName(String v) + { + this.userName = v; + } + + /** + * Set the password + * @param v The value + */ + public void setPassword(String v) + { + this.password = v; + } + + @Override + public Subject createSubject() + { + if (userName == null) + throw new IllegalStateException("UserName is null"); + + if (password == null) + throw new IllegalStateException("Password is null"); + + Subject subject = new Subject(); + + Principal p = new SimplePrincipal(userName); + subject.getPrincipals().add(p); + + PasswordCredential credential = new PasswordCredential(userName, password.toCharArray()); + subject.getPrivateCredentials().add(credential); + + return subject; + } + + @Override + public Subject createSubject(String securityDomain) + { + //we just ignore atm the arg using a singleton for each security domain + return createSubject(); + } + + @Override + public int hashCode() + { + final int prime = 31; + + int result = 1; + + result = prime * result + ((password == null) ? 0 : password.hashCode()); + result = prime * result + ((securityDomain == null) ? 0 : securityDomain.hashCode()); + result = prime * result + ((userName == null) ? 0 : userName.hashCode()); + + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + + if (obj == null) + return false; + + if (!(obj instanceof DefaultSubjectFactory)) + return false; + + DefaultSubjectFactory other = (DefaultSubjectFactory) obj; + + if (password == null) + { + if (other.password != null) + return false; + } + else if (!password.equals(other.password)) + return false; + + if (securityDomain == null) + { + if (other.securityDomain != null) + return false; + } + else if (!securityDomain.equals(other.securityDomain)) + return false; + + if (userName == null) + { + if (other.userName != null) + return false; + } + else if (!userName.equals(other.userName)) + return false; + + return true; + } + + @Override + public String toString() + { + return "DefaultSubjectFactory [securityDomain=" + securityDomain + ", userName=" + userName + "]"; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,60 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.security; + +import java.io.InputStream; +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Constructor + */ + private SecurityActions() + { + } + + /** + * Get the input stream for a resource in the context class loader + * @param name The name of the resource + * @return The input stream + */ + static InputStream getResourceAsStream(final String name) + { + if (System.getSecurityManager() == null) + return Thread.currentThread().getContextClassLoader().getResourceAsStream(name); + + return AccessController.doPrivileged(new PrivilegedAction() + { + public InputStream run() + { + return Thread.currentThread().getContextClassLoader().getResourceAsStream(name); + } + }); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/SimplePrincipal.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/SimplePrincipal.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/SimplePrincipal.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,94 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.security; + +import java.io.Serializable; +import java.security.Principal; + +/** + * Simple principal implementation + * @author Jesper Pedersen + */ +public class SimplePrincipal implements Principal, Serializable +{ + private static final long serialVersionUID = 1L; + + /** Principal name */ + private final String name; + + /** + * Constructor + * @param name The principal name + */ + public SimplePrincipal(String name) + { + this.name = name; + } + + /** + * {@inheritDoc} + */ + public String getName() + { + return name; + } + + /** + * {@inheritDoc} + */ + public boolean equals(Object o) + { + if (o == this) + return true; + + if (o == null || !(o instanceof Principal)) + return false; + + Principal p = (Principal)o; + + if (name == null) + { + return p.getName() == null; + } + else + { + return name.equals(p.getName()); + } + } + + /** + * {@inheritDoc} + */ + public int hashCode() + { + return name == null ? 7 : name.hashCode(); + } + + /** + * {@inheritDoc} + */ + public String toString() + { + return name; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the security integration for the IronJacamar container. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/picketbox/PicketBoxCallbackHandler.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/picketbox/PicketBoxCallbackHandler.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/picketbox/PicketBoxCallbackHandler.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,105 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.security.picketbox; + +import org.jboss.jca.core.CoreLogger; + +import java.io.IOException; +import java.io.Serializable; +import java.util.Arrays; + +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.UnsupportedCallbackException; + +import org.jboss.logging.Logger; +import org.jboss.security.auth.callback.JASPICallbackHandler; + +/** + * An implementation of the callback SPI using PicketBox + * + * @author Jesper Pedersen + */ +public class PicketBoxCallbackHandler implements CallbackHandler, Serializable +{ + /** Serial version uid */ + private static final long serialVersionUID = 1L; + + /** Log instance */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, PicketBoxCallbackHandler.class.getName()); + + /** Callback mappings */ + private org.jboss.jca.core.spi.security.Callback mappings; + + /** + * Constructor + */ + public PicketBoxCallbackHandler() + { + this(null); + } + + /** + * Constructor + * @param mappings The mappings + */ + public PicketBoxCallbackHandler(org.jboss.jca.core.spi.security.Callback mappings) + { + this.mappings = mappings; + } + + /** + * {@inheritDoc} + */ + public void handle(javax.security.auth.callback.Callback[] callbacks) throws UnsupportedCallbackException, + IOException + { + if (log.isTraceEnabled()) + log.tracef("handle(%s)", Arrays.toString(callbacks)); + + if (callbacks != null && callbacks.length > 0) + { + if (mappings != null && mappings.isMappingRequired()) + { + callbacks = mappings.mapCallbacks(callbacks); + } + + JASPICallbackHandler jaspi = new JASPICallbackHandler(); + jaspi.handle(callbacks); + } + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("PicketBoxCallbackHandler@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[mappings=").append(mappings); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/picketbox/PicketBoxSecurityContext.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/picketbox/PicketBoxSecurityContext.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/picketbox/PicketBoxSecurityContext.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,95 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.security.picketbox; + +import org.jboss.jca.core.spi.security.SecurityContext; + +import java.util.ArrayList; +import java.util.List; + +import javax.security.auth.Subject; + +/** + * SecurityContext implementation using PicketBox + * + * @author Jesper Pedersen + */ +public class PicketBoxSecurityContext implements SecurityContext +{ + private org.jboss.security.SecurityContext delegator; + + /** + * Constructor + * @param delegator The delegator + */ + public PicketBoxSecurityContext(org.jboss.security.SecurityContext delegator) + { + this.delegator = delegator; + } + + /** + * {@inheritDoc} + */ + public Subject getAuthenticatedSubject() + { + return delegator.getSubjectInfo().getAuthenticatedSubject(); + } + + /** + * {@inheritDoc} + */ + public void setAuthenticatedSubject(Subject subject) + { + delegator.getSubjectInfo().setAuthenticatedSubject(subject); + } + + /** + * {@inheritDoc} + */ + public String[] getRoles() + { + String[] roles = null; + + org.jboss.security.identity.RoleGroup pbRoles = delegator.getUtil().getRoles(); + if (pbRoles != null) + { + List l = new ArrayList(pbRoles.getRoles().size()); + for (org.jboss.security.identity.Role role : pbRoles.getRoles()) + { + l.add(role.getRoleName()); + } + roles = l.toArray(new String[l.size()]); + } + + return roles; + } + + /** + * Get the delegator + * @return The value + */ + org.jboss.security.SecurityContext getDelegator() + { + return delegator; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/picketbox/PicketBoxSecurityIntegration.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/picketbox/PicketBoxSecurityIntegration.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/picketbox/PicketBoxSecurityIntegration.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,105 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.security.picketbox; + +import org.jboss.jca.core.spi.security.Callback; +import org.jboss.jca.core.spi.security.SecurityIntegration; + +import javax.security.auth.callback.CallbackHandler; + +import org.jboss.security.SecurityContextAssociation; +import org.jboss.security.SecurityContextFactory; + +/** + * SecurityIntegration implementation using PicketBox + * + * @author Jesper Pedersen + */ +public class PicketBoxSecurityIntegration implements SecurityIntegration +{ + /** + * Constructor + */ + public PicketBoxSecurityIntegration() + { + } + + /** + * {@inheritDoc} + */ + public org.jboss.jca.core.spi.security.SecurityContext createSecurityContext(String sd) + throws Exception + { + org.jboss.security.SecurityContext sc = SecurityContextFactory.createSecurityContext(sd); + return new PicketBoxSecurityContext(sc); + } + + /** + * {@inheritDoc} + */ + public org.jboss.jca.core.spi.security.SecurityContext getSecurityContext() + { + org.jboss.security.SecurityContext sc = SecurityContextAssociation.getSecurityContext(); + + if (sc == null) + return null; + + return new PicketBoxSecurityContext(sc); + } + + /** + * {@inheritDoc} + */ + public void setSecurityContext(org.jboss.jca.core.spi.security.SecurityContext context) + { + if (context == null) + { + SecurityContextAssociation.setSecurityContext(null); + } + else if (context instanceof PicketBoxSecurityContext) + { + PicketBoxSecurityContext psc = (PicketBoxSecurityContext)context; + SecurityContextAssociation.setSecurityContext(psc.getDelegator()); + } + else + { + throw new IllegalArgumentException("Invalid SecurityContext: " + context); + } + } + + /** + * {@inheritDoc} + */ + public CallbackHandler createCallbackHandler() + { + return new PicketBoxCallbackHandler(); + } + + /** + * {@inheritDoc} + */ + public CallbackHandler createCallbackHandler(Callback callback) + { + return new PicketBoxCallbackHandler(callback); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/picketbox/PicketBoxSubjectFactory.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/picketbox/PicketBoxSubjectFactory.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/picketbox/PicketBoxSubjectFactory.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,90 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.security.picketbox; + +import org.jboss.jca.core.CoreLogger; + +import javax.security.auth.Subject; + +import org.jboss.logging.Logger; + +/** + * A SubjectFactory implementation backed by PicketBox + * + * @author Jesper Pedersen + */ +public class PicketBoxSubjectFactory implements org.jboss.jca.core.spi.security.SubjectFactory +{ + /** Delegator */ + private org.jboss.security.SubjectFactory delegator; + + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, PicketBoxSubjectFactory.class.getName()); + + /** + * Constructor + * @param delegator The delegator + */ + public PicketBoxSubjectFactory(org.jboss.security.SubjectFactory delegator) + { + this.delegator = delegator; + } + + /** + * {@inheritDoc} + */ + public Subject createSubject() + { + return delegator.createSubject(); + } + + /** + * {@inheritDoc} + */ + public Subject createSubject(String sd) + { + Subject subject = delegator.createSubject(sd); + + if (log.isTraceEnabled()) + { + log.tracef("Subject=%s", subject); + log.tracef("Subject identity=%s", Integer.toHexString(System.identityHashCode(subject))); + } + return subject; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("PicketBoxSubjectFactory@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[delegator=").append(delegator); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/picketbox/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/picketbox/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/security/picketbox/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +PicketBox implementation of the security integration SPI + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/connectionmanager/ComponentStack.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/connectionmanager/ComponentStack.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/connectionmanager/ComponentStack.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,55 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.connectionmanager; + +import java.util.Set; + +import javax.resource.ResourceException; + +/** + * ComponentStack. + * + * @author Adrian Brock + * @author Jesper Pedersen + */ +public interface ComponentStack +{ + /** + * Push a component context + * + * @param rawKey the raw key, e.g. the servlet or ejb context + * @param unsharableResources a set of real jndi names marked as unshareable + * @throws ResourceException for any error + */ + @SuppressWarnings("unchecked") + public void pushMetaAwareObject(final Object rawKey, Set unsharableResources) throws ResourceException; + + /** + * Pop a component context + * + * @param unsharableResources a set of real jndi names marked as unshareable + * @throws ResourceException for any error + */ + @SuppressWarnings("unchecked") + public void popMetaAwareObject(Set unsharableResources) throws ResourceException; +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/connectionmanager/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/connectionmanager/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/connectionmanager/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +The package contains SPI classes for the ConnectionManager implementations. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/graceful/GracefulCallback.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/graceful/GracefulCallback.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/graceful/GracefulCallback.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,42 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.graceful; + +/** + * The graceful callback + * + * @author Jesper Pedersen + */ +public interface GracefulCallback +{ + /** + * This method is triggered when a shutdown is cancelled + */ + public void cancel(); + + /** + * This method is triggered when either there are no active + * connections, or the specified timeout has occurred + */ + public void done(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/graceful/GracefulShutdown.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/graceful/GracefulShutdown.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/graceful/GracefulShutdown.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,79 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.graceful; + +/** + * The SPI for graceful shutdown + * + * @author Jesper Pedersen + */ +public interface GracefulShutdown +{ + /** + * Cancel shutdown + * @return True if the shutdown was canceled; false otherwise + */ + public boolean cancelShutdown(); + + /** + * Signal the component to prepare for shutdown + */ + public void prepareShutdown(); + + /** + * Signal the component to prepare for shutdown + * @param cb The callback handle + */ + public void prepareShutdown(GracefulCallback cb); + + /** + * Signal the component to prepare for shutdown + * @param shutdown The number of seconds after which shutdown is forced + */ + public void prepareShutdown(int shutdown); + + /** + * Signal the component to prepare for shutdown + * @param shutdown The number of seconds after which shutdown is forced + * @param cb The callback handle + */ + public void prepareShutdown(int shutdown, GracefulCallback cb); + + /** + * Shutdown the component + */ + public void shutdown(); + + /** + * Is the component shutdown + * @return True if shutdown; false if active + */ + public boolean isShutdown(); + + /** + * Get the delay until shutdown occurs + * @return The number of seconds, Integer.MAX_VALUE for active, + * or Integer.MIN_VALUE for inactive + */ + public int getDelay(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/graceful/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/graceful/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/graceful/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the SPI for components that support a graceful shutdown mechanism. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/mdr/AlreadyExistsException.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/mdr/AlreadyExistsException.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/mdr/AlreadyExistsException.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,70 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.mdr; + +/** + * AlreadyExistsException is thrown in case a metadata entry already is registered + * + * @author Jesper Pedersen + */ +public class AlreadyExistsException extends MetadataRepositoryException +{ + /** Serial version UID */ + private static final long serialVersionUID = 1L; + + /** + * Constructor + */ + public AlreadyExistsException() + { + super(); + } + + /** + * Constructor + * @param message The exception message + */ + public AlreadyExistsException(String message) + { + super(message); + } + + /** + * Constructor + * @param message The exception message + * @param cause The cause of the exception + */ + public AlreadyExistsException(String message, Throwable cause) + { + super(message, cause); + } + + /** + * Constructor + * @param cause The cause of the exception + */ + public AlreadyExistsException(Throwable cause) + { + super(cause); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/mdr/MetadataRepository.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/mdr/MetadataRepository.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/mdr/MetadataRepository.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,126 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.mdr; + +import org.jboss.jca.common.api.metadata.resourceadapter.Activation; +import org.jboss.jca.common.api.metadata.spec.Connector; + +import java.io.File; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * The SPI for the metadata repository + * + * @author Jesper Pedersen + */ +public interface MetadataRepository +{ + /** + * Register a resource adapter template + * @param uniqueId An unique id that represents the deployment + * @param root The deployment root + * @param md The connector metadata + * @param a The Activation metadata + * @exception AlreadyExistsException Thrown if the unique id is already registered + */ + public void registerResourceAdapter(String uniqueId, File root, Connector md, Activation a) + throws AlreadyExistsException; + + /** + * Unregister a resource adapter template + * @param uniqueId An unique id that represents the deployment + * @exception NotFoundException Thrown if the unique id isn't registered + */ + public void unregisterResourceAdapter(String uniqueId) throws NotFoundException; + + /** + * Check if there exists a resource adapter for a unique id + * @param uniqueId An unique id that represents the deployment + * @return True if there is a resource adapter; otherwise false + */ + public boolean hasResourceAdapter(String uniqueId); + + /** + * Get the metadata for a resource adapter + * @param uniqueId An unique id that represents the deployment + * @return The metadata + * @exception NotFoundException Thrown if the unique id isn't registered + */ + public Connector getResourceAdapter(String uniqueId) throws NotFoundException; + + /** + * Get the resource adapters unique ids registered + * @return The unique ids + */ + public Set getResourceAdapters(); + + /** + * Get the root for a resource adapter deployment + * @param uniqueId An unique id that represents the deployment + * @return The root + * @exception NotFoundException Thrown if the unique id isn't registered + */ + public File getRoot(String uniqueId) throws NotFoundException; + + /** + * Get the Activation metadata for a resource adapter deployment + * @param uniqueId An unique id that represents the deployment + * @return The metadata + * @exception NotFoundException Thrown if the unique id isn't registered + */ + public Activation getActivation(String uniqueId) throws NotFoundException; + + /** + * Register a JNDI mapping for a unique id + * @param uniqueId An unique id that represents the deployment + * @param clz The fully qualified class name + * @param jndi The JNDI name + */ + public void registerJndiMapping(String uniqueId, String clz, String jndi); + + /** + * Unregister a JNDI mapping for a unique id + * @param uniqueId An unique id that represents the deployment + * @param clz The fully qualified class name + * @param jndi The JNDI name + * @exception NotFoundException Thrown if the unique id isn't registered + */ + public void unregisterJndiMapping(String uniqueId, String clz, String jndi) throws NotFoundException; + + /** + * Check if there exists JNDI mappings for a unique id + * @param uniqueId An unique id that represents the deployment + * @return True if there are mappings; otherwise false + */ + public boolean hasJndiMappings(String uniqueId); + + /** + * Get the JNDI mappings for a unique id + * @param uniqueId An unique id that represents the deployment + * @return The mappings + * @exception NotFoundException Thrown if the unique id isn't registered + */ + public Map> getJndiMappings(String uniqueId) throws NotFoundException; +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/mdr/MetadataRepositoryException.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/mdr/MetadataRepositoryException.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/mdr/MetadataRepositoryException.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,70 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.mdr; + +/** + * Top level exception for the metadata repository + * + * @author Jesper Pedersen + */ +public class MetadataRepositoryException extends Exception +{ + /** Serial version UID */ + private static final long serialVersionUID = 1L; + + /** + * Constructor + */ + public MetadataRepositoryException() + { + super(); + } + + /** + * Constructor + * @param message The exception message + */ + public MetadataRepositoryException(String message) + { + super(message); + } + + /** + * Constructor + * @param message The exception message + * @param cause The cause of the exception + */ + public MetadataRepositoryException(String message, Throwable cause) + { + super(message, cause); + } + + /** + * Constructor + * @param cause The cause of the exception + */ + public MetadataRepositoryException(Throwable cause) + { + super(cause); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/mdr/NotFoundException.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/mdr/NotFoundException.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/mdr/NotFoundException.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,70 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.mdr; + +/** + * NotFoundExcepion is thrown in case a metadata entry isn't found in the repository + * + * @author Jesper Pedersen + */ +public class NotFoundException extends MetadataRepositoryException +{ + /** Serial version UID */ + private static final long serialVersionUID = 1L; + + /** + * Constructor + */ + public NotFoundException() + { + super(); + } + + /** + * Constructor + * @param message The exception message + */ + public NotFoundException(String message) + { + super(message); + } + + /** + * Constructor + * @param message The exception message + * @param cause The cause of the exception + */ + public NotFoundException(String message, Throwable cause) + { + super(message, cause); + } + + /** + * Constructor + * @param cause The cause of the exception + */ + public NotFoundException(Throwable cause) + { + super(cause); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/mdr/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/mdr/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/mdr/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the metadata repository SPI. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/naming/JndiStrategy.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/naming/JndiStrategy.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/naming/JndiStrategy.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,113 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.naming; + +import javax.naming.spi.ObjectFactory; + +/** + * The SPI for a JNDI strategy + * + * @author Jesper Pedersen + */ +public interface JndiStrategy extends Cloneable, ObjectFactory +{ + /** + * Bind connection factories for a deployment + * @param deployment The deployment name + * @param cfs The connection factories + * @return The JNDI names for the connection factories + * @exception Throwable Thrown if an error occurs + */ + public String[] bindConnectionFactories(String deployment, Object[] cfs) throws Throwable; + + /** + * Bind connection factories for a deployment + * @param deployment The deployment name + * @param cfs The connection factories + * @param jndis The JNDI names for the connection factories + * @return The JNDI names for the connection factories + * @exception Throwable Thrown if an error occurs + */ + public String[] bindConnectionFactories(String deployment, Object[] cfs, String[] jndis) throws Throwable; + + /** + * Unbind connection factories for a deployment + * @param deployment The deployment name + * @param cfs The connection factories + * @exception Throwable Thrown if an error occurs + */ + public void unbindConnectionFactories(String deployment, Object[] cfs) throws Throwable; + + /** + * Unbind connection factories for a deployment + * @param deployment The deployment name + * @param cfs The connection factories + * @param jndis The JNDI names for the connection factories + * @exception Throwable Thrown if an error occurs + */ + public void unbindConnectionFactories(String deployment, Object[] cfs, String[] jndis) throws Throwable; + + /** + * Bind admin objects for a deployment + * @param deployment The deployment name + * @param aos The admin objects + * @return The JNDI names for the admin objects + * @exception Throwable Thrown if an error occurs + */ + public String[] bindAdminObjects(String deployment, Object[] aos) throws Throwable; + + /** + * Bind admin objects for a deployment + * @param deployment The deployment name + * @param aos The admin objects + * @param jndis The JNDI names for the admin objects + * @return The JNDI names for the admin objects + * @exception Throwable Thrown if an error occurs + */ + public String[] bindAdminObjects(String deployment, Object[] aos, String[] jndis) throws Throwable; + + /** + * Unbind admin objects for a deployment + * @param deployment The deployment name + * @param aos The admin objects + * @exception Throwable Thrown if an error occurs + */ + public void unbindAdminObjects(String deployment, Object[] aos) throws Throwable; + + /** + * Unbind admin objects for a deployment + * @param deployment The deployment name + * @param aos The admin objects + * @param jndis The JNDI names for the admin objects + * @exception Throwable Thrown if an error occurs + */ + public void unbindAdminObjects(String deployment, Object[] aos, String[] jndis) throws Throwable; + + /** + * Clone the JNDI strategy implementation + * @return A copy of the implementation + * @exception CloneNotSupportedException Thrown if the copy operation isn't supported + * + */ + public JndiStrategy clone() throws CloneNotSupportedException; +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/naming/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/naming/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/naming/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the SPI for the JNDI strategy for connection factory binding. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/Activation.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/Activation.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/Activation.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,60 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.rar; + +import java.util.Map; +import java.util.Set; + +import javax.resource.ResourceException; +import javax.resource.spi.ActivationSpec; + +/** + * An activation representation + * + * @author Jesper Pedersen + */ +public interface Activation +{ + /** + * Get the config-property map with name and type pair + * @return The value + */ + public Map> getConfigProperties(); + + /** + * Get the required config-property set with names + * @return The value + */ + public Set getRequiredConfigProperties(); + + /** + * Create an instance of the associated activation spec. + * @return The value + * @exception NotFoundException Thrown if the class is no longer available + * @exception InstantiationException Thrown if an object couldn't created + * @exception IllegalAccessException Thrown if object access is inaccessible + * @exception ResourceException Thrown if the activation spec can't be associated with the resource adapter + */ + public ActivationSpec createInstance() + throws NotFoundException, InstantiationException, IllegalAccessException, ResourceException; +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/AlreadyExistsException.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/AlreadyExistsException.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/AlreadyExistsException.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,70 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.rar; + +/** + * AlreadyExistsException is thrown in case the resource adapter already is registered + * + * @author Jesper Pedersen + */ +public class AlreadyExistsException extends ResourceAdapterRepositoryException +{ + /** Serial version UID */ + private static final long serialVersionUID = 1L; + + /** + * Constructor + */ + public AlreadyExistsException() + { + super(); + } + + /** + * Constructor + * @param message The exception message + */ + public AlreadyExistsException(String message) + { + super(message); + } + + /** + * Constructor + * @param message The exception message + * @param cause The cause of the exception + */ + public AlreadyExistsException(String message, Throwable cause) + { + super(message, cause); + } + + /** + * Constructor + * @param cause The cause of the exception + */ + public AlreadyExistsException(Throwable cause) + { + super(cause); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/Endpoint.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/Endpoint.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/Endpoint.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,53 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.rar; + +import javax.resource.ResourceException; +import javax.resource.spi.ActivationSpec; +import javax.resource.spi.endpoint.MessageEndpointFactory; + +/** + * An endpoint representation + * + * @author Jesper Pedersen + */ +public interface Endpoint +{ + /** + * Activate an endpoint + * @param endpointFactory The message endpoint factory that should be used for the endpoint + * @param spec The activation spec that should be used for the endpoint + * @exception ResourceException Thrown if an error occurs + */ + public void activate(MessageEndpointFactory endpointFactory, + ActivationSpec spec) throws ResourceException; + + /** + * Deactivate an endpoint + * @param endpointFactory The message endpoint factory that should be used for the endpoint + * @param spec The activation spec that should be used for the endpoint + * @exception ResourceException Thrown if an error occurs + */ + public void deactivate(MessageEndpointFactory endpointFactory, + ActivationSpec spec) throws ResourceException; +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/MessageListener.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/MessageListener.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/MessageListener.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,43 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.rar; + +/** + * A message listener representation + * + * @author Jesper Pedersen + */ +public interface MessageListener +{ + /** + * Get the message listener type + * @return The value + */ + public Class getType(); + + /** + * Get the activation for the listener + * @return The value + */ + public Activation getActivation(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/NotFoundException.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/NotFoundException.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/NotFoundException.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,70 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.rar; + +/** + * NotFoundExcepion is thrown in case a resource adapter isn't found in the repository + * + * @author Jesper Pedersen + */ +public class NotFoundException extends ResourceAdapterRepositoryException +{ + /** Serial version UID */ + private static final long serialVersionUID = 1L; + + /** + * Constructor + */ + public NotFoundException() + { + super(); + } + + /** + * Constructor + * @param message The exception message + */ + public NotFoundException(String message) + { + super(message); + } + + /** + * Constructor + * @param message The exception message + * @param cause The cause of the exception + */ + public NotFoundException(String message, Throwable cause) + { + super(message, cause); + } + + /** + * Constructor + * @param cause The cause of the exception + */ + public NotFoundException(Throwable cause) + { + super(cause); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/ResourceAdapterRepository.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/ResourceAdapterRepository.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/ResourceAdapterRepository.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,100 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.rar; + +import java.util.List; +import java.util.Set; + +import javax.resource.spi.ResourceAdapter; + +/** + * The SPI for the resource adapter repository + * + * @author Jesper Pedersen + */ +public interface ResourceAdapterRepository +{ + /** + * Register a resource adapter + * @param ra The resource adapter instance + * @return The unique id for the resource adapter + */ + public String registerResourceAdapter(ResourceAdapter ra); + + /** + * Unregister a resource adapter + * @param key The key for the resource adapter instance + * @exception NotFoundException Thrown if the unique id isn't registered + */ + public void unregisterResourceAdapter(String key) throws NotFoundException; + + /** + * Get the resource adapter instance based on the unique id + * @param uniqueId An unique id that represents the deployment + * @return The resource adapter + * @exception NotFoundException Thrown if the unique id isn't registered + */ + public ResourceAdapter getResourceAdapter(String uniqueId) throws NotFoundException; + + /** + * Get the resource adapters unique ids registered + * @return The unique ids + */ + public Set getResourceAdapters(); + + /** + * Get the resource adapters unique ids registered which has the specified + * message listener type + * @param messageListenerType The message listener type + * @return The unique ids + */ + public Set getResourceAdapters(Class messageListenerType); + + /** + * Get an endpoint representation for a resource adapter + * @param uniqueId An unique id that represents the deployment + * @return The endpoint + * @exception NotFoundException Thrown if the unique id isn't registered + */ + public Endpoint getEndpoint(String uniqueId) throws NotFoundException; + + /** + * Get a list of message listeners supported for a resource adapter + * @param uniqueId An unique id that represents the deployment + * @return The list of message listeners + * @exception NotFoundException Thrown if the unique id isn't registered + * @exception InstantiationException Thrown if an object couldn't created + * @exception IllegalAccessException Thrown if object access is inaccessible + */ + public List getMessageListeners(String uniqueId) + throws NotFoundException, InstantiationException, IllegalAccessException; + + /** + * Set the recovery mode for a resource adapter + * @param uniqueId An unique id that represents the deployment + * @param isXA Is the resource adapter instance XA capable + * @exception NotFoundException Thrown if the unique id isn't registered + */ + public void setRecoveryForResourceAdapter(String uniqueId, boolean isXA) + throws NotFoundException; +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/ResourceAdapterRepositoryException.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/ResourceAdapterRepositoryException.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/ResourceAdapterRepositoryException.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,70 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.rar; + +/** + * Top level exception for the resource adapter repository + * + * @author Jesper Pedersen + */ +public class ResourceAdapterRepositoryException extends Exception +{ + /** Serial version UID */ + private static final long serialVersionUID = 1L; + + /** + * Constructor + */ + public ResourceAdapterRepositoryException() + { + super(); + } + + /** + * Constructor + * @param message The exception message + */ + public ResourceAdapterRepositoryException(String message) + { + super(message); + } + + /** + * Constructor + * @param message The exception message + * @param cause The cause of the exception + */ + public ResourceAdapterRepositoryException(String message, Throwable cause) + { + super(message, cause); + } + + /** + * Constructor + * @param cause The cause of the exception + */ + public ResourceAdapterRepositoryException(Throwable cause) + { + super(cause); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/rar/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the SPI for the resource adapter service registry. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/recovery/RecoveryPlugin.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/recovery/RecoveryPlugin.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/recovery/RecoveryPlugin.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,63 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.recovery; + +import javax.resource.ResourceException; + +/** + * Defines the contract for an XA recovery plugin. + * + * An implementation of this SPI can provide feedback to the JCA container + * if the physinal connection is still valid to use for getting recovery information + * from. + * + * An implementation of this SPI must have a default constructor and will have + * its Java bean properties set after initialization. + * + * @author Stefano Maestri + * @author Jesper Pedersen + */ +public interface RecoveryPlugin +{ + /** + * Check if the passed connection object instance is still valid, and hence + * the underlying physical connection + * + * @param c The connection instance + * @return True if the connection is still valid, otherwise false + * @exception ResourceException Thrown in case of an error + */ + public boolean isValid(Object c) throws ResourceException; + + /** + * Perform a close operation on the passed connection object instance - like + * a CCI Connection instance. + * + * Any error during this operation should result in an exception, which + * will force a close of the physical connection to the Enterprise Information System + * + * @param c The connection instance + * @exception ResourceException Thrown in case of an error + * @see javax.resource.cci.Connection + */ + public void close(Object c) throws ResourceException; +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/recovery/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/recovery/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/recovery/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the XA recovery extension. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/security/Callback.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/security/Callback.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/security/Callback.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,93 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.security; + +import java.io.Serializable; +import java.security.Principal; + +/** + * This SPI interface represents the security inflow contract in + * the container environment + * + * @author Jesper Pedersen + */ +public interface Callback extends Serializable +{ + /** + * Get the domain + * @return The domain + */ + public String getDomain(); + + /** + * Is an user mapping required + * @return The value + */ + public boolean isMappingRequired(); + + /** + * Get the default principal + * @return The value; null if no default principal + */ + public Principal getDefaultPrincipal(); + + /** + * Get the default groups + * @return The value; null if no default groups + */ + public String[] getDefaultGroups(); + + /** + * Map a principal + * @param name The principal name + * @return The value; null if no mapping could be found + */ + public Principal mapPrincipal(String name); + + /** + * Map a group + * @param name The group name + * @return The value; null if no mapping could be found + */ + public String mapGroup(String name); + + /** + * Applies all mappings in the array of {@code Callback} objects. + * + * @param callbacks an array of callbacks that will be mapped + * @return the new array of mapped callbacks + */ + public javax.security.auth.callback.Callback[] mapCallbacks(javax.security.auth.callback.Callback[] callbacks); + + /** + * Start + * @exception Throwable Thrown if an error occurs + */ + public void start() throws Throwable; + + /** + * Stop + * @exception Throwable Thrown if an error occurs + */ + public void stop() throws Throwable; +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/security/SecurityContext.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/security/SecurityContext.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/security/SecurityContext.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,51 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.security; + +import javax.security.auth.Subject; + +/** + * SecurityContext + * + * @author Jesper Pedersen + */ +public interface SecurityContext +{ + /** + * Get the authenticated subject + * @return The Subject, or null if unauthenticated + */ + public Subject getAuthenticatedSubject(); + + /** + * Set the authenticated subject + * @param subject The Subject + */ + public void setAuthenticatedSubject(Subject subject); + + /** + * Get the associated role names + * @return The role names, or null if none + */ + public String[] getRoles(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/security/SecurityIntegration.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/security/SecurityIntegration.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/security/SecurityIntegration.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,68 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.security; + +import javax.security.auth.callback.CallbackHandler; + +/** + * SecurityIntegration + * + * @author Jesper Pedersen + */ +public interface SecurityIntegration +{ + /** + * Create a security context + * @param sd The security domain + * @return The context + * @exception Exception Thrown in case of an error + */ + public SecurityContext createSecurityContext(String sd) throws Exception; + + /** + * Get the security context + * @return The context, or null if unset + */ + public SecurityContext getSecurityContext(); + + /** + * Set the security context + * @param context The context + */ + public void setSecurityContext(SecurityContext context); + + /** + * Create a default callback handler + * @return The handler + */ + public CallbackHandler createCallbackHandler(); + + /** + * Create a callback handler + * @param callback The callback configuration + * @return The handler + */ + public CallbackHandler createCallbackHandler(Callback callback); + + +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/security/SubjectFactory.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/security/SubjectFactory.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/security/SubjectFactory.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,46 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.security; + +import javax.security.auth.Subject; + +/** + * Subject factory + * + * @author Jesper Pedersen + */ +public interface SubjectFactory +{ + /** + * Create a Subject instance based on the default policy of the implementation + * @return The Subject + */ + public Subject createSubject(); + + /** + * Create a Subject instance + * @param sd The security domain + * @return The Subject + */ + public Subject createSubject(String sd); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/security/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/security/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/security/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the security SPI for the IronJacamar container. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/statistics/Statistics.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/statistics/Statistics.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/statistics/Statistics.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,39 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.statistics; + +/** + * Defines the contract for a statistics enabled resource adapter. + * + * This interface can be applied to ManagedConnectionFactory, ResourceAdapter + * and AdminObject instances. + * + * @author Jesper Pedersen + */ +public interface Statistics +{ + /** + * Get the statistics plugin + * @return The value + */ + public StatisticsPlugin getStatistics(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/statistics/StatisticsPlugin.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/statistics/StatisticsPlugin.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/statistics/StatisticsPlugin.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,86 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.statistics; + +import java.io.Serializable; +import java.util.Locale; +import java.util.Set; + +/** + * Defines the contract for a statistics plugin. + * + * @author Jesper Pedersen + */ +public interface StatisticsPlugin extends Serializable +{ + /** + * Get the statistics names + * @return The value + */ + public Set getNames(); + + /** + * Get the type + * @param name The name of the statistics + * @return The value + */ + public Class getType(String name); + + /** + * Get the description + * @param name The name of the statistics + * @return The value + */ + public String getDescription(String name); + + /** + * Get the description + * @param name The name of the statistics + * @param locale The locale + * @return The value + */ + public String getDescription(String name, Locale locale); + + /** + * Get the value of the statistics + * @param name The name of the statistics + * @return The value + */ + public Object getValue(String name); + + /** + * Is the statistics module enabled + * @return The value + */ + public boolean isEnabled(); + + /** + * Set the statistics module enabled + * @param v The value + */ + public void setEnabled(boolean v); + + /** + * Clear all statistics + */ + public void clear(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/statistics/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/statistics/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/statistics/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the SPI for exposing statistics information from the resource adapter. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/ConnectableResource.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/ConnectableResource.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/ConnectableResource.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,44 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction; + +/** + * Defines a resource as connectable, which allows the transaction manager + * to get access to the connection used by the transaction + * + * @author Jesper Pedersen + */ +public interface ConnectableResource +{ + /** + * Get a connection from the resource + * @return The connection + * @exception Exception If an error occurs + */ + public Object getConnection() throws Exception; + + /** + * Set connectable resource listener + * @param crl The connectable resource listener + */ + public void setConnectableResourceListener(ConnectableResourceListener crl); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/ConnectableResourceListener.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/ConnectableResourceListener.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/ConnectableResourceListener.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,42 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction; + +/** + * Defines a listener interface for ConnectableResource handles + * + * @author Jesper Pedersen + */ +public interface ConnectableResourceListener +{ + /** + * Handle created + * @param h The handle + */ + public void handleCreated(Object h); + + /** + * Handle closed + * @param h The handle + */ + public void handleClosed(Object h); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/FirstResource.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/FirstResource.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/FirstResource.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,32 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction; + +/** + * A tagging interface to identify an XAResource that should be considered + * the first resource, e.g. prepared first. + * + * @author Jesper Pedersen + */ +public interface FirstResource +{ +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/LastResource.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/LastResource.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/LastResource.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,35 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction; + +/** + * A tagging interface to identify an XAResource that does + * not support prepare and should be used in the last resource + * gambit. i.e. It is committed after the resources are + * prepared. If it fails to commit, roll everybody back. + * + * @author Adrian Brock + * @author Jesper Pedersen + */ +public interface LastResource +{ +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/TransactionIntegration.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/TransactionIntegration.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/TransactionIntegration.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,244 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction; + +import org.jboss.jca.core.api.connectionmanager.ConnectionManager; +import org.jboss.jca.core.spi.recovery.RecoveryPlugin; +import org.jboss.jca.core.spi.security.SubjectFactory; +import org.jboss.jca.core.spi.transaction.local.LocalXAResource; +import org.jboss.jca.core.spi.transaction.recovery.XAResourceRecovery; +import org.jboss.jca.core.spi.transaction.recovery.XAResourceRecoveryRegistry; +import org.jboss.jca.core.spi.transaction.usertx.UserTransactionRegistry; +import org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper; +import org.jboss.jca.core.spi.transaction.xa.XATerminator; + +import javax.resource.spi.ActivationSpec; +import javax.resource.spi.ManagedConnection; +import javax.resource.spi.ManagedConnectionFactory; +import javax.resource.spi.ResourceAdapter; +import javax.transaction.Transaction; +import javax.transaction.TransactionManager; +import javax.transaction.TransactionSynchronizationRegistry; +import javax.transaction.xa.XAResource; + +/** + * This interface defines the contract for a transaction manager integration + * with the IronJacamar container. + * + * The methods allows the IronJacamar container to create or get transaction + * related information from the transaction manager implementation and allows + * the implementation of this information to be specific for each instance of + * this interface. + * + * If a feature isn't supported by the transaction manager a null + * value should be returned. That way it is disabled in the IronJacamar container. + * + * @author Jesper Pedersen + */ +public interface TransactionIntegration +{ + /** + * Get the transaction manager + * @return The value + */ + public TransactionManager getTransactionManager(); + + /** + * Get the transaction synchronization registry + * @return The value + */ + public TransactionSynchronizationRegistry getTransactionSynchronizationRegistry(); + + /** + * Get the user transaction registry + * @return The value + */ + public UserTransactionRegistry getUserTransactionRegistry(); + + /** + * Get the recovery registry + * @return The value + */ + public XAResourceRecoveryRegistry getRecoveryRegistry(); + + /** + * Get the XATerminator + * @return The value + */ + public XATerminator getXATerminator(); + + /** + * Create an XAResourceRecovery instance + * + * @param rar The resource adapter + * @param as The activation spec + * @param productName The product name + * @param productVersion The product version + * @return The value + */ + public XAResourceRecovery createXAResourceRecovery(ResourceAdapter rar, + ActivationSpec as, + String productName, String productVersion); + + /** + * Create an XAResourceRecovery instance + * + * @param mcf The managed connection factory + * @param pad Should the branch qualifier for Xid's be padded + * @param override Should the isSameRM value be overriden; null for instance equally check + * @param wrapXAResource Should the XAResource be wrapped + * @param recoverUserName The user name for recovery + * @param recoverPassword The password for recovery + * @param recoverSecurityDomain The security domain for recovery + * @param subjectFactory The subject factory + * @param plugin The recovery plugin + * @param xastat The XAResource statistics implementation + * @return The value + */ + public XAResourceRecovery createXAResourceRecovery(ManagedConnectionFactory mcf, + Boolean pad, Boolean override, + Boolean wrapXAResource, + String recoverUserName, String recoverPassword, + String recoverSecurityDomain, + SubjectFactory subjectFactory, + RecoveryPlugin plugin, + XAResourceStatistics xastat); + + /** + * Create a LocalXAResource instance + * @param cm The connection manager + * @param productName The product name + * @param productVersion The product version + * @param jndiName The JNDI name for the resource + * @param xastat The XAResource statistics implementation + * @return The value + */ + public LocalXAResource createLocalXAResource(ConnectionManager cm, + String productName, String productVersion, + String jndiName, + XAResourceStatistics xastat); + + /** + * Create a connectable LocalXAResource instance + * @param cm The connection manager + * @param productName The product name + * @param productVersion The product version + * @param jndiName The JNDI name for the resource + * @param cr The connectable resource + * @param xastat The XAResource statistics implementation + * @return The value + */ + public LocalXAResource createConnectableLocalXAResource(ConnectionManager cm, + String productName, String productVersion, + String jndiName, ConnectableResource cr, + XAResourceStatistics xastat); + + /** + * Create a connectable LocalXAResource instance + * @param cm The connection manager + * @param productName The product name + * @param productVersion The product version + * @param jndiName The JNDI name for the resource + * @param mc The managed connection + * @param xastat The XAResource statistics implementation + * @return The value + */ + public LocalXAResource createConnectableLocalXAResource(ConnectionManager cm, + String productName, String productVersion, + String jndiName, ManagedConnection mc, + XAResourceStatistics xastat); + + /** + * Create an XAResource wrapper instance + * @param xares The XAResource instance + * @param pad Should the branch qualifier for Xid's be padded + * @param override Should the isSameRM value be overriden; null for instance equally check + * @param productName The product name + * @param productVersion The product version + * @param jndiName The JNDI name for the resource + * @param firstResource Is the resource a first resource + * @param xastat The XAResource statistics implementation + * @return The value + */ + public XAResourceWrapper createXAResourceWrapper(XAResource xares, + boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, boolean firstResource, + XAResourceStatistics xastat); + + /** + * Create a connectable XAResource wrapper instance + * @param xares The XAResource instance + * @param pad Should the branch qualifier for Xid's be padded + * @param override Should the isSameRM value be overriden; null for instance equally check + * @param productName The product name + * @param productVersion The product version + * @param jndiName The JNDI name for the resource + * @param cr The connectable resource + * @param xastat The XAResource statistics implementation + * @return The value + */ + public XAResourceWrapper createConnectableXAResourceWrapper(XAResource xares, + boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, ConnectableResource cr, + XAResourceStatistics xastat); + + /** + * Create a connectable XAResource wrapper instance + * @param xares The XAResource instance + * @param pad Should the branch qualifier for Xid's be padded + * @param override Should the isSameRM value be overriden; null for instance equally check + * @param productName The product name + * @param productVersion The product version + * @param jndiName The JNDI name for the resource + * @param mc The managed connection + * @param xastat The XAResource statistics implementation + * @return The value + */ + public XAResourceWrapper createConnectableXAResourceWrapper(XAResource xares, + boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, ManagedConnection mc, + XAResourceStatistics xastat); + + /** + * Is a first resource + * @param mc The managed connection + * @return The value + */ + public boolean isFirstResource(ManagedConnection mc); + + /** + * Is a connectable resource + * @param mc The managed connection + * @return The value + */ + public boolean isConnectableResource(ManagedConnection mc); + + /** + * Get the identifier for the transaction + * @param tx The transaction + * @return Its stable identifier + */ + public Object getIdentifier(Transaction tx); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/TransactionTimeoutConfiguration.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/TransactionTimeoutConfiguration.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/TransactionTimeoutConfiguration.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,55 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.transaction; + +import javax.transaction.RollbackException; +import javax.transaction.SystemException; + +/** + * The interface to implementated by a transaction manager + * that supports retrieving the current threads transaction timeout + * + * @author Adrian Brock + * @author Jesper Pedersen + */ +public interface TransactionTimeoutConfiguration +{ + /** + * Get the transaction timeout. + * + * @return The timeout in seconds associated with this thread + * @throws SystemException For any error + */ + public int getTransactionTimeout() throws SystemException; + + /** + * Get the time left before transaction timeout. + * + * @param errorRollback throw an error if the transaction is marked for rollback + * @return The remaining in the current transaction or -1 + * if there is no transaction + * @throws RollbackException If the transaction is marked for rollback and + * errorRollback is true + */ + public long getTimeLeftBeforeTransactionTimeout(boolean errorRollback) throws RollbackException; +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/TxUtils.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/TxUtils.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/TxUtils.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,143 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction; + +import javax.transaction.Status; +import javax.transaction.SystemException; +import javax.transaction.Transaction; + +/** + * Helper methods for transaction status and textual representation + * + * @author Jesper Pedersen + */ +public class TxUtils +{ + /** Transaction status strings */ + private static final String[] TX_STATUS_STRINGS = + { + "STATUS_ACTIVE", + "STATUS_MARKED_ROLLBACK", + "STATUS_PREPARED", + "STATUS_COMMITTED", + "STATUS_ROLLEDBACK", + "STATUS_UNKNOWN", + "STATUS_NO_TRANSACTION", + "STATUS_PREPARING", + "STATUS_COMMITTING", + "STATUS_ROLLING_BACK" + }; + + /** + * No instances + */ + private TxUtils() + { + } + + /** + * Is the transaction active + * @param tx The transaction + * @return True if active; otherwise false + */ + public static boolean isActive(Transaction tx) + { + if (tx == null) + return false; + + try + { + int status = tx.getStatus(); + + return status == Status.STATUS_ACTIVE; + } + catch (SystemException error) + { + throw new RuntimeException("Error during isActive()", error); + } + } + + /** + * Is the transaction uncommitted + * @param tx The transaction + * @return True if uncommitted; otherwise false + */ + public static boolean isUncommitted(Transaction tx) + { + if (tx == null) + return false; + + try + { + int status = tx.getStatus(); + + return status == Status.STATUS_ACTIVE || status == Status.STATUS_MARKED_ROLLBACK; + } + catch (SystemException error) + { + throw new RuntimeException("Error during isUncommitted()", error); + } + } + + /** + * Is the transaction completed + * @param tx The transaction + * @return True if completed; otherwise false + */ + public static boolean isCompleted(Transaction tx) + { + if (tx == null) + return true; + + try + { + int status = tx.getStatus(); + + return status == Status.STATUS_COMMITTED || + status == Status.STATUS_ROLLEDBACK || + status == Status.STATUS_NO_TRANSACTION; + } + catch (SystemException error) + { + throw new RuntimeException("Error during isCompleted()", error); + } + } + + /** + * Converts a transaction status to a text representation + * + * @param status The status index + * @return status as String or "STATUS_INVALID(value)" + * @see javax.transaction.Status + */ + public static String getStatusAsString(int status) + { + if (status >= Status.STATUS_ACTIVE && status <= Status.STATUS_ROLLING_BACK) + { + return TX_STATUS_STRINGS[status]; + } + else + { + return "STATUS_INVALID(" + status + ")"; + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/XAResourceStatistics.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/XAResourceStatistics.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/XAResourceStatistics.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,242 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction; + +import org.jboss.jca.core.spi.statistics.StatisticsPlugin; + +/** + * XAResource statistics + * + * @author Jesper Pedersen + */ +public interface XAResourceStatistics extends StatisticsPlugin +{ + /** + * Get the commit count + * @return The value + */ + public long getCommitCount(); + + /** + * Get the commit total time (milliseconds) + * @return The value + */ + public long getCommitTotalTime(); + + /** + * Get the commit average time (milliseconds) + * @return The value + */ + public long getCommitAverageTime(); + + /** + * Get the commit max time (milliseconds) + * @return The value + */ + public long getCommitMaxTime(); + + /** + * Delta commit + * @param time The milliseconds + */ + public void deltaCommit(long time); + + /** + * Get the end count + * @return The value + */ + public long getEndCount(); + + /** + * Get the end total time (milliseconds) + * @return The value + */ + public long getEndTotalTime(); + + /** + * Get the end average time (milliseconds) + * @return The value + */ + public long getEndAverageTime(); + + /** + * Get the end max time (milliseconds) + * @return The value + */ + public long getEndMaxTime(); + + /** + * Delta end + * @param time The milliseconds + */ + public void deltaEnd(long time); + + /** + * Get the forget count + * @return The value + */ + public long getForgetCount(); + + /** + * Get the forget total time (milliseconds) + * @return The value + */ + public long getForgetTotalTime(); + + /** + * Get the forget average time (milliseconds) + * @return The value + */ + public long getForgetAverageTime(); + + /** + * Get the forget max time (milliseconds) + * @return The value + */ + public long getForgetMaxTime(); + + /** + * Delta forget + * @param time The milliseconds + */ + public void deltaForget(long time); + + /** + * Get the prepare count + * @return The value + */ + public long getPrepareCount(); + + /** + * Get the prepare total time (milliseconds) + * @return The value + */ + public long getPrepareTotalTime(); + + /** + * Get the prepare average time (milliseconds) + * @return The value + */ + public long getPrepareAverageTime(); + + /** + * Get the prepare max time (milliseconds) + * @return The value + */ + public long getPrepareMaxTime(); + + /** + * Delta prepare + * @param time The milliseconds + */ + public void deltaPrepare(long time); + + /** + * Get the recover count + * @return The value + */ + public long getRecoverCount(); + + /** + * Get the recover total time (milliseconds) + * @return The value + */ + public long getRecoverTotalTime(); + + /** + * Get the recover average time (milliseconds) + * @return The value + */ + public long getRecoverAverageTime(); + + /** + * Get the recover max time (milliseconds) + * @return The value + */ + public long getRecoverMaxTime(); + + /** + * Delta recover + * @param time The milliseconds + */ + public void deltaRecover(long time); + + /** + * Get the rollback count + * @return The value + */ + public long getRollbackCount(); + + /** + * Get the rollback total time (milliseconds) + * @return The value + */ + public long getRollbackTotalTime(); + + /** + * Get the rollback average time (milliseconds) + * @return The value + */ + public long getRollbackAverageTime(); + + /** + * Get the rollback max time (milliseconds) + * @return The value + */ + public long getRollbackMaxTime(); + + /** + * Delta rollback + * @param time The milliseconds + */ + public void deltaRollback(long time); + + /** + * Get the start count + * @return The value + */ + public long getStartCount(); + + /** + * Get the start total time (milliseconds) + * @return The value + */ + public long getStartTotalTime(); + + /** + * Get the start average time (milliseconds) + * @return The value + */ + public long getStartAverageTime(); + + /** + * Get the start max time (milliseconds) + * @return The value + */ + public long getStartMaxTime(); + + /** + * Delta start + * @param time The milliseconds + */ + public void deltaStart(long time); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/local/LocalResourceException.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/local/LocalResourceException.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/local/LocalResourceException.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,58 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2015, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction.local; + +import javax.resource.ResourceException; + +/** + * LocalResourceException. + *

+ * Throwing this exception from your LocalTransaction.commit() or + * LocalTransaction.rollback() methods will result in a + * XAException.XAER_RMFAIL error code being sent to the transaction manager + * + * @author Jesper Pedersen + */ +public class LocalResourceException extends ResourceException +{ + /** Serial version UID */ + private static final long serialVersionUID = 1L; + + /** + * Creates a new instance. + * @param message message + */ + public LocalResourceException(String message) + { + this(message, null); + } + + /** + * Creates a new instance. + * @param message message + * @param t cause + */ + public LocalResourceException(String message, Throwable t) + { + super(message, t); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/local/LocalXAException.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/local/LocalXAException.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/local/LocalXAException.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,58 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction.local; + +import javax.transaction.xa.XAException; + +/** + * LocalXAException + * + * @author Jesper Pedersen + */ +public class LocalXAException extends XAException +{ + /** Serial version UID */ + private static final long serialVersionUID = 1299192262106064112L; + + /** + * Creates a new instance. + * @param message message + * @param errorcode error code + */ + public LocalXAException(String message, int errorcode) + { + this(message, errorcode, null); + } + + /** + * Creates a new instance. + * @param message message + * @param t cause + * @param errorcode error code + */ + public LocalXAException(String message, int errorcode, Throwable t) + { + super(message); + this.errorCode = errorcode; + initCause(t); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/local/LocalXAResource.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/local/LocalXAResource.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/local/LocalXAResource.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,48 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction.local; + +import org.jboss.jca.core.api.connectionmanager.ConnectionManager; +import org.jboss.jca.core.api.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.spi.transaction.LastResource; + +import javax.transaction.xa.XAResource; + +/** + * Local XA resource. + * + * @author Jesper Pedersen + */ +public interface LocalXAResource extends XAResource, LastResource +{ + /** + * Set the connection manager. + * @param cm The value + */ + public void setConnectionManager(ConnectionManager cm); + + /** + * Set the connection listener. + * @param cl The value + */ + public void setConnectionListener(ConnectionListener cl); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/local/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/local/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/local/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains extensions towards LocalTransaction. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the transaction SPI that defines extensions to JTA 1.1 + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/recovery/XAResourceRecovery.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/recovery/XAResourceRecovery.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/recovery/XAResourceRecovery.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,69 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction.recovery; + +import javax.transaction.xa.XAResource; + +/** + * During recovery of crashed XA transactions, the transaction system may use instances + * of this interface to obtain XAResources on which to perform recovery calls. + * Resource managers should register instances of this interface with the transaction + * recovery system via an XAResourceRecoveryRegistry. + * + * @author Jonathan Halliday (jonathan.halliday@redhat.com) + * @see XAResourceRecoveryRegistry + */ +public interface XAResourceRecovery +{ + /** + * Initialize the recovery plugin + * @exception Exception If an error occurs + */ + public void initialize() throws Exception; + + /** + * Shutdown the recovery plugin + * @exception Exception If an error occurs + */ + public void shutdown() throws Exception; + + /** + * Provides XAResource(s) to the transaction system for recovery purposes. + * + * @return An array of XAResource objects for use in transaction recovery + * In most cases the implementation will need to return only a single XAResource in the array. + * For more sophisticated cases, such as where multiple different connection types are supported, + * it may be necessary to return more than one. + * + * The Resource should be instantiated in such a way as to carry the necessary permissions to + * allow transaction recovery. For some deployments it may therefore be necessary or desirable to + * provide resource(s) based on e.g. database connection parameters such as username other than those + * used for the regular application connections to the same resource manager. + */ + public XAResource[] getXAResources(); + + /** + * Set the JNDI name for the resource + * @param jndiName The value + */ + public void setJndiName(String jndiName); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/recovery/XAResourceRecoveryRegistry.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/recovery/XAResourceRecoveryRegistry.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/recovery/XAResourceRecoveryRegistry.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,76 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction.recovery; + +/** + * The transaction management system may require assistance from resource + * managers in order to recover crashed XA transactions. By registering + * an XAResourceRecovery instance with the XAResourceRecoveryRegistry, + * resource manager connectors provide a way for the recovery system to + * callback to them and obtain the necessary information. + * + * This is useful for e.g. JDBC connection pools or JCA connectors that + * don't want to expose connection parameters to the transaction system. + * The connectors are responsible for instantiating a connection and + * using it to instantiate a set of XAResources. These are then exposed to + * the recovery system via the registered XAResourceRecovery instance. + * + * @author Jonathan Halliday (jonathan.halliday@redhat.com) + * @version $Revision$ + * @see XAResourceRecovery + */ +public interface XAResourceRecoveryRegistry +{ + /* + Implementor's note: + Although the transaction manager in JBossAS is pluggable, reading the JBossTS + recovery documentation may give some insight into the design of this + recovery system interface. The forum thread at + http://www.jboss.com/index.html?module=bb&op=viewtopic&t=100435 + may also be of interest. + */ + + /** + * Register an XAResourceRecovery instance with the transaction recovery system. + * This should be called by deployers that are deploying a new XA aware + * module that needs recovery support. For example, a database + * connection pool, JMS adapter or JCA connector. + * + * @param recovery The XAResourceRecovery instance to register. + */ + public void addXAResourceRecovery(XAResourceRecovery recovery); + + /** + * Unregister an XAResourceRecovery instance from the transaction recovery system. + * This should be called when an XA aware module is undeployed, to inform the + * recovery system that recovery is no longer required or supported. + * + * Note this method may block whilst an ongoing recovery operation is completed. + * Recovery behavior is undefined if the undeployment does not wait for this + * operation to complete. + * + * @param recovery The XAResourceRecovery instance to unregister. + * Implementations should fail silent if an attempt is made to unregister + * an XAResourceRecovery instance that is not currently registered. + */ + public void removeXAResourceRecovery(XAResourceRecovery recovery); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/recovery/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/recovery/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/recovery/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package defines a recovery extension. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/usertx/UserTransactionListener.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/usertx/UserTransactionListener.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/usertx/UserTransactionListener.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,40 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction.usertx; + +import java.util.EventListener; + +import javax.transaction.SystemException; + +/** + * UserTransactionListener. + * + * @author Jesper Pedersen + */ +public interface UserTransactionListener extends EventListener +{ + /** + * An user transaction has started + * @exception SystemException Thrown in case of an error + */ + public void userTransactionStarted() throws SystemException; +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/usertx/UserTransactionProvider.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/usertx/UserTransactionProvider.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/usertx/UserTransactionProvider.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,36 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction.usertx; + +/** + * UserTransactionProvider. + * + * @author Jesper Pedersen + */ +public interface UserTransactionProvider +{ + /** + * Set the user transaction registry + * @param v The value + */ + public void setUserTransactionRegistry(UserTransactionRegistry v); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/usertx/UserTransactionRegistry.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/usertx/UserTransactionRegistry.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/usertx/UserTransactionRegistry.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,59 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction.usertx; + +/** + * UserTransactionRegistry. + * + * @author Jesper Pedersen + */ +public interface UserTransactionRegistry +{ + /** + * Add a listener + * @param listener The listener + */ + public void addListener(UserTransactionListener listener); + + /** + * Remove a listener + * @param listener The listener + */ + public void removeListener(UserTransactionListener listener); + + /** + * Add a provider + * @param provider The provider + */ + public void addProvider(UserTransactionProvider provider); + + /** + * Remove a provider + * @param provider The provider + */ + public void removeProvider(UserTransactionProvider provider); + + /** + * Fire a user transaction started event + */ + public void userTransactionStarted(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/usertx/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/usertx/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/usertx/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains interfaces and classes for integration with UserTransactions. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/xa/XAResourceWrapper.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/xa/XAResourceWrapper.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/xa/XAResourceWrapper.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,56 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction.xa; + +import javax.transaction.xa.XAResource; + +/** + * An XAResource wrapper. + * + * @author Jesper Pedersen + */ +public interface XAResourceWrapper extends XAResource +{ + /** + * Get the XAResource that is being wrapped + * @return The XAResource + */ + public XAResource getResource(); + + /** + * Get product name + * @return Product name of the instance that created the wrapper if defined; otherwise null + */ + public String getProductName(); + + /** + * Get product version + * @return Product version of the instance that created the warpper if defined; otherwise null + */ + public String getProductVersion(); + + /** + * Get the JNDI name + * @return The value + */ + public String getJndiName(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/xa/XATerminator.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/xa/XATerminator.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/xa/XATerminator.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,73 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction.xa; + +import javax.resource.spi.work.Work; +import javax.resource.spi.work.WorkCompletedException; +import javax.transaction.xa.Xid; + +/** + * Extends XATerminator to include registration calls + * + * @author Adrian Brock + * @author Jesper Pedersen + */ +public interface XATerminator extends javax.resource.spi.XATerminator +{ + /** + * Invoked for transaction inflow of work + * + * @param work The work starting + * @param xid The xid of the work + * @param timeout The transaction timeout + * @throws WorkCompletedException with error code WorkException.TX_CONCURRENT_WORK_DISALLOWED + * when work is already present for the xid or whose completion is in progress, only + * the global part of the xid must be used for this check. + */ + public void registerWork(Work work, Xid xid, long timeout) throws WorkCompletedException; + + /** + * Invoked for transaction inflow of work + * + * @param work The work starting + * @param xid The xid of the work + * @throws WorkCompletedException With error code WorkException.TX_RECREATE_FAILED if it is unable + * to recreate the transaction context + */ + public void startWork(Work work, Xid xid) throws WorkCompletedException; + + /** + * Invoked when transaction inflow work ends + * + * @param work The work ending + * @param xid The xid of the work + */ + public void endWork(Work work, Xid xid); + + /** + * Invoked when the work fails + * + * @param work The work ending + * @param xid The xid of the work + */ + public void cancelWork(Work work, Xid xid); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/xa/XidWrapper.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/xa/XidWrapper.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/xa/XidWrapper.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,39 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.spi.transaction.xa; + +import javax.transaction.xa.Xid; + +/** + * A XidWrapper. + * + * @author Jesper Pedersen + * @version $Revision: 85945 $ + */ +public interface XidWrapper extends Xid +{ + /** + * Get the JNDI name + * @return The value + */ + public String getJndiName(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/xa/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/xa/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/transaction/xa/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains extensions for XA functionality. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/Address.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/Address.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/Address.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,217 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.workmanager; + +import java.io.Serializable; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Defines an address of a WorkManager + */ +public final class Address implements Comparable

, Serializable +{ + /** Serial version UID */ + private static final long serialVersionUID = 2L; + + /** The id of the WorkManager */ + private String workManagerId; + + /** The name of the WorkManager */ + private String workManagerName; + + /** The id of the Transport */ + private String transportId; + + private static final String ID = "ID"; + private static final String NAME = "NAME"; + private static final String TRANSPORT_ID = "TRANSPORT_ID"; + + /** + * create an instance from a Map + * @param map the map + * @return the instance + */ + public static Address fromMap(Map map) + { + return new Address(map.get(ID), map.get(NAME), map.get(TRANSPORT_ID)); + + } + + /** + * return a map representing the instance + * @return the map + */ + public Map toMap() + { + Map returnMap = new LinkedHashMap(3); + returnMap.put(ID, this.getWorkManagerId()); + returnMap.put(NAME, this.getWorkManagerName()); + returnMap.put(TRANSPORT_ID, this.getTransportId()); + return returnMap; + } + + /** + * Constructor + * @param workManagerId The id of the WorkManager + * @param workManagerName The name of the WorkManager + * @param transportId The id of the Transport + */ + public Address(String workManagerId, String workManagerName, String transportId) + { + if (workManagerId == null || workManagerId.trim().equals("")) + throw new IllegalArgumentException("WorkManagerId is undefined"); + + if (workManagerName == null || workManagerName.trim().equals("")) + throw new IllegalArgumentException("WorkManagerName is undefined"); + + this.workManagerId = workManagerId; + this.workManagerName = workManagerName; + this.transportId = transportId; + } + + /** + * Get the WorkManager id + * @return The value + */ + public String getWorkManagerId() + { + return workManagerId; + } + + /** + * Get the WorkManager name + * @return The value + */ + public String getWorkManagerName() + { + return workManagerName; + } + + /** + * Get the Transport id + * @return The value + */ + public String getTransportId() + { + return transportId; + } + + /** + * {@inheritDoc} + */ + public int hashCode() + { + int result = 37; + + result += 7 * workManagerId.hashCode(); + result += 7 * workManagerName.hashCode(); + result += transportId != null ? 7 * transportId.hashCode() : 7; + + return result; + } + + /** + * {@inheritDoc} + */ + public boolean equals(Object o) + { + if (this == o) + return true; + + if (o == null || !(o instanceof Address)) + return false; + + Address a = (Address)o; + + if (!workManagerId.equals(a.workManagerId)) + return false; + + if (!workManagerName.equals(a.workManagerName)) + return false; + + if (transportId != null) + { + if (!transportId.equals(a.transportId)) + return false; + } + else + { + if (a.transportId != null) + return false; + } + + return true; + } + + /** + * {@inheritDoc} + */ + public int compareTo(Address a) + { + int compare = workManagerId.compareTo(a.getWorkManagerId()); + if (compare != 0) + return compare; + + compare = workManagerName.compareTo(a.getWorkManagerName()); + if (compare != 0) + return compare; + + if (transportId != null) + { + if (a.getTransportId() != null) + { + return transportId.compareTo(a.getTransportId()); + } + else + { + return 1; + } + } + else + { + if (a.getTransportId() != null) + { + return -1; + } + } + + return 0; + } + + /** + * {@inheritDoc} + */ + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("Address@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[workManagerId=").append(workManagerId); + sb.append(" workManagerName=").append(workManagerName); + sb.append(" transportId=").append(transportId); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/notification/NotificationListener.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/notification/NotificationListener.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/notification/NotificationListener.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,97 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.workmanager.notification; + +import org.jboss.jca.core.spi.workmanager.Address; + +/** + * The notification listener gets notified about changes + */ +public interface NotificationListener +{ + /** + * A distributed work manager joined + * @param address The address + */ + public void join(Address address); + + /** + * A distributed work manager left + * @param address The address + */ + public void leave(Address address); + + /** + * Update the short thread pool information for a distributed work manager + * @param address The address + * @param free The number of free threads + */ + public void updateShortRunningFree(Address address, long free); + + /** + * Update the long thread pool information for a distributed work manager + * @param address The address + * @param free The number of free threads + */ + public void updateLongRunningFree(Address address, long free); + + /** + * Delta doWork accepted + */ + public void deltaDoWorkAccepted(); + + /** + * Delta doWork rejected + */ + public void deltaDoWorkRejected(); + + /** + * Delta startWork accepted + */ + public void deltaStartWorkAccepted(); + + /** + * Delta startWork rejected + */ + public void deltaStartWorkRejected(); + + /** + * Delta scheduleWork accepted + */ + public void deltaScheduleWorkAccepted(); + + /** + * Delta scheduleWork rejected + */ + public void deltaScheduleWorkRejected(); + + /** + * Delta work successful + */ + public void deltaWorkSuccessful(); + + /** + * Delta work failed + */ + public void deltaWorkFailed(); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/notification/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/notification/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/notification/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains interfaces around notifications + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the SPI for the IronJacamar WorkManager + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/policy/Policy.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/policy/Policy.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/policy/Policy.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,45 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.workmanager.policy; + +import org.jboss.jca.core.api.workmanager.DistributedWorkManager; + +import javax.resource.spi.work.DistributableWork; + +/** + * The policy interface defines how the distributed work manager to + * decide to distribute the work instance to another node. + * + * The work instance may contain a DistributableWorkContext which may + * provide additional information + */ +public interface Policy +{ + /** + * Should a distribution of the work happen + * @param dwm The invoking distributed work manager + * @param work The work instance + * @return True, if the work should be distributed; otherwise false + */ + public boolean shouldDistribute(DistributedWorkManager dwm, DistributableWork work); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/policy/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/policy/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/policy/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the SPI for the policy for the distributed work manager. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/selector/Selector.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/selector/Selector.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/selector/Selector.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,42 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.workmanager.selector; + +import org.jboss.jca.core.spi.workmanager.Address; + +import javax.resource.spi.work.DistributableWork; + +/** + * The selector interface defines how a node is selected when a + * work instance should be distributed + */ +public interface Selector +{ + /** + * Select a distributed work manager + * @param own The address of the invoking distributed work manager + * @param work The work instance + * @return The address of the selected distributed work manager; null if none could be selected + */ + public Address selectDistributedWorkManager(Address own, DistributableWork work); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/selector/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/selector/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/selector/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the SPI for the selector for the distributed work manager. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/transport/Transport.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/transport/Transport.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/transport/Transport.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,201 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.spi.workmanager.transport; + +import org.jboss.jca.core.api.workmanager.DistributedWorkManagerStatisticsValues; +import org.jboss.jca.core.spi.workmanager.Address; + +import javax.resource.spi.work.DistributableWork; +import javax.resource.spi.work.WorkException; + +/** + * The transport interface defines the methods for the physical transport + * of the work instances for a distributed work manager + */ +public interface Transport +{ + /** + * Get the identifier of the transport + * @return The value + */ + public String getId(); + + /** + * Startup the transport + * @exception Throwable In case of an error + */ + public void startup() throws Throwable; + + /** + * Shutdown the transport + * @exception Throwable In case of an error + */ + public void shutdown() throws Throwable; + + /** + * Initialize the transport + * @exception Throwable In case of an error + */ + public void initialize() throws Throwable; + + /** + * Is the transport initialized + * @return The value + */ + public boolean isInitialized(); + + /** + * Register + * @param address The address + */ + public void register(Address address); + + /** + * Unregister + * @param address The address + */ + public void unregister(Address address); + + /** + * Ping time to a distributed work manager + * @param address The address + * @return The ping time in milliseconds + */ + public long ping(Address address); + + /** + * Get The number of free thread in short running pool from a distributed work manager + * @param address The address + * @return The number of free thread in short running pool + */ + public long getShortRunningFree(Address address); + + /** + * Get The number of free thread in long running pool from a distributed work manager + * @param address The address + * @return The number of free thread in long running pool + */ + public long getLongRunningFree(Address address); + + /** + * Update The number of free thread in short running pool from a distributed work manager + * + * @param address The address + * @param freeCount the number of freeThread + */ + public void updateShortRunningFree(Address address, long freeCount); + + /** + * Update The number of free thread in long running pool from a distributed work manager + * + * @param address The address + * @param freeCount the number of freeThread + */ + public void updateLongRunningFree(Address address, long freeCount); + + /** + * Get the distributed statistics + * @param address The address + * @return The value + */ + public DistributedWorkManagerStatisticsValues getDistributedStatistics(Address address); + + /** + * Clear distributed statistics + * @param address The address + */ + public void clearDistributedStatistics(Address address); + + /** + * Delta doWork accepted + * @param address The address + */ + public void deltaDoWorkAccepted(Address address); + + /** + * Delta doWork rejected + * @param address The address + */ + public void deltaDoWorkRejected(Address address); + + /** + * Delta startWork accepted + * @param address The address + */ + public void deltaStartWorkAccepted(Address address); + + /** + * Delta startWork rejected + * @param address The address + */ + public void deltaStartWorkRejected(Address address); + + /** + * Delta scheduleWork accepted + * @param address The address + */ + public void deltaScheduleWorkAccepted(Address address); + + /** + * Delta scheduleWork rejected + * @param address The address + */ + public void deltaScheduleWorkRejected(Address address); + + /** + * Delta work successful + * @param address The address + */ + public void deltaWorkSuccessful(Address address); + + /** + * Delta work failed + * @param address The address + */ + public void deltaWorkFailed(Address address); + + /** + * doWork + * @param address The address + * @param work The work + * @exception WorkException Thrown if an error occurs + */ + public void doWork(Address address, DistributableWork work) throws WorkException; + + /** + * scheduleWork + * @param address The address + * @param work The work + * @exception WorkException Thrown if an error occurs + */ + public void scheduleWork(Address address, DistributableWork work) throws WorkException; + + /** + * startWork + * @param address The address + * @param work The work + * @return The delay + * @exception WorkException Thrown if an error occurs + */ + public long startWork(Address address, DistributableWork work) throws WorkException; +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/transport/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/transport/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/spi/workmanager/transport/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the SPI for the transport for the distributed work manager. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tracer/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tracer/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tracer/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,49 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2015, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tracer; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Get a system property + * @param name The property name + * @return The property value + */ + static String getSystemProperty(final String name) + { + return AccessController.doPrivileged(new PrivilegedAction() + { + public String run() + { + return System.getProperty(name); + } + }); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tracer/TraceEvent.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tracer/TraceEvent.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tracer/TraceEvent.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,474 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2015, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tracer; + +/** + * A trace event + * + * @author Jesper Pedersen + */ +public class TraceEvent +{ + /** Get connection listener */ + public static final int GET_CONNECTION_LISTENER = 0; + + /** Get connection listener (New) */ + public static final int GET_CONNECTION_LISTENER_NEW = 1; + + /** Get interleaving connection listener */ + public static final int GET_INTERLEAVING_CONNECTION_LISTENER = 2; + + /** Get connection listener interleaving (New) */ + public static final int GET_INTERLEAVING_CONNECTION_LISTENER_NEW = 3; + + /** Return connection listener */ + public static final int RETURN_CONNECTION_LISTENER = 10; + + /** Return connection listener with kill */ + public static final int RETURN_CONNECTION_LISTENER_WITH_KILL = 11; + + /** Return interleaving connection listener */ + public static final int RETURN_INTERLEAVING_CONNECTION_LISTENER = 12; + + /** Return interleaving connection listener with kill */ + public static final int RETURN_INTERLEAVING_CONNECTION_LISTENER_WITH_KILL = 13; + + /** Clear connection listener */ + public static final int CLEAR_CONNECTION_LISTENER = 14; + + /** Enlist connection listener */ + public static final int ENLIST_CONNECTION_LISTENER = 20; + + /** Enlist connection listener (Failed) */ + public static final int ENLIST_CONNECTION_LISTENER_FAILED = 21; + + /** Enlist interleaving connection listener */ + public static final int ENLIST_INTERLEAVING_CONNECTION_LISTENER = 22; + + /** Enlist interleaving connection listener (Failed) */ + public static final int ENLIST_INTERLEAVING_CONNECTION_LISTENER_FAILED = 23; + + /** Delist connection listener */ + public static final int DELIST_CONNECTION_LISTENER = 30; + + /** Delist connection listener (Failed) */ + public static final int DELIST_CONNECTION_LISTENER_FAILED = 31; + + /** Delist interleaving connection listener */ + public static final int DELIST_INTERLEAVING_CONNECTION_LISTENER = 32; + + /** Delist interleaving connection listener (Failed) */ + public static final int DELIST_INTERLEAVING_CONNECTION_LISTENER_FAILED = 33; + + /** Delist rollbacked connection listener */ + public static final int DELIST_ROLLEDBACK_CONNECTION_LISTENER = 34; + + /** Delist rollbacked connection listener (Failed) */ + public static final int DELIST_ROLLEDBACK_CONNECTION_LISTENER_FAILED = 35; + + /** Get connection */ + public static final int GET_CONNECTION = 40; + + /** Return connection */ + public static final int RETURN_CONNECTION = 41; + + /** Clear connection */ + public static final int CLEAR_CONNECTION = 42; + + /** Exception */ + public static final int EXCEPTION = 50; + + /** Create connection listner (GET) */ + public static final int CREATE_CONNECTION_LISTENER_GET = 60; + + /** Create connection listner (PREFILL) */ + public static final int CREATE_CONNECTION_LISTENER_PREFILL = 61; + + /** Create connection listner (INCREMENTER) */ + public static final int CREATE_CONNECTION_LISTENER_INCREMENTER = 62; + + /** Destroy connection listner (RETURN) */ + public static final int DESTROY_CONNECTION_LISTENER_RETURN = 70; + + /** Destroy connection listner (IDLE) */ + public static final int DESTROY_CONNECTION_LISTENER_IDLE = 71; + + /** Destroy connection listner (INVALID) */ + public static final int DESTROY_CONNECTION_LISTENER_INVALID = 72; + + /** Destroy connection listner (FLUSH) */ + public static final int DESTROY_CONNECTION_LISTENER_FLUSH = 73; + + /** Destroy connection listner (ERROR) */ + public static final int DESTROY_CONNECTION_LISTENER_ERROR = 74; + + /** Destroy connection listner (PREFILL) */ + public static final int DESTROY_CONNECTION_LISTENER_PREFILL = 75; + + /** Destroy connection listner (INCREMENTER) */ + public static final int DESTROY_CONNECTION_LISTENER_INCREMENTER = 76; + + /** Managed connection pool create */ + public static final int MANAGED_CONNECTION_POOL_CREATE = 80; + + /** Managed connection pool destroy */ + public static final int MANAGED_CONNECTION_POOL_DESTROY = 81; + + /** Push CCM context */ + public static final int PUSH_CCM_CONTEXT = 90; + + /** Pop CCM context */ + public static final int POP_CCM_CONTEXT = 91; + + /** Register CCM connection */ + public static final int REGISTER_CCM_CONNECTION = 92; + + /** Unregister CCM connection */ + public static final int UNREGISTER_CCM_CONNECTION = 93; + + /** CCM user transaction */ + public static final int CCM_USER_TRANSACTION = 94; + + /** Unknown CCM connection */ + public static final int UNKNOWN_CCM_CONNECTION = 95; + + /** Close CCM connection */ + public static final int CLOSE_CCM_CONNECTION = 96; + + /** Version */ + public static final int VERSION = 100; + + /** The pool */ + private String pool; + + /** The managed connection pool */ + private String mcp; + + /** The thread id */ + private long threadId; + + /** The type */ + private int type; + + /** The time stamp */ + private long timestamp; + + /** The connection listener */ + private String cl; + + /** The first payload */ + private String payload1; + + /** The second payload */ + private String payload2; + + /** + * Constructor + * @param pool The pool + * @param mcp The MCP + * @param type The event type + * @param cl The connection listener + */ + TraceEvent(String pool, String mcp, int type, String cl) + { + this(pool, mcp, Thread.currentThread().getId(), type, System.nanoTime(), cl, "", ""); + } + + /** + * Constructor + * @param pool The pool + * @param mcp The MCP + * @param type The event type + * @param cl The connection listener + * @param payload1 The first payload + */ + TraceEvent(String pool, String mcp, int type, String cl, String payload1) + { + this(pool, mcp, Thread.currentThread().getId(), type, System.nanoTime(), cl, payload1, ""); + } + + /** + * Constructor + * @param pool The pool + * @param mcp The MCP + * @param type The event type + * @param cl The connection listener + * @param payload1 The first payload + * @param payload2 The second payload + */ + TraceEvent(String pool, String mcp, int type, String cl, String payload1, String payload2) + { + this(pool, mcp, Thread.currentThread().getId(), type, System.nanoTime(), cl, payload1, payload2); + } + + /** + * Parse constructor + * @param pool The pool + * @param mcp The MCP + * @param threadId The thread id + * @param type The event type + * @param timestamp The timestamp + * @param cl The connection listener + * @param payload1 The first payload + * @param payload2 The second payload + */ + private TraceEvent(String pool, String mcp, long threadId, int type, long timestamp, String cl, + String payload1, String payload2) + { + this.pool = pool != null ? pool.replace('-', '_') : "Empty"; + this.mcp = mcp; + this.threadId = threadId; + this.type = type; + this.timestamp = timestamp; + this.cl = cl; + this.payload1 = payload1; + this.payload2 = payload2; + } + + /** + * Get the pool + * @return The value + */ + public String getPool() + { + return pool; + } + + /** + * Get the managed connection pool + * @return The value + */ + public String getManagedConnectionPool() + { + return mcp; + } + + /** + * Get the thread id + * @return The value + */ + public long getThreadId() + { + return threadId; + } + + /** + * Get the type + * @return The value + */ + public int getType() + { + return type; + } + + /** + * Get the timestamp + * @return The value + */ + public long getTimestamp() + { + return timestamp; + } + + /** + * Get the connection listener + * @return The value + */ + public String getConnectionListener() + { + return cl; + } + + /** + * Get the first payload + * @return The value + */ + public String getPayload1() + { + return payload1; + } + + /** + * Get the second payload + * @return The value + */ + public String getPayload2() + { + return payload2; + } + + /** + * {@inheritDoc} + */ + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("IJTRACER"); + sb.append("-"); + sb.append(pool); + sb.append("-"); + sb.append(mcp); + sb.append("-"); + sb.append(Long.toString(threadId)); + sb.append("-"); + sb.append(Integer.toString(type)); + sb.append("-"); + sb.append(Long.toString(timestamp)); + sb.append("-"); + sb.append(cl); + sb.append("-"); + sb.append(payload1); + sb.append("-"); + sb.append(payload2); + + return sb.toString(); + } + + /** + * As text + * @param event The event + * @return The text + */ + public static String asText(TraceEvent event) + { + switch (event.getType()) + { + case GET_CONNECTION_LISTENER: + return "getConnectionListener()"; + case GET_CONNECTION_LISTENER_NEW: + return "getConnectionListener(true)"; + case GET_INTERLEAVING_CONNECTION_LISTENER: + return "getConnectionListener() (I)"; + case GET_INTERLEAVING_CONNECTION_LISTENER_NEW: + return "getConnectionListener(true) (I)"; + case RETURN_CONNECTION_LISTENER: + return "returnConnectionListener()"; + case RETURN_CONNECTION_LISTENER_WITH_KILL: + return "returnConnectionListener(true)"; + case RETURN_INTERLEAVING_CONNECTION_LISTENER: + return "returnConnectionListener() (I)"; + case RETURN_INTERLEAVING_CONNECTION_LISTENER_WITH_KILL: + return "returnConnectionListener(true) (I)"; + case CLEAR_CONNECTION_LISTENER: + return "clearConnectionListener()"; + case ENLIST_CONNECTION_LISTENER: + return "enlistResource()"; + case ENLIST_CONNECTION_LISTENER_FAILED: + return "enlistResource(false)"; + case ENLIST_INTERLEAVING_CONNECTION_LISTENER: + return "enlistResource() (I)"; + case ENLIST_INTERLEAVING_CONNECTION_LISTENER_FAILED: + return "enlistResource(false) (I)"; + case DELIST_CONNECTION_LISTENER: + return "delistResource()"; + case DELIST_CONNECTION_LISTENER_FAILED: + return "delistResource(false)"; + case DELIST_INTERLEAVING_CONNECTION_LISTENER: + return "delistResource() (I)"; + case DELIST_INTERLEAVING_CONNECTION_LISTENER_FAILED: + return "delistResource(false) (I)"; + case DELIST_ROLLEDBACK_CONNECTION_LISTENER: + return "delistResource() (R)"; + case DELIST_ROLLEDBACK_CONNECTION_LISTENER_FAILED: + return "delistResource(false) (R)"; + case GET_CONNECTION: + return "getConnection(" + event.getPayload1() + ")"; + case RETURN_CONNECTION: + return "returnConnection(" + event.getPayload1() + ")"; + case CLEAR_CONNECTION: + return "clearConnection(" + event.getPayload1() + ")"; + case EXCEPTION: + return "exception"; + case CREATE_CONNECTION_LISTENER_GET: + return "createConnectionListener(GET)"; + case CREATE_CONNECTION_LISTENER_PREFILL: + return "createConnectionListener(PREFILL)"; + case CREATE_CONNECTION_LISTENER_INCREMENTER: + return "createConnectionListener(INCREMENTER)"; + case DESTROY_CONNECTION_LISTENER_RETURN: + return "destroyConnectionListener(RETURN)"; + case DESTROY_CONNECTION_LISTENER_IDLE: + return "destroyConnectionListener(IDLE)"; + case DESTROY_CONNECTION_LISTENER_INVALID: + return "destroyConnectionListener(INVALID)"; + case DESTROY_CONNECTION_LISTENER_FLUSH: + return "destroyConnectionListener(FLUSH)"; + case DESTROY_CONNECTION_LISTENER_ERROR: + return "destroyConnectionListener(ERROR)"; + case DESTROY_CONNECTION_LISTENER_PREFILL: + return "destroyConnectionListener(PREFILL)"; + case DESTROY_CONNECTION_LISTENER_INCREMENTER: + return "destroyConnectionListener(INCREMENTER)"; + case MANAGED_CONNECTION_POOL_CREATE: + return "createManagedConnectionPool()"; + case MANAGED_CONNECTION_POOL_DESTROY: + return "destroyManagedConnectionPool()"; + case PUSH_CCM_CONTEXT: + return "pushContext()"; + case POP_CCM_CONTEXT: + return "popContext()"; + case REGISTER_CCM_CONNECTION: + return "registerConnection()"; + case UNREGISTER_CCM_CONNECTION: + return "unregisterConnection()"; + case CCM_USER_TRANSACTION: + return "userTransaction()"; + case UNKNOWN_CCM_CONNECTION: + return "unknownConnection()"; + case CLOSE_CCM_CONNECTION: + return "closeConnection()"; + case VERSION: + return "version()"; + default: + } + + return ""; + } + + /** + * Parse a trace event + * @param data The data string + * @return The event + */ + public static TraceEvent parse(String data) + { + String[] raw = data.split("-"); + + String header = raw[0]; + String p = raw[1]; + String m = raw[2]; + long tid = Long.parseLong(raw[3]); + int t = Integer.parseInt(raw[4]); + long ts = Long.parseLong(raw[5]); + String c = raw[6]; + String pyl = ""; + String py2 = ""; + + if (raw.length >= 8) + pyl = raw[7]; + if (raw.length >= 9) + py2 = raw[8]; + + return new TraceEvent(p, m, tid, t, ts, c, pyl, py2); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tracer/Tracer.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tracer/Tracer.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tracer/Tracer.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,737 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2015, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tracer; + +import org.jboss.jca.Version; + +import java.io.CharArrayWriter; +import java.io.PrintWriter; + +import org.jboss.logging.Logger; + +/** + * The tracer class + * + * @author Jesper Pedersen + */ +public class Tracer +{ + /** Tracer logger */ + private static Logger log = Logger.getLogger(Tracer.class); + + /** Is the tracer enabled */ + private static boolean enabled = log.isTraceEnabled(); + + /** Are callstacks recorded */ + private static boolean recordCallstacks = false; + + /** Is the tracer confidential */ + private static boolean confidential = false; + + static + { + log.tracef("%s", new TraceEvent(Version.VERSION, "NONE", TraceEvent.VERSION, "NONE")); + + String value = SecurityActions.getSystemProperty("ironjacamar.tracer.callstacks"); + if (value != null && !value.trim().equals("")) + { + try + { + recordCallstacks = Boolean.valueOf(value); + } + catch (Throwable t) + { + // Assume record callstacks + recordCallstacks = true; + } + } + + value = SecurityActions.getSystemProperty("ironjacamar.tracer.confidential"); + if (value != null && !value.trim().equals("")) + { + try + { + confidential = Boolean.valueOf(value); + } + catch (Throwable t) + { + // Assume confidential + confidential = true; + } + } + } + + /** + * Is enabled + * @return The value + */ + public static boolean isEnabled() + { + return enabled; + } + + /** + * Set enabled + * @param v The value + */ + public static void setEnabled(boolean v) + { + enabled = v; + } + + /** + * Should callstacks be recorded + * @return The value + */ + public static boolean isRecordCallstacks() + { + return recordCallstacks && !confidential; + } + + /** + * Is confidential + * @return The value + */ + public static boolean isConfidential() + { + return confidential; + } + + /** + * Get connection listener + * @param poolName The name of the pool + * @param mcp The managed connection pool + * @param cl The connection listener + * @param pooled Is the connection pooled + * @param interleaving Interleaving flag + * @param callstack The call stack + */ + public static synchronized void getConnectionListener(String poolName, Object mcp, Object cl, + boolean pooled, boolean interleaving, + Throwable callstack) + { + if (!interleaving) + { + if (pooled) + { + log.tracef("%s", new TraceEvent(poolName, Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.GET_CONNECTION_LISTENER, + Integer.toHexString(System.identityHashCode(cl)), + !confidential && callstack != null ? toString(callstack) : "")); + } + else + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.GET_CONNECTION_LISTENER_NEW, + Integer.toHexString(System.identityHashCode(cl)), + !confidential && callstack != null ? toString(callstack) : "")); + } + } + else + { + if (pooled) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.GET_INTERLEAVING_CONNECTION_LISTENER, + Integer.toHexString(System.identityHashCode(cl)), + !confidential && callstack != null ? toString(callstack) : "")); + } + else + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.GET_INTERLEAVING_CONNECTION_LISTENER_NEW, + Integer.toHexString(System.identityHashCode(cl)), + !confidential && callstack != null ? toString(callstack) : "")); + } + } + } + + /** + * Return connection listener + * @param poolName The name of the pool + * @param mcp The managed connection pool + * @param cl The connection listener + * @param kill Kill the listener + * @param interleaving Interleaving flag + * @param callstack The call stack + */ + public static synchronized void returnConnectionListener(String poolName, Object mcp, + Object cl, boolean kill, boolean interleaving, + Throwable callstack) + { + if (!interleaving) + { + if (!kill) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.RETURN_CONNECTION_LISTENER, + Integer.toHexString(System.identityHashCode(cl)), + !confidential && callstack != null ? toString(callstack) : "")); + } + else + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.RETURN_CONNECTION_LISTENER_WITH_KILL, + Integer.toHexString(System.identityHashCode(cl)), + !confidential && callstack != null ? toString(callstack) : "")); + } + } + else + { + if (!kill) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.RETURN_INTERLEAVING_CONNECTION_LISTENER, + Integer.toHexString(System.identityHashCode(cl)), + !confidential && callstack != null ? toString(callstack) : "")); + } + else + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.RETURN_INTERLEAVING_CONNECTION_LISTENER_WITH_KILL, + Integer.toHexString(System.identityHashCode(cl)), + !confidential && callstack != null ? toString(callstack) : "")); + } + } + } + + /** + * Clear connection listener + * @param poolName The name of the pool + * @param mcp The managed connection pool + * @param cl The connection listener + */ + public static synchronized void clearConnectionListener(String poolName, Object mcp, Object cl) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.CLEAR_CONNECTION_LISTENER, + Integer.toHexString(System.identityHashCode(cl)))); + } + + /** + * Enlist connection listener + * @param poolName The name of the pool + * @param mcp The managed connection pool + * @param cl The connection listener + * @param tx The transaction + * @param success Outcome + * @param interleaving Interleaving flag + */ + public static synchronized void enlistConnectionListener(String poolName, Object mcp, Object cl, + String tx, + boolean success, boolean interleaving) + { + if (!interleaving) + { + if (success) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.ENLIST_CONNECTION_LISTENER, + Integer.toHexString(System.identityHashCode(cl)), + tx.replace('-', '_'))); + } + else + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.ENLIST_CONNECTION_LISTENER_FAILED, + Integer.toHexString(System.identityHashCode(cl)), + tx.replace('-', '_'))); + } + } + else + { + if (success) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.ENLIST_INTERLEAVING_CONNECTION_LISTENER, + Integer.toHexString(System.identityHashCode(cl)), + tx.replace('-', '_'))); + } + else + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.ENLIST_INTERLEAVING_CONNECTION_LISTENER_FAILED, + Integer.toHexString(System.identityHashCode(cl)), + tx.replace('-', '_'))); + } + } + } + + /** + * Delist connection listener + * @param poolName The name of the pool + * @param mcp The managed connection pool + * @param cl The connection listener + * @param tx The transaction + * @param success Is successful + * @param rollbacked Is the transaction rollbacked + * @param interleaving Interleaving flag + */ + public static synchronized void delistConnectionListener(String poolName, Object mcp, Object cl, String tx, + boolean success, boolean rollbacked, boolean interleaving) + { + if (!rollbacked) + { + if (!interleaving) + { + if (success) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.DELIST_CONNECTION_LISTENER, + Integer.toHexString(System.identityHashCode(cl)), + tx.replace('-', '_'))); + } + else + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.DELIST_CONNECTION_LISTENER_FAILED, + Integer.toHexString(System.identityHashCode(cl)), + tx.replace('-', '_'))); + } + } + else + { + if (success) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.DELIST_INTERLEAVING_CONNECTION_LISTENER, + Integer.toHexString(System.identityHashCode(cl)), + tx.replace('-', '_'))); + } + else + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.DELIST_INTERLEAVING_CONNECTION_LISTENER_FAILED, + Integer.toHexString(System.identityHashCode(cl)), + tx.replace('-', '_'))); + } + } + } + else + { + if (success) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.DELIST_ROLLEDBACK_CONNECTION_LISTENER, + Integer.toHexString(System.identityHashCode(cl)), + tx.replace('-', '_'))); + } + else + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.DELIST_ROLLEDBACK_CONNECTION_LISTENER_FAILED, + Integer.toHexString(System.identityHashCode(cl)), + tx.replace('-', '_'))); + } + } + } + + /** + * Get connection + * @param poolName The name of the pool + * @param mcp The managed connection pool + * @param cl The connection listener + * @param connection The connection + */ + public static synchronized void getConnection(String poolName, Object mcp, Object cl, Object connection) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.GET_CONNECTION, + Integer.toHexString(System.identityHashCode(cl)), + Integer.toHexString(System.identityHashCode(connection)))); + } + + /** + * Return connection + * @param poolName The name of the pool + * @param mcp The managed connection pool + * @param cl The connection listener + * @param connection The connection + */ + public static synchronized void returnConnection(String poolName, Object mcp, Object cl, Object connection) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.RETURN_CONNECTION, + Integer.toHexString(System.identityHashCode(cl)), + Integer.toHexString(System.identityHashCode(connection)))); + } + + /** + * Clear connection + * @param poolName The name of the pool + * @param mcp The managed connection pool + * @param cl The connection listener + * @param connection The connection + */ + public static synchronized void clearConnection(String poolName, Object mcp, Object cl, Object connection) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.CLEAR_CONNECTION, + Integer.toHexString(System.identityHashCode(cl)), + Integer.toHexString(System.identityHashCode(connection)))); + } + + /** + * Exception + * @param poolName The name of the pool + * @param mcp The managed connection pool + * @param cl The connection listener + * @param exception The exception + */ + public static synchronized void exception(String poolName, Object mcp, Object cl, Throwable exception) + { + if (!confidential) + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.EXCEPTION, + Integer.toHexString(System.identityHashCode(cl)), + toString(exception))); + } + + /** + * Create connection listener + * @param poolName The name of the pool + * @param mcp The managed connection pool + * @param cl The connection listener + * @param mc The managed connection + * @param get A GET operation + * @param prefill A PREFILL operation + * @param incrementer An INCREMENTER operation + * @param callstack The call stack + */ + public static synchronized void createConnectionListener(String poolName, Object mcp, Object cl, Object mc, + boolean get, boolean prefill, boolean incrementer, + Throwable callstack) + { + if (get) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.CREATE_CONNECTION_LISTENER_GET, + Integer.toHexString(System.identityHashCode(cl)), + Integer.toHexString(System.identityHashCode(mc)), + !confidential && callstack != null ? toString(callstack) : "")); + } + else if (prefill) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.CREATE_CONNECTION_LISTENER_PREFILL, + Integer.toHexString(System.identityHashCode(cl)), + Integer.toHexString(System.identityHashCode(mc)), + !confidential && callstack != null ? toString(callstack) : "")); + } + else if (incrementer) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.CREATE_CONNECTION_LISTENER_INCREMENTER, + Integer.toHexString(System.identityHashCode(cl)), + Integer.toHexString(System.identityHashCode(mc)), + !confidential && callstack != null ? toString(callstack) : "")); + } + } + + /** + * Destroy connection listener + * @param poolName The name of the pool + * @param mcp The managed connection pool + * @param cl The connection listener + * @param ret A RETURN operation + * @param idle An IDLE operation + * @param invalid An INVALID operation + * @param flush A FLUSH operation + * @param error An ERROR operation + * @param prefill A PREFILL operation + * @param incrementer An INCREMENTER operation + * @param callstack The call stack + */ + public static synchronized void destroyConnectionListener(String poolName, Object mcp, Object cl, + boolean ret, boolean idle, boolean invalid, + boolean flush, boolean error, + boolean prefill, boolean incrementer, + Throwable callstack) + { + if (ret) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.DESTROY_CONNECTION_LISTENER_RETURN, + Integer.toHexString(System.identityHashCode(cl)), + !confidential && callstack != null ? toString(callstack) : "")); + } + else if (idle) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.DESTROY_CONNECTION_LISTENER_IDLE, + Integer.toHexString(System.identityHashCode(cl)), + !confidential && callstack != null ? toString(callstack) : "")); + } + else if (invalid) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.DESTROY_CONNECTION_LISTENER_INVALID, + Integer.toHexString(System.identityHashCode(cl)), + !confidential && callstack != null ? toString(callstack) : "")); + } + else if (flush) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.DESTROY_CONNECTION_LISTENER_FLUSH, + Integer.toHexString(System.identityHashCode(cl)), + !confidential && callstack != null ? toString(callstack) : "")); + } + else if (error) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.DESTROY_CONNECTION_LISTENER_ERROR, + Integer.toHexString(System.identityHashCode(cl)), + !confidential && callstack != null ? toString(callstack) : "")); + } + else if (prefill) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.DESTROY_CONNECTION_LISTENER_PREFILL, + Integer.toHexString(System.identityHashCode(cl)), + !confidential && callstack != null ? toString(callstack) : "")); + } + else if (incrementer) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.DESTROY_CONNECTION_LISTENER_INCREMENTER, + Integer.toHexString(System.identityHashCode(cl)), + !confidential && callstack != null ? toString(callstack) : "")); + } + } + + /** + * Create managed connection pool + * @param poolName The name of the pool + * @param mcp The managed connection pool + */ + public static synchronized void createManagedConnectionPool(String poolName, Object mcp) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.MANAGED_CONNECTION_POOL_CREATE, + "NONE")); + } + + /** + * Destroy managed connection pool + * @param poolName The name of the pool + * @param mcp The managed connection pool + */ + public static synchronized void destroyManagedConnectionPool(String poolName, Object mcp) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.MANAGED_CONNECTION_POOL_DESTROY, + "NONE")); + } + + /** + * Push CCM context + * @param key The frame key + * @param callstack The call stack + */ + public static synchronized void pushCCMContext(String key, Throwable callstack) + { + log.tracef("%s", new TraceEvent("CachedConnectionManager", "NONE", TraceEvent.PUSH_CCM_CONTEXT, + "NONE", key, callstack != null ? toString(callstack) : "")); + } + + /** + * Pop CCM context + * @param key The frame key + * @param callstack The call stack + */ + public static synchronized void popCCMContext(String key, Throwable callstack) + { + log.tracef("%s", new TraceEvent("CachedConnectionManager", "NONE", TraceEvent.POP_CCM_CONTEXT, + "NONE", key, callstack != null ? toString(callstack) : "")); + } + + /** + * Register CCM connection + * @param poolName The name of the pool + * @param mcp The managed connection pool + * @param cl The connection listener + * @param connection The connection + * @param key The frame key + */ + public static synchronized void registerCCMConnection(String poolName, Object mcp, Object cl, + Object connection, String key) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.REGISTER_CCM_CONNECTION, + Integer.toHexString(System.identityHashCode(cl)), + Integer.toHexString(System.identityHashCode(connection)), + key)); + } + + /** + * Unregister CCM connection + * @param poolName The name of the pool + * @param mcp The managed connection pool + * @param cl The connection listener + * @param connection The connection + * @param key The frame key + */ + public static synchronized void unregisterCCMConnection(String poolName, Object mcp, Object cl, + Object connection, String key) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.UNREGISTER_CCM_CONNECTION, + Integer.toHexString(System.identityHashCode(cl)), + Integer.toHexString(System.identityHashCode(connection)), + key)); + } + + /** + * Unknown CCM connection + * @param poolName The name of the pool + * @param mcp The managed connection pool + * @param cl The connection listener + * @param connection The connection + * @param key The frame key + */ + public static synchronized void unknownCCMConnection(String poolName, Object mcp, Object cl, + Object connection, String key) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.UNKNOWN_CCM_CONNECTION, + Integer.toHexString(System.identityHashCode(cl)), + Integer.toHexString(System.identityHashCode(connection)), + key)); + } + + /** + * Close CCM connection + * @param poolName The name of the pool + * @param mcp The managed connection pool + * @param cl The connection listener + * @param connection The connection + * @param key The frame key + */ + public static synchronized void closeCCMConnection(String poolName, Object mcp, Object cl, + Object connection, String key) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.CLOSE_CCM_CONNECTION, + Integer.toHexString(System.identityHashCode(cl)), + Integer.toHexString(System.identityHashCode(connection)), + key)); + } + + /** + * CCM user transaction + * @param poolName The name of the pool + * @param mcp The managed connection pool + * @param cl The connection listener + * @param connection The connection + * @param key The frame key + */ + public static synchronized void ccmUserTransaction(String poolName, Object mcp, Object cl, + Object connection, String key) + { + log.tracef("%s", new TraceEvent(poolName, + Integer.toHexString(System.identityHashCode(mcp)), + TraceEvent.CCM_USER_TRANSACTION, + Integer.toHexString(System.identityHashCode(cl)), + Integer.toHexString(System.identityHashCode(connection)), + key)); + } + + /** + * Throwable to string + * @param exception The exception + * @return The string representation + */ + private static synchronized String toString(Throwable exception) + { + CharArrayWriter caw = new CharArrayWriter(); + PrintWriter pw = new PrintWriter(caw, true); + exception.printStackTrace(pw); + pw.flush(); + + char[] data = caw.toCharArray(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < data.length; i++) + { + char c = data[i]; + if (c == '\n') + { + sb = sb.append('|'); + } + else if (c == '\r') + { + sb = sb.append('/'); + } + else if (c == '\t') + { + sb = sb.append('\\'); + } + else if (c == ' ') + { + sb = sb.append('_'); + } + else + { + sb = sb.append(c); + } + } + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tracer/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tracer/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tracer/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,5 @@ + +This package contains the IronJacamar tracer, which generate opcodes for important +events in the Java EE Connector Architecture lifecycle, and for the IronJacamar +implementation. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/ConnectableXAResourceWrapperImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/ConnectableXAResourceWrapperImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/ConnectableXAResourceWrapperImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,187 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.spi.transaction.ConnectableResource; +import org.jboss.jca.core.spi.transaction.ConnectableResourceListener; + +import javax.transaction.xa.XAResource; + +/** + * A connectable XAResourceWrapper. + * + * @author Jesper Pedersen + */ +public class ConnectableXAResourceWrapperImpl extends XAResourceWrapperImpl + implements ConnectableResource, + org.jboss.tm.ConnectableResource +{ + /** The connectable resource */ + private ConnectableResource cr1; + + /** The connectable resource */ + private org.jboss.tm.ConnectableResource cr2; + + /** The connectable resource listener */ + private ConnectableResourceListener crl; + + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param pad pad + * @param override override + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param cr connectable resource + */ + public ConnectableXAResourceWrapperImpl(XAResource resource, boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, ConnectableResource cr) + { + super(resource, pad, override, productName, productVersion, jndiName); + this.cr1 = cr; + this.cr2 = null; + this.crl = null; + } + + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param pad pad + * @param override override + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param cr connectable resource + */ + public ConnectableXAResourceWrapperImpl(XAResource resource, boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, org.jboss.tm.ConnectableResource cr) + { + super(resource, pad, override, productName, productVersion, jndiName); + this.cr1 = null; + this.cr2 = cr; + this.crl = null; + } + + /** + * {@inheritDoc} + */ + public Object getConnection() throws Exception + { + Object result = null; + + if (cr1 != null) + { + result = cr1.getConnection(); + } + else + { + try + { + result = cr2.getConnection(); + } + catch (Throwable t) + { + throw new Exception(t.getMessage(), t); + } + } + + if (crl != null) + crl.handleCreated(result); + + return result; + } + + /** + * {@inheritDoc} + */ + public void setConnectableResourceListener(ConnectableResourceListener crl) + { + this.crl = crl; + } + + /** + * {@inheritDoc} + */ + public boolean equals(Object object) + { + if (object == this) + return true; + + if (object == null || !(object instanceof ConnectableXAResourceWrapperImpl)) + return false; + + ConnectableXAResourceWrapperImpl other = (ConnectableXAResourceWrapperImpl)object; + + if (!super.equals(other)) + return false; + + if (cr1 != null) + { + if (!cr1.equals(other.cr1)) + return false; + } + else + { + if (other.cr1 != null) + return false; + } + if (cr2 != null) + { + if (!cr2.equals(other.cr2)) + return false; + } + else + { + if (other.cr2 != null) + return false; + } + if (crl != null) + { + if (!crl.equals(other.crl)) + return false; + } + else + { + if (other.crl != null) + return false; + } + + return true; + } + + /** + * {@inheritDoc} + */ + public int hashCode() + { + int result = 31; + + result += cr1 != null ? 7 * cr1.hashCode() : 7; + result += cr2 != null ? 7 * cr2.hashCode() : 7; + result += crl != null ? 7 * crl.hashCode() : 7; + + return result; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/ConnectableXAResourceWrapperStatImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/ConnectableXAResourceWrapperStatImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/ConnectableXAResourceWrapperStatImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,192 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.spi.transaction.ConnectableResource; +import org.jboss.jca.core.spi.transaction.ConnectableResourceListener; +import org.jboss.jca.core.spi.transaction.XAResourceStatistics; + +import javax.transaction.xa.XAResource; + +/** + * A connectable XAResourceWrapper with statistics + * + * @author Jesper Pedersen + */ +public class ConnectableXAResourceWrapperStatImpl extends XAResourceWrapperStatImpl + implements ConnectableResource, + org.jboss.tm.ConnectableResource +{ + /** The connectable resource */ + private ConnectableResource cr1; + + /** The connectable resource */ + private org.jboss.tm.ConnectableResource cr2; + + /** The connectable resource listener */ + private ConnectableResourceListener crl; + + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param pad pad + * @param override override + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param cr connectable resource + * @param xastat The statistics + */ + public ConnectableXAResourceWrapperStatImpl(XAResource resource, boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, ConnectableResource cr, + XAResourceStatistics xastat) + { + super(resource, pad, override, productName, productVersion, jndiName, xastat); + this.cr1 = cr; + this.cr2 = null; + this.crl = null; + } + + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param pad pad + * @param override override + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param cr connectable resource + * @param xastat The statistics + */ + public ConnectableXAResourceWrapperStatImpl(XAResource resource, boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, org.jboss.tm.ConnectableResource cr, + XAResourceStatistics xastat) + { + super(resource, pad, override, productName, productVersion, jndiName, xastat); + this.cr1 = null; + this.cr2 = cr; + this.crl = null; + } + + /** + * {@inheritDoc} + */ + public Object getConnection() throws Exception + { + Object result = null; + + if (cr1 != null) + { + result = cr1.getConnection(); + } + else + { + try + { + result = cr2.getConnection(); + } + catch (Throwable t) + { + throw new Exception(t.getMessage(), t); + } + } + + if (crl != null) + crl.handleCreated(result); + + return result; + } + + /** + * {@inheritDoc} + */ + public void setConnectableResourceListener(ConnectableResourceListener crl) + { + this.crl = crl; + } + + /** + * {@inheritDoc} + */ + public boolean equals(Object object) + { + if (object == this) + return true; + + if (object == null || !(object instanceof ConnectableXAResourceWrapperStatImpl)) + return false; + + ConnectableXAResourceWrapperStatImpl other = (ConnectableXAResourceWrapperStatImpl)object; + + if (!super.equals(other)) + return false; + + if (cr1 != null) + { + if (!cr1.equals(other.cr1)) + return false; + } + else + { + if (other.cr1 != null) + return false; + } + if (cr2 != null) + { + if (!cr2.equals(other.cr2)) + return false; + } + else + { + if (other.cr2 != null) + return false; + } + if (crl != null) + { + if (!crl.equals(other.crl)) + return false; + } + else + { + if (other.crl != null) + return false; + } + + return true; + } + + /** + * {@inheritDoc} + */ + public int hashCode() + { + int result = 31; + + result += cr1 != null ? 7 * cr1.hashCode() : 7; + result += cr2 != null ? 7 * cr2.hashCode() : 7; + result += crl != null ? 7 * crl.hashCode() : 7; + + return result; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/FirstResourceConnectableXAResourceWrapperImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/FirstResourceConnectableXAResourceWrapperImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/FirstResourceConnectableXAResourceWrapperImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,99 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.spi.transaction.ConnectableResource; +import org.jboss.jca.core.spi.transaction.FirstResource; + +import javax.transaction.xa.XAResource; + +/** + * A first resource connectable XAResourceWrapper. + * + * @author Jesper Pedersen + */ +public class FirstResourceConnectableXAResourceWrapperImpl extends ConnectableXAResourceWrapperImpl + implements FirstResource, + org.jboss.tm.FirstResource +{ + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param pad pad + * @param override override + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param cr connectable resource + */ + public FirstResourceConnectableXAResourceWrapperImpl(XAResource resource, boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, ConnectableResource cr) + { + super(resource, pad, override, productName, productVersion, jndiName, cr); + } + + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param pad pad + * @param override override + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param cr connectable resource + */ + public FirstResourceConnectableXAResourceWrapperImpl(XAResource resource, boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, org.jboss.tm.ConnectableResource cr) + { + super(resource, pad, override, productName, productVersion, jndiName, cr); + } + + /** + * {@inheritDoc} + */ + public boolean equals(Object object) + { + if (object == this) + return true; + + if (object == null || !(object instanceof FirstResourceConnectableXAResourceWrapperImpl)) + return false; + + FirstResourceConnectableXAResourceWrapperImpl other = + (FirstResourceConnectableXAResourceWrapperImpl)object; + + if (!super.equals(other)) + return false; + + return true; + } + + /** + * {@inheritDoc} + */ + public int hashCode() + { + return super.hashCode(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/FirstResourceConnectableXAResourceWrapperStatImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/FirstResourceConnectableXAResourceWrapperStatImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/FirstResourceConnectableXAResourceWrapperStatImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,104 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.spi.transaction.ConnectableResource; +import org.jboss.jca.core.spi.transaction.FirstResource; +import org.jboss.jca.core.spi.transaction.XAResourceStatistics; + +import javax.transaction.xa.XAResource; + +/** + * A first resource connectable XAResourceWrapper with statistics + * + * @author Jesper Pedersen + */ +public class FirstResourceConnectableXAResourceWrapperStatImpl extends ConnectableXAResourceWrapperStatImpl + implements FirstResource, + org.jboss.tm.FirstResource +{ + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param pad pad + * @param override override + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param cr connectable resource + * @param xastat The statistics + */ + public FirstResourceConnectableXAResourceWrapperStatImpl(XAResource resource, boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, ConnectableResource cr, + XAResourceStatistics xastat) + { + super(resource, pad, override, productName, productVersion, jndiName, cr, xastat); + } + + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param pad pad + * @param override override + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param cr connectable resource + * @param xastat The statistics + */ + public FirstResourceConnectableXAResourceWrapperStatImpl(XAResource resource, boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, org.jboss.tm.ConnectableResource cr, + XAResourceStatistics xastat) + { + super(resource, pad, override, productName, productVersion, jndiName, cr, xastat); + } + + /** + * {@inheritDoc} + */ + public boolean equals(Object object) + { + if (object == this) + return true; + + if (object == null || !(object instanceof FirstResourceConnectableXAResourceWrapperStatImpl)) + return false; + + FirstResourceConnectableXAResourceWrapperStatImpl other = + (FirstResourceConnectableXAResourceWrapperStatImpl)object; + + if (!super.equals(other)) + return false; + + return true; + } + + /** + * {@inheritDoc} + */ + public int hashCode() + { + return super.hashCode(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/FirstResourceXAResourceWrapperImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/FirstResourceXAResourceWrapperImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/FirstResourceXAResourceWrapperImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,93 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.spi.transaction.FirstResource; + +import javax.transaction.xa.XAResource; + +/** + * A first resource XAResourceWrapper. + * + * @author Weston Price + * @author Jesper Pedersen + */ +public class FirstResourceXAResourceWrapperImpl extends XAResourceWrapperImpl + implements FirstResource, + org.jboss.tm.FirstResource +{ + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param productName product name + * @param productVersion product version + */ + public FirstResourceXAResourceWrapperImpl(XAResource resource, + String productName, String productVersion) + { + this(resource, false, null, productName, productVersion, null); + } + + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param pad pad + * @param override override + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + */ + public FirstResourceXAResourceWrapperImpl(XAResource resource, boolean pad, Boolean override, + String productName, String productVersion, + String jndiName) + { + super(resource, pad, override, productName, productVersion, jndiName); + } + + /** + * {@inheritDoc} + */ + public boolean equals(Object object) + { + if (object == this) + return true; + + if (object == null || !(object instanceof FirstResourceXAResourceWrapperImpl)) + return false; + + FirstResourceXAResourceWrapperImpl other = + (FirstResourceXAResourceWrapperImpl)object; + + if (!super.equals(other)) + return false; + + return true; + } + + /** + * {@inheritDoc} + */ + public int hashCode() + { + return super.hashCode(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/FirstResourceXAResourceWrapperStatImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/FirstResourceXAResourceWrapperStatImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/FirstResourceXAResourceWrapperStatImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,96 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.spi.transaction.FirstResource; +import org.jboss.jca.core.spi.transaction.XAResourceStatistics; + +import javax.transaction.xa.XAResource; + +/** + * A first resource XAResourceWrapper with statistics + * + * @author Jesper Pedersen + */ +public class FirstResourceXAResourceWrapperStatImpl extends XAResourceWrapperStatImpl + implements FirstResource, + org.jboss.tm.FirstResource +{ + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param productName product name + * @param productVersion product version + * @param xastat The statistics + */ + public FirstResourceXAResourceWrapperStatImpl(XAResource resource, + String productName, String productVersion, + XAResourceStatistics xastat) + { + this(resource, false, null, productName, productVersion, null, xastat); + } + + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param pad pad + * @param override override + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param xastat The statistics + */ + public FirstResourceXAResourceWrapperStatImpl(XAResource resource, boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, XAResourceStatistics xastat) + { + super(resource, pad, override, productName, productVersion, jndiName, xastat); + } + + /** + * {@inheritDoc} + */ + public boolean equals(Object object) + { + if (object == this) + return true; + + if (object == null || !(object instanceof FirstResourceXAResourceWrapperStatImpl)) + return false; + + FirstResourceXAResourceWrapperStatImpl other = + (FirstResourceXAResourceWrapperStatImpl)object; + + if (!super.equals(other)) + return false; + + return true; + } + + /** + * {@inheritDoc} + */ + public int hashCode() + { + return super.hashCode(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/LocalConnectableXAResourceImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/LocalConnectableXAResourceImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/LocalConnectableXAResourceImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,112 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.spi.transaction.ConnectableResource; +import org.jboss.jca.core.spi.transaction.ConnectableResourceListener; + +/** + * Local connectable XA resource implementation. + * + * @author Jesper Pedersen + */ +public class LocalConnectableXAResourceImpl extends LocalXAResourceImpl + implements ConnectableResource, org.jboss.tm.ConnectableResource +{ + /** Connectable resource */ + private ConnectableResource cr1; + + /** Connectable resource */ + private org.jboss.tm.ConnectableResource cr2; + + /** Connectable resource listener */ + private ConnectableResourceListener crl; + + /** + * Creates a new instance. + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param cr connectable resource + */ + public LocalConnectableXAResourceImpl(String productName, String productVersion, + String jndiName, ConnectableResource cr) + { + super(productName, productVersion, jndiName); + this.cr1 = cr; + this.cr2 = null; + this.crl = null; + } + + /** + * Creates a new instance. + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param cr connectable resource + */ + public LocalConnectableXAResourceImpl(String productName, String productVersion, + String jndiName, org.jboss.tm.ConnectableResource cr) + { + super(productName, productVersion, jndiName); + this.cr1 = null; + this.cr2 = cr; + this.crl = null; + } + + /** + * {@inheritDoc} + */ + public Object getConnection() throws Exception + { + Object result = null; + + if (cr1 != null) + { + result = cr1.getConnection(); + } + else + { + try + { + result = cr2.getConnection(); + } + catch (Throwable t) + { + throw new Exception(t.getMessage(), t); + } + } + + if (crl != null) + crl.handleCreated(result); + + return result; + } + + /** + * {@inheritDoc} + */ + public void setConnectableResourceListener(ConnectableResourceListener crl) + { + this.crl = crl; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/LocalConnectableXAResourceStatImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/LocalConnectableXAResourceStatImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/LocalConnectableXAResourceStatImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,117 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.spi.transaction.ConnectableResource; +import org.jboss.jca.core.spi.transaction.ConnectableResourceListener; +import org.jboss.jca.core.spi.transaction.XAResourceStatistics; + +/** + * Local connectable XA resource implementation with statistics + * + * @author Jesper Pedersen + */ +public class LocalConnectableXAResourceStatImpl extends LocalXAResourceStatImpl + implements ConnectableResource, org.jboss.tm.ConnectableResource +{ + /** Connectable resource */ + private ConnectableResource cr1; + + /** Connectable resource */ + private org.jboss.tm.ConnectableResource cr2; + + /** Connectable resource listener */ + private ConnectableResourceListener crl; + + /** + * Creates a new instance. + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param cr connectable resource + * @param xastat The statistics + */ + public LocalConnectableXAResourceStatImpl(String productName, String productVersion, + String jndiName, ConnectableResource cr, + XAResourceStatistics xastat) + { + super(productName, productVersion, jndiName, xastat); + this.cr1 = cr; + this.cr2 = null; + this.crl = null; + } + + /** + * Creates a new instance. + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param cr connectable resource + * @param xastat The statistics + */ + public LocalConnectableXAResourceStatImpl(String productName, String productVersion, + String jndiName, org.jboss.tm.ConnectableResource cr, + XAResourceStatistics xastat) + { + super(productName, productVersion, jndiName, xastat); + this.cr1 = null; + this.cr2 = cr; + this.crl = null; + } + + /** + * {@inheritDoc} + */ + public Object getConnection() throws Exception + { + Object result = null; + + if (cr1 != null) + { + result = cr1.getConnection(); + } + else + { + try + { + result = cr2.getConnection(); + } + catch (Throwable t) + { + throw new Exception(t.getMessage(), t); + } + } + + if (crl != null) + crl.handleCreated(result); + + return result; + } + + /** + * {@inheritDoc} + */ + public void setConnectableResourceListener(ConnectableResourceListener crl) + { + this.crl = crl; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/LocalXAResourceImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/LocalXAResourceImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/LocalXAResourceImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,320 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.connectionmanager.ConnectionManager; +import org.jboss.jca.core.api.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.spi.transaction.local.LocalResourceException; +import org.jboss.jca.core.spi.transaction.local.LocalXAException; +import org.jboss.jca.core.spi.transaction.local.LocalXAResource; + +import javax.resource.ResourceException; +import javax.transaction.xa.XAException; +import javax.transaction.xa.XAResource; +import javax.transaction.xa.Xid; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * Local XA resource implementation. + * + * @author Gurkan Erdogdu + * @author Jesper Pedersen + */ +public class LocalXAResourceImpl implements LocalXAResource, + org.jboss.jca.core.spi.transaction.LastResource, + org.jboss.tm.LastResource, + org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper, + org.jboss.tm.XAResourceWrapper +{ + /** Log instance */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, LocalXAResourceImpl.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** Connection listener */ + private ConnectionListener cl; + + /**Connection manager*/ + private ConnectionManager connectionManager = null; + + /** + * warned is set after one warning about a local participant in + * a multi-branch jta transaction is logged. + */ + private boolean warned = false; + + /** Current transction branch id */ + private Xid currentXid; + + /** Product name */ + private String productName; + + /** Product version */ + private String productVersion; + + /** Product version */ + private String jndiName; + + /** + * Creates a new instance. + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + */ + public LocalXAResourceImpl(String productName, String productVersion, + String jndiName) + { + this.productName = productName; + this.productVersion = productVersion; + this.jndiName = jndiName; + } + + /** + * {@inheritDoc} + */ + public void setConnectionManager(ConnectionManager connectionManager) + { + this.connectionManager = connectionManager; + } + + /** + * {@inheritDoc} + */ + public void setConnectionListener(ConnectionListener cl) + { + this.cl = cl; + } + + /** + * {@inheritDoc} + */ + public void start(Xid xid, int flags) throws XAException + { + log.tracef("start(%s, %s)", xid, flags); + + if (currentXid != null && flags == XAResource.TMNOFLAGS) + { + throw new LocalXAException(bundle.tryingStartNewTxWhenOldNotComplete( + currentXid, xid, flags), XAException.XAER_PROTO); + } + + if (currentXid == null && flags != XAResource.TMNOFLAGS) + { + throw new LocalXAException(bundle.tryingStartNewTxWithWrongFlags(xid, flags), XAException.XAER_PROTO); + } + + if (currentXid == null) + { + try + { + cl.getManagedConnection().getLocalTransaction().begin(); + } + catch (ResourceException re) + { + throw new LocalXAException(bundle.errorTryingStartLocalTx(), XAException.XAER_RMERR, re); + } + catch (Throwable t) + { + throw new LocalXAException(bundle.throwableTryingStartLocalTx(), XAException.XAER_RMERR, t); + } + + currentXid = xid; + } + } + + /** + * {@inheritDoc} + */ + public void end(Xid xid, int flags) throws XAException + { + log.tracef("end(%s,%s)", xid, flags); + } + + /** + * {@inheritDoc} + */ + public void commit(Xid xid, boolean onePhase) throws XAException + { + if (!xid.equals(currentXid)) + { + throw new LocalXAException(bundle.wrongXidInCommit(currentXid, xid), XAException.XAER_PROTO); + + } + + currentXid = null; + + try + { + cl.getManagedConnection().getLocalTransaction().commit(); + } + catch (LocalResourceException lre) + { + connectionManager.returnManagedConnection(cl, true); + throw new LocalXAException(bundle.couldNotCommitLocalTx(), XAException.XAER_RMFAIL, lre); + } + catch (ResourceException re) + { + connectionManager.returnManagedConnection(cl, true); + throw new LocalXAException(bundle.couldNotCommitLocalTx(), XAException.XA_RBROLLBACK, re); + } + } + + /** + * {@inheritDoc} + */ + public void forget(Xid xid) throws XAException + { + throw new LocalXAException(bundle.forgetNotSupportedInLocalTx(), XAException.XAER_RMERR); + } + + /** + * {@inheritDoc} + */ + public int getTransactionTimeout() throws XAException + { + return 0; + } + + /** + * {@inheritDoc} + */ + public boolean isSameRM(XAResource xaResource) throws XAException + { + return xaResource == this; + } + + /** + * {@inheritDoc} + */ + public int prepare(Xid xid) throws XAException + { + if (!warned) + { + log.prepareCalledOnLocaltx(); + } + warned = true; + + return XAResource.XA_OK; + } + + /** + * {@inheritDoc} + */ + public Xid[] recover(int flag) throws XAException + { + throw new LocalXAException(bundle.noRecoverWithLocalTxResourceManagers(), XAException.XAER_RMERR); + } + + /** + * {@inheritDoc} + */ + public void rollback(Xid xid) throws XAException + { + if (!xid.equals(currentXid)) + { + throw new LocalXAException(bundle.wrongXidInRollback(currentXid, xid), XAException.XAER_PROTO); + } + currentXid = null; + try + { + cl.getManagedConnection().getLocalTransaction().rollback(); + } + catch (LocalResourceException lre) + { + connectionManager.returnManagedConnection(cl, true); + throw new LocalXAException(bundle.couldNotRollbackLocalTx(), XAException.XAER_RMFAIL, lre); + } + catch (ResourceException re) + { + connectionManager.returnManagedConnection(cl, true); + throw new LocalXAException(bundle.couldNotRollbackLocalTx(), XAException.XAER_RMERR, re); + } + } + + /** + * {@inheritDoc} + */ + public boolean setTransactionTimeout(int seconds) throws XAException + { + return false; + } + + /** + * {@inheritDoc} + */ + public XAResource getResource() + { + return this; + } + + /** + * {@inheritDoc} + */ + public String getProductName() + { + return productName; + } + + /** + * {@inheritDoc} + */ + public String getProductVersion() + { + return productVersion; + } + + /** + * {@inheritDoc} + */ + public String getJndiName() + { + return jndiName; + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("LocalXAResourceImpl@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[connectionListener=").append(cl != null ? Integer.toHexString(System.identityHashCode(cl)) : "null"); + sb.append(" connectionManager=").append(connectionManager != null ? + Integer.toHexString(System.identityHashCode(connectionManager)) : "null"); + sb.append(" warned=").append(warned); + sb.append(" currentXid=").append(currentXid); + sb.append(" productName=").append(productName); + sb.append(" productVersion=").append(productVersion); + sb.append(" jndiName=").append(jndiName); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/LocalXAResourceStatImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/LocalXAResourceStatImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/LocalXAResourceStatImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,99 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.spi.transaction.XAResourceStatistics; + +import javax.transaction.xa.XAException; +import javax.transaction.xa.Xid; + +/** + * Local XA resource implementation with statistics + * + * @author Jesper Pedersen + */ +public class LocalXAResourceStatImpl extends LocalXAResourceImpl +{ + private XAResourceStatistics xastat; + + /** + * Creates a new instance. + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param xastat The statistics + */ + public LocalXAResourceStatImpl(String productName, String productVersion, + String jndiName, XAResourceStatistics xastat) + { + super(productName, productVersion, jndiName); + this.xastat = xastat; + } + + /** + * {@inheritDoc} + */ + public void start(Xid xid, int flags) throws XAException + { + long l1 = System.currentTimeMillis(); + try + { + super.start(xid, flags); + } + finally + { + xastat.deltaStart(System.currentTimeMillis() - l1); + } + } + + /** + * {@inheritDoc} + */ + public void commit(Xid xid, boolean onePhase) throws XAException + { + long l1 = System.currentTimeMillis(); + try + { + super.commit(xid, onePhase); + } + finally + { + xastat.deltaCommit(System.currentTimeMillis() - l1); + } + } + + /** + * {@inheritDoc} + */ + public void rollback(Xid xid) throws XAException + { + long l1 = System.currentTimeMillis(); + try + { + super.rollback(xid); + } + finally + { + xastat.deltaRollback(System.currentTimeMillis() - l1); + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,145 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.security.SimplePrincipal; +import org.jboss.jca.core.spi.security.SubjectFactory; + +import java.security.AccessController; +import java.security.Principal; +import java.security.PrivilegedAction; +import java.util.HashSet; +import java.util.Set; + +import javax.resource.spi.ManagedConnectionFactory; +import javax.resource.spi.security.PasswordCredential; +import javax.security.auth.Subject; + +/** + * Privileged Blocks + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Constructor + */ + private SecurityActions() + { + } + + /** + * Get a Subject instance + * @param recoverUserName The user name + * @param recoverPassword The password + * @param mcf The ManagedConnectionFactory + * @return The instance + */ + static Subject createSubject(final String recoverUserName, final String recoverPassword, + final ManagedConnectionFactory mcf) + { + if (System.getSecurityManager() == null) + { + Set principals = new HashSet(); + Set pubCredentials = new HashSet(); + Set privCredentials = new HashSet(); + + // Principals + Principal p = new SimplePrincipal(recoverUserName); + principals.add(p); + + // PublicCredentials + // None + + // PrivateCredentials + PasswordCredential pc = new PasswordCredential(recoverUserName, recoverPassword.toCharArray()); + pc.setManagedConnectionFactory(mcf); + privCredentials.add(pc); + + return new Subject(false, principals, pubCredentials, privCredentials); + } + + return AccessController.doPrivileged(new PrivilegedAction() + { + public Subject run() + { + Set principals = new HashSet(); + Set pubCredentials = new HashSet(); + Set privCredentials = new HashSet(); + + // Principals + Principal p = new SimplePrincipal(recoverUserName); + principals.add(p); + + // PublicCredentials + // None + + // PrivateCredentials + PasswordCredential pc = new PasswordCredential(recoverUserName, recoverPassword.toCharArray()); + pc.setManagedConnectionFactory(mcf); + privCredentials.add(pc); + + return new Subject(false, principals, pubCredentials, privCredentials); + } + }); + } + + /** + * Get a Subject instance + * @param subjectFactory The subject factory + * @param domain The domain + * @return The instance + */ + static Subject createSubject(final SubjectFactory subjectFactory, final String domain) + { + if (System.getSecurityManager() == null) + return subjectFactory.createSubject(domain); + + return AccessController.doPrivileged(new PrivilegedAction() + { + public Subject run() + { + return subjectFactory.createSubject(domain); + } + }); + } + + /** + * Get the PasswordCredential from the Subject + * @param subject The subject + * @return The instances + */ + static Set getPasswordCredentials(final Subject subject) + { + if (System.getSecurityManager() == null) + return subject.getPrivateCredentials(PasswordCredential.class); + + return AccessController.doPrivileged(new PrivilegedAction>() + { + public Set run() + { + return subject.getPrivateCredentials(PasswordCredential.class); + } + }); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/TransactionIntegrationImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/TransactionIntegrationImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/TransactionIntegrationImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,385 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.api.connectionmanager.ConnectionManager; +import org.jboss.jca.core.spi.recovery.RecoveryPlugin; +import org.jboss.jca.core.spi.security.SubjectFactory; +import org.jboss.jca.core.spi.transaction.ConnectableResource; +import org.jboss.jca.core.spi.transaction.TransactionIntegration; +import org.jboss.jca.core.spi.transaction.XAResourceStatistics; +import org.jboss.jca.core.spi.transaction.local.LocalXAResource; +import org.jboss.jca.core.spi.transaction.recovery.XAResourceRecovery; +import org.jboss.jca.core.spi.transaction.recovery.XAResourceRecoveryRegistry; +import org.jboss.jca.core.spi.transaction.usertx.UserTransactionRegistry; +import org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper; +import org.jboss.jca.core.spi.transaction.xa.XATerminator; + +import javax.resource.spi.ActivationSpec; +import javax.resource.spi.ManagedConnection; +import javax.resource.spi.ManagedConnectionFactory; +import javax.resource.spi.ResourceAdapter; +import javax.transaction.Transaction; +import javax.transaction.TransactionManager; +import javax.transaction.TransactionSynchronizationRegistry; +import javax.transaction.xa.XAResource; + +/** + * This class provide an implementation of the transaction integration for + * the IronJacamar container using JBossTS. + * + * @author Jesper Pedersen + */ +public class TransactionIntegrationImpl implements TransactionIntegration +{ + /** The transaction manager */ + private TransactionManager tm; + + /** The transaction synchronization registry */ + private TransactionSynchronizationRegistry tsr; + + /** User transaction registry */ + private UserTransactionRegistry utr; + + /** XATerminator */ + private org.jboss.tm.JBossXATerminator terminator; + + /** Recovery registry */ + private org.jboss.tm.XAResourceRecoveryRegistry rr; + + /** + * Constructor + * @param tm The transaction manager + * @param tsr The transaction synchronization registry + * @param utr The user transaction registry + * @param terminator The XA terminator + * @param rr The recovery registry + */ + public TransactionIntegrationImpl(TransactionManager tm, + TransactionSynchronizationRegistry tsr, + org.jboss.tm.usertx.UserTransactionRegistry utr, + org.jboss.tm.JBossXATerminator terminator, + org.jboss.tm.XAResourceRecoveryRegistry rr) + { + if (tm instanceof org.jboss.tm.TransactionTimeoutConfiguration) + { + this.tm = new TransactionManagerDelegator(tm); + } + else + { + this.tm = tm; + } + this.tsr = tsr; + this.utr = new UserTransactionRegistryImpl(utr); + this.terminator = terminator; + this.rr = rr; + } + + /** + * Get the transaction manager + * @return The value + */ + public TransactionManager getTransactionManager() + { + return tm; + } + + /** + * Get the transaction synchronization registry + * @return The value + */ + public TransactionSynchronizationRegistry getTransactionSynchronizationRegistry() + { + return tsr; + } + + /** + * Get the user transaction registry + * @return The value + */ + public UserTransactionRegistry getUserTransactionRegistry() + { + return utr; + } + + /** + * Get the recovery registry + * @return The value + */ + public XAResourceRecoveryRegistry getRecoveryRegistry() + { + if (rr == null) + return null; + + return new XAResourceRecoveryRegistryImpl(rr); + } + + /** + * Get the XATerminator + * @return The value + */ + public XATerminator getXATerminator() + { + return new XATerminatorImpl(terminator); + } + + /** + * {@inheritDoc} + */ + public XAResourceRecovery createXAResourceRecovery(ResourceAdapter rar, + ActivationSpec as, + String productName, String productVersion) + { + return new XAResourceRecoveryInflowImpl(rar, as, productName, productVersion); + } + + /** + * {@inheritDoc} + */ + public XAResourceRecovery createXAResourceRecovery(ManagedConnectionFactory mcf, + Boolean pad, Boolean override, + Boolean wrapXAResource, + String recoverUserName, String recoverPassword, + String recoverSecurityDomain, + SubjectFactory subjectFactory, + RecoveryPlugin plugin, + XAResourceStatistics xastat) + { + return new XAResourceRecoveryImpl(this, mcf, pad, override, wrapXAResource, + recoverUserName, recoverPassword, recoverSecurityDomain, + subjectFactory, plugin, xastat); + } + + /** + * {@inheritDoc} + */ + public LocalXAResource createConnectableLocalXAResource(ConnectionManager cm, + String productName, String productVersion, + String jndiName, ConnectableResource cr, + XAResourceStatistics xastat) + { + LocalXAResource result = null; + if (xastat != null && xastat.isEnabled()) + { + result = new LocalConnectableXAResourceStatImpl(productName, productVersion, jndiName, cr, xastat); + } + else + { + result = new LocalConnectableXAResourceImpl(productName, productVersion, jndiName, cr); + } + result.setConnectionManager(cm); + + return result; + } + + /** + * {@inheritDoc} + */ + public LocalXAResource createConnectableLocalXAResource(ConnectionManager cm, + String productName, String productVersion, + String jndiName, ManagedConnection mc, + XAResourceStatistics xastat) + { + LocalXAResource result = null; + if (xastat != null && xastat.isEnabled()) + { + result = new LocalConnectableXAResourceStatImpl(productName, productVersion, jndiName, + (org.jboss.tm.ConnectableResource)mc, + xastat); + } + else + { + result = new LocalConnectableXAResourceImpl(productName, productVersion, jndiName, + (org.jboss.tm.ConnectableResource)mc); + } + result.setConnectionManager(cm); + + return result; + } + + /** + * {@inheritDoc} + */ + public LocalXAResource createLocalXAResource(ConnectionManager cm, + String productName, String productVersion, + String jndiName, + XAResourceStatistics xastat) + { + LocalXAResource result = null; + if (xastat != null && xastat.isEnabled()) + { + result = new LocalXAResourceStatImpl(productName, productVersion, jndiName, xastat); + } + else + { + result = new LocalXAResourceImpl(productName, productVersion, jndiName); + } + result.setConnectionManager(cm); + + return result; + } + + /** + * {@inheritDoc} + */ + public XAResourceWrapper createConnectableXAResourceWrapper(XAResource xares, + boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, + ConnectableResource cr, + XAResourceStatistics xastat) + { + if (cr instanceof org.jboss.jca.core.spi.transaction.FirstResource || + cr instanceof org.jboss.tm.FirstResource) + { + if (xastat != null && xastat.isEnabled()) + { + return new FirstResourceConnectableXAResourceWrapperStatImpl(xares, pad, override, + productName, productVersion, jndiName, + cr, xastat); + } + else + { + return new FirstResourceConnectableXAResourceWrapperImpl(xares, pad, override, + productName, productVersion, jndiName, + cr); + } + } + else + { + if (xastat != null && xastat.isEnabled()) + { + return new ConnectableXAResourceWrapperStatImpl(xares, pad, override, + productName, productVersion, jndiName, + cr, xastat); + } + else + { + return new ConnectableXAResourceWrapperImpl(xares, pad, override, + productName, productVersion, jndiName, + cr); + } + } + } + + /** + * {@inheritDoc} + */ + public XAResourceWrapper createConnectableXAResourceWrapper(XAResource xares, + boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, + ManagedConnection mc, + XAResourceStatistics xastat) + { + if (mc instanceof org.jboss.jca.core.spi.transaction.FirstResource || + mc instanceof org.jboss.tm.FirstResource) + { + if (xastat != null && xastat.isEnabled()) + { + return new FirstResourceConnectableXAResourceWrapperStatImpl(xares, pad, override, + productName, productVersion, jndiName, + (org.jboss.tm.ConnectableResource)mc, + xastat); + } + else + { + return new FirstResourceConnectableXAResourceWrapperImpl(xares, pad, override, + productName, productVersion, jndiName, + (org.jboss.tm.ConnectableResource)mc); + } + } + else + { + if (xastat != null && xastat.isEnabled()) + { + return new ConnectableXAResourceWrapperStatImpl(xares, pad, override, + productName, productVersion, jndiName, + (org.jboss.tm.ConnectableResource)mc, xastat); + } + else + { + return new ConnectableXAResourceWrapperImpl(xares, pad, override, + productName, productVersion, jndiName, + (org.jboss.tm.ConnectableResource)mc); + } + } + } + + /** + * {@inheritDoc} + */ + public XAResourceWrapper createXAResourceWrapper(XAResource xares, + boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, boolean firstResource, + XAResourceStatistics xastat) + { + if (firstResource) + { + if (xastat != null && xastat.isEnabled()) + { + return new FirstResourceXAResourceWrapperStatImpl(xares, pad, override, productName, productVersion, + jndiName, xastat); + } + else + { + return new FirstResourceXAResourceWrapperImpl(xares, pad, override, productName, productVersion, jndiName); + } + } + else + { + if (xastat != null && xastat.isEnabled()) + { + return new XAResourceWrapperStatImpl(xares, pad, override, productName, productVersion, jndiName, xastat); + } + else + { + return new XAResourceWrapperImpl(xares, pad, override, productName, productVersion, jndiName); + } + } + } + + /** + * {@inheritDoc} + */ + public boolean isFirstResource(ManagedConnection mc) + { + return mc != null && mc instanceof org.jboss.tm.FirstResource; + } + + /** + * {@inheritDoc} + */ + public boolean isConnectableResource(ManagedConnection mc) + { + return mc != null && mc instanceof org.jboss.tm.ConnectableResource; + } + + /** + * {@inheritDoc} + */ + public Object getIdentifier(Transaction tx) + { + return tx; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/TransactionManagerDelegator.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/TransactionManagerDelegator.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/TransactionManagerDelegator.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,149 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.spi.transaction.TransactionTimeoutConfiguration; + +import javax.transaction.HeuristicMixedException; +import javax.transaction.HeuristicRollbackException; +import javax.transaction.InvalidTransactionException; +import javax.transaction.NotSupportedException; +import javax.transaction.RollbackException; +import javax.transaction.SystemException; +import javax.transaction.Transaction; +import javax.transaction.TransactionManager; + +/** + * This class provide a delegator implementation of the transaction manager + * + * @author Jesper Pedersen + */ +public class TransactionManagerDelegator implements TransactionManager, TransactionTimeoutConfiguration +{ + /** The transaction manager */ + private TransactionManager tm; + + /** + * Constructor + * @param tm The transaction manager + */ + public TransactionManagerDelegator(TransactionManager tm) + { + this.tm = tm; + } + + /** + * {@inheritDoc} + */ + public void begin() throws NotSupportedException, SystemException + { + tm.begin(); + } + + /** + * {@inheritDoc} + */ + public void commit() throws RollbackException, HeuristicMixedException, + HeuristicRollbackException, SecurityException, IllegalStateException, + SystemException + { + tm.commit(); + } + + /** + * {@inheritDoc} + */ + public int getStatus() throws SystemException + { + return tm.getStatus(); + } + + /** + * {@inheritDoc} + */ + public Transaction getTransaction() throws SystemException + { + return tm.getTransaction(); + } + + /** + * {@inheritDoc} + */ + public void resume(Transaction tobj) throws InvalidTransactionException, IllegalStateException, SystemException + { + tm.resume(tobj); + } + + /** + * {@inheritDoc} + */ + public void rollback() throws IllegalStateException, SecurityException, SystemException + { + tm.rollback(); + } + + /** + * {@inheritDoc} + */ + public void setRollbackOnly() throws IllegalStateException, SystemException + { + tm.setRollbackOnly(); + } + + /** + * {@inheritDoc} + */ + public void setTransactionTimeout(int seconds) throws SystemException + { + tm.setTransactionTimeout(seconds); + } + + /** + * {@inheritDoc} + */ + public Transaction suspend() throws SystemException + { + return tm.suspend(); + } + + /** + * {@inheritDoc} + */ + public int getTransactionTimeout() throws SystemException + { + if (tm instanceof org.jboss.tm.TransactionTimeoutConfiguration) + return ((org.jboss.tm.TransactionTimeoutConfiguration)tm).getTransactionTimeout(); + + return 0; + } + + /** + * {@inheritDoc} + */ + public long getTimeLeftBeforeTransactionTimeout(boolean errorRollback) throws RollbackException + { + if (tm instanceof org.jboss.tm.TransactionTimeoutConfiguration) + return ((org.jboss.tm.TransactionTimeoutConfiguration)tm).getTimeLeftBeforeTransactionTimeout(errorRollback); + + return 0; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/UserTransactionListenerImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/UserTransactionListenerImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/UserTransactionListenerImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,54 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import javax.transaction.SystemException; + +/** + * UserTransactionListener implementation + * + * @author Jesper Pedersen + */ +public class UserTransactionListenerImpl implements org.jboss.jca.core.spi.transaction.usertx.UserTransactionListener, + org.jboss.tm.usertx.UserTransactionListener +{ + /** The user transaction listener */ + private org.jboss.jca.core.spi.transaction.usertx.UserTransactionListener utl; + + /** + * Constructor + * @param utl The user transaction listener + */ + public UserTransactionListenerImpl(org.jboss.jca.core.spi.transaction.usertx.UserTransactionListener utl) + { + this.utl = utl; + } + + /** + * An user transaction has started + * @exception SystemException Thrown in case of an error + */ + public void userTransactionStarted() throws SystemException + { + utl.userTransactionStarted(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/UserTransactionProviderImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/UserTransactionProviderImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/UserTransactionProviderImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,61 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +/** + * UserTransactionProvider implementation + * + * @author Jesper Pedersen + */ +public class UserTransactionProviderImpl implements org.jboss.jca.core.spi.transaction.usertx.UserTransactionProvider, + org.jboss.tm.usertx.UserTransactionProvider +{ + /** The user transaction provider */ + private org.jboss.jca.core.spi.transaction.usertx.UserTransactionProvider utp; + + /** + * Constructor + * @param utp The user transaction provider + */ + public UserTransactionProviderImpl(org.jboss.jca.core.spi.transaction.usertx.UserTransactionProvider utp) + { + this.utp = utp; + } + + /** + * Set the user transaction registry + * @param v The value + */ + public void setUserTransactionRegistry(org.jboss.jca.core.spi.transaction.usertx.UserTransactionRegistry v) + { + utp.setUserTransactionRegistry(v); + } + + /** + * Set the user transaction registry + * @param v The value + */ + public void setTransactionRegistry(org.jboss.tm.usertx.UserTransactionRegistry v) + { + ((org.jboss.tm.usertx.UserTransactionProvider)utp).setTransactionRegistry(v); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/UserTransactionRegistryImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/UserTransactionRegistryImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/UserTransactionRegistryImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,121 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.spi.transaction.usertx.UserTransactionListener; +import org.jboss.jca.core.spi.transaction.usertx.UserTransactionProvider; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * UserTransactionRegistry implementation + * + * @author Jesper Pedersen + */ +public class UserTransactionRegistryImpl implements org.jboss.jca.core.spi.transaction.usertx.UserTransactionRegistry +{ + /** The delegator */ + private org.jboss.tm.usertx.UserTransactionRegistry delegator; + + /** Listener map */ + private Map listeners; + + /** Provider map */ + private Map providers; + + /** + * Constructor + * @param delegator The delegator instance + */ + public UserTransactionRegistryImpl(org.jboss.tm.usertx.UserTransactionRegistry delegator) + { + this.delegator = delegator; + this.listeners = + Collections.synchronizedMap(new HashMap()); + this.providers = + Collections.synchronizedMap(new HashMap()); + } + + /** + * Add a listener + * @param listener The listener + */ + public void addListener(UserTransactionListener listener) + { + UserTransactionListenerImpl impl = new UserTransactionListenerImpl(listener); + + delegator.addListener(impl); + listeners.put(listener, impl); + } + + /** + * Remove a listener + * @param listener The listener + */ + public void removeListener(UserTransactionListener listener) + { + UserTransactionListenerImpl impl = listeners.get(listener); + + if (impl != null) + { + delegator.removeListener(impl); + listeners.remove(listener); + } + } + + /** + * Add a provider + * @param provider The provider + */ + public void addProvider(UserTransactionProvider provider) + { + UserTransactionProviderImpl impl = new UserTransactionProviderImpl(provider); + + delegator.addProvider(impl); + providers.put(provider, impl); + } + + /** + * Remove a provider + * @param provider The provider + */ + public void removeProvider(UserTransactionProvider provider) + { + UserTransactionProviderImpl impl = providers.get(provider); + + if (impl != null) + { + delegator.removeProvider(impl); + providers.remove(provider); + } + } + + /** + * Fire a user transaction started event + */ + public void userTransactionStarted() + { + delegator.userTransactionStarted(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XAResourceRecoveryImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XAResourceRecoveryImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XAResourceRecoveryImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,482 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.recovery.ValidatingManagedConnectionFactoryRecoveryPlugin; +import org.jboss.jca.core.spi.recovery.RecoveryPlugin; +import org.jboss.jca.core.spi.security.SubjectFactory; +import org.jboss.jca.core.spi.transaction.TransactionIntegration; +import org.jboss.jca.core.spi.transaction.XAResourceStatistics; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.HashSet; +import java.util.Set; + +import javax.resource.ResourceException; +import javax.resource.spi.ManagedConnection; +import javax.resource.spi.ManagedConnectionFactory; +import javax.resource.spi.ValidatingManagedConnectionFactory; +import javax.resource.spi.security.PasswordCredential; +import javax.security.auth.Subject; +import javax.transaction.xa.XAResource; + +import org.jboss.logging.Logger; + +/** + * An XAResourceRecovery implementation. + * + * @author Stefano Maestri + * @author Jesper Pedersen + */ +public class XAResourceRecoveryImpl implements org.jboss.jca.core.spi.transaction.recovery.XAResourceRecovery, + org.jboss.tm.XAResourceRecovery +{ + /** Log instance */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, XAResourceRecoveryImpl.class.getName()); + + private final TransactionIntegration ti; + + private final ManagedConnectionFactory mcf; + + private final Boolean padXid; + + private final Boolean isSameRMOverrideValue; + + private final Boolean wrapXAResource; + + private final String recoverUserName; + + private final String recoverPassword; + + private final String recoverSecurityDomain; + + private final SubjectFactory subjectFactory; + + private final RecoveryPlugin plugin; + + private final XAResourceStatistics xastat; + + private ManagedConnection recoverMC; + + private String jndiName; + + /** + * Create a new XAResourceRecoveryImpl. + * + * @param ti ti + * @param mcf mcf + * @param padXid padXid + * @param isSameRMOverrideValue isSameRMOverrideValue + * @param wrapXAResource wrapXAResource + * @param recoverUserName recoverUserName + * @param recoverPassword recoverPassword + * @param recoverSecurityDomain recoverSecurityDomain + * @param subjectFactory subjectFactory + * @param plugin recovery plugin + * @param xastat The XAResource statistics implementation + */ + public XAResourceRecoveryImpl(TransactionIntegration ti, + ManagedConnectionFactory mcf, + Boolean padXid, Boolean isSameRMOverrideValue, Boolean wrapXAResource, + String recoverUserName, String recoverPassword, String recoverSecurityDomain, + SubjectFactory subjectFactory, + RecoveryPlugin plugin, + XAResourceStatistics xastat) + { + if (ti == null) + throw new IllegalArgumentException("TransactionIntegration is null"); + + if (mcf == null) + throw new IllegalArgumentException("MCF is null"); + + if (plugin == null) + throw new IllegalArgumentException("Plugin is null"); + + this.ti = ti; + this.mcf = mcf; + this.padXid = padXid; + this.isSameRMOverrideValue = isSameRMOverrideValue; + this.wrapXAResource = wrapXAResource; + this.recoverUserName = recoverUserName; + this.recoverPassword = recoverPassword; + this.recoverSecurityDomain = recoverSecurityDomain; + this.subjectFactory = subjectFactory; + + if (plugin instanceof ValidatingManagedConnectionFactoryRecoveryPlugin && + mcf instanceof ValidatingManagedConnectionFactory) + { + this.plugin = null; + } + else + { + this.plugin = plugin; + } + + this.xastat = xastat; + + this.recoverMC = null; + this.jndiName = null; + } + + /** + * {@inheritDoc} + */ + @Override + public void initialize() throws Exception + { + } + + /** + * {@inheritDoc} + */ + @Override + public void shutdown() throws Exception + { + if (recoverMC != null) + close(recoverMC); + } + + /** + * Set the jndiName. + * + * @param jndiName The jndiName to set. + */ + public void setJndiName(String jndiName) + { + this.jndiName = jndiName; + } + + /** + * Provides XAResource(s) to the transaction system for recovery purposes. + * + * @return An array of XAResource objects for use in transaction recovery + * In most cases the implementation will need to return only a single XAResource in the array. + * For more sophisticated cases, such as where multiple different connection types are supported, + * it may be necessary to return more than one. + * + * The Resource should be instantiated in such a way as to carry the necessary permissions to + * allow transaction recovery. For some deployments it may therefore be necessary or desirable to + * provide resource(s) based on e.g. database connection parameters such as username other than those + * used for the regular application connections to the same resource manager. + */ + @Override + public XAResource[] getXAResources() + { + try + { + Subject subject = getSubject(); + + // Check if we got a valid Subject instance; requirement for recovery + if (subject != null) + { + ManagedConnection mc = open(subject); + XAResource xaResource = null; + + Object connection = null; + try + { + connection = openConnection(mc, subject); + xaResource = mc.getXAResource(); + } + catch (ResourceException reconnect) + { + closeConnection(connection); + connection = null; + close(mc); + mc = open(subject); + xaResource = mc.getXAResource(); + } + finally + { + boolean forceDestroy = closeConnection(connection); + connection = null; + + if (forceDestroy) + { + close(mc); + mc = open(subject); + xaResource = mc.getXAResource(); + } + } + + if (wrapXAResource && !(xaResource instanceof org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper)) + { + String eisProductName = null; + String eisProductVersion = null; + + try + { + if (mc.getMetaData() != null) + { + eisProductName = mc.getMetaData().getEISProductName(); + eisProductVersion = mc.getMetaData().getEISProductVersion(); + } + } + catch (ResourceException re) + { + // Ignore + } + + if (eisProductName == null) + eisProductName = jndiName; + + if (eisProductVersion == null) + eisProductVersion = jndiName; + + xaResource = ti.createXAResourceWrapper(xaResource, + padXid, + isSameRMOverrideValue, + eisProductName, + eisProductVersion, + jndiName, false, + xastat); + } + + log.debugf("Recovery XAResource=%s for %s", xaResource, jndiName); + + return new XAResource[]{xaResource}; + } + else + { + log.nullSubjectCrashRecovery(jndiName); + } + } + catch (ResourceException re) + { + log.exceptionDuringCrashRecovery(jndiName, re.getMessage(), re); + } + + return new XAResource[0]; + } + + /** + * This method provide the Subject used for the XA Resource Recovery + * integration with the XAResourceRecoveryRegistry. + * + * This isn't done through the SecurityAssociation functionality of JBossSX + * as the Subject returned here should only be used for recovery. + * + * @return The recovery subject; null if no Subject could be created + */ + private Subject getSubject() + { + return AccessController.doPrivileged(new PrivilegedAction() + { + /** + * run method + */ + public Subject run() + { + if (recoverUserName != null && recoverPassword != null) + { + log.debugf("Recovery user name=%s", recoverUserName); + + // User name and password use-case + Subject subject = SecurityActions.createSubject(recoverUserName, recoverPassword, mcf); + + log.debugf("Recovery Subject=%s", subject); + + return subject; + } + else + { + // Security-domain use-case + try + { + // Select the domain + String domain = recoverSecurityDomain; + + if (domain != null && subjectFactory != null) + { + Subject subject = SecurityActions.createSubject(subjectFactory, domain); + + Set pcs = SecurityActions.getPasswordCredentials(subject); + if (pcs.size() > 0) + { + for (PasswordCredential pc : pcs) + { + pc.setManagedConnectionFactory(mcf); + } + } + + log.debugf("Recovery Subject=%s", subject); + + return subject; + } + else + { + log.noCrashRecoverySecurityDomain(jndiName); + } + } + catch (Throwable t) + { + log.exceptionDuringCrashRecoverySubject(jndiName, t.getMessage(), t); + } + + return null; + } + } + }); + } + + /** + * Open a managed connection + * @param s The subject + * @return The managed connection + * @exception ResourceException Thrown in case of an error + */ + @SuppressWarnings("unchecked") + private ManagedConnection open(Subject s) throws ResourceException + { + log.debugf("Open managed connection (%s)", s); + + if (recoverMC == null) + recoverMC = mcf.createManagedConnection(s, null); + + if (plugin == null) + { + try + { + ValidatingManagedConnectionFactory vmcf = (ValidatingManagedConnectionFactory)mcf; + + Set connectionSet = new HashSet(1); + connectionSet.add(recoverMC); + + Set invalid = vmcf.getInvalidConnections(connectionSet); + + if (invalid != null && invalid.size() > 0) + { + log.debugf("Invalid managed connection: %s", recoverMC); + + close(recoverMC); + recoverMC = mcf.createManagedConnection(s, null); + } + } + catch (ResourceException re) + { + log.debugf("Exception during invalid check", re); + + close(recoverMC); + recoverMC = mcf.createManagedConnection(s, null); + } + } + + return recoverMC; + } + + /** + * Close a managed connection + * @param mc The managed connection + */ + private void close(ManagedConnection mc) + { + log.debugf("Closing managed connection for recovery (%s)", mc); + + if (mc != null) + { + try + { + mc.cleanup(); + } + catch (ResourceException ire) + { + log.debugf("Error during recovery cleanup", ire); + } + } + + if (mc != null) + { + try + { + mc.destroy(); + } + catch (ResourceException ire) + { + log.debugf("Error during recovery destroy", ire); + } + } + + // The managed connection for recovery is now gone + recoverMC = null; + } + + /** + * Open a connection + * @param mc The managed connection + * @param s The subject + * @return The connection handle + * @exception ResourceException Thrown in case of an error + */ + private Object openConnection(ManagedConnection mc, Subject s) throws ResourceException + { + if (plugin == null) + return null; + + log.debugf("Open connection (%s, %s)", mc, s); + + return mc.getConnection(s, null); + } + + /** + * Close a connection + * @param c The connection + * @return Should the managed connection be forced closed + */ + private boolean closeConnection(Object c) + { + if (plugin == null) + return false; + + log.debugf("Closing connection for recovery check (%s)", c); + + boolean forceClose = false; + + if (c != null) + { + try + { + forceClose = !plugin.isValid(c); + } + catch (ResourceException re) + { + log.debugf("Error during recovery plugin isValid()", re); + forceClose = true; + } + + try + { + plugin.close(c); + } + catch (ResourceException re) + { + log.debugf("Error during recovery plugin close()", re); + forceClose = true; + } + } + + log.debugf("Force close=%s", forceClose); + + return forceClose; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XAResourceRecoveryInflowImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XAResourceRecoveryInflowImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XAResourceRecoveryInflowImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,152 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.CoreLogger; + +import javax.resource.NotSupportedException; +import javax.resource.ResourceException; +import javax.resource.spi.ActivationSpec; +import javax.resource.spi.ResourceAdapter; +import javax.transaction.xa.XAResource; + +import org.jboss.logging.Logger; + +/** + * An XAResourceRecovery for inflow implementation. + * + * @author Jesper Pedersen + */ +public class XAResourceRecoveryInflowImpl implements org.jboss.jca.core.spi.transaction.recovery.XAResourceRecovery, + org.jboss.tm.XAResourceRecovery +{ + /** Log instance */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + XAResourceRecoveryInflowImpl.class.getName()); + + private ResourceAdapter resourceAdapter; + + private ActivationSpec activationSpec; + + private String productName; + + private String productVersion; + + private String jndiName; + + /** + * Constructor + * + * @param rar The resource adapter + * @param as The activation spec + * @param productName The product name + * @param productVersion The product version + */ + public XAResourceRecoveryInflowImpl(ResourceAdapter rar, ActivationSpec as, + String productName, String productVersion) + { + if (rar == null) + throw new IllegalArgumentException("ResourceAdapter is null"); + + if (as == null) + throw new IllegalArgumentException("ActivationSpec is null"); + + this.resourceAdapter = rar; + this.activationSpec = as; + this.productName = productName; + this.productVersion = productVersion; + this.jndiName = null; + } + + /** + * {@inheritDoc} + */ + @Override + public void initialize() throws Exception + { + } + + /** + * {@inheritDoc} + */ + @Override + public void shutdown() throws Exception + { + } + + /** + * {@inheritDoc} + */ + public void setJndiName(String jndiName) + { + this.jndiName = jndiName; + } + + /** + * {@inheritDoc} + */ + @Override + public XAResource[] getXAResources() + { + try + { + XAResource[] result = resourceAdapter.getXAResources(new ActivationSpec[] {activationSpec}); + + if (result == null || result.length == 0) + return result; + + XAResource[] newResult = new XAResource[result.length]; + for (int i = 0; i < result.length; i++) + { + newResult[i] = new XAResourceWrapperImpl(result[i], productName, productVersion); + } + return newResult; + } + catch (NotSupportedException nse) + { + // Ignore + } + catch (ResourceException re) + { + log.exceptionDuringCrashRecoveryInflow(resourceAdapter.getClass().getName(), activationSpec, re); + } + + return new XAResource[0]; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("XAResourceRecoveryInflowImpl@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("["); + sb.append(" rar=").append(resourceAdapter.getClass().getName()); + sb.append(" as=").append(activationSpec); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XAResourceRecoveryRegistryImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XAResourceRecoveryRegistryImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XAResourceRecoveryRegistryImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,65 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.spi.transaction.recovery.XAResourceRecovery; + +/** + * An XAResourceRecoveryRegistry implementation + */ +public class XAResourceRecoveryRegistryImpl + implements org.jboss.jca.core.spi.transaction.recovery.XAResourceRecoveryRegistry +{ + /** Delegator */ + private org.jboss.tm.XAResourceRecoveryRegistry delegator; + + /** + * Constructor + * @param delegator The delegator + */ + public XAResourceRecoveryRegistryImpl(org.jboss.tm.XAResourceRecoveryRegistry delegator) + { + this.delegator = delegator; + } + + /** + * {@inheritDoc} + */ + public void addXAResourceRecovery(XAResourceRecovery recovery) + { + if (!(recovery instanceof org.jboss.tm.XAResourceRecovery)) + throw new IllegalArgumentException("Recovery is not a org.jboss.tm.XAResourceRecovery instance"); + + delegator.addXAResourceRecovery((org.jboss.tm.XAResourceRecovery)recovery); + } + + /** + * {@inheritDoc} + */ + public void removeXAResourceRecovery(XAResourceRecovery recovery) + { + if (!(recovery instanceof org.jboss.tm.XAResourceRecovery)) + throw new IllegalArgumentException("Recovery is not a org.jboss.tm.XAResourceRecovery instance"); + + delegator.removeXAResourceRecovery((org.jboss.tm.XAResourceRecovery)recovery); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XAResourceWrapperImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XAResourceWrapperImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XAResourceWrapperImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,376 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.transaction.xa.XidWrapper; + +import javax.transaction.xa.XAException; +import javax.transaction.xa.XAResource; +import javax.transaction.xa.Xid; + +import org.jboss.logging.Logger; + +/** + * A XAResourceWrapper. + * + * @author Weston Price + * @author Jesper Pedersen + */ +public class XAResourceWrapperImpl implements org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper, + org.jboss.tm.XAResourceWrapper +{ + /** Log instance */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, XAResourceWrapperImpl.class.getName()); + + /** The XA resource */ + private final XAResource xaResource; + + /** Pad */ + private final boolean pad; + + /** Override Rm Value */ + private final Boolean overrideRmValue; + + /** Product name */ + private final String productName; + + /** Product version */ + private final String productVersion; + + /** Product version */ + private final String jndiName; + + /** Cached hashCode() */ + private transient int cachedHashCode; + + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param productName product name + * @param productVersion product version + */ + public XAResourceWrapperImpl(XAResource resource, + String productName, String productVersion) + { + this(resource, false, null, productName, productVersion, null); + } + + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param pad pad + * @param override override + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + */ + public XAResourceWrapperImpl(XAResource resource, boolean pad, Boolean override, + String productName, String productVersion, + String jndiName) + { + this.overrideRmValue = override; + this.pad = pad; + this.xaResource = resource; + this.productName = productName; + this.productVersion = productVersion; + this.jndiName = jndiName; + } + + /** + * {@inheritDoc} + */ + public void commit(Xid xid, boolean onePhase) throws XAException + { + if (pad) + xid = convertXid(xid); + + xaResource.commit(xid, onePhase); + } + + /** + * {@inheritDoc} + */ + public void end(Xid xid, int flags) throws XAException + { + if (pad) + xid = convertXid(xid); + + xaResource.end(xid, flags); + } + + /** + * {@inheritDoc} + */ + public void forget(Xid xid) throws XAException + { + if (pad) + xid = convertXid(xid); + + xaResource.forget(xid); + } + + /** + * {@inheritDoc} + */ + public int getTransactionTimeout() throws XAException + { + return xaResource.getTransactionTimeout(); + } + + /** + * {@inheritDoc} + */ + public boolean isSameRM(XAResource resource) throws XAException + { + if (overrideRmValue != null) + { + if (log.isTraceEnabled()) + { + log.trace("Executing isSameRM with override value" + overrideRmValue + " for XAResourceWrapper" + this); + } + return overrideRmValue.booleanValue(); + } + else + { + if (resource instanceof org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper) + { + org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper other = + (org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper)resource; + return xaResource.isSameRM(other.getResource()); + } + else + { + return xaResource.isSameRM(resource); + } + + } + } + + /** + * {@inheritDoc} + */ + public int prepare(Xid xid) throws XAException + { + if (pad) + xid = convertXid(xid); + + return xaResource.prepare(xid); + } + + /** + * {@inheritDoc} + */ + public Xid[] recover(int flag) throws XAException + { + return xaResource.recover(flag); + } + + /** + * {@inheritDoc} + */ + public void rollback(Xid xid) throws XAException + { + if (pad) + xid = convertXid(xid); + + xaResource.rollback(xid); + } + + /** + * {@inheritDoc} + */ + public boolean setTransactionTimeout(int flag) throws XAException + { + return xaResource.setTransactionTimeout(flag); + } + + /** + * {@inheritDoc} + */ + public void start(Xid xid, int flags) throws XAException + { + if (pad) + xid = convertXid(xid); + + xaResource.start(xid, flags); + } + + /** + * Get the XAResource that is being wrapped + * @return The XAResource + */ + public XAResource getResource() + { + return xaResource; + } + + /** + * Get product name + * @return Product name of the instance if defined; otherwise null + */ + public String getProductName() + { + return productName; + } + + /** + * Get product version + * @return Product version of the instance if defined; otherwise null + */ + public String getProductVersion() + { + return productVersion; + } + + /** + * {@inheritDoc} + */ + public String getJndiName() + { + return jndiName; + } + + /** + * Return wrapper for given xid. + * @param xid xid + * @return return wrapper + */ + private Xid convertXid(Xid xid) + { + if (xid instanceof XidWrapper) + return xid; + else + return new XidWrapperImpl(xid, pad, jndiName); + } + + /** + * {@inheritDoc} + */ + public boolean equals(Object object) + { + if (object == this) + return true; + + if (object == null || !(object instanceof XAResourceWrapperImpl)) + return false; + + XAResourceWrapperImpl other = (XAResourceWrapperImpl)object; + if (xaResource != null) + { + if (!xaResource.equals(other.xaResource)) + return false; + } + else + { + if (other.xaResource != null) + return false; + } + + if (pad != other.pad) + return false; + + if (overrideRmValue != null) + { + if (!overrideRmValue.equals(other.overrideRmValue)) + return false; + } + else + { + if (other.overrideRmValue != null) + return false; + } + + if (productName != null) + { + if (!productName.equals(other.productName)) + return false; + } + else + { + if (other.productName != null) + return false; + } + + if (productVersion != null) + { + if (!productVersion.equals(other.productVersion)) + return false; + } + else + { + if (other.productVersion != null) + return false; + } + + if (jndiName != null) + { + if (!jndiName.equals(other.jndiName)) + return false; + } + else + { + if (other.jndiName != null) + return false; + } + + return true; + } + + /** + * {@inheritDoc} + */ + public int hashCode() + { + if (cachedHashCode == 0) + { + int result = 31; + result += xaResource != null ? 7 * xaResource.hashCode() : 7; + result += pad ? 7 : 1; + result += overrideRmValue != null ? 7 * overrideRmValue.hashCode() : 7; + result += productName != null ? 7 * productName.hashCode() : 7; + result += productVersion != null ? 7 * productVersion.hashCode() : 7; + result += jndiName != null ? 7 * jndiName.hashCode() : 7; + + cachedHashCode = result; + } + + return cachedHashCode; + } + + /** + * {@inheritDoc} + */ + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("XAResourceWrapperImpl@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[xaResource=").append(xaResource); + sb.append(" pad=").append(pad); + sb.append(" overrideRmValue=").append(overrideRmValue); + sb.append(" productName=").append(productName); + sb.append(" productVersion=").append(productVersion); + sb.append(" jndiName=").append(jndiName); + sb.append("]"); + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XAResourceWrapperStatImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XAResourceWrapperStatImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XAResourceWrapperStatImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,183 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.spi.transaction.XAResourceStatistics; + +import javax.transaction.xa.XAException; +import javax.transaction.xa.XAResource; +import javax.transaction.xa.Xid; + +/** + * A XAResourceWrapper with statistics + * + * @author Jesper Pedersen + */ +public class XAResourceWrapperStatImpl extends XAResourceWrapperImpl +{ + /** XAResource statistics */ + private XAResourceStatistics xastat; + + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param productName product name + * @param productVersion product version + * @param xastat The statistics + */ + public XAResourceWrapperStatImpl(XAResource resource, + String productName, String productVersion, + XAResourceStatistics xastat) + { + this(resource, false, null, productName, productVersion, null, xastat); + } + + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param pad pad + * @param override override + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param xastat The statistics + */ + public XAResourceWrapperStatImpl(XAResource resource, boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, XAResourceStatistics xastat) + { + super(resource, pad, override, productName, productVersion, jndiName); + this.xastat = xastat; + } + + /** + * {@inheritDoc} + */ + public void commit(Xid xid, boolean onePhase) throws XAException + { + long l1 = System.currentTimeMillis(); + try + { + super.commit(xid, onePhase); + } + finally + { + xastat.deltaCommit(System.currentTimeMillis() - l1); + } + } + + /** + * {@inheritDoc} + */ + public void end(Xid xid, int flags) throws XAException + { + long l1 = System.currentTimeMillis(); + try + { + super.end(xid, flags); + } + finally + { + xastat.deltaEnd(System.currentTimeMillis() - l1); + } + } + + /** + * {@inheritDoc} + */ + public void forget(Xid xid) throws XAException + { + long l1 = System.currentTimeMillis(); + try + { + super.forget(xid); + } + finally + { + xastat.deltaForget(System.currentTimeMillis() - l1); + } + } + + /** + * {@inheritDoc} + */ + public int prepare(Xid xid) throws XAException + { + long l1 = System.currentTimeMillis(); + try + { + return super.prepare(xid); + } + finally + { + xastat.deltaPrepare(System.currentTimeMillis() - l1); + } + } + + /** + * {@inheritDoc} + */ + public Xid[] recover(int flag) throws XAException + { + long l1 = System.currentTimeMillis(); + try + { + return super.recover(flag); + } + finally + { + xastat.deltaRecover(System.currentTimeMillis() - l1); + } + } + + /** + * {@inheritDoc} + */ + public void rollback(Xid xid) throws XAException + { + long l1 = System.currentTimeMillis(); + try + { + super.rollback(xid); + } + finally + { + xastat.deltaRollback(System.currentTimeMillis() - l1); + } + } + + /** + * {@inheritDoc} + */ + public void start(Xid xid, int flags) throws XAException + { + long l1 = System.currentTimeMillis(); + try + { + super.start(xid, flags); + } + finally + { + xastat.deltaStart(System.currentTimeMillis() - l1); + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XATerminatorImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XATerminatorImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XATerminatorImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,139 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import javax.resource.spi.work.Work; +import javax.resource.spi.work.WorkCompletedException; +import javax.transaction.xa.XAException; +import javax.transaction.xa.Xid; + +import org.jboss.tm.JBossXATerminator; + +/** + * XATerminator implementation + * + * @author Jesper Pedersen + */ +public class XATerminatorImpl implements org.jboss.jca.core.spi.transaction.xa.XATerminator +{ + /** Delegator */ + private JBossXATerminator delegator; + + /** + * Constructor + * @param delegator The delegator + */ + public XATerminatorImpl(JBossXATerminator delegator) + { + this.delegator = delegator; + } + + /** + * {@inheritDoc} + */ + public void commit(Xid xid, boolean onePhase) throws XAException + { + delegator.commit(xid, onePhase); + } + + /** + * {@inheritDoc} + */ + public void forget(Xid xid) throws XAException + { + delegator.forget(xid); + } + + /** + * {@inheritDoc} + */ + public int prepare(Xid xid) throws XAException + { + return delegator.prepare(xid); + } + + /** + * {@inheritDoc} + */ + public Xid[] recover(int flags) throws XAException + { + return delegator.recover(flags); + } + + /** + * {@inheritDoc} + */ + public void rollback(Xid xid) throws XAException + { + delegator.rollback(xid); + } + + /** + * Invoked for transaction inflow of work + * + * @param work The work starting + * @param xid The xid of the work + * @param timeout The transaction timeout + * @throws WorkCompletedException with error code WorkException.TX_CONCURRENT_WORK_DISALLOWED + * when work is already present for the xid or whose completion is in progress, only + * the global part of the xid must be used for this check. + */ + public void registerWork(Work work, Xid xid, long timeout) throws WorkCompletedException + { + delegator.registerWork(work, xid, timeout); + } + + /** + * Invoked for transaction inflow of work + * + * @param work The work starting + * @param xid The xid of the work + * @throws WorkCompletedException With error code WorkException.TX_RECREATE_FAILED if it is unable + * to recreate the transaction context + */ + public void startWork(Work work, Xid xid) throws WorkCompletedException + { + delegator.startWork(work, xid); + } + + /** + * Invoked when transaction inflow work ends + * + * @param work The work ending + * @param xid The xid of the work + */ + public void endWork(Work work, Xid xid) + { + delegator.endWork(work, xid); + } + + /** + * Invoked when the work fails + * + * @param work The work ending + * @param xid The xid of the work + */ + public void cancelWork(Work work, Xid xid) + { + delegator.cancelWork(work, xid); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XidWrapperImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XidWrapperImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/XidWrapperImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,157 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.jbossts; + +import org.jboss.jca.core.spi.transaction.xa.XidWrapper; + +import java.util.Arrays; + +import javax.transaction.xa.Xid; + +/** + * A XidWrapper. + * + * @author Weston Price + * @author Jesper Pedersen + */ +public class XidWrapperImpl implements XidWrapper +{ + /** The formatId */ + private int formatId; + + /** The globalTransactionId */ + private byte[] globalTransactionId; + + /** The branchQualifier */ + private byte[] branchQualifier; + + /** The jndi name */ + private String jndiName; + + /** Cached toString() */ + private transient String cachedToString; + + /** Cached hashCode() */ + private transient int cachedHashCode; + + /** + * Creates a new XidWrapperImpl instance. + * @param xid The Xid instances + * @param pad Should the branch qualifier be padded + * @param jndiName The JNDI name + */ + public XidWrapperImpl(Xid xid, boolean pad, String jndiName) + { + this.branchQualifier = pad ? new byte[Xid.MAXBQUALSIZE] : new byte[xid.getBranchQualifier().length]; + System.arraycopy(xid.getBranchQualifier(), 0, branchQualifier, 0, xid.getBranchQualifier().length); + + this.globalTransactionId = xid.getGlobalTransactionId(); + this.formatId = xid.getFormatId(); + this.jndiName = jndiName; + } + + /** + * {@inheritDoc} + */ + public byte[] getBranchQualifier() + { + return branchQualifier.clone(); + } + + /** + * {@inheritDoc} + */ + public int getFormatId() + { + return formatId; + } + + /** + * {@inheritDoc} + */ + public byte[] getGlobalTransactionId() + { + return globalTransactionId.clone(); + } + + /** + * {@inheritDoc} + */ + public String getJndiName() + { + return jndiName; + } + + /** + * {@inheritDoc} + */ + public boolean equals(Object object) + { + if (object == this) + return true; + + if (object == null || !(object instanceof Xid)) + return false; + + Xid other = (Xid)object; + return + ( + formatId == other.getFormatId() && + Arrays.equals(globalTransactionId, other.getGlobalTransactionId()) && + Arrays.equals(branchQualifier, other.getBranchQualifier()) + ); + } + + /** + * {@inheritDoc} + */ + public int hashCode() + { + if (cachedHashCode == 0) + { + cachedHashCode = formatId; + for (int i = 0; i < globalTransactionId.length; ++i) + cachedHashCode += globalTransactionId[i]; + } + return cachedHashCode; + } + + /** + * {@inheritDoc} + */ + public String toString() + { + if (cachedToString == null) + { + StringBuilder sb = new StringBuilder(); + sb.append("XidWrapperImpl@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[formatId=").append(getFormatId()); + sb.append(" globalTransactionId=").append(Arrays.toString(getGlobalTransactionId())); + sb.append(" branchQualifier=").append(Arrays.toString(getBranchQualifier())); + sb.append(" jndiName=").append(jndiName); + sb.append("]"); + cachedToString = sb.toString(); + } + + return cachedToString; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/jbossts/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains an implementation of the transaction SPI using JBossTS as its backend. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/ConnectableXAResourceWrapperImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/ConnectableXAResourceWrapperImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/ConnectableXAResourceWrapperImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,80 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.noopts; + +import org.jboss.jca.core.spi.transaction.ConnectableResource; +import org.jboss.jca.core.spi.transaction.ConnectableResourceListener; + +import javax.transaction.xa.XAResource; + +/** + * A connectable XAResourceWrapper + * + * @author Jesper Pedersen + */ +public class ConnectableXAResourceWrapperImpl extends XAResourceWrapperImpl implements ConnectableResource +{ + /** Connectable resource */ + private ConnectableResource cr; + + /** Connectable resource listener */ + private ConnectableResourceListener crl; + + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param override override + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param cr connectable resource + */ + public ConnectableXAResourceWrapperImpl(XAResource resource, Boolean override, + String productName, String productVersion, + String jndiName, ConnectableResource cr) + { + super(resource, override, productName, productVersion, jndiName); + this.cr = cr; + this.crl = null; + } + + /** + * {@inheritDoc} + */ + public Object getConnection() throws Exception + { + Object result = cr.getConnection(); + + if (crl != null) + crl.handleCreated(result); + + return result; + } + + /** + * {@inheritDoc} + */ + public void setConnectableResourceListener(ConnectableResourceListener crl) + { + this.crl = crl; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/LocalConnectableXAResourceImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/LocalConnectableXAResourceImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/LocalConnectableXAResourceImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,76 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.noopts; + +import org.jboss.jca.core.spi.transaction.ConnectableResource; +import org.jboss.jca.core.spi.transaction.ConnectableResourceListener; + +/** + * Local connectable XA resource implementation. + * + * @author Jesper Pedersen + */ +public class LocalConnectableXAResourceImpl extends LocalXAResourceImpl + implements ConnectableResource +{ + /** Connectable resource */ + private ConnectableResource cr; + + /** Connectable resource listener */ + private ConnectableResourceListener crl; + + /** + * Creates a new instance. + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + * @param cr connectable resource + */ + public LocalConnectableXAResourceImpl(String productName, String productVersion, + String jndiName, ConnectableResource cr) + { + super(productName, productVersion, jndiName); + this.cr = cr; + this.crl = null; + } + + /** + * {@inheritDoc} + */ + public Object getConnection() throws Exception + { + Object result = cr.getConnection(); + + if (crl != null) + crl.handleCreated(result); + + return result; + } + + /** + * {@inheritDoc} + */ + public void setConnectableResourceListener(ConnectableResourceListener crl) + { + this.crl = crl; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/LocalXAResourceImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/LocalXAResourceImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/LocalXAResourceImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,222 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.noopts; + +import org.jboss.jca.core.api.connectionmanager.ConnectionManager; +import org.jboss.jca.core.api.connectionmanager.listener.ConnectionListener; +import org.jboss.jca.core.spi.transaction.local.LocalXAException; +import org.jboss.jca.core.spi.transaction.local.LocalXAResource; +import org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper; + +import javax.resource.ResourceException; +import javax.transaction.xa.XAException; +import javax.transaction.xa.XAResource; +import javax.transaction.xa.Xid; + +/** + * Local XA resource implementation. + * + * @author Jesper Pedersen + */ +public class LocalXAResourceImpl implements LocalXAResource, XAResourceWrapper +{ + /** Connection listener */ + private ConnectionListener cl; + + /**Connection manager*/ + private ConnectionManager connectionManager = null; + + /** Product name */ + private String productName; + + /** Product version */ + private String productVersion; + + /** Product version */ + private String jndiName; + + /** + * Creates a new instance. + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + */ + public LocalXAResourceImpl(String productName, String productVersion, + String jndiName) + { + this.cl = null; + this.connectionManager = null; + this.productName = productName; + this.productVersion = productVersion; + this.jndiName = jndiName; + } + + /** + * {@inheritDoc} + */ + public void setConnectionManager(ConnectionManager connectionManager) + { + this.connectionManager = connectionManager; + } + + /** + * {@inheritDoc} + */ + public void setConnectionListener(ConnectionListener cl) + { + this.cl = cl; + } + + /** + * {@inheritDoc} + */ + public void start(Xid xid, int flags) throws XAException + { + try + { + cl.getManagedConnection().getLocalTransaction().begin(); + } + catch (ResourceException re) + { + throw new LocalXAException("start", XAException.XAER_RMERR, re); + } + } + + /** + * {@inheritDoc} + */ + public void end(Xid xid, int flags) throws XAException + { + } + + /** + * {@inheritDoc} + */ + public void commit(Xid xid, boolean onePhase) throws XAException + { + try + { + cl.getManagedConnection().getLocalTransaction().commit(); + } + catch (ResourceException re) + { + connectionManager.returnManagedConnection(cl, true); + throw new LocalXAException("commit", XAException.XA_RBROLLBACK, re); + } + } + + /** + * {@inheritDoc} + */ + public void forget(Xid xid) throws XAException + { + throw new LocalXAException("Error", XAException.XAER_RMERR); + } + + /** + * {@inheritDoc} + */ + public int getTransactionTimeout() throws XAException + { + return 0; + } + + /** + * {@inheritDoc} + */ + public boolean isSameRM(XAResource xaResource) throws XAException + { + return xaResource == this; + } + + /** + * {@inheritDoc} + */ + public int prepare(Xid xid) throws XAException + { + return XAResource.XA_OK; + } + + /** + * {@inheritDoc} + */ + public Xid[] recover(int flag) throws XAException + { + throw new LocalXAException("Error", XAException.XAER_RMERR); + } + + /** + * {@inheritDoc} + */ + public void rollback(Xid xid) throws XAException + { + try + { + cl.getManagedConnection().getLocalTransaction().rollback(); + } + catch (ResourceException re) + { + connectionManager.returnManagedConnection(cl, true); + throw new LocalXAException("rollback", XAException.XAER_RMERR, re); + } + } + + /** + * {@inheritDoc} + */ + public boolean setTransactionTimeout(int seconds) throws XAException + { + return false; + } + + /** + * {@inheritDoc} + */ + public XAResource getResource() + { + return this; + } + + /** + * {@inheritDoc} + */ + public String getProductName() + { + return productName; + } + + /** + * {@inheritDoc} + */ + public String getProductVersion() + { + return productVersion; + } + + /** + * {@inheritDoc} + */ + public String getJndiName() + { + return jndiName; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/TransactionImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/TransactionImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/TransactionImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,233 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.noopts; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.transaction.HeuristicMixedException; +import javax.transaction.HeuristicRollbackException; +import javax.transaction.RollbackException; +import javax.transaction.Status; +import javax.transaction.Synchronization; +import javax.transaction.SystemException; +import javax.transaction.Transaction; +import javax.transaction.xa.XAResource; + +/** + * A transaction implementation + * @author Jesper Pedersen + */ +public class TransactionImpl implements Transaction, Serializable +{ + private static final long serialVersionUID = 3L; + private transient Long key; + private transient int status; + private transient Set syncs; + private transient Map resources; + + /** + * Constructor + * @param key The transaction key + */ + public TransactionImpl(Long key) + { + this.key = key; + this.status = Status.STATUS_ACTIVE; + this.syncs = new HashSet(); + this.resources = new HashMap(); + } + + /** + * {@inheritDoc} + */ + public void commit() throws RollbackException, + HeuristicMixedException, + HeuristicRollbackException, + SecurityException, + IllegalStateException, + SystemException + { + if (status == Status.STATUS_UNKNOWN) + throw new IllegalStateException("Status unknown"); + + if (status == Status.STATUS_MARKED_ROLLBACK) + throw new IllegalStateException("Status marked rollback"); + + finish(true); + } + + /** + * {@inheritDoc} + */ + public boolean delistResource(XAResource xaRes, int flag) throws IllegalStateException, + SystemException + { + if (status == Status.STATUS_UNKNOWN) + throw new IllegalStateException("Status unknown"); + + if (status != Status.STATUS_ACTIVE && status != Status.STATUS_MARKED_ROLLBACK) + throw new IllegalStateException("Status not valid"); + + return true; + } + + /** + * {@inheritDoc} + */ + public boolean enlistResource(XAResource xaRes) throws RollbackException, + IllegalStateException, + SystemException + { + if (status == Status.STATUS_UNKNOWN) + throw new IllegalStateException("Status unknown"); + + return true; + } + + /** + * {@inheritDoc} + */ + public int getStatus() throws SystemException + { + return status; + } + + /** + * {@inheritDoc} + */ + public void registerSynchronization(Synchronization sync) throws RollbackException, + IllegalStateException, + SystemException + { + if (status == Status.STATUS_UNKNOWN) + throw new IllegalStateException("Status unknown"); + + syncs.add(sync); + } + + /** + * {@inheritDoc} + */ + public void rollback() throws IllegalStateException, + SystemException + { + if (status == Status.STATUS_UNKNOWN) + throw new IllegalStateException("Status unknown"); + + finish(false); + } + + /** + * {@inheritDoc} + */ + public void setRollbackOnly() throws IllegalStateException, + SystemException + { + if (status == Status.STATUS_UNKNOWN) + throw new IllegalStateException("Status unknown"); + + status = Status.STATUS_MARKED_ROLLBACK; + } + + /** + * Get rollback only + * @return The value + */ + boolean getRollbackOnly() + { + if (status == Status.STATUS_UNKNOWN) + throw new IllegalStateException("Status unknown"); + + return status == Status.STATUS_MARKED_ROLLBACK; + } + + /** + * Put a resource + * @param key The key + * @param value The value + */ + void putResource(Object key, Object value) + { + resources.put(key, value); + } + + /** + * Get a resource + * @param key The key + * @return The value + */ + Object getResource(Object key) + { + return resources.get(key); + } + + /** + * Get the transaction key + * @return The value + */ + Long getKey() + { + return key; + } + + /** + * Active + */ + void active() + { + status = Status.STATUS_ACTIVE; + } + + /** + * Finish transaction + * @param commit Commit (true), or rollback (false) + */ + private void finish(boolean commit) + { + for (Synchronization s : syncs) + { + s.beforeCompletion(); + } + + if (commit) + { + status = Status.STATUS_COMMITTED; + } + else + { + status = Status.STATUS_ROLLEDBACK; + } + + for (Synchronization s : syncs) + { + s.afterCompletion(status); + } + + status = Status.STATUS_UNKNOWN; + syncs.clear(); + resources.clear(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/TransactionIntegrationImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/TransactionIntegrationImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/TransactionIntegrationImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,247 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.noopts; + +import org.jboss.jca.core.api.connectionmanager.ConnectionManager; +import org.jboss.jca.core.spi.recovery.RecoveryPlugin; +import org.jboss.jca.core.spi.security.SubjectFactory; +import org.jboss.jca.core.spi.transaction.ConnectableResource; +import org.jboss.jca.core.spi.transaction.TransactionIntegration; +import org.jboss.jca.core.spi.transaction.XAResourceStatistics; +import org.jboss.jca.core.spi.transaction.local.LocalXAResource; +import org.jboss.jca.core.spi.transaction.recovery.XAResourceRecovery; +import org.jboss.jca.core.spi.transaction.recovery.XAResourceRecoveryRegistry; +import org.jboss.jca.core.spi.transaction.usertx.UserTransactionRegistry; +import org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper; +import org.jboss.jca.core.spi.transaction.xa.XATerminator; + +import javax.resource.spi.ActivationSpec; +import javax.resource.spi.ManagedConnection; +import javax.resource.spi.ManagedConnectionFactory; +import javax.resource.spi.ResourceAdapter; +import javax.transaction.Transaction; +import javax.transaction.TransactionManager; +import javax.transaction.TransactionSynchronizationRegistry; +import javax.transaction.xa.XAResource; + +/** + * This class provide an implementation of the transaction integration for + * the IronJacamar container using NoopTS. + * + * @author Jesper Pedersen + */ +public class TransactionIntegrationImpl implements TransactionIntegration +{ + /** The transaction manager */ + private TransactionManager tm; + + /** The transaction synchronization registry */ + private TransactionSynchronizationRegistry tsr; + + /** User transaction registry */ + private UserTransactionRegistry utr; + + /** XATerminator */ + private XATerminator terminator; + + /** Recovery registry */ + private XAResourceRecoveryRegistry rr; + + /** + * Constructor + * @param tm The transaction manager + * @param tsr The transaction synchronization registry + * @param utr The user transaction registry + * @param terminator The XA terminator + * @param rr The recovery registry + */ + public TransactionIntegrationImpl(TransactionManager tm, + TransactionSynchronizationRegistry tsr, + UserTransactionRegistry utr, + XATerminator terminator, + XAResourceRecoveryRegistry rr) + { + this.tm = tm; + this.tsr = tsr; + this.utr = utr; + this.terminator = terminator; + this.rr = rr; + } + + /** + * {@inheritDoc} + */ + public TransactionManager getTransactionManager() + { + return tm; + } + + /** + * {@inheritDoc} + */ + public TransactionSynchronizationRegistry getTransactionSynchronizationRegistry() + { + return tsr; + } + + /** + * {@inheritDoc} + */ + public UserTransactionRegistry getUserTransactionRegistry() + { + return utr; + } + + /** + * {@inheritDoc} + */ + public XAResourceRecoveryRegistry getRecoveryRegistry() + { + return rr; + } + + /** + * {@inheritDoc} + */ + public XATerminator getXATerminator() + { + return terminator; + } + + /** + * {@inheritDoc} + */ + public XAResourceRecovery createXAResourceRecovery(ResourceAdapter rar, ActivationSpec as, + String productName, String productVersion) + { + return new XAResourceRecoveryImpl(); + } + + /** + * {@inheritDoc} + */ + public XAResourceRecovery createXAResourceRecovery(ManagedConnectionFactory mcf, + Boolean pad, Boolean override, + Boolean wrapXAResource, + String recoverUserName, String recoverPassword, + String recoverSecurityDomain, + SubjectFactory subjectFactory, + RecoveryPlugin plugin, + XAResourceStatistics xastat) + { + return new XAResourceRecoveryImpl(); + } + + /** + * {@inheritDoc} + */ + public LocalXAResource createConnectableLocalXAResource(ConnectionManager cm, + String productName, String productVersion, + String jndiName, ConnectableResource cr, + XAResourceStatistics xastat) + { + return new LocalConnectableXAResourceImpl(productName, productVersion, jndiName, cr); + } + + /** + * {@inheritDoc} + */ + public LocalXAResource createConnectableLocalXAResource(ConnectionManager cm, + String productName, String productVersion, + String jndiName, ManagedConnection mc, + XAResourceStatistics xastat) + { + return new LocalConnectableXAResourceImpl(productName, productVersion, jndiName, (ConnectableResource)mc); + } + + /** + * {@inheritDoc} + */ + public LocalXAResource createLocalXAResource(ConnectionManager cm, + String productName, String productVersion, + String jndiName, + XAResourceStatistics xastat) + { + return new LocalXAResourceImpl(productName, productVersion, jndiName); + } + + /** + * {@inheritDoc} + */ + public XAResourceWrapper createConnectableXAResourceWrapper(XAResource xares, + boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, ConnectableResource cr, + XAResourceStatistics xastat) + { + return new ConnectableXAResourceWrapperImpl(xares, override, productName, productVersion, jndiName, cr); + } + + /** + * {@inheritDoc} + */ + public XAResourceWrapper createConnectableXAResourceWrapper(XAResource xares, + boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, ManagedConnection mc, + XAResourceStatistics xastat) + { + return new ConnectableXAResourceWrapperImpl(xares, override, productName, productVersion, jndiName, + (ConnectableResource)mc); + } + + /** + * {@inheritDoc} + */ + public XAResourceWrapper createXAResourceWrapper(XAResource xares, + boolean pad, Boolean override, + String productName, String productVersion, + String jndiName, boolean firstResource, + XAResourceStatistics xastat) + { + return new XAResourceWrapperImpl(xares, override, productName, productVersion, jndiName); + } + + /** + * {@inheritDoc} + */ + public boolean isFirstResource(ManagedConnection mc) + { + return mc != null && mc instanceof org.jboss.jca.core.spi.transaction.FirstResource; + } + + /** + * {@inheritDoc} + */ + public boolean isConnectableResource(ManagedConnection mc) + { + return mc != null && mc instanceof ConnectableResource; + } + + /** + * {@inheritDoc} + */ + public Object getIdentifier(Transaction tx) + { + return tx; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/TransactionManagerImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/TransactionManagerImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/TransactionManagerImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,208 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.noopts; + +import java.io.Serializable; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.transaction.HeuristicMixedException; +import javax.transaction.HeuristicRollbackException; +import javax.transaction.InvalidTransactionException; +import javax.transaction.NotSupportedException; +import javax.transaction.RollbackException; +import javax.transaction.Status; +import javax.transaction.SystemException; +import javax.transaction.Transaction; +import javax.transaction.TransactionManager; + +/** + * A transaction manager implementation + * @author Jesper Pedersen + */ +public class TransactionManagerImpl implements TransactionManager, Serializable +{ + private static final long serialVersionUID = 1L; + private static final String JNDI_NAME = "java:/TransactionManager"; + private TxRegistry registry; + + /** + * Constructor + */ + public TransactionManagerImpl() + { + this.registry = null; + } + + /** + * Set the registry + * @param v The value + */ + public void setRegistry(TxRegistry v) + { + registry = v; + } + + /** + * {@inheritDoc} + */ + public void begin() throws NotSupportedException, + SystemException + { + Transaction tx = registry.getTransaction(); + + if (tx != null) + throw new NotSupportedException(); + + registry.startTransaction(); + } + + /** + * {@inheritDoc} + */ + public void commit() throws RollbackException, + HeuristicMixedException, + HeuristicRollbackException, + SecurityException, + IllegalStateException, + SystemException + { + Transaction tx = registry.getTransaction(); + + if (tx == null) + throw new SystemException(); + + if (tx.getStatus() == Status.STATUS_ROLLEDBACK || + tx.getStatus() == Status.STATUS_MARKED_ROLLBACK) + throw new RollbackException(); + + registry.commitTransaction(); + } + + /** + * {@inheritDoc} + */ + public int getStatus() throws SystemException + { + Transaction tx = registry.getTransaction(); + + if (tx == null) + return Status.STATUS_NO_TRANSACTION; + + return tx.getStatus(); + } + + /** + * {@inheritDoc} + */ + public Transaction getTransaction() throws SystemException + { + return registry.getTransaction(); + } + + /** + * {@inheritDoc} + */ + public void resume(Transaction tobj) throws InvalidTransactionException, + IllegalStateException, + SystemException + { + if (!(tobj instanceof TransactionImpl)) + throw new SystemException(); + + registry.assignTransaction((TransactionImpl)tobj); + } + + /** + * {@inheritDoc} + */ + public void rollback() throws IllegalStateException, + SecurityException, + SystemException + { + Transaction tx = registry.getTransaction(); + + if (tx == null) + throw new IllegalStateException(); + + registry.rollbackTransaction(); + } + + /** + * {@inheritDoc} + */ + public void setRollbackOnly() throws IllegalStateException, + SystemException + { + Transaction tx = registry.getTransaction(); + + if (tx == null) + throw new IllegalStateException(); + + tx.setRollbackOnly(); + } + + /** + * {@inheritDoc} + */ + public void setTransactionTimeout(int seconds) throws SystemException + { + } + + /** + * {@inheritDoc} + */ + public Transaction suspend() throws SystemException + { + Transaction tx = registry.getTransaction(); + + registry.assignTransaction(null); + + return tx; + } + + /** + * Start + * @exception Throwable Thrown if an error occurs + */ + public void start() throws Throwable + { + Context context = new InitialContext(); + + context.bind(JNDI_NAME, this); + + context.close(); + } + + /** + * Stop + * @exception Throwable Thrown if an error occurs + */ + public void stop() throws Throwable + { + Context context = new InitialContext(); + + context.unbind(JNDI_NAME); + + context.close(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/TransactionSynchronizationRegistryImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/TransactionSynchronizationRegistryImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/TransactionSynchronizationRegistryImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,188 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.noopts; + +import java.io.Serializable; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.transaction.Status; +import javax.transaction.Synchronization; +import javax.transaction.TransactionSynchronizationRegistry; + +/** + * A transaction synchronization registry implementation + * @author Jesper Pedersen + */ +public class TransactionSynchronizationRegistryImpl implements TransactionSynchronizationRegistry, Serializable +{ + private static final long serialVersionUID = 3L; + private static final String JNDI_NAME = "java:/TransactionSynchronizationRegistry"; + private transient TxRegistry registry; + + /** + * Constructor + */ + public TransactionSynchronizationRegistryImpl() + { + this.registry = null; + } + + /** + * Set the registry + * @param v The value + */ + public void setRegistry(TxRegistry v) + { + registry = v; + } + + /** + * {@inheritDoc} + */ + public Object getTransactionKey() + { + TransactionImpl tx = registry.getTransaction(); + + if (tx != null) + return tx.getKey(); + + return null; + } + + /** + * {@inheritDoc} + */ + public void putResource(Object key, Object value) + { + TransactionImpl tx = registry.getTransaction(); + tx.putResource(key, value); + } + + /** + * {@inheritDoc} + */ + public Object getResource(Object key) + { + TransactionImpl tx = registry.getTransaction(); + return tx.getResource(key); + } + + /** + * {@inheritDoc} + */ + public void registerInterposedSynchronization(Synchronization sync) + { + TransactionImpl tx = registry.getTransaction(); + + if (tx == null) + throw new IllegalStateException(); + + try + { + tx.registerSynchronization(sync); + } + catch (Throwable t) + { + // Nothing to do + } + } + + /** + * {@inheritDoc} + */ + public int getTransactionStatus() + { + TransactionImpl tx = registry.getTransaction(); + + if (tx == null) + return Status.STATUS_NO_TRANSACTION; + + try + { + return tx.getStatus(); + } + catch (Throwable t) + { + return Status.STATUS_UNKNOWN; + } + } + + /** + * {@inheritDoc} + */ + public void setRollbackOnly() + { + TransactionImpl tx = registry.getTransaction(); + + if (tx == null) + throw new IllegalStateException(); + + try + { + tx.setRollbackOnly(); + } + catch (Throwable t) + { + // Nothing to do + } + } + + /** + * {@inheritDoc} + */ + public boolean getRollbackOnly() + { + TransactionImpl tx = registry.getTransaction(); + + if (tx == null) + throw new IllegalStateException(); + + return tx.getRollbackOnly(); + } + + /** + * Start + * @exception Throwable Thrown if an error occurs + */ + public void start() throws Throwable + { + Context context = new InitialContext(); + + context.bind(JNDI_NAME, this); + + context.close(); + } + + /** + * Stop + * @exception Throwable Thrown if an error occurs + */ + public void stop() throws Throwable + { + Context context = new InitialContext(); + + context.unbind(JNDI_NAME); + + context.close(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/TxRegistry.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/TxRegistry.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/TxRegistry.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,137 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.noopts; + +import java.io.Serializable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import javax.transaction.SystemException; + +/** + * The transaction registry + * @author Jesper Pedersen + */ +public class TxRegistry implements Serializable +{ + private static final long serialVersionUID = 1L; + private ConcurrentMap txs; + + /** + * Constructor + */ + public TxRegistry() + { + this.txs = new ConcurrentHashMap(); + } + + /** + * Get the transaction for the current thread + * @return The value + */ + public TransactionImpl getTransaction() + { + return txs.get(Long.valueOf(Thread.currentThread().getId())); + } + + /** + * Start a transaction + */ + public void startTransaction() + { + Long key = Long.valueOf(Thread.currentThread().getId()); + TransactionImpl tx = txs.get(key); + + if (tx == null) + { + TransactionImpl newTx = new TransactionImpl(key); + tx = txs.putIfAbsent(key, newTx); + if (tx == null) + tx = newTx; + } + + tx.active(); + } + + /** + * Commit a transaction + * @exception SystemException Thrown if an error occurs + */ + public void commitTransaction() throws SystemException + { + Long key = Long.valueOf(Thread.currentThread().getId()); + TransactionImpl tx = txs.get(key); + if (tx != null) + { + try + { + tx.commit(); + } + catch (Throwable t) + { + SystemException se = new SystemException("Error during commit"); + se.initCause(t); + throw se; + } + } + else + { + throw new IllegalStateException("No transaction to commit"); + } + } + + /** + * Rollback a transaction + * @exception SystemException Thrown if an error occurs + */ + public void rollbackTransaction() throws SystemException + { + Long key = Long.valueOf(Thread.currentThread().getId()); + TransactionImpl tx = txs.get(key); + if (tx != null) + { + try + { + tx.rollback(); + } + catch (Throwable t) + { + SystemException se = new SystemException("Error during rollback"); + se.initCause(t); + throw se; + } + } + else + { + throw new IllegalStateException("No transaction to rollback"); + } + } + + /** + * Assign a transaction + * @param v The value + */ + public void assignTransaction(TransactionImpl v) + { + txs.put(Long.valueOf(Thread.currentThread().getId()), v); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/UserTransactionImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/UserTransactionImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/UserTransactionImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,192 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.noopts; + +import org.jboss.jca.core.spi.transaction.usertx.UserTransactionProvider; +import org.jboss.jca.core.spi.transaction.usertx.UserTransactionRegistry; + +import java.io.Serializable; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.transaction.HeuristicMixedException; +import javax.transaction.HeuristicRollbackException; +import javax.transaction.NotSupportedException; +import javax.transaction.RollbackException; +import javax.transaction.Status; +import javax.transaction.SystemException; +import javax.transaction.Transaction; +import javax.transaction.UserTransaction; + +/** + * A transaction manager implementation + * @author Jesper Pedersen + */ +public class UserTransactionImpl implements UserTransactionProvider, UserTransaction, Serializable +{ + private static final long serialVersionUID = 2L; + private static final String JNDI_NAME = "java:/UserTransaction"; + private transient TxRegistry registry; + private transient UserTransactionRegistry userTransactionRegistry; + + /** + * Constructor + */ + public UserTransactionImpl() + { + this.registry = null; + this.userTransactionRegistry = null; + } + + /** + * Set the registry + * @param v The value + */ + public void setRegistry(TxRegistry v) + { + registry = v; + } + + /** + * Set the user transaction registry + * @param v The value + */ + public void setUserTransactionRegistry(UserTransactionRegistry v) + { + userTransactionRegistry = v; + } + + /** + * {@inheritDoc} + */ + public void begin() throws NotSupportedException, + SystemException + { + Transaction tx = registry.getTransaction(); + + if (tx != null && tx.getStatus() != Status.STATUS_UNKNOWN) + throw new SystemException(); + + registry.startTransaction(); + + if (userTransactionRegistry != null) + userTransactionRegistry.userTransactionStarted(); + } + + /** + * {@inheritDoc} + */ + public void commit() throws RollbackException, + HeuristicMixedException, + HeuristicRollbackException, + SecurityException, + IllegalStateException, + SystemException + { + Transaction tx = registry.getTransaction(); + + if (tx == null) + throw new SystemException(); + + if (tx.getStatus() == Status.STATUS_ROLLING_BACK || + tx.getStatus() == Status.STATUS_ROLLEDBACK || + tx.getStatus() == Status.STATUS_MARKED_ROLLBACK) + throw new RollbackException(); + + registry.commitTransaction(); + } + + /** + * {@inheritDoc} + */ + public void rollback() throws IllegalStateException, + SecurityException, + SystemException + { + Transaction tx = registry.getTransaction(); + + if (tx == null) + throw new IllegalStateException(); + + registry.rollbackTransaction(); + } + + /** + * {@inheritDoc} + */ + public void setRollbackOnly() throws IllegalStateException, + SystemException + { + Transaction tx = registry.getTransaction(); + + if (tx == null) + throw new IllegalStateException(); + + tx.setRollbackOnly(); + } + + /** + * {@inheritDoc} + */ + public int getStatus() throws SystemException + { + Transaction tx = registry.getTransaction(); + + if (tx == null) + return Status.STATUS_NO_TRANSACTION; + + return tx.getStatus(); + } + + /** + * {@inheritDoc} + */ + public void setTransactionTimeout(int seconds) throws SystemException + { + } + + /** + * Start + * @exception Throwable Thrown if an error occurs + */ + public void start() throws Throwable + { + Context context = new InitialContext(); + + context.bind(JNDI_NAME, this); + + context.close(); + } + + /** + * Stop + * @exception Throwable Thrown if an error occurs + */ + public void stop() throws Throwable + { + Context context = new InitialContext(); + + context.unbind(JNDI_NAME); + + context.close(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/UserTransactionRegistryImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/UserTransactionRegistryImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/UserTransactionRegistryImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,115 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.noopts; + +import org.jboss.jca.core.spi.transaction.usertx.UserTransactionListener; +import org.jboss.jca.core.spi.transaction.usertx.UserTransactionProvider; +import org.jboss.jca.core.spi.transaction.usertx.UserTransactionRegistry; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import javax.transaction.SystemException; + +/** + * UserTransactionRegistry implementation. + * + * @author Jesper Pedersen + */ +public class UserTransactionRegistryImpl implements UserTransactionRegistry +{ + /** Listeners */ + private Set listeners; + + /** Providers */ + private Set providers; + + /** + * Constructor + */ + public UserTransactionRegistryImpl() + { + this.listeners = Collections.synchronizedSet(new HashSet()); + this.providers = Collections.synchronizedSet(new HashSet()); + } + + /** + * {@inheritDoc} + */ + public void addListener(UserTransactionListener listener) + { + if (listener != null) + listeners.add(listener); + } + + /** + * {@inheritDoc} + */ + public void removeListener(UserTransactionListener listener) + { + if (listener != null) + listeners.remove(listener); + } + + /** + * {@inheritDoc} + */ + public void addProvider(UserTransactionProvider provider) + { + if (provider != null) + { + provider.setUserTransactionRegistry(this); + providers.add(provider); + } + } + + /** + * {@inheritDoc} + */ + public void removeProvider(UserTransactionProvider provider) + { + if (provider != null) + { + provider.setUserTransactionRegistry(null); + providers.remove(provider); + } + } + + /** + * {@inheritDoc} + */ + public void userTransactionStarted() + { + for (UserTransactionListener utl : listeners) + { + try + { + utl.userTransactionStarted(); + } + catch (SystemException se) + { + // Ignore + } + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/XAResourceRecoveryImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/XAResourceRecoveryImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/XAResourceRecoveryImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,74 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.noopts; + +import org.jboss.jca.core.spi.transaction.recovery.XAResourceRecovery; + +import javax.transaction.xa.XAResource; + +/** + * An XAResourceRecovery implementation. + * + * @author Jesper Pedersen + */ +public class XAResourceRecoveryImpl implements XAResourceRecovery +{ + /** + * Constructor + */ + public XAResourceRecoveryImpl() + { + } + + /** + * {@inheritDoc} + */ + @Override + public void initialize() throws Exception + { + } + + /** + * {@inheritDoc} + */ + @Override + public void shutdown() throws Exception + { + } + + /** + * {@inheritDoc} + */ + @Override + public XAResource[] getXAResources() + { + return new XAResource[0]; + } + + /** + * {@inheritDoc} + */ + @Override + public void setJndiName(String jndiName) + { + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/XAResourceWrapperImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/XAResourceWrapperImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/XAResourceWrapperImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,212 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2011, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.noopts; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper; + +import javax.transaction.xa.XAException; +import javax.transaction.xa.XAResource; +import javax.transaction.xa.Xid; + +import org.jboss.logging.Logger; + +/** + * A XAResourceWrapper. + * + * @author Jesper Pedersen + */ +public class XAResourceWrapperImpl implements XAResourceWrapper +{ + /** Log instance */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, XAResourceWrapperImpl.class.getName()); + + /** The XA resource */ + private XAResource xaResource; + + /** Override Rm Value */ + private Boolean overrideRmValue; + + /** Product name */ + private String productName; + + /** Product version */ + private String productVersion; + + /** Product version */ + private String jndiName; + + /** + * Creates a new wrapper instance. + * @param resource xaresource + * @param override override + * @param productName product name + * @param productVersion product version + * @param jndiName jndi name + */ + public XAResourceWrapperImpl(XAResource resource, Boolean override, + String productName, String productVersion, + String jndiName) + { + this.xaResource = resource; + this.overrideRmValue = override; + this.productName = productName; + this.productVersion = productVersion; + this.jndiName = jndiName; + } + + /** + * {@inheritDoc} + */ + public void commit(Xid xid, boolean onePhase) throws XAException + { + xaResource.commit(xid, onePhase); + } + + /** + * {@inheritDoc} + */ + public void end(Xid xid, int flags) throws XAException + { + xaResource.end(xid, flags); + } + + /** + * {@inheritDoc} + */ + public void forget(Xid xid) throws XAException + { + xaResource.forget(xid); + } + + /** + * {@inheritDoc} + */ + public int getTransactionTimeout() throws XAException + { + return xaResource.getTransactionTimeout(); + } + + /** + * {@inheritDoc} + */ + public boolean isSameRM(XAResource resource) throws XAException + { + if (overrideRmValue != null) + { + if (log.isTraceEnabled()) + { + log.trace("Executing isSameRM with override value" + overrideRmValue + " for XAResourceWrapper" + this); + } + return overrideRmValue.booleanValue(); + } + else + { + if (resource instanceof org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper) + { + org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper other = + (org.jboss.jca.core.spi.transaction.xa.XAResourceWrapper)resource; + return xaResource.isSameRM(other.getResource()); + } + else + { + return xaResource.isSameRM(resource); + } + + } + } + + /** + * {@inheritDoc} + */ + public int prepare(Xid xid) throws XAException + { + return xaResource.prepare(xid); + } + + /** + * {@inheritDoc} + */ + public Xid[] recover(int flag) throws XAException + { + return xaResource.recover(flag); + } + + /** + * {@inheritDoc} + */ + public void rollback(Xid xid) throws XAException + { + xaResource.rollback(xid); + } + + /** + * {@inheritDoc} + */ + public boolean setTransactionTimeout(int flag) throws XAException + { + return xaResource.setTransactionTimeout(flag); + } + + /** + * {@inheritDoc} + */ + public void start(Xid xid, int flags) throws XAException + { + xaResource.start(xid, flags); + } + + /** + * Get the XAResource that is being wrapped + * @return The XAResource + */ + public XAResource getResource() + { + return xaResource; + } + + /** + * Get product name + * @return Product name of the instance if defined; otherwise null + */ + public String getProductName() + { + return productName; + } + + /** + * Get product version + * @return Product version of the instance if defined; otherwise null + */ + public String getProductVersion() + { + return productVersion; + } + + /** + * {@inheritDoc} + */ + public String getJndiName() + { + return jndiName; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/XATerminatorImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/XATerminatorImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/XATerminatorImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,113 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.noopts; + +import org.jboss.jca.core.spi.transaction.xa.XATerminator; + +import java.io.Serializable; + +import javax.resource.spi.work.Work; +import javax.resource.spi.work.WorkCompletedException; +import javax.transaction.xa.XAException; +import javax.transaction.xa.XAResource; +import javax.transaction.xa.Xid; + +/** + * An XATerminator implementation + * @author Jesper Pedersen + */ +public class XATerminatorImpl implements XATerminator, Serializable +{ + private static final long serialVersionUID = 1L; + + /** + * Constructor + */ + public XATerminatorImpl() + { + } + + /** + * {@inheritDoc} + */ + public void commit(Xid xid, boolean onePhase) throws XAException + { + } + + /** + * {@inheritDoc} + */ + public void forget(Xid xid) throws XAException + { + } + + /** + * {@inheritDoc} + */ + public int prepare(Xid xid) throws XAException + { + return XAResource.XA_OK; + } + + /** + * {@inheritDoc} + */ + public Xid[] recover(int flag) throws XAException + { + return new Xid[0]; + } + + /** + * {@inheritDoc} + */ + public void rollback(Xid xid) throws XAException + { + } + + /** + * {@inheritDoc} + */ + public void registerWork(Work work, Xid xid, long timeout) throws WorkCompletedException + { + } + + /** + * {@inheritDoc} + */ + public void startWork(Work work, Xid xid) throws WorkCompletedException + { + } + + /** + * {@inheritDoc} + */ + public void endWork(Work work, Xid xid) + { + } + + /** + * {@inheritDoc} + */ + public void cancelWork(Work work, Xid xid) + { + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/XidImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/XidImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/XidImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,62 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.tx.noopts; + +import javax.transaction.xa.Xid; + +/** + * A Xid implementation + * @author Jesper Pedersen + */ +public class XidImpl implements Xid +{ + /** + * Constructor + */ + public XidImpl() + { + } + + /** + * {@inheritDoc} + */ + public byte[] getBranchQualifier() + { + return new byte[] {0}; + } + + /** + * {@inheritDoc} + */ + public int getFormatId() + { + return 0; + } + + /** + * {@inheritDoc} + */ + public byte[] getGlobalTransactionId() + { + return new byte[] {0}; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/noopts/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains a no-operation transaction manager implementation which can be used instead of a real implementation + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/tx/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains internal transaction related interfaces and classes that are shared across all transaction manager integrations. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/util/Injection.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/util/Injection.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/util/Injection.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,630 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2013, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.util; + +import java.io.File; +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Locale; +import java.util.Properties; +import java.util.StringTokenizer; + +/** + * Injection utility which can inject values into objects. This file is a copy + * of the com.github.fungal.api.util.Injection class. + * + * @author Jesper Pedersen + */ +public class Injection +{ + /** + * Constructor + */ + public Injection() + { + } + + /** + * Inject a value into an object property + * @param object The object + * @param propertyName The property name + * @param propertyValue The property value + * @exception NoSuchMethodException If the property method cannot be found + * @exception IllegalAccessException If the property method cannot be accessed + * @exception InvocationTargetException If the property method cannot be executed + */ + @SuppressWarnings("unchecked") + public void inject(Object object, String propertyName, Object propertyValue) + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException + { + inject(object, propertyName, propertyValue, null, false); + } + + /** + * Inject a value into an object property + * @param object The object + * @param propertyName The property name + * @param propertyValue The property value + * @param propertyType The property type as a fully quilified class name + * @exception NoSuchMethodException If the property method cannot be found + * @exception IllegalAccessException If the property method cannot be accessed + * @exception InvocationTargetException If the property method cannot be executed + */ + @SuppressWarnings("unchecked") + public void inject(Object object, String propertyName, Object propertyValue, String propertyType) + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException + { + inject(object, propertyName, propertyValue, propertyType, false); + } + + /** + * Inject a value into an object property + * @param object The object + * @param propertyName The property name + * @param propertyValue The property value + * @param propertyType The property type as a fully quilified class name + * @param includeFields Should fields be included for injection if a method can't be found + * @exception NoSuchMethodException If the property method cannot be found + * @exception IllegalAccessException If the property method cannot be accessed + * @exception InvocationTargetException If the property method cannot be executed + */ + @SuppressWarnings("unchecked") + public void inject(Object object, + String propertyName, Object propertyValue, String propertyType, + boolean includeFields) + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException + { + if (object == null) + throw new IllegalArgumentException("Object is null"); + + if (propertyName == null || propertyName.trim().equals("")) + throw new IllegalArgumentException("PropertyName is undefined"); + + String methodName = "set" + propertyName.substring(0, 1).toUpperCase(Locale.US); + if (propertyName.length() > 1) + { + methodName += propertyName.substring(1); + } + + Method method = findMethod(object.getClass(), methodName, propertyType); + + if (method != null) + { + Class parameterClass = method.getParameterTypes()[0]; + Object parameterValue = null; + try + { + parameterValue = getValue(propertyName, parameterClass, propertyValue, + SecurityActions.getClassLoader(object.getClass())); + } + catch (Throwable t) + { + throw new InvocationTargetException(t, t.getMessage()); + } + + if (!parameterClass.isPrimitive() || parameterValue != null) + method.invoke(object, new Object[] {parameterValue}); + } + else + { + if (!includeFields) + throw new NoSuchMethodException("Method " + methodName + " not found"); + + // Ok, we didn't find a method - assume field + Field field = findField(object.getClass(), propertyName, propertyType); + + if (field != null) + { + Class fieldClass = field.getType(); + Object fieldValue = null; + try + { + fieldValue = getValue(propertyName, fieldClass, propertyValue, + SecurityActions.getClassLoader(object.getClass())); + } + catch (Throwable t) + { + throw new InvocationTargetException(t, t.getMessage()); + } + + field.set(object, fieldValue); + } + else + { + throw new NoSuchMethodException("Field " + propertyName + " not found"); + } + } + } + + /** + * Compare the type of a class with the actual value + * @param classType The class type + * @param propertyType The property type + * @return True if they match, or if there is a primitive mapping + */ + private boolean argumentMatches(String classType, String propertyType) + { + return (classType.equals(propertyType)) + || (classType.equals("java.lang.Byte") && propertyType.equals("byte")) + || (classType.equals("java.lang.Short") && propertyType.equals("short")) + || (classType.equals("java.lang.Integer") && propertyType.equals("int")) + || (classType.equals("java.lang.Long") && propertyType.equals("long")) + || (classType.equals("java.lang.Float") && propertyType.equals("float")) + || (classType.equals("java.lang.Double") && propertyType.equals("double")) + || (classType.equals("java.lang.Boolean") && propertyType.equals("boolean")) + || (classType.equals("java.lang.Character") && propertyType.equals("char")); + } + + /** + * Find a method + * @param clz The class + * @param methodName The method name + * @param propertyType The property type; can be null + * @return The method; null if not found + */ + protected Method findMethod(Class clz, String methodName, String propertyType) + { + while (!clz.equals(Object.class)) + { + List hits = null; + Method[] methods = SecurityActions.getDeclaredMethods(clz); + for (int i = 0; i < methods.length; i++) + { + final Method method = methods[i]; + if (methodName.equals(method.getName()) && method.getParameterTypes().length == 1) + { + if (propertyType == null || argumentMatches(propertyType, method.getParameterTypes()[0].getName())) + { + if (hits == null) + hits = new ArrayList(1); + + SecurityActions.setAccessible(method); + + hits.add(method); + } + } + } + + if (hits != null) + { + if (hits.size() == 1) + { + return hits.get(0); + } + else + { + Collections.sort(hits, new MethodSorter()); + if (propertyType != null) + { + for (Method m : hits) + { + if (propertyType.equals(m.getParameterTypes()[0].getName())) + return m; + } + } + + return hits.get(0); + } + } + + clz = clz.getSuperclass(); + } + + return null; + } + + /** + * Find a field + * @param clz The class + * @param fieldName The field name + * @param fieldType The field type; can be null + * @return The field; null if not found + */ + protected Field findField(Class clz, String fieldName, String fieldType) + { + while (!clz.equals(Object.class)) + { + List hits = null; + Field[] fields = SecurityActions.getDeclaredFields(clz); + for (int i = 0; i < fields.length; i++) + { + final Field field = fields[i]; + if (fieldName.equals(field.getName())) + { + if (fieldType == null || argumentMatches(fieldType, field.getType().getName())) + { + if (hits == null) + hits = new ArrayList(1); + + SecurityActions.setAccessible(field); + + hits.add(field); + } + } + } + + if (hits != null) + { + if (hits.size() == 1) + { + return hits.get(0); + } + else + { + Collections.sort(hits, new FieldSorter()); + if (fieldType != null) + { + for (Field f : hits) + { + if (fieldType.equals(f.getType().getName())) + return f; + } + } + + return hits.get(0); + } + } + + clz = clz.getSuperclass(); + } + + return null; + } + + /** + * Get the value + * @param name The value name + * @param clz The value class + * @param v The value + * @param cl The class loader + * @return The substituted value + * @exception Exception Thrown in case of an error + */ + protected Object getValue(String name, Class clz, Object v, ClassLoader cl) throws Exception + { + if (v instanceof String) + { + String substituredValue = getSubstitutionValue((String)v); + + if (clz.equals(String.class)) + { + v = substituredValue; + } + else if (clz.equals(byte.class) || clz.equals(Byte.class)) + { + if (substituredValue != null && !substituredValue.trim().equals("")) + v = Byte.valueOf(substituredValue); + } + else if (clz.equals(short.class) || clz.equals(Short.class)) + { + if (substituredValue != null && !substituredValue.trim().equals("")) + v = Short.valueOf(substituredValue); + } + else if (clz.equals(int.class) || clz.equals(Integer.class)) + { + if (substituredValue != null && !substituredValue.trim().equals("")) + v = Integer.valueOf(substituredValue); + } + else if (clz.equals(long.class) || clz.equals(Long.class)) + { + if (substituredValue != null && !substituredValue.trim().equals("")) + v = Long.valueOf(substituredValue); + } + else if (clz.equals(float.class) || clz.equals(Float.class)) + { + if (substituredValue != null && !substituredValue.trim().equals("")) + v = Float.valueOf(substituredValue); + } + else if (clz.equals(double.class) || clz.equals(Double.class)) + { + if (substituredValue != null && !substituredValue.trim().equals("")) + v = Double.valueOf(substituredValue); + } + else if (clz.equals(boolean.class) || clz.equals(Boolean.class)) + { + if (substituredValue != null && !substituredValue.trim().equals("")) + v = Boolean.valueOf(substituredValue); + } + else if (clz.equals(char.class) || clz.equals(Character.class)) + { + if (substituredValue != null && !substituredValue.trim().equals("")) + v = Character.valueOf(substituredValue.charAt(0)); + } + else if (clz.equals(InetAddress.class)) + { + v = InetAddress.getByName(substituredValue); + } + else if (clz.equals(Class.class)) + { + v = Class.forName(substituredValue, true, cl); + } + else if (clz.equals(Properties.class)) + { + Properties prop = new Properties(); + + StringTokenizer st = new StringTokenizer(substituredValue, " ,"); + while (st.hasMoreTokens()) + { + String token = st.nextToken(); + String key = ""; + String value = ""; + + int index = token.indexOf("="); + if (index != -1) + { + key = token.substring(0, index); + + if (token.length() > index + 1) + value = token.substring(index + 1); + } + else + { + key = token; + } + + if (!"".equals(key)) + prop.setProperty(key, value); + } + + v = prop; + } + else + { + try + { + Constructor constructor = SecurityActions.getConstructor(clz, String.class); + v = constructor.newInstance(substituredValue); + } + catch (Throwable t) + { + // Try static String valueOf method + try + { + Method valueOf = SecurityActions.getMethod(clz, "valueOf", String.class); + v = valueOf.invoke((Object)null, substituredValue); + } + catch (Throwable inner) + { + throw new IllegalArgumentException("Unknown property resolution for property " + name); + } + } + } + } + + return v; + } + + /** + * System property substitution + * @param input The input string + * @return The output + */ + protected String getSubstitutionValue(String input) + { + if (input == null || input.trim().equals("")) + return input; + + while (input.indexOf("${") != -1) + { + int from = input.indexOf("${"); + int to = input.indexOf("}"); + int dv = input.indexOf(":", from + 2); + + if (dv != -1) + { + if (dv > to) + dv = -1; + } + + String systemProperty = ""; + String defaultValue = ""; + if (dv == -1) + { + String s = input.substring(from + 2, to); + if ("/".equals(s)) + { + systemProperty = File.separator; + } + else if (":".equals(s)) + { + systemProperty = File.pathSeparator; + } + else + { + systemProperty = SecurityActions.getSystemProperty(s); + } + } + else + { + systemProperty = SecurityActions.getSystemProperty(input.substring(from + 2, dv)); + defaultValue = input.substring(dv + 1, to); + } + String prefix = ""; + String postfix = ""; + + if (from != 0) + { + prefix = input.substring(0, from); + } + + if (to + 1 < input.length() - 1) + { + postfix = input.substring(to + 1); + } + + if (systemProperty != null && !systemProperty.trim().equals("")) + { + input = prefix + systemProperty + postfix; + } + else if (!defaultValue.trim().equals("")) + { + input = prefix + defaultValue + postfix; + } + else + { + input = prefix + postfix; + } + } + return input; + } + + /** + * Method sorter + */ + static class MethodSorter implements Comparator, Serializable + { + private static final long serialVersionUID = 1L; + + /** + * Constructor + */ + MethodSorter() + { + } + + /** + * {@inheritDoc} + */ + public int compare(Method o1, Method o2) + { + int m1 = o1.getModifiers(); + int m2 = o2.getModifiers(); + + if (Modifier.isPublic(m1)) + return -1; + + if (Modifier.isPublic(m2)) + return 1; + + if (Modifier.isProtected(m1)) + return -1; + + if (Modifier.isProtected(m2)) + return 1; + + if (Modifier.isPrivate(m1)) + return -1; + + if (Modifier.isPrivate(m2)) + return 1; + + return 0; + } + + /** + * {@inheritDoc} + */ + public boolean equals(Object o) + { + if (this == o) + return true; + + if (o == null || !(o instanceof MethodSorter)) + return false; + + return true; + } + + /** + * {@inheritDoc} + */ + public int hashCode() + { + return 42; + } + } + + /** + * Field sorter + */ + static class FieldSorter implements Comparator, Serializable + { + private static final long serialVersionUID = 1L; + + /** + * Constructor + */ + FieldSorter() + { + } + + /** + * {@inheritDoc} + */ + public int compare(Field o1, Field o2) + { + int m1 = o1.getModifiers(); + int m2 = o2.getModifiers(); + + if (Modifier.isPublic(m1)) + return -1; + + if (Modifier.isPublic(m2)) + return 1; + + if (Modifier.isProtected(m1)) + return -1; + + if (Modifier.isProtected(m2)) + return 1; + + if (Modifier.isPrivate(m1)) + return -1; + + if (Modifier.isPrivate(m2)) + return 1; + + return 0; + } + + /** + * {@inheritDoc} + */ + public boolean equals(Object o) + { + if (this == o) + return true; + + if (o == null || !(o instanceof FieldSorter)) + return false; + + return true; + } + + /** + * {@inheritDoc} + */ + public int hashCode() + { + return 42; + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/util/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/util/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/util/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,211 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.util; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Constructor + */ + private SecurityActions() + { + } + + /** + * Get the classloader. + * @param c The class + * @return The classloader + */ + static ClassLoader getClassLoader(final Class c) + { + if (System.getSecurityManager() == null) + return c.getClassLoader(); + + return AccessController.doPrivileged(new PrivilegedAction() + { + public ClassLoader run() + { + return c.getClassLoader(); + } + }); + } + + /** + * Get a system property + * @param name The property name + * @return The property value + */ + static String getSystemProperty(final String name) + { + if (System.getSecurityManager() == null) + { + return System.getProperty(name); + } + else + { + return (String)AccessController.doPrivileged(new PrivilegedAction() + { + public Object run() + { + return System.getProperty(name); + } + }); + } + } + + /** + * Get the declared methods + * @param c The class + * @return The methods + */ + static Method[] getDeclaredMethods(final Class c) + { + if (System.getSecurityManager() == null) + return c.getDeclaredMethods(); + + return AccessController.doPrivileged(new PrivilegedAction() + { + public Method[] run() + { + return c.getDeclaredMethods(); + } + }); + } + + /** + * Get the declared fields + * @param c The class + * @return The fields + */ + static Field[] getDeclaredFields(final Class c) + { + if (System.getSecurityManager() == null) + return c.getDeclaredFields(); + + return AccessController.doPrivileged(new PrivilegedAction() + { + public Field[] run() + { + return c.getDeclaredFields(); + } + }); + } + + /** + * Set accessibleo + * @param ao The object + */ + static void setAccessible(final AccessibleObject ao) + { + if (System.getSecurityManager() == null) + ao.setAccessible(true); + + AccessController.doPrivileged(new PrivilegedAction() + { + public Object run() + { + ao.setAccessible(true); + return null; + } + }); + } + + /** + * Get the constructor + * @param c The class + * @param params The parameters + * @return The constructor + * @exception NoSuchMethodException If a matching method is not found. + */ + static Constructor getConstructor(final Class c, final Class... params) + throws NoSuchMethodException + { + if (System.getSecurityManager() == null) + return c.getConstructor(params); + + Constructor result = AccessController.doPrivileged(new PrivilegedAction>() + { + public Constructor run() + { + try + { + return c.getConstructor(params); + } + catch (NoSuchMethodException e) + { + return null; + } + } + }); + + if (result != null) + return result; + + throw new NoSuchMethodException(); + } + + /** + * Get the method + * @param c The class + * @param name The name + * @param params The parameters + * @return The method + * @exception NoSuchMethodException If a matching method is not found. + */ + static Method getMethod(final Class c, final String name, final Class... params) + throws NoSuchMethodException + { + if (System.getSecurityManager() == null) + return c.getMethod(name, params); + + Method result = AccessController.doPrivileged(new PrivilegedAction() + { + public Method run() + { + try + { + return c.getMethod(name, params); + } + catch (NoSuchMethodException e) + { + return null; + } + } + }); + + if (result != null) + return result; + + throw new NoSuchMethodException(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/util/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/util/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/util/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +Utility classes + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/ClassBundle.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/ClassBundle.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/ClassBundle.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,156 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * A class bundle + * @author Jesper Pedersen + */ +public class ClassBundle implements Serializable +{ + /** SerialVersionUID */ + private static final long serialVersionUID = 1L; + + /** The definitions */ + private List definitions; + + + /** + * create an instance from a Map + * @param mapList list of map reperesenting ClassDefinition + * @return the instance + */ + public static ClassBundle fromListOfMaps(List> mapList) + { + ArrayList listOfDefinitions = new ArrayList(mapList.size()); + for (Map classDefinitionMap : mapList) + { + listOfDefinitions.add(ClassDefinition.fromMap(classDefinitionMap)); + } + return new ClassBundle(listOfDefinitions); + + } + + /** + * return a list maps representing classDefinitions of this instance + * @return the list of maps + */ + public List> toListOfMaps() + { + ArrayList> returnList = new ArrayList>(this.getDefinitions().size()); + for (ClassDefinition classDefinition : this.getDefinitions()) + { + returnList.add(classDefinition.toMap()); + } + return returnList; + } + + /** + * Constructor + */ + public ClassBundle() + { + this(new ArrayList(1)); + } + + /** + * Constructor + * @param definitions The definitions + */ + public ClassBundle(List definitions) + { + this.definitions = definitions; + } + + /** + * Get the definitions + * @return The value + */ + public List getDefinitions() + { + return definitions; + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() + { + int result = 17; + + result += definitions != null ? 7 * definitions.hashCode() : 0; + + return result; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object other) + { + if (other == null) + return false; + + if (other == this) + return true; + + if (!(other instanceof ClassBundle)) + return false; + + ClassBundle cb = (ClassBundle)other; + if (definitions == null) + { + if (cb.definitions != null) + return false; + } + else + { + if (!definitions.equals(cb.definitions)) + return false; + } + + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("ClassBundle@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[definitions=").append(definitions); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/ClassBundleFactory.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/ClassBundleFactory.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/ClassBundleFactory.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,206 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import org.jboss.jca.core.CoreLogger; + +import java.io.Serializable; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +import org.jboss.logging.Logger; + +/** + * A class bundle factory + * @author Jesper Pedersen + */ +public class ClassBundleFactory +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + ClassBundleFactory.class.getName()); + + /** + * Constructor + */ + private ClassBundleFactory() + { + } + + /** + * Create a class bundle + * @param s The serializable + * @return The bundle + */ + public static ClassBundle createClassBundle(Serializable s) + { + if (s == null) + return null; + + log.tracef("Creating class bundle for: %s", s); + + ClassBundle cb = new ClassBundle(); + + Class[] classes = s.getClass().getInterfaces(); + if (classes != null && classes.length > 0) + { + for (Class clz : classes) + { + String name = clz.getName(); + + if (!name.startsWith("java") && !name.startsWith("javax")) + { + log.tracef("Creating class definition for: %s", name); + + ClassDefinition cd = ClassDefinitionFactory.createClassDefinition(s, clz); + if (!cb.getDefinitions().contains(cd)) + cb.getDefinitions().add(cd); + } + } + } + else + { + if (log.isTraceEnabled()) + log.tracef("No interfaces for: %s", s.getClass().getName()); + } + + classes = SecurityActions.getDeclaredClasses(s.getClass()); + if (classes != null && classes.length > 0) + { + for (Class clz : classes) + { + String name = clz.getName(); + + if (!name.startsWith("java") && !name.startsWith("javax")) + { + log.tracef("Creating class definition for: %s", name); + + ClassDefinition cd = ClassDefinitionFactory.createClassDefinition(s, clz); + if (!cb.getDefinitions().contains(cd)) + cb.getDefinitions().add(cd); + } + } + } + else + { + if (log.isTraceEnabled()) + log.tracef("No classes for: %s", s.getClass().getName()); + } + + classes = getFields(s.getClass()); + if (classes != null && classes.length > 0) + { + for (Class clz : classes) + { + String name = clz.getName(); + + if (!name.startsWith("java") && !name.startsWith("javax")) + { + log.tracef("Creating class definition for: %s", name); + + ClassDefinition cd = ClassDefinitionFactory.createClassDefinition(s, clz); + if (!cb.getDefinitions().contains(cd)) + cb.getDefinitions().add(cd); + } + } + } + else + { + if (log.isTraceEnabled()) + log.tracef("No fields for: %s", s.getClass().getName()); + } + + Class clz = s.getClass().getSuperclass(); + while (clz != null) + { + String name = clz.getName(); + if (!name.startsWith("java") && !name.startsWith("javax")) + { + log.tracef("Creating class definition for: %s", name); + + ClassDefinition cd = ClassDefinitionFactory.createClassDefinition(s, clz); + if (!cb.getDefinitions().contains(cd)) + cb.getDefinitions().add(cd); + + clz = clz.getSuperclass(); + } + else + { + clz = null; + } + } + + cb.getDefinitions().add(ClassDefinitionFactory.createClassDefinition(s)); + + log.tracef("Class bundle: %s", cb); + + return cb; + } + + /** + * Get the classes for all the fields + * @param clz The class + * @return The classes; empty array if none + */ + private static Class[] getFields(Class clz) + { + List> result = new ArrayList>(); + + Class c = clz; + while (!c.equals(Object.class)) + { + try + { + Field[] fields = SecurityActions.getDeclaredFields(c); + if (fields.length > 0) + { + for (Field f : fields) + { + Class defClz = f.getType(); + String defClzName = defClz.getName(); + + if (!defClz.isPrimitive() && !defClz.isArray() && + !defClzName.startsWith("java") && !defClzName.startsWith("javax")) + { + if (!result.contains(defClz)) + { + log.tracef("Adding field: %s", defClzName); + + result.add(defClz); + } + } + } + } + } + catch (Throwable t) + { + // Ignore + } + + c = c.getSuperclass(); + } + + return result.toArray(new Class[result.size()]); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/ClassDefinition.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/ClassDefinition.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/ClassDefinition.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,179 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * A definition of a class + * @author Jesper Pedersen + */ +public class ClassDefinition implements Serializable +{ + /** SerialVersionUID */ + private static final long serialVersionUID = 1L; + + /** The name */ + private String name; + + /** The serialVersionUID */ + private long svu; + + /** The data */ + private byte[] data; + + + private static final String NAME = "NAME"; + private static final String SVU = "SVU"; + private static final String DATA = "DATA"; + + + /** + * create an instance from a Map + * @param map the map + * @return the instance + */ + public static ClassDefinition fromMap(Map map) + { + return new ClassDefinition((String) map.get(NAME), (Long) map.get(SVU), (byte[]) map.get(DATA)); + + } + + /** + * return a map representing the instance + * @return the map + */ + public Map toMap() + { + Map returnMap = new LinkedHashMap(3); + returnMap.put(NAME, this.getName()); + returnMap.put(SVU, this.getSerialVersionUID()); + returnMap.put(DATA, this.getData()); + return returnMap; + } + + /** + * Constructor + * @param name The name of the class + * @param serialVersionUID The serial version unique identifier + * @param data The class + */ + public ClassDefinition(String name, long serialVersionUID, byte[] data) + { + this.name = name; + this.svu = serialVersionUID; + this.data = new byte[data.length]; + + System.arraycopy(data, 0, this.data, 0, data.length); + } + + /** + * Get the name + * @return The value + */ + public String getName() + { + return name; + } + + /** + * Get the serial version identifier + * @return The value + */ + public long getSerialVersionUID() + { + return svu; + } + + /** + * Get the data + * @return The value + */ + public byte[] getData() + { + byte[] copy = new byte[data.length]; + System.arraycopy(data, 0, copy, 0, data.length); + return copy; + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() + { + int result = 17; + + result += 7 * name.hashCode(); + result += 7 * svu; + result += 7 * Arrays.hashCode(data); + + return result; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object other) + { + if (other == null) + return false; + + if (other == this) + return true; + + if (!(other instanceof ClassDefinition)) + return false; + + ClassDefinition cd = (ClassDefinition)other; + + if (!name.equals(cd.name)) + return false; + + if (svu != cd.svu) + return false; + + return Arrays.equals(data, cd.data); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("ClassDefinition@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[name=").append(name); + sb.append(" serialVersionUID=").append(svu); + sb.append(" data=").append(Arrays.toString(data)); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/ClassDefinitionFactory.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/ClassDefinitionFactory.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/ClassDefinitionFactory.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,144 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.lang.reflect.Field; + +/** + * A class definition factory + * @author Jesper Pedersen + */ +public class ClassDefinitionFactory +{ + /** + * Constructor + */ + private ClassDefinitionFactory() + { + } + + /** + * Create a class definition + * @param s The serializable + * @return The definition + */ + public static ClassDefinition createClassDefinition(Serializable s) + { + return createClassDefinition(s, s.getClass()); + } + + /** + * Create a class definition + * @param s The serializable + * @param clz The class + * @return The definition + */ + public static ClassDefinition createClassDefinition(Serializable s, Class clz) + { + if (s == null || clz == null) + return null; + + String name = clz.getName(); + long serialVersionUID = 0L; + byte[] data = null; + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + InputStream is = null; + try + { + try + { + Field svuf = getSerialVersionUID(clz); + if (svuf != null) + serialVersionUID = (long)svuf.get(s); + } + catch (Throwable t) + { + // No serialVersionUID value + } + + String clzName = name.replace('.', '/') + ".class"; + + is = SecurityActions.getClassLoader(s.getClass()).getResourceAsStream(clzName); + int i = is.read(); + while (i != -1) + { + baos.write(i); + i = is.read(); + } + + data = baos.toByteArray(); + + return new ClassDefinition(name, serialVersionUID, data); + } + catch (Throwable t) + { + // Ignore + } + finally + { + if (is != null) + { + try + { + is.close(); + } + catch (IOException ioe) + { + // Ignore + } + } + } + return null; + } + + /** + * Find the serialVersionUID field + * @param clz The class + * @return The field or null if none were found + */ + private static Field getSerialVersionUID(Class clz) + { + Class c = clz; + while (c != null) + { + try + { + Field svuf = SecurityActions.getDeclaredField(clz, "serialVersionUID"); + SecurityActions.setAccessible(svuf); + return svuf; + } + catch (Throwable t) + { + // No serialVersionUID definition + } + c = c.getSuperclass(); + } + + return null; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/DistributedWorkManagerImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/DistributedWorkManagerImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/DistributedWorkManagerImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,801 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.workmanager.DistributedWorkManager; +import org.jboss.jca.core.api.workmanager.DistributedWorkManagerStatistics; +import org.jboss.jca.core.spi.workmanager.Address; +import org.jboss.jca.core.spi.workmanager.notification.NotificationListener; +import org.jboss.jca.core.spi.workmanager.policy.Policy; +import org.jboss.jca.core.spi.workmanager.selector.Selector; +import org.jboss.jca.core.spi.workmanager.transport.Transport; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +import javax.resource.spi.work.DistributableWork; +import javax.resource.spi.work.Work; +import javax.resource.spi.work.WorkException; +import javax.resource.spi.work.WorkManager; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * The distributed work manager implementation. + * + * @author Jesper Pedersen + */ +public class DistributedWorkManagerImpl extends WorkManagerImpl implements DistributedWorkManager +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + DistributedWorkManagerImpl.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** Policy */ + private Policy policy; + + /** Selector */ + private Selector selector; + + /** Transport */ + private Transport transport; + + /** Notification listeners */ + private Collection listeners; + + /** Distributed statistics enabled */ + private boolean distributedStatisticsEnabled; + + /** Distributed statistics */ + private DistributedWorkManagerStatisticsImpl distributedStatistics; + + /** Should doWork be enabled for distribution */ + private boolean doWorkDistributionEnabled; + + /** Should startWork be enabled for distribution */ + private boolean startWorkDistributionEnabled; + + /** Should scheduleWork be enabled for distribution */ + private boolean scheduleWorkDistributionEnabled; + + /** Local address */ + private Address localAddress; + + /** + * Constructor + */ + public DistributedWorkManagerImpl() + { + super(); + this.policy = null; + this.selector = null; + this.transport = null; + this.listeners = Collections.synchronizedList(new ArrayList(3)); + this.distributedStatisticsEnabled = true; + this.distributedStatistics = null; + this.doWorkDistributionEnabled = true; + this.startWorkDistributionEnabled = true; + this.scheduleWorkDistributionEnabled = true; + this.localAddress = null; + } + + /** + * {@inheritDoc} + */ + public Policy getPolicy() + { + return policy; + } + + /** + * {@inheritDoc} + */ + public synchronized void setPolicy(Policy v) + { + if (policy != null) + { + if (policy instanceof NotificationListener) + listeners.remove((NotificationListener)policy); + } + + policy = v; + + if (policy != null) + { + if (policy instanceof NotificationListener) + listeners.add((NotificationListener)policy); + } + } + + /** + * {@inheritDoc} + */ + public Selector getSelector() + { + return selector; + } + + /** + * {@inheritDoc} + */ + public synchronized void setSelector(Selector v) + { + if (selector != null) + { + if (selector instanceof NotificationListener) + listeners.remove((NotificationListener)selector); + } + + selector = v; + + if (selector != null) + { + if (selector instanceof NotificationListener) + listeners.add((NotificationListener)selector); + } + } + + /** + * {@inheritDoc} + */ + public Transport getTransport() + { + return transport; + } + + /** + * {@inheritDoc} + */ + public synchronized void setTransport(Transport v) + { + if (transport != null) + { + if (transport instanceof NotificationListener) + listeners.remove((NotificationListener)transport); + + removeDistributedStatistics(); + } + + transport = v; + + if (transport != null) + { + if (transport instanceof NotificationListener) + listeners.add((NotificationListener)transport); + + initDistributedStatistics(); + } + } + + /** + * {@inheritDoc} + */ + public boolean isDistributedStatisticsEnabled() + { + return distributedStatisticsEnabled; + } + + /** + * {@inheritDoc} + */ + public void setDistributedStatisticsEnabled(boolean v) + { + distributedStatisticsEnabled = v; + } + + /** + * {@inheritDoc} + */ + public Collection getNotificationListeners() + { + return listeners; + } + + /** + * Set the listeners + * @param v The value + */ + void setNotificationListeners(Collection v) + { + listeners = v; + } + + /** + * {@inheritDoc} + */ + public void setDoWorkDistributionEnabled(boolean v) + { + doWorkDistributionEnabled = v; + } + + /** + * {@inheritDoc} + */ + public boolean isDoWorkDistributionEnabled() + { + return doWorkDistributionEnabled; + } + + /** + * {@inheritDoc} + */ + public void setStartWorkDistributionEnabled(boolean v) + { + startWorkDistributionEnabled = v; + } + + /** + * {@inheritDoc} + */ + public boolean isStartWorkDistributionEnabled() + { + return startWorkDistributionEnabled; + } + + /** + * {@inheritDoc} + */ + public void setScheduleWorkDistributionEnabled(boolean v) + { + scheduleWorkDistributionEnabled = v; + } + + /** + * {@inheritDoc} + */ + public boolean isScheduleWorkDistributionEnabled() + { + return scheduleWorkDistributionEnabled; + } + + /** + * {@inheritDoc} + */ + public void localDoWork(Work work) throws WorkException + { + if (transport != null) + { + checkTransport(); + + if (getLongRunningThreadPool() != null && WorkManagerUtil.isLongRunning(work)) + { + transport.updateLongRunningFree(getLocalAddress(), + getLongRunningThreadPool().getNumberOfFreeThreads() - 1); + } + else + { + transport.updateShortRunningFree(getLocalAddress(), + getShortRunningThreadPool().getNumberOfFreeThreads() - 1); + } + + WorkEventListener wel = new WorkEventListener(WorkManagerUtil.isLongRunning(work), + getShortRunningThreadPool(), + getLongRunningThreadPool(), + getLocalAddress(), + transport); + + super.doWork(work, WorkManager.INDEFINITE, null, wel); + } + else + { + super.doWork(work); + } + } + + /** + * {@inheritDoc} + */ + public void localScheduleWork(Work work) throws WorkException + { + if (transport != null) + { + checkTransport(); + + if (getLongRunningThreadPool() != null && WorkManagerUtil.isLongRunning(work)) + { + transport.updateLongRunningFree(getLocalAddress(), + getLongRunningThreadPool().getNumberOfFreeThreads() - 1); + } + else + { + transport.updateShortRunningFree(getLocalAddress(), + getShortRunningThreadPool().getNumberOfFreeThreads() - 1); + } + + WorkEventListener wel = new WorkEventListener(WorkManagerUtil.isLongRunning(work), + getShortRunningThreadPool(), + getLongRunningThreadPool(), + getLocalAddress(), + transport); + + super.scheduleWork(work, WorkManager.INDEFINITE, null, wel); + } + else + { + super.scheduleWork(work); + } + } + + /** + * {@inheritDoc} + */ + public long localStartWork(Work work) throws WorkException + { + if (transport != null) + { + checkTransport(); + + if (getLongRunningThreadPool() != null && WorkManagerUtil.isLongRunning(work)) + { + transport.updateLongRunningFree(getLocalAddress(), + getLongRunningThreadPool().getNumberOfFreeThreads() - 1); + } + else + { + transport.updateShortRunningFree(getLocalAddress(), + getShortRunningThreadPool().getNumberOfFreeThreads() - 1); + } + + WorkEventListener wel = new WorkEventListener(WorkManagerUtil.isLongRunning(work), + getShortRunningThreadPool(), + getLongRunningThreadPool(), + getLocalAddress(), + transport); + + return super.startWork(work, WorkManager.INDEFINITE, null, wel); + } + else + { + return super.startWork(work); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void doWork(Work work) throws WorkException + { + if (policy == null || selector == null || transport == null || + work == null || !(work instanceof DistributableWork) || !doWorkDistributionEnabled) + { + localDoWork(work); + } + else + { + doFirstChecks(work, WorkManager.INDEFINITE, null); + checkTransport(); + + DistributableWork dw = (DistributableWork)work; + boolean executed = false; + + if (policy.shouldDistribute(this, dw)) + { + Address dwmAddress = selector.selectDistributedWorkManager(getLocalAddress(), dw); + if (dwmAddress != null && !getLocalAddress().equals(dwmAddress)) + { + transport.doWork(dwmAddress, dw); + executed = true; + } + } + + if (!executed) + { + localDoWork(work); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public long startWork(Work work) throws WorkException + { + if (policy == null || selector == null || transport == null || + work == null || !(work instanceof DistributableWork) || !startWorkDistributionEnabled) + { + return localStartWork(work); + } + else + { + doFirstChecks(work, WorkManager.INDEFINITE, null); + checkTransport(); + + DistributableWork dw = (DistributableWork)work; + + if (policy.shouldDistribute(this, dw)) + { + Address dwmAddress = selector.selectDistributedWorkManager(getLocalAddress(), dw); + if (dwmAddress != null && !getLocalAddress().equals(dwmAddress)) + { + return transport.startWork(dwmAddress, dw); + } + } + + return localStartWork(work); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void scheduleWork(Work work) throws WorkException + { + if (policy == null || selector == null || transport == null || + work == null || !(work instanceof DistributableWork) || !scheduleWorkDistributionEnabled) + { + localScheduleWork(work); + } + else + { + doFirstChecks(work, WorkManager.INDEFINITE, null); + checkTransport(); + + DistributableWork dw = (DistributableWork)work; + boolean executed = false; + + if (policy.shouldDistribute(this, dw)) + { + Address dwmAddress = selector.selectDistributedWorkManager(getLocalAddress(), dw); + if (dwmAddress != null && !getLocalAddress().equals(dwmAddress)) + { + transport.scheduleWork(dwmAddress, dw); + executed = true; + } + } + + if (!executed) + { + localScheduleWork(work); + } + } + } + + /** + * Check the transport + * @exception WorkException In case of an error + */ + private void checkTransport() throws WorkException + { + if (!transport.isInitialized()) + { + try + { + transport.initialize(); + initialize(); + } + catch (Throwable t) + { + WorkException we = new WorkException("Exception during transport initialization"); + we.initCause(t); + throw we; + } + } + } + + /** + * {@inheritDoc} + */ + public DistributedWorkManagerStatistics getDistributedStatistics() + { + return distributedStatistics; + } + + /** + * Set the distributed statistics + * @param v The value + */ + void setDistributedStatistics(DistributedWorkManagerStatisticsImpl v) + { + distributedStatistics = v; + } + + /** + * Init distributed statistics + */ + private synchronized void initDistributedStatistics() + { + if (distributedStatistics == null) + { + distributedStatistics = new DistributedWorkManagerStatisticsImpl(); + listeners.add((NotificationListener)distributedStatistics); + } + } + + /** + * Remove distributed statistics + */ + private synchronized void removeDistributedStatistics() + { + if (distributedStatistics != null) + { + listeners.remove((NotificationListener)distributedStatistics); + distributedStatistics.setTransport(null); + distributedStatistics = null; + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void deltaDoWorkAccepted() + { + log.trace("deltaDoWorkAccepted"); + + super.deltaDoWorkAccepted(); + + if (distributedStatisticsEnabled && distributedStatistics != null && transport != null) + { + try + { + checkTransport(); + distributedStatistics.sendDeltaDoWorkAccepted(); + } + catch (WorkException we) + { + log.debugf("deltaDoWorkAccepted: %s", we.getMessage(), we); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void deltaDoWorkRejected() + { + log.trace("deltaDoWorkRejected"); + + super.deltaDoWorkRejected(); + + if (distributedStatisticsEnabled && distributedStatistics != null && transport != null) + { + try + { + checkTransport(); + distributedStatistics.sendDeltaDoWorkRejected(); + } + catch (WorkException we) + { + log.debugf("deltaDoWorkRejected: %s", we.getMessage(), we); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void deltaStartWorkAccepted() + { + log.trace("deltaStartWorkAccepted"); + + super.deltaStartWorkAccepted(); + + if (distributedStatisticsEnabled && distributedStatistics != null && transport != null) + { + try + { + checkTransport(); + distributedStatistics.sendDeltaStartWorkAccepted(); + } + catch (WorkException we) + { + log.debugf("deltaStartWorkAccepted: %s", we.getMessage(), we); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void deltaStartWorkRejected() + { + log.trace("deltaStartWorkRejected"); + + super.deltaStartWorkRejected(); + + if (distributedStatisticsEnabled && distributedStatistics != null && transport != null) + { + try + { + checkTransport(); + distributedStatistics.sendDeltaStartWorkRejected(); + } + catch (WorkException we) + { + log.debugf("deltaStartWorkRejected: %s", we.getMessage(), we); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void deltaScheduleWorkAccepted() + { + log.trace("deltaScheduleWorkAccepted"); + + super.deltaScheduleWorkAccepted(); + + if (distributedStatisticsEnabled && distributedStatistics != null && transport != null) + { + try + { + checkTransport(); + distributedStatistics.sendDeltaScheduleWorkAccepted(); + } + catch (WorkException we) + { + log.debugf("deltaScheduleWorkAccepted: %s", we.getMessage(), we); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void deltaScheduleWorkRejected() + { + log.trace("deltaScheduleWorkRejected"); + + super.deltaScheduleWorkRejected(); + + if (distributedStatisticsEnabled && distributedStatistics != null && transport != null) + { + try + { + checkTransport(); + distributedStatistics.sendDeltaScheduleWorkRejected(); + } + catch (WorkException we) + { + log.debugf("deltaScheduleWorkRejected: %s", we.getMessage(), we); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void deltaWorkSuccessful() + { + log.trace("deltaWorkSuccessful"); + + super.deltaWorkSuccessful(); + + if (distributedStatisticsEnabled && distributedStatistics != null && transport != null) + { + try + { + checkTransport(); + distributedStatistics.sendDeltaWorkSuccessful(); + } + catch (WorkException we) + { + log.debugf("deltaWorkSuccessful: %s", we.getMessage(), we); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void deltaWorkFailed() + { + log.trace("deltaWorkFailed"); + + super.deltaWorkFailed(); + + if (distributedStatisticsEnabled && distributedStatistics != null && transport != null) + { + try + { + checkTransport(); + distributedStatistics.sendDeltaWorkFailed(); + } + catch (WorkException we) + { + log.debugf("deltaWorkFailed: %s", we.getMessage(), we); + } + } + } + + /** + * Get local address + * @return The value + */ + Address getLocalAddress() + { + if (localAddress == null) + localAddress = new Address(getId(), getName(), transport != null ? transport.getId() : null); + + return localAddress; + } + + /** + * Initialize + */ + public void initialize() + { + if (distributedStatistics != null) + { + distributedStatistics.setOwnId(getLocalAddress()); + distributedStatistics.setTransport(transport); + } + } + + /** + * Clone the WorkManager implementation + * @return A copy of the implementation + * @exception CloneNotSupportedException Thrown if the copy operation isn't supported + * + */ + @Override + public org.jboss.jca.core.api.workmanager.WorkManager clone() throws CloneNotSupportedException + { + DistributedWorkManagerImpl wm = (DistributedWorkManagerImpl)super.clone(); + wm.listeners = Collections.synchronizedList(new ArrayList(3)); + wm.setPolicy(getPolicy()); + wm.setSelector(getSelector()); + wm.setTransport(getTransport()); + wm.setDistributedStatisticsEnabled(isDistributedStatisticsEnabled()); + wm.setDoWorkDistributionEnabled(isDoWorkDistributionEnabled()); + wm.setStartWorkDistributionEnabled(isStartWorkDistributionEnabled()); + wm.setScheduleWorkDistributionEnabled(isScheduleWorkDistributionEnabled()); + + return wm; + } + + /** + * {@inheritDoc} + */ + @Override + public void toString(StringBuilder sb) + { + sb.append(" policy=").append(policy); + sb.append(" selector=").append(selector); + sb.append(" transport=").append(transport); + sb.append(" distributedStatisticsEnabled=").append(distributedStatisticsEnabled); + sb.append(" distributedStatistics=").append(distributedStatistics); + sb.append(" listeners(").append(listeners.hashCode()).append("=").append(listeners); + sb.append(" doWorkDistributionEnabled=").append(doWorkDistributionEnabled); + sb.append(" startWorkDistributionEnabled=").append(startWorkDistributionEnabled); + sb.append(" scheduleWorkDistributionEnabled=").append(scheduleWorkDistributionEnabled); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/DistributedWorkManagerStatisticsImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/DistributedWorkManagerStatisticsImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/DistributedWorkManagerStatisticsImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,523 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.workmanager.DistributedWorkManagerStatistics; +import org.jboss.jca.core.api.workmanager.DistributedWorkManagerStatisticsValues; +import org.jboss.jca.core.spi.workmanager.Address; +import org.jboss.jca.core.spi.workmanager.notification.NotificationListener; +import org.jboss.jca.core.spi.workmanager.transport.Transport; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; + +import org.jboss.logging.Logger; + +/** + * The JBoss distributed work manager statistics implementation + */ +public class DistributedWorkManagerStatisticsImpl implements DistributedWorkManagerStatistics, + NotificationListener +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + DistributedWorkManagerStatistics.class.getName()); + + /** Own identifier */ + private Address own; + + /** Transport */ + private Transport transport; + + /** Work managers */ + private Set
workManagers; + + /** Successful */ + private AtomicInteger successful; + + /** Failed */ + private AtomicInteger failed; + + /** DoWork: Accepted */ + private AtomicInteger doWorkAccepted; + + /** DoWork: Rejected */ + private AtomicInteger doWorkRejected; + + /** ScheduleWork: Accepted */ + private AtomicInteger scheduleWorkAccepted; + + /** ScheduleWork: Rejected */ + private AtomicInteger scheduleWorkRejected; + + /** StartWork: Accepted */ + private AtomicInteger startWorkAccepted; + + /** StartWork: Rejected */ + private AtomicInteger startWorkRejected; + + /** Initialized */ + private boolean initialized; + + /** + * Constructor + */ + public DistributedWorkManagerStatisticsImpl() + { + this(null, null); + } + + /** + * Constructor + * @param ownId The local distributed work managers identifier + * @param t The transport + */ + public DistributedWorkManagerStatisticsImpl(Address ownId, Transport t) + { + this.own = ownId; + this.transport = t; + this.workManagers = Collections.synchronizedSet(new HashSet
()); + this.successful = new AtomicInteger(0); + this.failed = new AtomicInteger(0); + this.doWorkAccepted = new AtomicInteger(0); + this.doWorkRejected = new AtomicInteger(0); + this.scheduleWorkAccepted = new AtomicInteger(0); + this.scheduleWorkRejected = new AtomicInteger(0); + this.startWorkAccepted = new AtomicInteger(0); + this.startWorkRejected = new AtomicInteger(0); + this.initialized = false; + } + + /** + * Set own id + * @param v The value + */ + public void setOwnId(Address v) + { + own = v; + } + + /** + * Set transport + * @param v The value + */ + public void setTransport(Transport v) + { + transport = v; + } + + /** + * {@inheritDoc} + */ + public void initialize(DistributedWorkManagerStatisticsValues values) + { + successful.set(values.getWorkSuccessful()); + failed.set(values.getWorkFailed()); + doWorkAccepted.set(values.getDoWorkAccepted()); + doWorkRejected.set(values.getDoWorkRejected()); + scheduleWorkAccepted.set(values.getScheduleWorkAccepted()); + scheduleWorkRejected.set(values.getScheduleWorkRejected()); + startWorkAccepted.set(values.getStartWorkAccepted()); + startWorkRejected.set(values.getStartWorkRejected()); + initialized = true; + } + + /** + * {@inheritDoc} + */ + public void join(Address address) + { + log.tracef("join(%s)", address); + + workManagers.add(address); + + if (!initialized && own != null && transport != null) + { + if (!own.equals(address) && transport.isInitialized()) + { + DistributedWorkManagerStatisticsValues values = transport.getDistributedStatistics(address); + if (values != null) + initialize(values); + } + } + } + + /** + * {@inheritDoc} + */ + public void leave(Address address) + { + log.tracef("leave(%s)", address); + + workManagers.remove(address); + } + + /** + * {@inheritDoc} + */ + public void updateShortRunningFree(Address address, long free) + { + } + + /** + * {@inheritDoc} + */ + public void updateLongRunningFree(Address address, long free) + { + } + + /** + * {@inheritDoc} + */ + public int getWorkActive() + { + return -1; + } + + /** + * {@inheritDoc} + */ + public int getWorkSuccessful() + { + return successful.get(); + } + + /** + * {@inheritDoc} + */ + public void deltaWorkSuccessful() + { + successful.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getWorkFailed() + { + return failed.get(); + } + + /** + * {@inheritDoc} + */ + public void deltaWorkFailed() + { + failed.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getDoWorkAccepted() + { + return doWorkAccepted.get(); + } + + /** + * {@inheritDoc} + */ + public void deltaDoWorkAccepted() + { + doWorkAccepted.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getDoWorkRejected() + { + return doWorkRejected.get(); + } + + /** + * {@inheritDoc} + */ + public void deltaDoWorkRejected() + { + doWorkRejected.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getScheduleWorkAccepted() + { + return scheduleWorkAccepted.get(); + } + + /** + * {@inheritDoc} + */ + public void deltaScheduleWorkAccepted() + { + scheduleWorkAccepted.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getScheduleWorkRejected() + { + return scheduleWorkRejected.get(); + } + + /** + * {@inheritDoc} + */ + public void deltaScheduleWorkRejected() + { + scheduleWorkRejected.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getStartWorkAccepted() + { + return startWorkAccepted.get(); + } + + /** + * {@inheritDoc} + */ + public void deltaStartWorkAccepted() + { + startWorkAccepted.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getStartWorkRejected() + { + return startWorkRejected.get(); + } + + /** + * {@inheritDoc} + */ + public void deltaStartWorkRejected() + { + startWorkRejected.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public synchronized void clear() + { + successful.set(0); + failed.set(0); + doWorkAccepted.set(0); + doWorkRejected.set(0); + scheduleWorkAccepted.set(0); + scheduleWorkRejected.set(0); + startWorkAccepted.set(0); + startWorkRejected.set(0); + + log.tracef("clear: %s", workManagers); + + if (own != null && transport != null && transport.isInitialized()) + transport.clearDistributedStatistics(own); + } + + /** + * Send: doWork accepted + */ + void sendDeltaDoWorkAccepted() + { + doWorkAccepted.incrementAndGet(); + + log.tracef("sendDeltaDoWorkAccepted: %s", workManagers); + + if (own != null && transport != null && transport.isInitialized()) + { + for (Address address : workManagers) + { + if (!own.equals(address)) + transport.deltaDoWorkAccepted(address); + } + } + } + + /** + * Send: doWork rejected + */ + void sendDeltaDoWorkRejected() + { + doWorkRejected.incrementAndGet(); + + log.tracef("sendDeltaDoWorkRejected: %s", workManagers); + + if (own != null && transport != null && transport.isInitialized()) + { + for (Address address : workManagers) + { + if (!own.equals(address)) + transport.deltaDoWorkRejected(address); + } + } + } + + /** + * Send: scheduleWork accepted + */ + void sendDeltaScheduleWorkAccepted() + { + scheduleWorkAccepted.incrementAndGet(); + + log.tracef("sendDeltaScheduleWorkAccepted: %s", workManagers); + + if (own != null && transport != null && transport.isInitialized()) + { + for (Address address : workManagers) + { + if (!own.equals(address)) + transport.deltaScheduleWorkAccepted(address); + } + } + } + + /** + * Send: scheduleWork rejected + */ + void sendDeltaScheduleWorkRejected() + { + scheduleWorkRejected.incrementAndGet(); + + log.tracef("sendDeltaScheduleWorkRejected: %s", workManagers); + + if (own != null && transport != null && transport.isInitialized()) + { + for (Address address : workManagers) + { + if (!own.equals(address)) + transport.deltaScheduleWorkRejected(address); + } + } + } + + /** + * Send: startWork accepted + */ + void sendDeltaStartWorkAccepted() + { + startWorkAccepted.incrementAndGet(); + + log.tracef("sendDeltaStartWorkAccepted: %s", workManagers); + + if (own != null && transport != null && transport.isInitialized()) + { + for (Address address : workManagers) + { + if (!own.equals(address)) + transport.deltaStartWorkAccepted(address); + } + } + } + + /** + * Send: startWork rejected + */ + void sendDeltaStartWorkRejected() + { + startWorkRejected.incrementAndGet(); + + log.tracef("sendDeltaStartWorkRejected: %s", workManagers); + + if (own != null && transport != null && transport.isInitialized()) + { + for (Address address : workManagers) + { + if (!own.equals(address)) + transport.deltaStartWorkRejected(address); + } + } + } + + /** + * Send: work successful + */ + void sendDeltaWorkSuccessful() + { + successful.incrementAndGet(); + + log.tracef("sendDeltaWorkSuccessful: %s", workManagers); + + if (own != null && transport != null && transport.isInitialized()) + { + for (Address address : workManagers) + { + if (!own.equals(address)) + transport.deltaWorkSuccessful(address); + } + } + } + + /** + * Send: work failed + */ + void sendDeltaWorkFailed() + { + failed.incrementAndGet(); + + log.tracef("sendDeltaWorkFailed: %s", workManagers); + + if (own != null && transport != null && transport.isInitialized()) + { + for (Address address : workManagers) + { + if (!own.equals(address)) + transport.deltaWorkFailed(address); + } + } + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("DistributedWorkManagerStatisticsImpl@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[transport=").append(transport); + sb.append(" successful=").append(getWorkSuccessful()); + sb.append(" failed=").append(getWorkFailed()); + sb.append(" doWorkAccepted=").append(getDoWorkAccepted()); + sb.append(" doWorkRejected=").append(getDoWorkRejected()); + sb.append(" scheduleWorkAccepted=").append(getScheduleWorkAccepted()); + sb.append(" scheduleWorkRejected=").append(getScheduleWorkRejected()); + sb.append(" startWorkAccepted=").append(getStartWorkAccepted()); + sb.append(" startWorkRejected=").append(getStartWorkRejected()); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/ResourceAdapterClassLoader.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/ResourceAdapterClassLoader.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/ResourceAdapterClassLoader.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,116 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import org.jboss.jca.core.CoreLogger; + +import org.jboss.logging.Logger; + +/** + * Resource adapter class loader + * @author Jesper Pedersen + */ +public class ResourceAdapterClassLoader extends ClassLoader +{ + /** The logger */ + private static CoreLogger log = + Logger.getMessageLogger(CoreLogger.class, ResourceAdapterClassLoader.class.getName()); + + /** The work class loader */ + private WorkClassLoader workClassLoader; + + /** + * Constructor + * @param cl The class loader for the resource adapter + * @param wcl The work class loader + */ + public ResourceAdapterClassLoader(ClassLoader cl, WorkClassLoader wcl) + { + super(cl); + this.workClassLoader = wcl; + } + + /** + * {@inheritDoc} + */ + @Override + public Class loadClass(String name) throws ClassNotFoundException + { + if (log.isTraceEnabled()) + log.tracef("%s: loadClass(%s)", Integer.toHexString(System.identityHashCode(this)), name); + + try + { + return super.loadClass(name); + } + catch (Throwable t) + { + // Default to delegate + if (log.isTraceEnabled()) + log.tracef("%s: Failed to load=%s", Integer.toHexString(System.identityHashCode(this)), name); + } + + return workClassLoader.loadClass(name, false); + } + + /** + * Find a class + * @param name The fully qualified class name + * @return The class + * @throws ClassNotFoundException If the class could not be found + */ + @Override + public Class findClass(String name) throws ClassNotFoundException + { + if (log.isTraceEnabled()) + log.tracef("%s: findClass(%s)", Integer.toHexString(System.identityHashCode(this)), name); + + try + { + return getParent().loadClass(name); + } + catch (Throwable t) + { + // Default to delegate + if (log.isTraceEnabled()) + log.tracef("%s: Failed to find=%s", Integer.toHexString(System.identityHashCode(this)), name); + } + + return workClassLoader.lookup(name); + } + + /** + * {@inheritDoc} + */ + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("ResourceAdapterClassLoader@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[parent=").append(getParent()); + sb.append(" workClassLoader=").append(Integer.toHexString(System.identityHashCode(workClassLoader))); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,221 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Constructor + */ + private SecurityActions() + { + } + + /** + * Get the classloader. + * @param c The class + * @return The classloader + */ + static ClassLoader getClassLoader(final Class c) + { + if (System.getSecurityManager() == null) + return c.getClassLoader(); + + return AccessController.doPrivileged(new PrivilegedAction() + { + public ClassLoader run() + { + return c.getClassLoader(); + } + }); + } + + /** + * Get the thread context class loader + * @return The class loader + */ + static ClassLoader getThreadContextClassLoader() + { + return AccessController.doPrivileged(new PrivilegedAction() + { + @Override + public ClassLoader run() + { + return Thread.currentThread().getContextClassLoader(); + } + }); + } + + /** + * Set the thread context class loader + * @param cl The class loader + */ + static void setThreadContextClassLoader(final ClassLoader cl) + { + AccessController.doPrivileged(new PrivilegedAction() + { + @Override + public Object run() + { + Thread.currentThread().setContextClassLoader(cl); + return null; + } + }); + } + + /** + * Get the declared classes + * @param c The class + * @return The classes + */ + static Class[] getDeclaredClasses(final Class c) + { + if (System.getSecurityManager() == null) + return c.getDeclaredClasses(); + + return AccessController.doPrivileged(new PrivilegedAction[]>() + { + public Class[] run() + { + return c.getDeclaredClasses(); + } + }); + } + + /** + * Get the declared fields + * @param c The class + * @return The fields + */ + static Field[] getDeclaredFields(final Class c) + { + if (System.getSecurityManager() == null) + return c.getDeclaredFields(); + + return AccessController.doPrivileged(new PrivilegedAction() + { + public Field[] run() + { + return c.getDeclaredFields(); + } + }); + } + + /** + * Get the declared field + * @param c The class + * @param name The name + * @return The field + * @exception NoSuchFieldException If a matching field is not found. + */ + static Field getDeclaredField(final Class c, final String name) + throws NoSuchFieldException + { + if (System.getSecurityManager() == null) + return c.getDeclaredField(name); + + Field result = AccessController.doPrivileged(new PrivilegedAction() + { + public Field run() + { + try + { + return c.getDeclaredField(name); + } + catch (NoSuchFieldException e) + { + return null; + } + } + }); + + if (result != null) + return result; + + throw new NoSuchFieldException(); + } + + /** + * Set accessible + * @param ao The object + */ + static void setAccessible(final AccessibleObject ao) + { + if (System.getSecurityManager() == null) + ao.setAccessible(true); + + AccessController.doPrivileged(new PrivilegedAction() + { + public Object run() + { + ao.setAccessible(true); + return null; + } + }); + } + + /** + * Get the method + * @param c The class + * @param name The name + * @param params The parameters + * @return The method + * @exception NoSuchMethodException If a matching method is not found. + */ + static Method getMethod(final Class c, final String name, final Class... params) + throws NoSuchMethodException + { + if (System.getSecurityManager() == null) + return c.getMethod(name, params); + + Method result = AccessController.doPrivileged(new PrivilegedAction() + { + public Method run() + { + try + { + return c.getMethod(name, params); + } + catch (NoSuchMethodException e) + { + return null; + } + } + }); + + if (result != null) + return result; + + throw new NoSuchMethodException(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/StatisticsExecutorImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/StatisticsExecutorImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/StatisticsExecutorImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,104 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.workmanager.StatisticsExecutor; + +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.TimeUnit; + +import org.jboss.logging.Logger; +import org.jboss.threads.BlockingExecutor; +import org.jboss.threads.JBossThreadPoolExecutor; +import org.jboss.threads.management.ThreadPoolExecutorMBean; + +/** + * A StatisticsExecutor implementation keeping track of numberOfFreeThreads + * + * @author Stefano Maestri + */ + +public class StatisticsExecutorImpl implements StatisticsExecutor +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + StatisticsExecutorImpl.class.getName()); + + private final BlockingExecutor realExecutor; + + /** + * StatisticsExecutorImpl constructor + * @param realExecutor the real executor we are delegating + */ + public StatisticsExecutorImpl(BlockingExecutor realExecutor) + { + this.realExecutor = realExecutor; + } + + + @Override + public void execute(Runnable runnable) + { + realExecutor.execute(runnable); + } + + @Override + public void executeBlocking(Runnable runnable) throws RejectedExecutionException, InterruptedException + { + realExecutor.executeBlocking(runnable); + } + + @Override + public void executeBlocking(Runnable runnable, long l, TimeUnit timeUnit) throws RejectedExecutionException, + InterruptedException + { + realExecutor.executeBlocking(runnable, l, timeUnit); + } + + @Override + public void executeNonBlocking(Runnable runnable) throws RejectedExecutionException + { + realExecutor.executeNonBlocking(runnable); + } + + @Override + public long getNumberOfFreeThreads() + { + if (realExecutor instanceof JBossThreadPoolExecutor) + { + return ((JBossThreadPoolExecutor) realExecutor).getMaximumPoolSize() - + ((JBossThreadPoolExecutor) realExecutor).getActiveCount(); + } + else if (realExecutor instanceof ThreadPoolExecutorMBean) + { + return ((ThreadPoolExecutorMBean) realExecutor).getMaxThreads() - + ((ThreadPoolExecutorMBean) realExecutor).getCurrentThreadCount(); + } + else + { + return 0; + } + + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkClassLoader.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkClassLoader.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkClassLoader.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,305 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import org.jboss.jca.core.CoreLogger; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Vector; + +import org.jboss.logging.Logger; + +/** + * Work class loader + * @author Jesper Pedersen + */ +public class WorkClassLoader extends ClassLoader +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, WorkClassLoader.class.getName()); + + /** The resource adapter class loader */ + private ResourceAdapterClassLoader resourceAdapterClassLoader; + + /** + * Constructor + * @param cb The class bundle + */ + public WorkClassLoader(ClassBundle cb) + { + this(cb, null); + } + + /** + * Constructor + * @param cb The class bundle + * @param resourceAdapterClassLoader The resource adapter class loader + */ + public WorkClassLoader(ClassBundle cb, ResourceAdapterClassLoader resourceAdapterClassLoader) + { + super(SecurityActions.getClassLoader(WorkClassLoader.class)); + + List> classes = new ArrayList>(cb.getDefinitions().size()); + final boolean trace = log.isTraceEnabled(); + for (ClassDefinition cd : cb.getDefinitions()) + { + if (trace) + log.tracef("%s: Defining class=%s", Integer.toHexString(System.identityHashCode(this)), cd.getName()); + + Class c = defineClass(cd.getName(), cd.getData(), 0, cd.getData().length); + classes.add(c); + } + + for (Class c : classes) + { + if (trace) + log.tracef("%s: Resolving class=%s", Integer.toHexString(System.identityHashCode(this)), c.getName()); + + resolveClass(c); + } + + this.resourceAdapterClassLoader = resourceAdapterClassLoader; + } + + /** + * Set the resource adapter class loader + * @param v The value + */ + public void setResourceAdapterClassLoader(ResourceAdapterClassLoader v) + { + if (log.isTraceEnabled()) + log.tracef("%s: setResourceAdapterClassLoader(%s)", Integer.toHexString(System.identityHashCode(this)), v); + + resourceAdapterClassLoader = v; + } + + /** + * {@inheritDoc} + */ + @Override + public Class loadClass(String name) throws ClassNotFoundException + { + if (log.isTraceEnabled()) + log.tracef("%s: loadClass(%s)", Integer.toHexString(System.identityHashCode(this)), name); + + Class result = super.loadClass(name); + + if (result != null) + return result; + + if (resourceAdapterClassLoader != null) + { + try + { + return resourceAdapterClassLoader.loadClass(name); + } + catch (ClassNotFoundException cnfe) + { + // Default to parent + } + catch (NoClassDefFoundError ncdfe) + { + // Default to parent + } + } + + return loadClass(name, false); + } + + /** + * {@inheritDoc} + */ + @Override + public Class loadClass(String name, boolean resolve) throws ClassNotFoundException + { + return super.loadClass(name, resolve); + } + + /** + * {@inheritDoc} + */ + @Override + public Class findClass(String name) throws ClassNotFoundException + { + if (log.isTraceEnabled()) + log.tracef("%s: findClass(%s)", Integer.toHexString(System.identityHashCode(this)), name); + + if (resourceAdapterClassLoader != null) + { + try + { + return resourceAdapterClassLoader.findClass(name); + } + catch (Throwable t) + { + // Default to parent + } + } + + return super.findClass(name); + } + + /** + * Lookup a class + * @param name The fully qualified class name + * @return The class + * @exception ClassNotFoundException Thrown if the class can't be found + */ + Class lookup(String name) throws ClassNotFoundException + { + return super.findClass(name); + } + + /** + * {@inheritDoc} + */ + @Override + public URL getResource(String name) + { + URL resource = null; + + if (resourceAdapterClassLoader != null) + resource = resourceAdapterClassLoader.getResource(name); + + if (resource != null) + return resource; + + return super.getResource(name); + } + + /** + * {@inheritDoc} + */ + @Override + public InputStream getResourceAsStream(String name) + { + InputStream is = null; + + if (resourceAdapterClassLoader != null) + is = resourceAdapterClassLoader.getResourceAsStream(name); + + if (is != null) + return is; + + return super.getResourceAsStream(name); + } + + /** + * {@inheritDoc} + */ + @Override + public Enumeration getResources(String name) + throws IOException + { + Vector v = new Vector(); + + Enumeration e = null; + + if (resourceAdapterClassLoader != null) + e = resourceAdapterClassLoader.getResources(name); + + if (e != null) + { + while (e.hasMoreElements()) + { + v.add(e.nextElement()); + } + } + + e = super.getResources(name); + while (e.hasMoreElements()) + { + v.add(e.nextElement()); + } + + return v.elements(); + } + + /** + * {@inheritDoc} + */ + @Override + public void clearAssertionStatus() + { + super.clearAssertionStatus(); + + if (resourceAdapterClassLoader != null) + resourceAdapterClassLoader.clearAssertionStatus(); + } + + /** + * {@inheritDoc} + */ + @Override + public void setClassAssertionStatus(String className, boolean enabled) + { + if (resourceAdapterClassLoader != null) + resourceAdapterClassLoader.setClassAssertionStatus(className, enabled); + + super.setClassAssertionStatus(className, enabled); + } + + /** + * {@inheritDoc} + */ + @Override + public void setDefaultAssertionStatus(boolean enabled) + { + if (resourceAdapterClassLoader != null) + resourceAdapterClassLoader.setDefaultAssertionStatus(enabled); + + super.setDefaultAssertionStatus(enabled); + } + + /** + * {@inheritDoc} + */ + @Override + public void setPackageAssertionStatus(String packageName, boolean enabled) + { + if (resourceAdapterClassLoader != null) + resourceAdapterClassLoader.setPackageAssertionStatus(packageName, enabled); + + super.setPackageAssertionStatus(packageName, enabled); + } + + /** + * {@inheritDoc} + */ + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("WorkClassLoader@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[parent=").append(getParent()); + sb.append(" resourceAdapterClassLoader=").append(resourceAdapterClassLoader); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkEventListener.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkEventListener.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkEventListener.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,110 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import org.jboss.jca.core.api.workmanager.StatisticsExecutor; +import org.jboss.jca.core.spi.workmanager.Address; +import org.jboss.jca.core.spi.workmanager.transport.Transport; + +import javax.resource.spi.work.WorkAdapter; +import javax.resource.spi.work.WorkEvent; + + +/** + * Work event listener + * @author Jesper Pedersen + */ +public class WorkEventListener extends WorkAdapter +{ + /** Short or long running work */ + private boolean isLong; + + /** The short thread pool */ + private StatisticsExecutor shortThreadPool; + + /** The long thread pool */ + private StatisticsExecutor longThreadPool; + + /** The address */ + private Address address; + + /** The transport */ + private Transport transport; + + /** + * Constructor + * @param isLong Is long running work instance + * @param shortThreadPool The short running thread pool + * @param longThreadPool The long running thread pool + * @param address The address + * @param transport The transport + */ + public WorkEventListener(boolean isLong, + StatisticsExecutor shortThreadPool, + StatisticsExecutor longThreadPool, + Address address, + Transport transport) + { + this.isLong = isLong; + this.shortThreadPool = shortThreadPool; + this.longThreadPool = longThreadPool; + this.address = address; + this.transport = transport; + } + + /** + * {@inheritDoc} + */ + @Override + public void workCompleted(WorkEvent e) + { + done(); + } + + /** + * {@inheritDoc} + */ + @Override + public void workRejected(WorkEvent e) + { + done(); + } + + /** + * Send the done signal to other nodes + * We are adding 1 to the result, since the thread officially has been released yet, but will be shortly + */ + private void done() + { + if (longThreadPool != null && isLong) + { + transport.updateLongRunningFree(address, + longThreadPool.getNumberOfFreeThreads() + 1); + } + else + { + transport.updateShortRunningFree(address, + shortThreadPool.getNumberOfFreeThreads() + 1); + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerCoordinator.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerCoordinator.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerCoordinator.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,469 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.workmanager.DistributedWorkManager; +import org.jboss.jca.core.api.workmanager.WorkManager; +import org.jboss.jca.core.spi.workmanager.Address; +import org.jboss.jca.core.spi.workmanager.notification.NotificationListener; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.jboss.logging.Logger; + +/** + * Coordinator for WorkManager instances + * @author Jesper Pedersen + */ +public class WorkManagerCoordinator +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + WorkManagerCoordinator.class.getName()); + + /** The instance */ + private static final WorkManagerCoordinator INSTANCE = new WorkManagerCoordinator(); + + /** The work managers */ + private ConcurrentMap workmanagers; + + /** The default work manager */ + private WorkManager defaultWorkManager; + + /** The activate work managers */ + private Map activeWorkmanagers; + + /** The ref count for activate work managers */ + private Map refCountWorkmanagers; + + /** + * Constructor + */ + private WorkManagerCoordinator() + { + this.workmanagers = new ConcurrentHashMap(); + this.defaultWorkManager = null; + this.activeWorkmanagers = new HashMap(); + this.refCountWorkmanagers = new HashMap(); + } + + /** + * Get the instance + * @return The instance + */ + public static WorkManagerCoordinator getInstance() + { + return INSTANCE; + } + + /** + * Register work manager + * @param wm The work manager + */ + public void registerWorkManager(WorkManager wm) + { + if (wm != null) + { + if (wm.getName() == null || wm.getName().trim().equals("")) + throw new IllegalArgumentException("The name of WorkManager is invalid: " + wm); + + log.tracef("Registering WorkManager: %s", wm); + + if (!workmanagers.keySet().contains(wm.getName())) + { + workmanagers.put(wm.getName(), wm); + + // Replay events for distributed work managers + if (wm instanceof DistributedWorkManager) + { + WorkManagerEventQueue wmeq = WorkManagerEventQueue.getInstance(); + List events = wmeq.getEvents(wm.getName()); + + if (events.size() > 0) + { + log.tracef("%s: Events=%s", wm.getName(), events); + + for (WorkManagerEvent event : events) + { + if (event.getType() == WorkManagerEvent.TYPE_JOIN) + { + DistributedWorkManager dwm = resolveDistributedWorkManager(event.getAddress()); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.join(event.getAddress()); + } + } + } + else if (event.getType() == WorkManagerEvent.TYPE_LEAVE) + { + DistributedWorkManager dwm = + (DistributedWorkManager)activeWorkmanagers.get(event.getAddress().getWorkManagerId()); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.leave(event.getAddress()); + } + } + + removeWorkManager(event.getAddress().getWorkManagerId()); + } + else if (event.getType() == WorkManagerEvent.TYPE_UPDATE_SHORT_RUNNING) + { + DistributedWorkManager dwm = + (DistributedWorkManager)activeWorkmanagers.get(event.getAddress().getWorkManagerId()); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.updateShortRunningFree(event.getAddress(), event.getValue()); + } + } + } + else if (event.getType() == WorkManagerEvent.TYPE_UPDATE_LONG_RUNNING) + { + DistributedWorkManager dwm = + (DistributedWorkManager)activeWorkmanagers.get(event.getAddress().getWorkManagerId()); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.updateLongRunningFree(event.getAddress(), event.getValue()); + } + } + } + } + } + } + } + } + } + + /** + * Unregister work manager + * @param wm The work manager + */ + public void unregisterWorkManager(WorkManager wm) + { + if (wm != null) + { + if (wm.getName() == null || wm.getName().trim().equals("")) + throw new IllegalArgumentException("The name of WorkManager is invalid: " + wm); + + log.tracef("Unregistering WorkManager: %s", wm); + + if (workmanagers.keySet().contains(wm.getName())) + { + workmanagers.remove(wm.getName()); + + // Clear any events + if (wm instanceof DistributedWorkManager) + { + WorkManagerEventQueue wmeq = WorkManagerEventQueue.getInstance(); + List events = wmeq.getEvents(wm.getName()); + events.clear(); + } + } + } + } + + /** + * Get the default work manager + * @return The work manager + */ + public WorkManager getDefaultWorkManager() + { + return defaultWorkManager; + } + + /** + * Set the default work manager + * @param wm The work manager + */ + public void setDefaultWorkManager(WorkManager wm) + { + log.tracef("Default WorkManager: %s", wm); + + String currentName = null; + + if (defaultWorkManager != null) + currentName = defaultWorkManager.getName(); + + defaultWorkManager = wm; + + if (wm != null) + { + workmanagers.put(wm.getName(), wm); + } + else if (currentName != null) + { + workmanagers.remove(currentName); + } + } + + /** + * Resolve a work manager + * @param address The work manager address + * @return The value + */ + public WorkManager resolveWorkManager(Address address) + { + log.tracef("resolveWorkManager(%s)", address); + log.tracef(" ActiveWorkManagers: %s", activeWorkmanagers); + + WorkManager wm = activeWorkmanagers.get(address.getWorkManagerId()); + if (wm != null) + { + log.tracef(" WorkManager: %s", wm); + + return wm; + } + + try + { + // Create a new instance + WorkManager template = workmanagers.get(address.getWorkManagerName()); + + if (template != null) + { + wm = template.clone(); + wm.setId(address.getWorkManagerId()); + + if (wm instanceof DistributedWorkManager) + { + DistributedWorkManager dwm = (DistributedWorkManager)wm; + dwm.initialize(); + } + + activeWorkmanagers.put(address.getWorkManagerId(), wm); + refCountWorkmanagers.put(address.getWorkManagerId(), Integer.valueOf(0)); + + log.tracef("Created WorkManager: %s", wm); + + return wm; + } + } + catch (Throwable t) + { + //throw new IllegalStateException("The WorkManager couldn't be created: " + name); + } + + return null; + } + + /** + * Resolve a distributed work manager + * @param address The work manager address + * @return The value + */ + public DistributedWorkManager resolveDistributedWorkManager(Address address) + { + log.tracef("resolveDistributedWorkManager(%s)", address); + log.tracef(" ActiveWorkManagers: %s", activeWorkmanagers); + + WorkManager wm = activeWorkmanagers.get(address.getWorkManagerId()); + + if (wm != null) + { + if (wm instanceof DistributedWorkManager) + { + log.tracef(" WorkManager: %s", wm); + + return (DistributedWorkManager)wm; + } + else + { + log.tracef(" WorkManager not distributable: %s", wm); + + return null; + } + } + + try + { + // Create a new instance + WorkManager template = workmanagers.get(address.getWorkManagerName()); + + if (template != null) + { + wm = template.clone(); + wm.setId(address.getWorkManagerId()); + + if (wm instanceof DistributedWorkManager) + { + DistributedWorkManager dwm = (DistributedWorkManager)wm; + dwm.initialize(); + + activeWorkmanagers.put(address.getWorkManagerId(), dwm); + refCountWorkmanagers.put(address.getWorkManagerId(), Integer.valueOf(0)); + + log.tracef("Created WorkManager: %s", dwm); + + return dwm; + } + } + } + catch (Throwable t) + { + //throw new IllegalStateException("The WorkManager couldn't be created: " + name); + } + + return null; + } + + /** + * Create a work manager + * @param id The id of the work manager + * @param name The name of the work manager; if null default value is used + * @return The work manager + */ + public synchronized WorkManager createWorkManager(String id, String name) + { + if (id == null || id.trim().equals("")) + throw new IllegalArgumentException("The id of WorkManager is invalid: " + id); + + // Check for an active work manager + if (activeWorkmanagers.keySet().contains(id)) + { + log.tracef("RefCounting WorkManager: %s", id); + + Integer i = refCountWorkmanagers.get(id); + refCountWorkmanagers.put(id, Integer.valueOf(i.intValue() + 1)); + + WorkManager wm = activeWorkmanagers.get(id); + if (wm instanceof DistributedWorkManager) + { + + DistributedWorkManager dwm = (DistributedWorkManager)wm; + if (dwm.getTransport() != null) + dwm.getTransport().register(new Address(wm.getId(), wm.getName(), dwm.getTransport().getId())); + } + + return wm; + } + + try + { + // Create a new instance + WorkManager template = null; + if (name != null) + { + template = workmanagers.get(name); + } + else + { + template = defaultWorkManager; + } + + if (template == null) + throw new IllegalArgumentException("The WorkManager wasn't found: " + name); + + WorkManager wm = template.clone(); + wm.setId(id); + + if (wm instanceof DistributedWorkManager) + { + DistributedWorkManager dwm = (DistributedWorkManager)wm; + dwm.initialize(); + + if (dwm.getTransport() != null) + { + dwm.getTransport().register(new Address(wm.getId(), wm.getName(), dwm.getTransport().getId())); + } + else + { + log.debugf("DistributedWorkManager '%s' doesn't have a transport associated", dwm.getName()); + } + } + + activeWorkmanagers.put(id, wm); + refCountWorkmanagers.put(id, Integer.valueOf(1)); + + log.tracef("Created WorkManager: %s", wm); + + return wm; + } + catch (Throwable t) + { + throw new IllegalStateException("The WorkManager couldn't be created: " + name, t); + } + } + + /** + * Remove a work manager + * @param id The id of the work manager + */ + public synchronized void removeWorkManager(String id) + { + if (id == null || id.trim().equals("")) + throw new IllegalArgumentException("The id of WorkManager is invalid: " + id); + + Integer i = refCountWorkmanagers.get(id); + if (i != null) + { + int newValue = i.intValue() - 1; + if (newValue == 0) + { + log.tracef("Removed WorkManager: %s", id); + + WorkManager wm = activeWorkmanagers.get(id); + if (wm instanceof DistributedWorkManager) + { + DistributedWorkManager dwm = (DistributedWorkManager)wm; + if (dwm.getTransport() != null) + dwm.getTransport().unregister(new Address(wm.getId(), wm.getName(), dwm.getTransport().getId())); + } + + activeWorkmanagers.remove(id); + refCountWorkmanagers.remove(id); + } + else + { + log.tracef("DerefCount WorkManager: %s", id); + + refCountWorkmanagers.put(id, Integer.valueOf(newValue)); + } + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerEvent.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerEvent.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerEvent.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,165 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.workmanager.Address; + +import org.jboss.logging.Logger; + +/** + * A WorkManager event + * @author Jesper Pedersen + */ +public class WorkManagerEvent +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + WorkManagerEvent.class.getName()); + + /** JOIN */ + public static final int TYPE_JOIN = 0; + + /** LEAVE */ + public static final int TYPE_LEAVE = 1; + + /** UPDATE_SHORT_RUNNING */ + public static final int TYPE_UPDATE_SHORT_RUNNING = 2; + + /** UPDATE_LONG_RUNNING */ + public static final int TYPE_UPDATE_LONG_RUNNING = 3; + + /** The type */ + private int type; + + /** The address */ + private Address address; + + /** The value */ + private long value; + + /** + * Constructor + * @param type The type + * @param address The address + */ + public WorkManagerEvent(int type, Address address) + { + this(type, address, 0L); + } + + /** + * Constructor + * @param type The type + * @param address The address + * @param value The value for the type + */ + public WorkManagerEvent(int type, Address address, long value) + { + this.type = type; + this.address = address; + this.value = value; + } + + /** + * Get the type + * @return The value + */ + public int getType() + { + return type; + } + + /** + * Get the address + * @return The value + */ + public Address getAddress() + { + return address; + } + + /** + * Get the value + * @return The value + */ + public long getValue() + { + return value; + } + + /** + * {@inheritDoc} + */ + public int hashCode() + { + int result = 31; + + result += 7 * type; + result += 7 * address.hashCode(); + + return result; + } + + /** + * {@inheritDoc} + */ + public boolean equals(Object o) + { + if (o == this) + return true; + + if (o == null) + return false; + + if (!(o instanceof WorkManagerEvent)) + return false; + + WorkManagerEvent wme = (WorkManagerEvent)o; + + if (type != wme.getType()) + return false; + + if (!address.equals(wme.getAddress())) + return false; + + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("WorkManagerEvent@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[type=").append(type); + sb.append(" address=").append(address); + sb.append(" value=").append(value); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerEventQueue.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerEventQueue.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerEventQueue.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,106 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import org.jboss.jca.core.CoreLogger; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.jboss.logging.Logger; + +/** + * Event queue for WorkManager instances + * @author Jesper Pedersen + */ +public class WorkManagerEventQueue +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + WorkManagerEventQueue.class.getName()); + + /** The instance */ + private static final WorkManagerEventQueue INSTANCE = new WorkManagerEventQueue(); + + /** The work managers */ + private Map> events; + + /** + * Constructor + */ + private WorkManagerEventQueue() + { + this.events = new HashMap>(); + } + + /** + * Get the instance + * @return The instance + */ + public static WorkManagerEventQueue getInstance() + { + return INSTANCE; + } + + /** + * Add an event + * @param event The event + */ + public synchronized void addEvent(WorkManagerEvent event) + { + log.tracef("addEvent(%s)", event); + + List e = events.get(event.getAddress().getWorkManagerName()); + + if (e == null) + { + e = new ArrayList(); + events.put(event.getAddress().getWorkManagerName(), e); + } + + e.add(event); + } + + /** + * Get events + * @param workManagerName The name of the WorkManager + * @return The list of events + */ + public synchronized List getEvents(String workManagerName) + { + List result = new ArrayList(); + List e = events.get(workManagerName); + + if (e != null) + { + result.addAll(e); + e.clear(); + } + + log.tracef("getEvents(%s): %s", workManagerName, result); + + return result; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,1478 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.workmanager.DistributableContext; +import org.jboss.jca.core.api.workmanager.StatisticsExecutor; +import org.jboss.jca.core.api.workmanager.WorkManager; +import org.jboss.jca.core.api.workmanager.WorkManagerStatistics; +import org.jboss.jca.core.spi.graceful.GracefulCallback; +import org.jboss.jca.core.spi.security.Callback; +import org.jboss.jca.core.spi.security.SecurityIntegration; +import org.jboss.jca.core.spi.transaction.xa.XATerminator; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.resource.spi.ResourceAdapter; +import javax.resource.spi.ResourceAdapterAssociation; +import javax.resource.spi.work.ExecutionContext; +import javax.resource.spi.work.HintsContext; +import javax.resource.spi.work.SecurityContext; +import javax.resource.spi.work.TransactionContext; +import javax.resource.spi.work.Work; +import javax.resource.spi.work.WorkCompletedException; +import javax.resource.spi.work.WorkContext; +import javax.resource.spi.work.WorkContextErrorCodes; +import javax.resource.spi.work.WorkContextLifecycleListener; +import javax.resource.spi.work.WorkContextProvider; +import javax.resource.spi.work.WorkEvent; +import javax.resource.spi.work.WorkException; +import javax.resource.spi.work.WorkListener; +import javax.resource.spi.work.WorkRejectedException; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; +import org.jboss.threads.BlockingExecutor; +import org.jboss.threads.ExecutionTimedOutException; + +/** + * The work manager implementation. + * + * @author Jesper Pedersen + */ +public class WorkManagerImpl implements WorkManager +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, WorkManagerImpl.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /**Work run method name*/ + private static final String RUN_METHOD_NAME = "run"; + + /**Work release method name*/ + private static final String RELEASE_METHOD_NAME = "release"; + + /**Supported work context set*/ + private static final Set> SUPPORTED_WORK_CONTEXT_CLASSES = + new HashSet>(4); + + /** The id */ + private String id; + + /** The name */ + private String name; + + /** Running in spec compliant mode */ + private boolean specCompliant; + + /** The short running executor */ + private StatisticsExecutor shortRunningExecutor; + + /** The long running executor */ + private StatisticsExecutor longRunningExecutor; + + /** The XA terminator */ + private XATerminator xaTerminator; + + /** Validated work instances */ + private Set validatedWork; + + /** Security module for callback */ + private Callback callbackSecurity; + + /** Security integration module */ + private SecurityIntegration securityIntegration; + + /** Resource adapter */ + private ResourceAdapter resourceAdapter; + + /** Shutdown */ + private AtomicBoolean shutdown; + + /** Scheduled executor for graceful shutdown */ + private ScheduledExecutorService scheduledExecutorService; + + /** Graceful job */ + private ScheduledFuture scheduledGraceful; + + /** Graceful call back */ + private GracefulCallback gracefulCallback; + + /** Active work wrappers */ + private Set activeWorkWrappers; + + /** Enable statistics */ + private boolean statisticsEnabled; + + /** Statistics */ + private WorkManagerStatisticsImpl statistics; + + /**Default supported workcontext types*/ + static + { + SUPPORTED_WORK_CONTEXT_CLASSES.add(TransactionContext.class); + SUPPORTED_WORK_CONTEXT_CLASSES.add(SecurityContext.class); + SUPPORTED_WORK_CONTEXT_CLASSES.add(HintsContext.class); + SUPPORTED_WORK_CONTEXT_CLASSES.add(DistributableContext.class); + } + + /** + * Constructor - by default the WorkManager is running in spec-compliant mode + */ + public WorkManagerImpl() + { + id = null; + name = null; + specCompliant = true; + validatedWork = new HashSet(); + resourceAdapter = null; + shutdown = new AtomicBoolean(false); + scheduledExecutorService = null; + scheduledGraceful = null; + gracefulCallback = null; + activeWorkWrappers = new HashSet(); + statisticsEnabled = true; + statistics = new WorkManagerStatisticsImpl(); + } + + /** + * Get the unique id of the work manager + * @return The value + */ + public String getId() + { + if (id == null) + return name; + + return id; + } + + /** + * Set the unique id of the work manager + * @param v The value + */ + public void setId(String v) + { + id = v; + } + + /** + * Get the name of the work manager + * @return The value + */ + public String getName() + { + return name; + } + + /** + * Set the name of the work manager + * @param v The value + */ + public void setName(String v) + { + name = v; + } + + /** + * Retrieve the executor for short running tasks + * @return The executor + */ + public StatisticsExecutor getShortRunningThreadPool() + { + return shortRunningExecutor; + } + + /** + * Set the executor for short running tasks + * @param executor The executor + */ + public void setShortRunningThreadPool(BlockingExecutor executor) + { + if (log.isTraceEnabled()) + log.trace("short running executor:" + (executor != null ? executor.getClass() : "null")); + + if (executor != null) + { + if (executor instanceof StatisticsExecutor) + { + this.shortRunningExecutor = (StatisticsExecutor) executor; + } + else + { + this.shortRunningExecutor = new StatisticsExecutorImpl(executor); + } + } + } + + /** + * Retrieve the executor for long running tasks + * @return The executor + */ + public StatisticsExecutor getLongRunningThreadPool() + { + return longRunningExecutor; + } + + /** + * Set the executor for long running tasks + * @param executor The executor + */ + public void setLongRunningThreadPool(BlockingExecutor executor) + { + if (log.isTraceEnabled()) + log.trace("long running executor:" + (executor != null ? executor.getClass() : "null")); + + if (executor != null) + { + if (executor instanceof StatisticsExecutor) + { + this.longRunningExecutor = (StatisticsExecutor) executor; + } + else + { + this.longRunningExecutor = new StatisticsExecutorImpl(executor); + } + } + } + + /** + * Get the XATerminator + * @return The XA terminator + */ + public XATerminator getXATerminator() + { + return xaTerminator; + } + + /** + * Set the XATerminator + * @param xaTerminator The XA terminator + */ + public void setXATerminator(XATerminator xaTerminator) + { + this.xaTerminator = xaTerminator; + } + + /** + * Is spec compliant + * @return True if spec compliant; otherwise false + */ + public boolean isSpecCompliant() + { + return specCompliant; + } + + /** + * Set spec compliant flag + * @param v The value + */ + public void setSpecCompliant(boolean v) + { + specCompliant = v; + } + + /** + * Get the callback security module + * @return The value + */ + public Callback getCallbackSecurity() + { + return callbackSecurity; + } + + /** + * Set callback security module + * @param v The value + */ + public void setCallbackSecurity(Callback v) + { + callbackSecurity = v; + } + + /** + * Get the security integration module + * @return The value + */ + public SecurityIntegration getSecurityIntegration() + { + return securityIntegration; + } + + /** + * Set security intergation module + * @param v The value + */ + public void setSecurityIntegration(SecurityIntegration v) + { + securityIntegration = v; + } + + /** + * Get the resource adapter + * @return The value + */ + public ResourceAdapter getResourceAdapter() + { + return resourceAdapter; + } + + /** + * Set the resource adapter + * @param v The value + */ + public void setResourceAdapter(ResourceAdapter v) + { + resourceAdapter = v; + } + + /** + * {@inheritDoc} + */ + public boolean isStatisticsEnabled() + { + return statisticsEnabled; + } + + /** + * {@inheritDoc} + */ + public void setStatisticsEnabled(boolean v) + { + statisticsEnabled = v; + } + + /** + * Get the statistics + * @return The value + */ + public WorkManagerStatistics getStatistics() + { + return statistics; + } + + /** + * Set the statistics + * @param v The value + */ + void setStatistics(WorkManagerStatisticsImpl v) + { + statistics = v; + } + + /** + * Clone the WorkManager implementation + * @return A copy of the implementation + * @exception CloneNotSupportedException Thrown if the copy operation isn't supported + * + */ + @Override + public WorkManager clone() throws CloneNotSupportedException + { + WorkManagerImpl wm = (WorkManagerImpl) super.clone(); + wm.setId(getId()); + wm.setName(getName()); + wm.setShortRunningThreadPool(getShortRunningThreadPool()); + wm.setLongRunningThreadPool(getLongRunningThreadPool()); + wm.setXATerminator(getXATerminator()); + wm.setSpecCompliant(isSpecCompliant()); + wm.setCallbackSecurity(getCallbackSecurity()); + wm.setSecurityIntegration(getSecurityIntegration()); + wm.setStatistics(statistics); + + return wm; + } + + /** + * {@inheritDoc} + */ + public void doWork(Work work) throws WorkException + { + doWork(work, WorkManager.INDEFINITE, null, null); + } + + /** + * {@inheritDoc} + */ + public void doWork(Work work, long startTimeout, ExecutionContext execContext, WorkListener workListener) + throws WorkException + { + log.tracef("doWork(%s, %s, %s, %s)", work, startTimeout, execContext, workListener); + + WorkException exception = null; + WorkWrapper wrapper = null; + try + { + doFirstChecks(work, startTimeout, execContext); + + if (workListener != null) + { + WorkEvent event = new WorkEvent(this, WorkEvent.WORK_ACCEPTED, work, null); + workListener.workAccepted(event); + } + + deltaDoWorkAccepted(); + + if (execContext == null) + { + execContext = new ExecutionContext(); + } + + final CountDownLatch completedLatch = new CountDownLatch(1); + + wrapper = createWorkWrapper(securityIntegration, work, execContext, workListener, null, completedLatch); + + setup(wrapper, workListener); + + BlockingExecutor executor = getExecutor(work); + + if (startTimeout == WorkManager.INDEFINITE) + { + executor.executeBlocking(wrapper); + } + else + { + executor.executeBlocking(wrapper, startTimeout, TimeUnit.MILLISECONDS); + } + + completedLatch.await(); + } + catch (ExecutionTimedOutException etoe) + { + exception = new WorkRejectedException(etoe); + exception.setErrorCode(WorkRejectedException.START_TIMED_OUT); + } + catch (RejectedExecutionException ree) + { + exception = new WorkRejectedException(ree); + } + catch (WorkCompletedException wce) + { + if (wrapper != null) + wrapper.setWorkException(wce); + } + catch (WorkException we) + { + exception = we; + } + catch (InterruptedException ie) + { + Thread.currentThread().interrupt(); + exception = new WorkRejectedException(bundle.interruptedWhileRequestingPermit()); + } + finally + { + if (exception != null) + { + if (workListener != null) + { + WorkEvent event = new WorkEvent(this, WorkEvent.WORK_REJECTED, work, exception); + workListener.workRejected(event); + } + + log.tracef("Exception %s for %s", exception, this); + + deltaDoWorkRejected(); + + throw exception; + } + + if (wrapper != null) + { + checkWorkCompletionException(wrapper); + } + } + } + + /** + * {@inheritDoc} + */ + public long startWork(Work work) throws WorkException + { + return startWork(work, WorkManager.INDEFINITE, null, null); + } + + /** + * {@inheritDoc} + */ + public long startWork(Work work, long startTimeout, ExecutionContext execContext, WorkListener workListener) + throws WorkException + { + log.tracef("startWork(%s, %s, %s, %s)", work, startTimeout, execContext, workListener); + + WorkException exception = null; + WorkWrapper wrapper = null; + try + { + long started = System.currentTimeMillis(); + + doFirstChecks(work, startTimeout, execContext); + + if (workListener != null) + { + WorkEvent event = new WorkEvent(this, WorkEvent.WORK_ACCEPTED, work, null); + workListener.workAccepted(event); + } + + deltaStartWorkAccepted(); + + if (execContext == null) + { + execContext = new ExecutionContext(); + } + + final CountDownLatch startedLatch = new CountDownLatch(1); + + wrapper = createWorkWrapper(securityIntegration, work, execContext, workListener, startedLatch, null); + + setup(wrapper, workListener); + + BlockingExecutor executor = getExecutor(work); + + if (startTimeout == WorkManager.INDEFINITE) + { + executor.executeBlocking(wrapper); + } + else + { + executor.executeBlocking(wrapper, startTimeout, TimeUnit.MILLISECONDS); + } + + startedLatch.await(); + + return System.currentTimeMillis() - started; + } + catch (ExecutionTimedOutException etoe) + { + exception = new WorkRejectedException(etoe); + exception.setErrorCode(WorkRejectedException.START_TIMED_OUT); + } + catch (RejectedExecutionException ree) + { + exception = new WorkRejectedException(ree); + } + catch (WorkCompletedException wce) + { + if (wrapper != null) + wrapper.setWorkException(wce); + } + catch (WorkException we) + { + exception = we; + } + catch (InterruptedException ie) + { + Thread.currentThread().interrupt(); + exception = new WorkRejectedException(bundle.interruptedWhileRequestingPermit()); + } + finally + { + if (exception != null) + { + if (workListener != null) + { + WorkEvent event = new WorkEvent(this, WorkEvent.WORK_REJECTED, work, exception); + workListener.workRejected(event); + } + + log.tracef("Exception %s for %s", exception, this); + + deltaStartWorkRejected(); + + throw exception; + } + + if (wrapper != null) + checkWorkCompletionException(wrapper); + } + + return WorkManager.UNKNOWN; + } + + /** + * {@inheritDoc} + */ + public void scheduleWork(Work work) throws WorkException + { + scheduleWork(work, WorkManager.INDEFINITE, null, null); + } + + /** + * {@inheritDoc} + */ + public void scheduleWork(Work work, long startTimeout, ExecutionContext execContext, WorkListener workListener) + throws WorkException + { + log.tracef("scheduleWork(%s, %s, %s, %s)", work, startTimeout, execContext, workListener); + + WorkException exception = null; + WorkWrapper wrapper = null; + try + { + doFirstChecks(work, startTimeout, execContext); + + if (workListener != null) + { + WorkEvent event = new WorkEvent(this, WorkEvent.WORK_ACCEPTED, work, null); + workListener.workAccepted(event); + } + + deltaScheduleWorkAccepted(); + + if (execContext == null) + { + execContext = new ExecutionContext(); + } + + wrapper = createWorkWrapper(securityIntegration, work, execContext, workListener, null, null); + + setup(wrapper, workListener); + + BlockingExecutor executor = getExecutor(work); + + if (startTimeout == WorkManager.INDEFINITE) + { + executor.executeBlocking(wrapper); + } + else + { + executor.executeBlocking(wrapper, startTimeout, TimeUnit.MILLISECONDS); + } + } + catch (ExecutionTimedOutException etoe) + { + exception = new WorkRejectedException(etoe); + exception.setErrorCode(WorkRejectedException.START_TIMED_OUT); + } + catch (RejectedExecutionException ree) + { + exception = new WorkRejectedException(ree); + } + catch (WorkCompletedException wce) + { + if (wrapper != null) + wrapper.setWorkException(wce); + } + catch (WorkException we) + { + exception = we; + } + catch (InterruptedException ie) + { + Thread.currentThread().interrupt(); + exception = new WorkRejectedException(bundle.interruptedWhileRequestingPermit()); + } + finally + { + if (exception != null) + { + if (workListener != null) + { + WorkEvent event = new WorkEvent(this, WorkEvent.WORK_REJECTED, work, exception); + workListener.workRejected(event); + } + + log.tracef("Exception %s for %s", exception, this); + + deltaScheduleWorkRejected(); + + throw exception; + } + + if (wrapper != null) + checkWorkCompletionException(wrapper); + } + } + + /** + * Crestes a wrapper for work + * + * @param securityIntegration the security integration + * @param work the work + * @param executionContext the execution context + * @param workListener the work listener + * @param startedLatch latch that will be notified when work starts execution. Can be null. + * @param completedLatch latch that will be notified when work completes execution. Can be null. + * @return the created work wrapper + */ + protected WorkWrapper createWorkWrapper(SecurityIntegration securityIntegration, Work work, + ExecutionContext executionContext, WorkListener workListener, CountDownLatch startedLatch, + CountDownLatch completedLatch) + { + return new WorkWrapper(this, securityIntegration, work, executionContext, workListener, + startedLatch, completedLatch, System.currentTimeMillis()); + } + + /** + * Delta doWork accepted + */ + protected void deltaDoWorkAccepted() + { + if (statisticsEnabled) + statistics.deltaDoWorkAccepted(); + } + + /** + * Delta doWork rejected + */ + protected void deltaDoWorkRejected() + { + if (statisticsEnabled) + statistics.deltaDoWorkRejected(); + } + + /** + * Delta startWork accepted + */ + protected void deltaStartWorkAccepted() + { + if (statisticsEnabled) + statistics.deltaStartWorkAccepted(); + } + + /** + * Delta startWork rejected + */ + protected void deltaStartWorkRejected() + { + if (statisticsEnabled) + statistics.deltaStartWorkRejected(); + } + + /** + * Delta scheduleWork accepted + */ + protected void deltaScheduleWorkAccepted() + { + if (statisticsEnabled) + statistics.deltaScheduleWorkAccepted(); + } + + /** + * Delta scheduleWork rejected + */ + protected void deltaScheduleWorkRejected() + { + if (statisticsEnabled) + statistics.deltaScheduleWorkRejected(); + } + + /** + * Delta work successful + */ + protected void deltaWorkSuccessful() + { + if (statisticsEnabled) + statistics.deltaWorkSuccessful(); + } + + /** + * Delta work failed + */ + protected void deltaWorkFailed() + { + if (statisticsEnabled) + statistics.deltaWorkFailed(); + } + + /** + * Do first checks for work starting methods + * @param work to check + * @param startTimeout to check + * @param execContext to check + * @throws WorkException in case of check don't pass + */ + public void doFirstChecks(Work work, long startTimeout, ExecutionContext execContext) throws WorkException + { + if (isShutdown()) + throw new WorkRejectedException(bundle.workmanagerShutdown()); + + if (work == null) + throw new WorkRejectedException(bundle.workIsNull()); + + if (startTimeout < 0) + throw new WorkRejectedException(bundle.startTimeoutIsNegative(startTimeout)); + + checkAndVerifyWork(work, execContext); + } + + /** + * {@inheritDoc} + */ + public boolean cancelShutdown() + { + if (scheduledGraceful != null) + { + boolean result = scheduledGraceful.cancel(false); + + if (result) + { + shutdown.set(false); + + if (gracefulCallback != null) + gracefulCallback.cancel(); + + scheduledGraceful = null; + gracefulCallback = null; + } + else + { + return false; + } + } + else if (shutdown.get()) + { + shutdown.set(false); + + if (gracefulCallback != null) + gracefulCallback.cancel(); + + gracefulCallback = null; + } + else + { + return false; + } + + return true; + } + + /** + * {@inheritDoc} + */ + public void prepareShutdown() + { + prepareShutdown(0, null); + } + + /** + * {@inheritDoc} + */ + public void prepareShutdown(GracefulCallback cb) + { + prepareShutdown(0, cb); + } + + /** + * {@inheritDoc} + */ + public void prepareShutdown(int seconds) + { + prepareShutdown(seconds, null); + } + + /** + * {@inheritDoc} + */ + public void prepareShutdown(int seconds, GracefulCallback cb) + { + shutdown.set(true); + + if (gracefulCallback == null) + gracefulCallback = cb; + + if (seconds > 0) + { + if (scheduledGraceful == null) + { + if (scheduledExecutorService == null) + scheduledExecutorService = Executors.newScheduledThreadPool(1); + + scheduledGraceful = + scheduledExecutorService.schedule(new WorkManagerShutdown(this), seconds, TimeUnit.SECONDS); + } + } + else + { + synchronized (activeWorkWrappers) + { + if (activeWorkWrappers.size() == 0) + shutdown(); + } + } + } + + /** + * {@inheritDoc} + */ + public synchronized void shutdown() + { + shutdown.set(true); + + synchronized (activeWorkWrappers) + { + for (WorkWrapper ww : activeWorkWrappers) + { + ww.getWork().release(); + } + } + + if (scheduledExecutorService != null) + { + if (scheduledGraceful != null && !scheduledGraceful.isDone()) + scheduledGraceful.cancel(true); + + scheduledGraceful = null; + scheduledExecutorService.shutdownNow(); + scheduledExecutorService = null; + } + + if (gracefulCallback != null) + { + gracefulCallback.done(); + gracefulCallback = null; + } + } + + /** + * {@inheritDoc} + */ + public boolean isShutdown() + { + return shutdown.get(); + } + + /** + * {@inheritDoc} + */ + public int getDelay() + { + if (scheduledGraceful != null) + return (int)scheduledGraceful.getDelay(TimeUnit.SECONDS); + + if (shutdown.get()) + return Integer.MIN_VALUE; + + return Integer.MAX_VALUE; + } + + /** + * Add work wrapper to active set + * @param ww The work wrapper + */ + void addWorkWrapper(WorkWrapper ww) + { + synchronized (activeWorkWrappers) + { + activeWorkWrappers.add(ww); + + if (statisticsEnabled) + statistics.setWorkActive(activeWorkWrappers.size()); + } + } + + /** + * Remove work wrapper from active set + * @param ww The work wrapper + */ + void removeWorkWrapper(WorkWrapper ww) + { + synchronized (activeWorkWrappers) + { + activeWorkWrappers.remove(ww); + + if (statisticsEnabled) + statistics.setWorkActive(activeWorkWrappers.size()); + } + } + + /** + * Get the executor + * @param work The work instance + * @return The executor + */ + private BlockingExecutor getExecutor(Work work) + { + BlockingExecutor executor = shortRunningExecutor; + if (longRunningExecutor != null && WorkManagerUtil.isLongRunning(work)) + { + executor = longRunningExecutor; + } + + fireHintsComplete(work); + + return executor; + } + + /** + * Fire complete for HintsContext + * @param work The work instance + */ + private void fireHintsComplete(Work work) + { + if (work != null && work instanceof WorkContextProvider) + { + WorkContextProvider wcProvider = (WorkContextProvider) work; + List contexts = wcProvider.getWorkContexts(); + + if (contexts != null && contexts.size() > 0) + { + Iterator it = contexts.iterator(); + while (it.hasNext()) + { + WorkContext wc = it.next(); + if (wc instanceof HintsContext) + { + HintsContext hc = (HintsContext) wc; + if (hc instanceof WorkContextLifecycleListener) + { + WorkContextLifecycleListener listener = (WorkContextLifecycleListener)hc; + listener.contextSetupComplete(); + } + } + } + } + } + } + + /** + * Check and verify work before submitting. + * @param work the work instance + * @param executionContext any execution context that is passed by apadater + * @throws WorkException if any exception occurs + */ + private void checkAndVerifyWork(Work work, ExecutionContext executionContext) throws WorkException + { + if (specCompliant) + { + verifyWork(work); + } + + if (work instanceof WorkContextProvider) + { + //Implements WorkContextProvider and not-null ExecutionContext + if (executionContext != null) + { + throw new WorkRejectedException(bundle.workExecutionContextMustNullImplementsWorkContextProvider()); + } + } + } + + /** + * Verify the given work instance. + * @param work The work + * @throws WorkException Thrown if a spec compliant issue is found + */ + private void verifyWork(Work work) throws WorkException + { + Class workClass = work.getClass(); + String className = workClass.getName(); + + if (!validatedWork.contains(className)) + { + + if (isWorkMethodSynchronized(workClass, RUN_METHOD_NAME)) + throw new WorkException(bundle.runMethodIsSynchronized(className)); + + if (isWorkMethodSynchronized(workClass, RELEASE_METHOD_NAME)) + throw new WorkException(bundle.releaseMethodIsSynchronized(className)); + + validatedWork.add(className); + } + } + + /** + * Checks, if Work implementation class method is synchronized + * @param workClass - implementation class + * @param methodName - could be "run" or "release" + * @return true, if method is synchronized, false elsewhere + */ + private boolean isWorkMethodSynchronized(Class workClass, String methodName) + { + try + { + Method method = SecurityActions.getMethod(workClass, methodName, new Class[0]); + if (Modifier.isSynchronized(method.getModifiers())) + return true; + } + catch (NoSuchMethodException e) + { + //Never happens, Work implementation should have these methods + } + + return false; + } + + /** + * Checks work completed status. + * @param wrapper work wrapper instance + * @throws {@link WorkException} if work is completed with an exception + */ + private void checkWorkCompletionException(WorkWrapper wrapper) throws WorkException + { + if (wrapper.getWorkException() != null) + { + log.tracef("Exception %s for %s", wrapper.getWorkException(), this); + + deltaWorkFailed(); + + throw wrapper.getWorkException(); + } + + deltaWorkSuccessful(); + } + + /** + * Setup work context's of the given work instance. + * + * @param wrapper The work wrapper instance + * @param workListener The work listener + * @throws WorkCompletedException if any work context related exceptions occurs + * @throws WorkException if any exception occurs + */ + private void setup(WorkWrapper wrapper, WorkListener workListener) throws WorkCompletedException, WorkException + { + log.tracef("Setting up work: %s, work listener: %s", wrapper, workListener); + + Work work = wrapper.getWork(); + + if (resourceAdapter != null) + { + if (SecurityActions.getClassLoader(work.getClass()) instanceof WorkClassLoader) + { + WorkClassLoader wcl = (WorkClassLoader)SecurityActions.getClassLoader(work.getClass()); + ResourceAdapterClassLoader racl = + new ResourceAdapterClassLoader(SecurityActions.getClassLoader(resourceAdapter.getClass()), + wcl); + + wcl.setResourceAdapterClassLoader(racl); + } + if (work instanceof ResourceAdapterAssociation) + { + try + { + ResourceAdapterAssociation raa = (ResourceAdapterAssociation)work; + raa.setResourceAdapter(resourceAdapter); + } + catch (Throwable t) + { + throw new WorkException(bundle.resourceAdapterAssociationFailed(work.getClass().getName()), t); + } + } + } + + //If work is an instanceof WorkContextProvider + if (work instanceof WorkContextProvider) + { + WorkContextProvider wcProvider = (WorkContextProvider) work; + List contexts = wcProvider.getWorkContexts(); + + if (contexts != null && contexts.size() > 0) + { + boolean isTransactionContext = false; + boolean isSecurityContext = false; + boolean isHintcontext = false; + + for (WorkContext context : contexts) + { + Class contextType = null; + + // Get supported work context class + contextType = getSupportedWorkContextClass(context.getClass()); + + // Not supported + if (contextType == null) + { + if (log.isTraceEnabled()) + { + log.tracef("Not supported work context class : %s", context.getClass().getName()); + } + + WorkCompletedException wce = + new WorkCompletedException(bundle.unsupportedWorkContextClass(context.getClass().getName()), + WorkContextErrorCodes.UNSUPPORTED_CONTEXT_TYPE); + + fireWorkContextSetupFailed(context, WorkContextErrorCodes.UNSUPPORTED_CONTEXT_TYPE, + workListener, work, wce); + + throw wce; + } + // Duplicate checks + else + { + // TransactionContext duplicate + if (isTransactionContext(contextType)) + { + if (isTransactionContext) + { + if (log.isTraceEnabled()) + { + log.tracef("Duplicate transaction work context : %s", context.getClass().getName()); + } + + WorkCompletedException wce = + new WorkCompletedException(bundle.duplicateTransactionWorkContextClass(context.getClass() + .getName()), WorkContextErrorCodes.DUPLICATE_CONTEXTS); + + fireWorkContextSetupFailed(context, WorkContextErrorCodes.DUPLICATE_CONTEXTS, + workListener, work, wce); + + throw wce; + } + else + { + isTransactionContext = true; + } + } + // SecurityContext duplicate + else if (isSecurityContext(contextType)) + { + if (isSecurityContext) + { + if (log.isTraceEnabled()) + { + log.tracef("Duplicate security work context : %s", context.getClass().getName()); + } + + WorkCompletedException wce = + new WorkCompletedException(bundle.duplicateSecurityWorkContextClass(context.getClass() + .getName()), WorkContextErrorCodes.DUPLICATE_CONTEXTS); + + fireWorkContextSetupFailed(context, WorkContextErrorCodes.DUPLICATE_CONTEXTS, + workListener, work, wce); + + throw wce; + } + else + { + isSecurityContext = true; + } + } + // HintContext duplicate + else if (isHintContext(contextType)) + { + if (isHintcontext) + { + if (log.isTraceEnabled()) + { + log.tracef("Duplicate hint work context : %s", context.getClass().getName()); + } + + WorkCompletedException wce = + new WorkCompletedException(bundle.duplicateHintWorkContextClass(context.getClass() + .getName()), WorkContextErrorCodes.DUPLICATE_CONTEXTS); + + fireWorkContextSetupFailed(context, WorkContextErrorCodes.DUPLICATE_CONTEXTS, + workListener, work, wce); + + throw wce; + } + else + { + isHintcontext = true; + } + } + } + + // Add workcontext instance to the work + wrapper.addWorkContext(contextType, context); + } + } + } + } + + /** + * Calls listener with given error code. + * @param workContext work context listener + * @param errorCode error code + * @param workListener work listener + * @param work work instance + * @param exception exception + */ + private void fireWorkContextSetupFailed(Object workContext, String errorCode, + WorkListener workListener, Work work, WorkException exception) + { + if (workListener != null) + { + WorkEvent event = new WorkEvent(this, WorkEvent.WORK_STARTED, work, null); + workListener.workStarted(event); + } + + if (workContext instanceof WorkContextLifecycleListener) + { + WorkContextLifecycleListener listener = (WorkContextLifecycleListener) workContext; + listener.contextSetupFailed(errorCode); + } + + if (workListener != null) + { + WorkEvent event = new WorkEvent(this, WorkEvent.WORK_COMPLETED, work, exception); + workListener.workCompleted(event); + } + } + + /** + * Returns true if contexts is a transaction context. + * + * @param workContextType context type + * @return true if contexts is a transaction context + */ + private boolean isTransactionContext(Class workContextType) + { + if (workContextType.isAssignableFrom(TransactionContext.class)) + { + return true; + } + + return false; + } + + /** + * Returns true if contexts is a security context. + * + * @param workContextType context type + * @return true if contexts is a security context + */ + private boolean isSecurityContext(Class workContextType) + { + if (workContextType.isAssignableFrom(SecurityContext.class)) + { + return true; + } + + return false; + } + + /** + * Returns true if contexts is a hint context. + * + * @param workContextType context type + * @return true if contexts is a hint context + */ + private boolean isHintContext(Class workContextType) + { + if (workContextType.isAssignableFrom(HintsContext.class)) + { + return true; + } + + return false; + } + + /** + * Returns work context class if given work context is supported by server, + * returns null instance otherwise. + * + * @param work context class + * @param adaptorWorkContext adaptor supplied work context class + * @return work context class + */ + @SuppressWarnings("unchecked") + private Class getSupportedWorkContextClass(Class adaptorWorkContext) + { + for (Class supportedWorkContext : SUPPORTED_WORK_CONTEXT_CLASSES) + { + // Assignable or not + if (supportedWorkContext.isAssignableFrom(adaptorWorkContext)) + { + Class clz = adaptorWorkContext; + + while (clz != null) + { + // Supported by the server + if (clz.equals(supportedWorkContext)) + { + return clz; + } + + clz = clz.getSuperclass(); + } + } + } + + return null; + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append(getClass().getName()).append("@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[id=").append(getId()); + sb.append(" name=").append(name); + sb.append(" specCompliant=").append(specCompliant); + sb.append(" shortRunningExecutor=").append(shortRunningExecutor); + sb.append(" longRunningExecutor=").append(longRunningExecutor); + sb.append(" xaTerminator=").append(xaTerminator); + sb.append(" validatedWork=").append(validatedWork); + sb.append(" callbackSecurity=").append(callbackSecurity); + sb.append(" securityIntegration=").append(securityIntegration); + sb.append(" resourceAdapter=").append(resourceAdapter); + sb.append(" shutdown=").append(shutdown); + sb.append(" activeWorkWrappers=["); + synchronized (activeWorkWrappers) + { + if (activeWorkWrappers.size() > 0) + { + Iterator it = activeWorkWrappers.iterator(); + + while (it.hasNext()) + { + WorkWrapper ww = it.next(); + sb.append("WorkWrapper@").append(Integer.toHexString(System.identityHashCode(ww))); + + if (it.hasNext()) + sb.append(", "); + } + } + } + sb.append("]"); + + sb.append(" statistics=").append(statistics); + + toString(sb); + + sb.append("]"); + + return sb.toString(); + } + + /** + * Additional string representation + * @param sb The string builder + */ + public void toString(StringBuilder sb) + { + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerShutdown.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerShutdown.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerShutdown.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,51 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2014, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import org.jboss.jca.core.api.workmanager.WorkManager; + +/** + * Shutdown a WorkManager + * @author Jesper Pedersen + */ +class WorkManagerShutdown implements Runnable +{ + private WorkManager wm; + + /** + * Constructor + * @param wm The work manager + */ + WorkManagerShutdown(WorkManager wm) + { + this.wm = wm; + } + + /** + * {@inheritDoc} + */ + public void run() + { + wm.shutdown(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerStatisticsImpl.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerStatisticsImpl.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerStatisticsImpl.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,261 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import org.jboss.jca.core.api.workmanager.WorkManagerStatistics; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * The JBoss work manager statistics implementation + */ +public class WorkManagerStatisticsImpl implements WorkManagerStatistics +{ + /** Active */ + private AtomicInteger active; + + /** Successful */ + private AtomicInteger successful; + + /** Failed */ + private AtomicInteger failed; + + /** DoWork: Accepted */ + private AtomicInteger doWorkAccepted; + + /** DoWork: Rejected */ + private AtomicInteger doWorkRejected; + + /** ScheduleWork: Accepted */ + private AtomicInteger scheduleWorkAccepted; + + /** ScheduleWork: Rejected */ + private AtomicInteger scheduleWorkRejected; + + /** StartWork: Accepted */ + private AtomicInteger startWorkAccepted; + + /** StartWork: Rejected */ + private AtomicInteger startWorkRejected; + + /** + * Constructor + */ + public WorkManagerStatisticsImpl() + { + active = new AtomicInteger(0); + successful = new AtomicInteger(0); + failed = new AtomicInteger(0); + doWorkAccepted = new AtomicInteger(0); + doWorkRejected = new AtomicInteger(0); + scheduleWorkAccepted = new AtomicInteger(0); + scheduleWorkRejected = new AtomicInteger(0); + startWorkAccepted = new AtomicInteger(0); + startWorkRejected = new AtomicInteger(0); + } + + /** + * {@inheritDoc} + */ + public int getWorkActive() + { + return active.get(); + } + + /** + * Set the number of active work instances + * @param v The value + */ + void setWorkActive(int v) + { + active.set(v); + } + + /** + * {@inheritDoc} + */ + public int getWorkSuccessful() + { + return successful.get(); + } + + /** + * Delta work successful + */ + void deltaWorkSuccessful() + { + successful.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getWorkFailed() + { + return failed.get(); + } + + /** + * Delta work failed + */ + void deltaWorkFailed() + { + failed.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getDoWorkAccepted() + { + return doWorkAccepted.get(); + } + + /** + * Delta doWork accepted + */ + void deltaDoWorkAccepted() + { + doWorkAccepted.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getDoWorkRejected() + { + return doWorkRejected.get(); + } + + /** + * Delta doWork rejected + */ + void deltaDoWorkRejected() + { + doWorkRejected.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getScheduleWorkAccepted() + { + return scheduleWorkAccepted.get(); + } + + /** + * Delta scheduleWork accepted + */ + void deltaScheduleWorkAccepted() + { + scheduleWorkAccepted.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getScheduleWorkRejected() + { + return scheduleWorkRejected.get(); + } + + /** + * Delta scheduleWork rejected + */ + void deltaScheduleWorkRejected() + { + scheduleWorkRejected.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getStartWorkAccepted() + { + return startWorkAccepted.get(); + } + + /** + * Delta startWork accepted + */ + void deltaStartWorkAccepted() + { + startWorkAccepted.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public int getStartWorkRejected() + { + return startWorkRejected.get(); + } + + /** + * Delta startWork rejected + */ + void deltaStartWorkRejected() + { + startWorkRejected.incrementAndGet(); + } + + /** + * {@inheritDoc} + */ + public synchronized void clear() + { + active.set(0); + successful.set(0); + failed.set(0); + doWorkAccepted.set(0); + doWorkRejected.set(0); + scheduleWorkAccepted.set(0); + scheduleWorkRejected.set(0); + startWorkAccepted.set(0); + startWorkRejected.set(0); + } + + /** + * String representation + * @return The string + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append("WorkManagerStatistics@").append(Integer.toHexString(System.identityHashCode(this))); + sb.append("[active=").append(getWorkActive()); + sb.append(" successful=").append(getWorkSuccessful()); + sb.append(" failed=").append(getWorkFailed()); + sb.append(" doWorkAccepted=").append(getDoWorkAccepted()); + sb.append(" doWorkRejected=").append(getDoWorkRejected()); + sb.append(" scheduleWorkAccepted=").append(getScheduleWorkAccepted()); + sb.append(" scheduleWorkRejected=").append(getScheduleWorkRejected()); + sb.append(" startWorkAccepted=").append(getStartWorkAccepted()); + sb.append(" startWorkRejected=").append(getStartWorkRejected()); + sb.append("]"); + + return sb.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerUtil.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerUtil.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkManagerUtil.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,172 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import org.jboss.jca.core.api.workmanager.DistributableContext; + +import java.io.Serializable; +import java.util.Iterator; +import java.util.List; + +import javax.resource.spi.work.DistributableWork; +import javax.resource.spi.work.HintsContext; +import javax.resource.spi.work.Work; +import javax.resource.spi.work.WorkContext; +import javax.resource.spi.work.WorkContextProvider; + +/** + * Utility methods for the WorkManager + * + * @author Stefano Maestri + * @author Jesper Pedersen + */ +public class WorkManagerUtil +{ + /** + * + * Utility method to decide if a work will have to run under long running thread pool + * + * @param work the work + * @return true if long running thread pool is required + */ + public static boolean isLongRunning(Work work) + { + if (work != null && work instanceof WorkContextProvider) + { + WorkContextProvider wcProvider = (WorkContextProvider) work; + List contexts = wcProvider.getWorkContexts(); + + if (contexts != null && contexts.size() > 0) + { + boolean found = false; + Iterator it = contexts.iterator(); + while (!found && it.hasNext()) + { + WorkContext wc = it.next(); + if (wc instanceof HintsContext) + { + HintsContext hc = (HintsContext) wc; + if (hc.getHints().containsKey(HintsContext.LONGRUNNING_HINT)) + { + Serializable value = hc.getHints().get(HintsContext.LONGRUNNING_HINT); + if (value != null) + { + if (value instanceof String) + { + return Boolean.valueOf((String)value); + } + else if (value instanceof Boolean) + { + return ((Boolean)value).booleanValue(); + } + } + else + { + // Assume true + return true; + } + } + } + } + } + } + + return false; + } + + /** + * Get should distribute override + * @param work The work instance + * @return The override, if none return null + */ + public static Boolean getShouldDistribute(DistributableWork work) + { + if (work != null && work instanceof WorkContextProvider) + { + List contexts = ((WorkContextProvider)work).getWorkContexts(); + if (contexts != null) + { + for (WorkContext wc : contexts) + { + if (wc instanceof DistributableContext) + { + DistributableContext dc = (DistributableContext)wc; + return dc.getDistribute(); + } + else if (wc instanceof HintsContext) + { + HintsContext hc = (HintsContext)wc; + if (hc.getHints().keySet().contains(DistributableContext.DISTRIBUTE)) + { + Serializable value = hc.getHints().get(DistributableContext.DISTRIBUTE); + if (value != null && value instanceof Boolean) + { + return (Boolean)value; + } + } + } + } + } + } + + return null; + } + + /** + * Get explicit work manager override + * @param work The work instance + * @return The override, if none return null + */ + public static String getWorkManager(DistributableWork work) + { + if (work != null && work instanceof WorkContextProvider) + { + List contexts = ((WorkContextProvider)work).getWorkContexts(); + if (contexts != null) + { + for (WorkContext wc : contexts) + { + if (wc instanceof DistributableContext) + { + DistributableContext dc = (DistributableContext)wc; + return dc.getWorkManager(); + } + else if (wc instanceof HintsContext) + { + HintsContext hc = (HintsContext)wc; + if (hc.getHints().keySet().contains(DistributableContext.WORKMANAGER)) + { + Serializable value = hc.getHints().get(DistributableContext.WORKMANAGER); + if (value != null && value instanceof String) + { + return (String)value; + } + } + } + } + } + } + + return null; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkObjectInputStream.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkObjectInputStream.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkObjectInputStream.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,92 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectStreamClass; +import java.io.StreamCorruptedException; + +/** + * Work object input stream + * @author Jesper Pedersen + */ +public class WorkObjectInputStream extends ObjectInputStream +{ + /** The classloader to use */ + private WorkClassLoader wcl; + + /** + * Constructor + * @param is The input stream + * @exception StreamCorruptedException - if the stream header is incorrect + * @exception IOException - if an I/O error occurs while reading stream header + */ + public WorkObjectInputStream(InputStream is) throws StreamCorruptedException, IOException + { + this(is, null); + } + + /** + * Constructor + * @param is The input stream + * @param wcl The work class loader + * @exception StreamCorruptedException - if the stream header is incorrect + * @exception IOException - if an I/O error occurs while reading stream header + */ + public WorkObjectInputStream(InputStream is, WorkClassLoader wcl) throws StreamCorruptedException, IOException + { + super(is); + this.wcl = wcl; + } + + /** + * Set the work class loader + * @param v The value + */ + public void setWorkClassLoader(WorkClassLoader v) + { + wcl = v; + } + + /** + * {@inheritDoc} + */ + @Override + public Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException + { + if (wcl != null) + { + try + { + return wcl.loadClass(desc.getName()); + } + catch (Throwable t) + { + // Fallback to super + } + } + return super.resolveClass(desc); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkWrapper.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkWrapper.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/WorkWrapper.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,602 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2010, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.security.SecurityIntegration; + +import java.security.Principal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CountDownLatch; + +import javax.resource.spi.work.ExecutionContext; +import javax.resource.spi.work.TransactionContext; +import javax.resource.spi.work.Work; +import javax.resource.spi.work.WorkCompletedException; +import javax.resource.spi.work.WorkContext; +import javax.resource.spi.work.WorkContextErrorCodes; +import javax.resource.spi.work.WorkContextLifecycleListener; +import javax.resource.spi.work.WorkEvent; +import javax.resource.spi.work.WorkException; +import javax.resource.spi.work.WorkListener; +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.message.callback.CallerPrincipalCallback; +import javax.security.auth.message.callback.GroupPrincipalCallback; +import javax.transaction.xa.Xid; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * Wraps the resource adapter's work. + * + * @author Jesper Pedersen + * @version $Revision: 71538 $ + */ +public class WorkWrapper implements Runnable +{ + /** The log */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + WorkWrapper.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** The work */ + private Work work; + + /** The execution context */ + private ExecutionContext executionContext; + + /**If work is an instance of WorkContextProvider, it may contain WorkContext instances */ + private Map, WorkContext> workContexts; + + /** the work listener */ + private WorkListener workListener; + + /** The work manager */ + protected WorkManagerImpl workManager; + + /** The security integration */ + protected SecurityIntegration securityIntegration; + + /** The start time */ + private long startTime; + + /** Any exception */ + private WorkException exception; + + /** Started latch */ + private CountDownLatch startedLatch; + + /** Completed latch */ + private CountDownLatch completedLatch; + + /** + * Create a new WorkWrapper + * + * @param workManager the work manager + * @param si The security integration + * @param work the work + * @param executionContext the execution context + * @param workListener the WorkListener + * @param startedLatch The latch for when work has started + * @param completedLatch The latch for when work has completed + * @param startTime The start time + * @throws IllegalArgumentException for null work, execution context or a negative start timeout + */ + public WorkWrapper(WorkManagerImpl workManager, + SecurityIntegration si, + Work work, + ExecutionContext executionContext, + WorkListener workListener, + CountDownLatch startedLatch, + CountDownLatch completedLatch, + long startTime) + { + super(); + + if (workManager == null) + throw new IllegalArgumentException("Null work manager"); + if (si == null) + throw new IllegalArgumentException("Null security integration"); + if (work == null) + throw new IllegalArgumentException("Null work"); + if (executionContext == null) + throw new IllegalArgumentException("Null execution context"); + + this.workManager = workManager; + this.securityIntegration = si; + this.work = work; + this.executionContext = executionContext; + this.workListener = workListener; + this.startedLatch = startedLatch; + this.completedLatch = completedLatch; + this.startTime = startTime; + this.workContexts = null; + } + + /** + * Get the work manager + * + * @return the work manager + */ + public org.jboss.jca.core.api.workmanager.WorkManager getWorkManager() + { + return workManager; + } + + /** + * Retrieve the work + * + * @return the work + */ + public Work getWork() + { + return work; + } + + /** + * Retrieve the exection context + * + * @return the execution context + */ + public ExecutionContext getExecutionContext() + { + return executionContext; + } + + /** + * Retrieve the work listener + * + * @return the WorkListener + */ + public WorkListener getWorkListener() + { + return workListener; + } + + /** + * Get any exception + * + * @return the exception or null if there is none + */ + public WorkException getWorkException() + { + return exception; + } + + /** + * Set work exception + * @param e The exception + */ + void setWorkException(WorkException e) + { + exception = e; + } + + /** + * Run + */ + public void run() + { + ClassLoader oldCL = SecurityActions.getThreadContextClassLoader(); + SecurityActions.setThreadContextClassLoader(work.getClass().getClassLoader()); + + org.jboss.jca.core.spi.security.SecurityContext oldSC = securityIntegration.getSecurityContext(); + + try + { + start(); + workManager.addWorkWrapper(this); + + if (startedLatch != null) + startedLatch.countDown(); + + runWork(); + + end(); + } + catch (Throwable t) + { + if (t instanceof WorkCompletedException) + { + exception = (WorkCompletedException) t; + } + else + { + exception = new WorkCompletedException(t.getMessage(), t); + } + + cancel(); + } + finally + { + workManager.removeWorkWrapper(this); + work.release(); + + if (workListener != null) + { + WorkEvent event = new WorkEvent(workManager, WorkEvent.WORK_COMPLETED, work, exception); + workListener.workCompleted(event); + } + + securityIntegration.setSecurityContext(oldSC); + SecurityActions.setThreadContextClassLoader(oldCL); + + if (startedLatch != null) + { + while (startedLatch.getCount() != 0) + startedLatch.countDown(); + } + + if (completedLatch != null) + completedLatch.countDown(); + + log.tracef("Executed work: %s", this); + } + } + + /** + * Start + * @throws WorkException for any error + */ + protected void start() throws WorkException + { + log.tracef("Starting work: %s", this); + + if (workListener != null) + { + long duration = System.currentTimeMillis() - startTime; + if (duration < 0) + duration = javax.resource.spi.work.WorkManager.UNKNOWN; + + WorkEvent event = new WorkEvent(workManager, WorkEvent.WORK_STARTED, work, null, duration); + workListener.workStarted(event); + } + + // Transaction setup + ExecutionContext ctx = getWorkContext(TransactionContext.class); + if (ctx == null) + { + ctx = getExecutionContext(); + } + + if (ctx != null) + { + Xid xid = ctx.getXid(); + if (xid != null) + { + //JBAS-4002 base value is in seconds as per the API, here we convert to millis + long timeout = (ctx.getTransactionTimeout() * 1000); + workManager.getXATerminator().registerWork(work, xid, timeout); + } + } + + // Fire complete for transaction context + fireWorkContextSetupComplete(ctx); + + // Security setup + javax.resource.spi.work.SecurityContext securityContext = + getWorkContext(javax.resource.spi.work.SecurityContext.class); + if (securityContext != null && workManager.getCallbackSecurity() != null) + { + log.tracef("Setting security context: %s", securityContext); + + try + { + // Security context + org.jboss.jca.core.spi.security.SecurityContext sc = null; + + // Setup callback handler + CallbackHandler cbh = null; + if (workManager.getCallbackSecurity() != null) + { + cbh = securityIntegration.createCallbackHandler(workManager.getCallbackSecurity()); + } + + if (cbh == null) + cbh = securityIntegration.createCallbackHandler(); + + // Subjects for execution environment + Subject executionSubject = null; + Subject serviceSubject = null; + + log.tracef("Callback security: %s", workManager.getCallbackSecurity()); + + if (securityIntegration.getSecurityContext() == null || + workManager.getCallbackSecurity().getDomain() != null) + { + String scDomain = workManager.getCallbackSecurity().getDomain(); + + log.tracef("Creating security context: %s", scDomain); + + if (scDomain == null || scDomain.trim().equals("")) + { + fireWorkContextSetupFailed(securityContext); + throw new WorkException(bundle.securityContextSetupFailedSinceCallbackSecurityDomainWasEmpty()); + } + + sc = securityIntegration.createSecurityContext(scDomain); + securityIntegration.setSecurityContext(sc); + } + else + { + sc = securityIntegration.getSecurityContext(); + + log.tracef("Using security context: %s", sc); + } + + executionSubject = sc.getAuthenticatedSubject(); + + if (executionSubject == null) + { + log.trace("Creating empty subject"); + + executionSubject = new Subject(); + } + + // Resource adapter callback + securityContext.setupSecurityContext(cbh, executionSubject, serviceSubject); + + if (workManager.getCallbackSecurity() != null) + { + List callbacks = new ArrayList(); + if (workManager.getCallbackSecurity().getDefaultPrincipal() != null) + { + Principal defaultPrincipal = workManager.getCallbackSecurity().getDefaultPrincipal(); + + log.tracef("Adding default principal: %s", defaultPrincipal); + + CallerPrincipalCallback cpc = + new CallerPrincipalCallback(executionSubject, defaultPrincipal); + + callbacks.add(cpc); + } + + if (workManager.getCallbackSecurity().getDefaultGroups() != null) + { + String[] defaultGroups = workManager.getCallbackSecurity().getDefaultGroups(); + + if (log.isTraceEnabled()) + log.tracef("Adding default groups: %s", Arrays.toString(defaultGroups)); + + GroupPrincipalCallback gpc = + new GroupPrincipalCallback(executionSubject, defaultGroups); + + callbacks.add(gpc); + } + + if (callbacks.size() > 0) + { + Callback[] cb = new Callback[callbacks.size()]; + cbh.handle(callbacks.toArray(cb)); + } + } + + log.tracef("Setting authenticated subject (%s) on security context (%s)", executionSubject, sc); + + // Set the authenticated subject + sc.setAuthenticatedSubject(executionSubject); + + // Fire complete for security context + fireWorkContextSetupComplete(securityContext); + } + catch (Throwable t) + { + log.securityContextSetupFailed(t.getMessage(), t); + fireWorkContextSetupFailed(securityContext); + throw new WorkException(bundle.securityContextSetupFailed(t.getMessage()), t); + } + } + else if (securityContext != null && workManager.getCallbackSecurity() == null) + { + log.securityContextSetupFailedCallbackSecurityNull(); + fireWorkContextSetupFailed(securityContext); + throw new WorkException(bundle.securityContextSetupFailedSinceCallbackSecurityWasNull()); + } + + if (ctx != null) + { + Xid xid = ctx.getXid(); + if (xid != null) + { + workManager.getXATerminator().startWork(work, xid); + } + } + + log.tracef("Started work: %s", this); + } + + /** + * Runs the work. + * + * @throws WorkCompletedException if there is an error completing work execution + */ + protected void runWork() throws WorkCompletedException + { + work.run(); + } + + /** + * End + */ + protected void end() + { + log.tracef("Ending work: %s", this); + + ExecutionContext ctx = getWorkContext(TransactionContext.class); + if (ctx == null) + { + ctx = getExecutionContext(); + } + + if (ctx != null) + { + Xid xid = ctx.getXid(); + if (xid != null) + { + workManager.getXATerminator().endWork(work, xid); + } + } + + log.tracef("Ended work: %s", this); + } + + /** + * Cancel + */ + protected void cancel() + { + log.tracef("Cancel work: %s", this); + + ExecutionContext ctx = getWorkContext(TransactionContext.class); + if (ctx == null) + { + ctx = getExecutionContext(); + } + + if (ctx != null) + { + Xid xid = ctx.getXid(); + if (xid != null) + { + workManager.getXATerminator().cancelWork(work, xid); + } + } + + log.tracef("Canceled work: %s", this); + } + + /** + * Returns work context instance. + * + * @param class type info + * @param workContextClass work context type + * @return work context instance + */ + public T getWorkContext(Class workContextClass) + { + T instance = null; + + if (workContexts != null && workContexts.containsKey(workContextClass)) + { + instance = workContextClass.cast(workContexts.get(workContextClass)); + } + + return instance; + } + + /** + * Adds new work context. + * + * @param workContext new work context + * @param workContextClass work context class + */ + public void addWorkContext(Class workContextClass, WorkContext workContext) + { + if (workContextClass == null) + { + throw new IllegalArgumentException("Work context class is null"); + } + + if (workContext == null) + { + throw new IllegalArgumentException("Work context is null"); + } + + if (workContexts == null) + { + workContexts = new HashMap, WorkContext>(1); + } + + log.tracef("Adding work context %s for %s", workContextClass, this); + + workContexts.put(workContextClass, workContext); + } + + /** + * Calls listener after work context is setted up. + * @param listener work context listener + */ + private void fireWorkContextSetupComplete(Object workContext) + { + if (workContext != null && workContext instanceof WorkContextLifecycleListener) + { + log.tracef("WorkContextSetupComplete(%s) for %s", workContext, this); + + WorkContextLifecycleListener listener = (WorkContextLifecycleListener)workContext; + listener.contextSetupComplete(); + } + } + + /** + * Calls listener if setup failed + * @param listener work context listener + */ + private void fireWorkContextSetupFailed(Object workContext) + { + if (workContext != null && workContext instanceof WorkContextLifecycleListener) + { + log.tracef("WorkContextSetupFailed(%s) for %s", workContext, this); + + WorkContextLifecycleListener listener = (WorkContextLifecycleListener)workContext; + listener.contextSetupFailed(WorkContextErrorCodes.CONTEXT_SETUP_FAILED); + } + } + + /** + * String representation + * @return The string + */ + public String toString() + { + StringBuilder buffer = new StringBuilder(100); + buffer.append("WorkWrapper@").append(Integer.toHexString(System.identityHashCode(this))); + buffer.append("[workManger=").append(workManager); + buffer.append(" work=").append(work); + + if (executionContext != null && executionContext.getXid() != null) + { + buffer.append(" xid=").append(executionContext.getXid()); + buffer.append(" txTimeout=").append(executionContext.getTransactionTimeout()); + } + + buffer.append(" workListener=").append(workListener); + + buffer.append(" workContexts=").append(workContexts); + + buffer.append(" exception=").append(exception); + + buffer.append("]"); + + return buffer.toString(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/notification/AbstractNotificationListener.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/notification/AbstractNotificationListener.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/notification/AbstractNotificationListener.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,213 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager.notification; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.workmanager.Address; +import org.jboss.jca.core.spi.workmanager.notification.NotificationListener; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.jboss.logging.Logger; + +/** + * An abstract notification listener + * + * @author Jesper Pedersen + */ +public abstract class AbstractNotificationListener implements NotificationListener +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + AbstractNotificationListener.class.getName()); + + /** Short running */ + protected Map> shortRunning; + + /** Long running */ + protected Map> longRunning; + + /** + * Constructor + */ + public AbstractNotificationListener() + { + this.shortRunning = Collections.synchronizedMap(new HashMap>()); + this.longRunning = Collections.synchronizedMap(new HashMap>()); + } + + /** + * {@inheritDoc} + */ + public void join(Address address) + { + log.tracef("join(%s)", address); + + Map sr = shortRunning.get(address.getWorkManagerId()); + + if (sr == null) + sr = Collections.synchronizedMap(new HashMap()); + + sr.put(address, Long.valueOf(0)); + shortRunning.put(address.getWorkManagerId(), sr); + + Map lr = longRunning.get(address.getWorkManagerId()); + + if (lr == null) + lr = Collections.synchronizedMap(new HashMap()); + + lr.put(address, Long.valueOf(0)); + longRunning.put(address.getWorkManagerId(), lr); + } + + /** + * {@inheritDoc} + */ + public void leave(Address address) + { + log.tracef("leave(%s)", address); + + Map sr = shortRunning.get(address.getWorkManagerId()); + + if (sr != null) + { + sr.remove(address); + + if (sr.size() > 0) + { + shortRunning.put(address.getWorkManagerId(), sr); + } + else + { + shortRunning.remove(address.getWorkManagerId()); + } + } + + Map lr = longRunning.get(address.getWorkManagerId()); + + if (lr != null) + { + lr.remove(address); + + if (lr.size() > 0) + { + longRunning.put(address.getWorkManagerId(), lr); + } + else + { + longRunning.remove(address.getWorkManagerId()); + } + } + } + + /** + * {@inheritDoc} + */ + public void updateShortRunningFree(Address address, long free) + { + log.tracef("updateShortRunningFree(%s, %d)", address, free); + + Map sr = shortRunning.get(address.getWorkManagerId()); + + if (sr != null) + { + sr.put(address, Long.valueOf(free)); + shortRunning.put(address.getWorkManagerId(), sr); + } + } + + /** + * {@inheritDoc} + */ + public void updateLongRunningFree(Address address, long free) + { + log.tracef("updateLongRunningFree(%s, %d)", address, free); + + Map lr = longRunning.get(address.getWorkManagerId()); + + if (lr != null) + { + lr.put(address, Long.valueOf(free)); + longRunning.put(address.getWorkManagerId(), lr); + } + } + + + /** + * {@inheritDoc} + */ + public void deltaDoWorkAccepted() + { + } + + /** + * {@inheritDoc} + */ + public void deltaDoWorkRejected() + { + } + + /** + * {@inheritDoc} + */ + public void deltaStartWorkAccepted() + { + } + + /** + * {@inheritDoc} + */ + public void deltaStartWorkRejected() + { + } + + /** + * {@inheritDoc} + */ + public void deltaScheduleWorkAccepted() + { + } + + /** + * {@inheritDoc} + */ + public void deltaScheduleWorkRejected() + { + } + + /** + * {@inheritDoc} + */ + public void deltaWorkSuccessful() + { + } + + /** + * {@inheritDoc} + */ + public void deltaWorkFailed() + { + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/notification/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/notification/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/notification/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains implementations for the notification listener functionality. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,5 @@ + +This package contains the WorkManager implementation. +

+See chapter 10 of the JCA specification for more information. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/policy/AbstractPolicy.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/policy/AbstractPolicy.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/policy/AbstractPolicy.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,94 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager.policy; + +import org.jboss.jca.core.api.workmanager.DistributableContext; +import org.jboss.jca.core.api.workmanager.DistributedWorkManager; +import org.jboss.jca.core.spi.workmanager.policy.Policy; +import org.jboss.jca.core.workmanager.notification.AbstractNotificationListener; + +import java.io.Serializable; +import java.util.List; + +import javax.resource.spi.work.DistributableWork; +import javax.resource.spi.work.HintsContext; +import javax.resource.spi.work.WorkContext; +import javax.resource.spi.work.WorkContextProvider; + +/** + * An abstract policy + * + * @author Jesper Pedersen + */ +public abstract class AbstractPolicy extends AbstractNotificationListener implements Policy +{ + /** + * Constructor + */ + public AbstractPolicy() + { + } + + /** + * Get should distribute override + * @param work The work instance + * @return The override, if none return null + */ + protected Boolean getShouldDistribute(DistributableWork work) + { + if (work != null && work instanceof WorkContextProvider) + { + List contexts = ((WorkContextProvider)work).getWorkContexts(); + if (contexts != null) + { + for (WorkContext wc : contexts) + { + if (wc instanceof DistributableContext) + { + DistributableContext dc = (DistributableContext)wc; + return dc.getDistribute(); + } + else if (wc instanceof HintsContext) + { + HintsContext hc = (HintsContext)wc; + if (hc.getHints().keySet().contains(DistributableContext.DISTRIBUTE)) + { + Serializable value = hc.getHints().get(DistributableContext.DISTRIBUTE); + if (value != null && value instanceof Boolean) + { + return (Boolean)value; + } + } + } + } + } + } + + return null; + } + + /** + * {@inheritDoc} + */ + public abstract boolean shouldDistribute(DistributedWorkManager dwm, DistributableWork work); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/policy/Always.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/policy/Always.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/policy/Always.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,68 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager.policy; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.workmanager.DistributedWorkManager; +import org.jboss.jca.core.workmanager.WorkManagerUtil; + +import javax.resource.spi.work.DistributableWork; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * The always distribute policy + * + * @author Jesper Pedersen + */ +public class Always extends AbstractPolicy +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, Always.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** + * Constructor + */ + public Always() + { + } + + /** + * {@inheritDoc} + */ + public synchronized boolean shouldDistribute(DistributedWorkManager dwm, DistributableWork work) + { + log.tracef("Work=%s", work); + + Boolean override = WorkManagerUtil.getShouldDistribute(work); + if (override != null) + return override.booleanValue(); + + return true; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/policy/Never.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/policy/Never.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/policy/Never.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,68 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager.policy; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.workmanager.DistributedWorkManager; +import org.jboss.jca.core.workmanager.WorkManagerUtil; + +import javax.resource.spi.work.DistributableWork; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * The never distribute policy + * + * @author Jesper Pedersen + */ +public class Never extends AbstractPolicy +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, Never.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** + * Constructor + */ + public Never() + { + } + + /** + * {@inheritDoc} + */ + public synchronized boolean shouldDistribute(DistributedWorkManager dwm, DistributableWork work) + { + log.tracef("Work=%s", work); + + Boolean override = WorkManagerUtil.getShouldDistribute(work); + if (override != null) + return override.booleanValue(); + + return false; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/policy/WaterMark.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/policy/WaterMark.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/policy/WaterMark.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,96 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager.policy; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.workmanager.DistributedWorkManager; +import org.jboss.jca.core.workmanager.WorkManagerUtil; + +import javax.resource.spi.work.DistributableWork; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * The always distribute policy + * + * @author Jesper Pedersen + */ +public class WaterMark extends AbstractPolicy +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, WaterMark.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + private int watermark = 0; + + /** + * Constructor + */ + public WaterMark() + { + } + + /** + * {@inheritDoc} + */ + @Override + public synchronized boolean shouldDistribute(DistributedWorkManager dwm, DistributableWork work) + { + log.tracef("Work=%s", work); + + Boolean override = WorkManagerUtil.getShouldDistribute(work); + if (override != null) + return override.booleanValue(); + + if (WorkManagerUtil.isLongRunning(work) && dwm.getLongRunningThreadPool() != null) + { + return !(dwm.getLongRunningThreadPool().getNumberOfFreeThreads() > watermark); + } + else + { + return !(dwm.getShortRunningThreadPool().getNumberOfFreeThreads() > watermark); + } + } + + /** + * Get the water mark value + * @return The value + */ + public int getWatermark() + { + return watermark; + } + + /** + * Set the water mark value + * @param value The value + */ + public void setWatermark(int value) + { + this.watermark = value; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/policy/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/policy/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/policy/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the policies for the distributed work manager. + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/selector/AbstractSelector.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/selector/AbstractSelector.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/selector/AbstractSelector.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,84 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager.selector; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.workmanager.Address; +import org.jboss.jca.core.spi.workmanager.selector.Selector; +import org.jboss.jca.core.workmanager.WorkManagerUtil; +import org.jboss.jca.core.workmanager.notification.AbstractNotificationListener; + +import java.util.HashMap; +import java.util.Map; + +import javax.resource.spi.work.DistributableWork; + +import org.jboss.logging.Logger; + +/** + * Common base class for selector implementations + */ +public abstract class AbstractSelector extends AbstractNotificationListener implements Selector +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, + AbstractSelector.class.getName()); + + /** + * Constructor + */ + public AbstractSelector() + { + } + + /** + * Get explicit work manager override + * @param wmId The work manager identifier + * @param work The work instance + * @return The selection map + */ + protected Map getSelectionMap(String wmId, DistributableWork work) + { + log.tracef("getSelectionMap(%s, %s)", wmId, work); + log.tracef("ShortRunning: %s", shortRunning); + log.tracef("LongRunning: %s", longRunning); + + Map sorted = null; + + if (WorkManagerUtil.isLongRunning(work)) + { + if (longRunning.get(wmId) != null) + sorted = new HashMap(longRunning.get(wmId)); + } + + if (sorted == null && shortRunning.get(wmId) != null) + sorted = new HashMap(shortRunning.get(wmId)); + + return sorted; + } + + /** + * {@inheritDoc} + */ + public abstract Address selectDistributedWorkManager(Address own, DistributableWork work); +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/selector/FirstAvailable.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/selector/FirstAvailable.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/selector/FirstAvailable.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,103 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager.selector; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.workmanager.Address; + +import java.util.Map; + +import javax.resource.spi.work.DistributableWork; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * The first available selector + * + * @author Jesper Pedersen + */ +public class FirstAvailable extends AbstractSelector +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, FirstAvailable.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** + * Constructor + */ + public FirstAvailable() + { + } + + /** + * {@inheritDoc} + */ + public synchronized Address selectDistributedWorkManager(Address own, DistributableWork work) + { + log.tracef("Own: %s, Work: %s", own, work); + + /* + TODO + + String value = getWorkManager(work); + if (value != null) + { + if (trace) + log.tracef("WorkManager: %s", value); + + return value; + } + */ + + Map selectionMap = getSelectionMap(own.getWorkManagerId(), work); + // No sorting needed + + log.tracef("SelectionMap: %s", selectionMap); + + if (selectionMap != null) + { + for (Map.Entry entry : selectionMap.entrySet()) + { + Address id = entry.getKey(); + if (!own.equals(id)) + { + Long free = entry.getValue(); + if (free != null && free.longValue() > 0) + { + log.tracef("WorkManager: %s", id); + + return id; + } + } + } + } + + log.tracef("WorkManager: None"); + + return null; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/selector/MaxFreeThreads.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/selector/MaxFreeThreads.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/selector/MaxFreeThreads.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,102 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager.selector; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.workmanager.Address; + +import java.util.Map; + +import javax.resource.spi.work.DistributableWork; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * The max free threads selector + * + * @author Jesper Pedersen + */ +public class MaxFreeThreads extends AbstractSelector +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, MaxFreeThreads.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** + * Constructor + */ + public MaxFreeThreads() + { + } + + /** + * {@inheritDoc} + */ + @Override + public synchronized Address selectDistributedWorkManager(Address own, DistributableWork work) + { + /* + TODO + String value = getWorkManager(work); + if (value != null) + { + if (trace) + log.tracef("WorkManager: %s", value); + + return value; + } + */ + + Map selectionMap = getSelectionMap(own.getWorkManagerId(), work); + Address result = null; + long freeThread = 0L; + + if (selectionMap != null) + { + for (Map.Entry entry : selectionMap.entrySet()) + { + Address id = entry.getKey(); + if (!own.equals(id)) + { + Long free = entry.getValue(); + if (free != null && free.longValue() > 0) + { + if (free.longValue() > freeThread) + { + result = id; + freeThread = free.longValue(); + } + } + } + } + } + + log.tracef("WorkManager: %s (%s)", result, freeThread); + + return result; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/selector/PingTime.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/selector/PingTime.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/selector/PingTime.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,102 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager.selector; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.workmanager.Address; + +import java.util.Map; + +import javax.resource.spi.work.DistributableWork; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * The ping time selector + * + * @author Jesper Pedersen + */ +public class PingTime extends AbstractSelector +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, PingTime.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** + * Constructor + */ + public PingTime() + { + } + + /** + * {@inheritDoc} + */ + public Address selectDistributedWorkManager(Address own, DistributableWork work) + { + /* + TODO + String value = getWorkManager(work); + if (value != null) + { + if (trace) + log.tracef("WorkManager: %s", value); + + return value; + } + */ + + Map selectionMap = getSelectionMap(own.getWorkManagerId(), work); + Address result = null; + long pingTime = Long.MAX_VALUE; + + if (selectionMap != null) + { + for (Map.Entry entry : selectionMap.entrySet()) + { + Address id = entry.getKey(); + if (!own.equals(id)) + { + Long free = entry.getValue(); + if (free != null && free.longValue() > 0) + { + long l = Long.MAX_VALUE; // TODO dwm.getTransport().ping(id); + if (l < pingTime) + { + result = id; + pingTime = l; + } + } + } + } + } + + log.tracef("WorkManager: %s (%s)", result, pingTime); + + return result; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/selector/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/selector/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/selector/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the selectors for the distributed work manager + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/AbstractRemoteTransport.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/AbstractRemoteTransport.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/AbstractRemoteTransport.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,1173 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.workmanager.transport.remote; + +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.workmanager.DistributedWorkManager; +import org.jboss.jca.core.api.workmanager.DistributedWorkManagerStatisticsValues; +import org.jboss.jca.core.api.workmanager.StatisticsExecutor; +import org.jboss.jca.core.api.workmanager.WorkManager; +import org.jboss.jca.core.spi.workmanager.Address; +import org.jboss.jca.core.spi.workmanager.notification.NotificationListener; +import org.jboss.jca.core.spi.workmanager.transport.Transport; +import org.jboss.jca.core.workmanager.ClassBundle; +import org.jboss.jca.core.workmanager.ClassBundleFactory; +import org.jboss.jca.core.workmanager.WorkManagerCoordinator; +import org.jboss.jca.core.workmanager.WorkManagerEvent; +import org.jboss.jca.core.workmanager.WorkManagerEventQueue; +import org.jboss.jca.core.workmanager.transport.remote.ProtocolMessages.Request; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ExecutorService; + +import javax.resource.spi.work.DistributableWork; +import javax.resource.spi.work.WorkException; + +import org.jboss.logging.Logger; + +/** + * An abstract transport for remote communication + * + * @author Stefano Maestri + * @author Jesper Pedersen + * @param the type + */ +public abstract class AbstractRemoteTransport implements Transport +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, AbstractRemoteTransport.class.getName()); + + /** The identifier of the transport */ + private String id; + + /** The kernel executorService*/ + protected ExecutorService executorService; + + /** The nodes */ + protected Map nodes; + + /** + * Constructor + */ + public AbstractRemoteTransport() + { + this.executorService = null; + this.nodes = Collections.synchronizedMap(new HashMap()); + } + + /** + * {@inheritDoc} + */ + public String getId() + { + return id; + } + + /** + * Set the identifier + * @param id The value + */ + public void setId(String id) + { + this.id = id; + } + + /** + * {@inheritDoc} + */ + @Override + public long ping(Address address) + { + log.tracef("PING(%s)", address); + + if (address.getTransportId() == null || getId().equals(address.getTransportId())) + return localPing(); + + long start = System.currentTimeMillis(); + try + { + T addr = nodes.get(address); + sendMessage(addr, Request.PING); + } + catch (WorkException e1) + { + if (log.isDebugEnabled()) + { + log.debug("Error", e1); + } + return Long.MAX_VALUE; + } + + return System.currentTimeMillis() - start; + } + + @Override + public long getShortRunningFree(Address address) + { + log.tracef("GET_SHORT_RUNNING_FREE(%s)", address); + + if (address.getTransportId() == null || getId().equals(address.getTransportId())) + return localGetShortRunningFree(address); + + try + { + T addr = nodes.get(address); + return (long)sendMessage(addr, Request.GET_SHORTRUNNING_FREE, address); + } + catch (WorkException e1) + { + if (log.isDebugEnabled()) + { + log.debug("Error", e1); + } + return 0L; + } + } + + @Override + public long getLongRunningFree(Address address) + { + log.tracef("GET_LONGRUNNING_FREE(%s)", address); + + if (address.getTransportId() == null || getId().equals(address.getTransportId())) + return localGetLongRunningFree(address); + + try + { + T addr = nodes.get(address); + return (long)sendMessage(addr, Request.GET_LONGRUNNING_FREE, address); + } + catch (WorkException e1) + { + if (log.isDebugEnabled()) + { + log.debug("Error", e1); + } + return 0L; + } + } + + @Override + public void updateShortRunningFree(Address address, long freeCount) + { + log.tracef("UPDATE_SHORT_RUNNING_FREE(%s, %d)", address, freeCount); + + localUpdateShortRunningFree(address, freeCount); + + if (address.getTransportId() != null && getId().equals(address.getTransportId())) + { + for (Entry entry : nodes.entrySet()) + { + Address a = entry.getKey(); + if (!getId().equals(a.getTransportId())) + { + try + { + sendMessage(entry.getValue(), Request.UPDATE_SHORTRUNNING_FREE, address, freeCount); + } + catch (WorkException e1) + { + if (log.isDebugEnabled()) + { + log.debug("Error", e1); + } + } + } + } + } + } + + @Override + public void updateLongRunningFree(Address address, long freeCount) + { + log.tracef("UPDATE_LONG_RUNNING_FREE(%s, %d)", address, freeCount); + + localUpdateLongRunningFree(address, freeCount); + + if (address.getTransportId() != null && getId().equals(address.getTransportId())) + { + for (Entry entry : nodes.entrySet()) + { + Address a = entry.getKey(); + if (!getId().equals(a.getTransportId())) + { + try + { + sendMessage(entry.getValue(), Request.UPDATE_LONGRUNNING_FREE, address, freeCount); + } + catch (WorkException e1) + { + if (log.isDebugEnabled()) + { + log.debug("Error", e1); + } + } + } + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public DistributedWorkManagerStatisticsValues getDistributedStatistics(Address address) + { + log.tracef("GET_DISTRIBUTED_STATISTICS(%s)", address); + + if (address.getTransportId() == null || getId().equals(address.getTransportId())) + return localGetDistributedStatistics(address); + + try + { + T addr = nodes.get(address); + return (DistributedWorkManagerStatisticsValues)sendMessage(addr, Request.GET_DISTRIBUTED_STATISTICS, address); + } + catch (WorkException e1) + { + if (log.isDebugEnabled()) + { + log.debug("Error", e1); + } + return null; + } + } + + /** + * {@inheritDoc} + */ + @Override + public void clearDistributedStatistics(Address address) + { + log.tracef("CLEAR_DISTRIBUTED_STATISTICS(%s)", address); + + if (!getId().equals(address.getTransportId())) + localClearDistributedStatistics(address); + + if (address.getTransportId() != null && getId().equals(address.getTransportId())) + { + for (Entry entry : nodes.entrySet()) + { + Address a = entry.getKey(); + if (!getId().equals(a.getTransportId())) + { + try + { + sendMessage(entry.getValue(), Request.CLEAR_DISTRIBUTED_STATISTICS, address); + } + catch (WorkException e1) + { + if (log.isDebugEnabled()) + { + log.debug("Error", e1); + } + } + } + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void deltaDoWorkAccepted(Address address) + { + log.tracef("DELTA_DOWORK_ACCEPTED(%s)", address); + + if (address.getTransportId() != null && !getId().equals(address.getTransportId())) + { + try + { + T addr = nodes.get(address); + sendMessage(addr, Request.DELTA_DOWORK_ACCEPTED, address); + } + catch (WorkException e1) + { + if (log.isDebugEnabled()) + { + log.debug("Error", e1); + } + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void deltaDoWorkRejected(Address address) + { + log.tracef("DELTA_DOWORK_REJECTED(%s)", address); + + if (address.getTransportId() != null && !getId().equals(address.getTransportId())) + { + try + { + T addr = nodes.get(address); + sendMessage(addr, Request.DELTA_DOWORK_REJECTED, address); + } + catch (WorkException e1) + { + if (log.isDebugEnabled()) + { + log.debug("Error", e1); + } + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void deltaStartWorkAccepted(Address address) + { + log.tracef("DELTA_STARTWORK_ACCEPTED(%s)", address); + + if (address.getTransportId() != null && !getId().equals(address.getTransportId())) + { + try + { + T addr = nodes.get(address); + sendMessage(addr, Request.DELTA_STARTWORK_ACCEPTED, address); + } + catch (WorkException e1) + { + if (log.isDebugEnabled()) + { + log.debug("Error", e1); + } + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void deltaStartWorkRejected(Address address) + { + log.tracef("DELTA_STARTWORK_REJECTED(%s)", address); + + if (address.getTransportId() != null && !getId().equals(address.getTransportId())) + { + try + { + T addr = nodes.get(address); + sendMessage(addr, Request.DELTA_STARTWORK_REJECTED, address); + } + catch (WorkException e1) + { + if (log.isDebugEnabled()) + { + log.debug("Error", e1); + } + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void deltaScheduleWorkAccepted(Address address) + { + log.tracef("DELTA_SCHEDULEWORK_ACCEPTED(%s)", address); + + if (address.getTransportId() != null && !getId().equals(address.getTransportId())) + { + try + { + T addr = nodes.get(address); + sendMessage(addr, Request.DELTA_SCHEDULEWORK_ACCEPTED, address); + } + catch (WorkException e1) + { + if (log.isDebugEnabled()) + { + log.debug("Error", e1); + } + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void deltaScheduleWorkRejected(Address address) + { + log.tracef("DELTA_SCHEDULEWORK_REJECTED(%s)", address); + + if (address.getTransportId() != null && !getId().equals(address.getTransportId())) + { + try + { + T addr = nodes.get(address); + sendMessage(addr, Request.DELTA_SCHEDULEWORK_REJECTED, address); + } + catch (WorkException e1) + { + if (log.isDebugEnabled()) + { + log.debug("Error", e1); + } + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void deltaWorkSuccessful(Address address) + { + log.tracef("DELTA_WORK_SUCCESSFUL(%s)", address); + + if (address.getTransportId() != null && !getId().equals(address.getTransportId())) + { + try + { + T addr = nodes.get(address); + sendMessage(addr, Request.DELTA_WORK_SUCCESSFUL, address); + } + catch (WorkException e1) + { + if (log.isDebugEnabled()) + { + log.debug("Error", e1); + } + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void deltaWorkFailed(Address address) + { + log.tracef("DELTA_WORK_FAILED(%s)", address); + + if (address.getTransportId() != null && !getId().equals(address.getTransportId())) + { + try + { + T addr = nodes.get(address); + sendMessage(addr, Request.DELTA_WORK_FAILED, address); + } + catch (WorkException e1) + { + if (log.isDebugEnabled()) + { + log.debug("Error", e1); + } + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public void doWork(Address address, DistributableWork work) throws WorkException + { + log.tracef("DO_WORK(%s, %s)", address, work); + + ClassBundle cb = ClassBundleFactory.createClassBundle(work); + + T addr = nodes.get(address); + sendMessage(addr, Request.DO_WORK, address, cb, work); + } + + /** + * {@inheritDoc} + */ + @Override + public void scheduleWork(Address address, DistributableWork work) throws WorkException + { + log.tracef("SCHEDULE_WORK(%s, %s)", address, work); + + ClassBundle cb = ClassBundleFactory.createClassBundle(work); + + T addr = nodes.get(address); + sendMessage(addr, Request.SCHEDULE_WORK, address, cb, work); + } + + /** + * {@inheritDoc} + */ + @Override + public long startWork(Address address, DistributableWork work) throws WorkException + { + log.tracef("START_WORK(%s, %s)", address, work); + + ClassBundle cb = ClassBundleFactory.createClassBundle(work); + + T addr = nodes.get(address); + return (long)sendMessage(addr, Request.START_WORK, address, cb, work); + } + + /** + * Get the executorService. + * + * @return the executorService. + */ + public ExecutorService getExecutorService() + { + return executorService; + } + + /** + * Set the executorService. + * + * @param executorService The executorService to set. + */ + public void setExecutorService(ExecutorService executorService) + { + this.executorService = executorService; + } + + /** + * {@inheritDoc} + */ + public void register(Address address) + { + nodes.put(address, null); + + if (address.getTransportId() == null || address.getTransportId().equals(getId())) + { + Set sent = new HashSet(); + for (T addr : nodes.values()) + { + if (addr != null && !sent.contains(addr)) + { + sent.add(addr); + try + { + sendMessage(addr, Request.WORKMANAGER_ADD, address, (Serializable)getOwnAddress()); + } + catch (Throwable t) + { + log.error("Register " + t.getMessage(), t); + } + } + } + } + } + + /** + * {@inheritDoc} + */ + public void unregister(Address address) + { + nodes.remove(address); + + if (address.getTransportId() == null || address.getTransportId().equals(getId())) + { + Set sent = new HashSet(); + for (T addr : nodes.values()) + { + if (addr != null && !sent.contains(addr)) + { + sent.add(addr); + try + { + sendMessage(addr, Request.WORKMANAGER_REMOVE, address); + } + catch (Throwable t) + { + log.error("Unregister: " + t.getMessage(), t); + } + } + } + } + } + + /** + * Get the addresses + * @param physicalAddress the physical address + * @return The logical addresses associated + */ + public Set

getAddresses(T physicalAddress) + { + Set
result = new HashSet
(); + + for (Map.Entry entry : nodes.entrySet()) + { + if (entry.getValue() == null || entry.getValue().equals(physicalAddress)) + { + result.add(entry.getKey()); + } + } + + log.tracef("Addresses: %s", result); + + return Collections.unmodifiableSet(result); + } + + /** + * join + * @param logicalAddress the logical address + * @param physicalAddress the physical address + */ + public void join(Address logicalAddress, T physicalAddress) + { + log.tracef("JOIN(%s, %s)", logicalAddress, physicalAddress); + + if (!nodes.containsKey(logicalAddress)) + { + nodes.put(logicalAddress, physicalAddress); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(logicalAddress); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.join(logicalAddress); + } + } + else + { + WorkManagerEventQueue wmeq = WorkManagerEventQueue.getInstance(); + wmeq.addEvent(new WorkManagerEvent(WorkManagerEvent.TYPE_JOIN, logicalAddress)); + } + } + } + + /** + * leave + * @param physicalAddress the physical address + */ + public void leave(T physicalAddress) + { + log.tracef("LEAVE(%s)", physicalAddress); + + Set
remove = new HashSet
(); + + for (Map.Entry entry : nodes.entrySet()) + { + if (entry.getValue() != null && entry.getValue().equals(physicalAddress)) + { + remove.add(entry.getKey()); + } + } + + if (remove.size() > 0) + { + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + + for (Address logicalAddress : remove) + { + nodes.remove(logicalAddress); + + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(logicalAddress); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.leave(logicalAddress); + } + } + else + { + WorkManagerEventQueue wmeq = WorkManagerEventQueue.getInstance(); + wmeq.addEvent(new WorkManagerEvent(WorkManagerEvent.TYPE_LEAVE, logicalAddress)); + } + } + } + } + + /** + * localPing + * @return the ping value + */ + public long localPing() + { + log.tracef("LOCAL_PING()"); + + return 0L; + } + + /** + * localWorkManagerAdd + * + * @param address the logical address + * @param physicalAddress the physical address + */ + public void localWorkManagerAdd(Address address, T physicalAddress) + { + log.tracef("LOCAL_WORKMANAGER_ADD(%s, %s)", address, physicalAddress); + + join(address, physicalAddress); + } + + /** + * localWorkManagerRemove + * + * @param address the logical address + */ + public void localWorkManagerRemove(Address address) + { + log.tracef("LOCAL_WORKMANAGER_REMOVE(%s)", address); + + nodes.remove(address); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(address); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.leave(address); + } + } + else + { + WorkManagerEventQueue wmeq = WorkManagerEventQueue.getInstance(); + wmeq.addEvent(new WorkManagerEvent(WorkManagerEvent.TYPE_LEAVE, address)); + } + } + + /** + * localDoWork + * + * @param address the logical address + * @param work the work + * @throws WorkException in case of error + */ + public void localDoWork(Address address, DistributableWork work) throws WorkException + { + log.tracef("LOCAL_DO_WORK(%s, %s)", address, work); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(address); + + dwm.localDoWork(work); + } + + /** + * localStartWork + * + * @param address the logical address + * @param work the work + * @return the start value + * @throws WorkException in case of error + */ + public long localStartWork(Address address, DistributableWork work) throws WorkException + { + log.tracef("LOCAL_START_WORK(%s, %s)", address, work); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(address); + + return dwm.localStartWork(work); + } + + /** + * localScheduleWork + * + * @param address the logical address + * @param work the work + * @throws WorkException in case of error + */ + public void localScheduleWork(Address address, DistributableWork work) throws WorkException + { + log.tracef("LOCAL_SCHEDULE_WORK(%s, %s)", address, work); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(address); + + dwm.localScheduleWork(work); + } + + /** + * localGetShortRunningFree + * + * @param address the logical address + * @return the free count + */ + public long localGetShortRunningFree(Address address) + { + log.tracef("LOCAL_GET_SHORTRUNNING_FREE(%s)", address); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + WorkManager wm = wmc.resolveWorkManager(address); + + if (wm != null) + { + StatisticsExecutor executor = wm.getShortRunningThreadPool(); + if (executor != null) + return executor.getNumberOfFreeThreads(); + } + + return 0L; + } + + /** + * localGetLongRunningFree + * + * @param address the logical address + * @return the free count + */ + public long localGetLongRunningFree(Address address) + { + log.tracef("LOCAL_GET_LONGRUNNING_FREE(%s)", address); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + WorkManager wm = wmc.resolveWorkManager(address); + + if (wm != null) + { + StatisticsExecutor executor = wm.getLongRunningThreadPool(); + if (executor != null) + return executor.getNumberOfFreeThreads(); + } + + return 0L; + } + + /** + * localUpdateShortRunningFree + * + * @param logicalAddress the logical address + * @param freeCount the free count + */ + public void localUpdateShortRunningFree(Address logicalAddress, Long freeCount) + { + log.tracef("LOCAL_UPDATE_SHORTRUNNING_FREE(%s, %d)", logicalAddress, freeCount); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(logicalAddress); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.updateShortRunningFree(logicalAddress, freeCount); + } + } + else + { + WorkManagerEventQueue wmeq = WorkManagerEventQueue.getInstance(); + wmeq.addEvent(new WorkManagerEvent(WorkManagerEvent.TYPE_UPDATE_SHORT_RUNNING, logicalAddress, freeCount)); + } + } + + /** + * localUpdateLongRunningFree + * + * @param logicalAddress the logical address + * @param freeCount the free count + */ + public void localUpdateLongRunningFree(Address logicalAddress, Long freeCount) + { + log.tracef("LOCAL_UPDATE_LONGRUNNING_FREE(%s, %d)", logicalAddress, freeCount); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(logicalAddress); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.updateLongRunningFree(logicalAddress, freeCount); + } + } + else + { + WorkManagerEventQueue wmeq = WorkManagerEventQueue.getInstance(); + wmeq.addEvent(new WorkManagerEvent(WorkManagerEvent.TYPE_UPDATE_LONG_RUNNING, logicalAddress, freeCount)); + } + } + + /** + * localGetDistributedStatistics + * + * @param address the logical address + * @return The value + */ + public DistributedWorkManagerStatisticsValues localGetDistributedStatistics(Address address) + { + log.tracef("LOCAL_GET_DISTRIBUTED_STATISTICS(%s)", address); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(address); + + if (dwm != null) + { + DistributedWorkManagerStatisticsValues values = + new DistributedWorkManagerStatisticsValues(dwm.getDistributedStatistics().getWorkSuccessful(), + dwm.getDistributedStatistics().getWorkFailed(), + dwm.getDistributedStatistics().getDoWorkAccepted(), + dwm.getDistributedStatistics().getDoWorkRejected(), + dwm.getDistributedStatistics().getScheduleWorkAccepted(), + dwm.getDistributedStatistics().getScheduleWorkRejected(), + dwm.getDistributedStatistics().getStartWorkAccepted(), + dwm.getDistributedStatistics().getStartWorkRejected()); + + return values; + } + + return null; + } + + /** + * localClearDistributedStatistics + * + * @param logicalAddress the logical address + */ + public void localClearDistributedStatistics(Address logicalAddress) + { + log.tracef("LOCAL_CLEAR_DISTRIBUTED_STATISTICS(%s)", logicalAddress); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(logicalAddress); + + if (dwm != null) + { + if (dwm.isDistributedStatisticsEnabled()) + { + DistributedWorkManagerStatisticsValues v = + new DistributedWorkManagerStatisticsValues(0, 0, 0, 0, 0, 0, 0, 0); + dwm.getDistributedStatistics().initialize(v); + } + } + } + + /** + * Local delta doWork accepted + * @param address the logical address + */ + public void localDeltaDoWorkAccepted(Address address) + { + log.tracef("LOCAL_DELTA_DOWORK_ACCEPTED(%s)", address); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(address); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.deltaDoWorkAccepted(); + } + } + } + + /** + * Local delta doWork rejected + * @param address the logical address + */ + public void localDeltaDoWorkRejected(Address address) + { + log.tracef("LOCAL_DELTA_DOWORK_REJECTED(%s)", address); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(address); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.deltaDoWorkRejected(); + } + } + } + + /** + * Local delta startWork accepted + * @param address the logical address + */ + public void localDeltaStartWorkAccepted(Address address) + { + log.tracef("LOCAL_DELTA_STARTWORK_ACCEPTED(%s)", address); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(address); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.deltaStartWorkAccepted(); + } + } + } + + /** + * Local delta startWork rejected + * @param address the logical address + */ + public void localDeltaStartWorkRejected(Address address) + { + log.tracef("LOCAL_DELTA_STARTWORK_REJECTED(%s)", address); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(address); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.deltaStartWorkRejected(); + } + } + } + + /** + * Local delta scheduleWork accepted + * @param address the logical address + */ + public void localDeltaScheduleWorkAccepted(Address address) + { + log.tracef("LOCAL_DELTA_SCHEDULEWORK_ACCEPTED(%s)", address); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(address); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.deltaScheduleWorkAccepted(); + } + } + } + + /** + * Local delta scheduleWork rejected + * @param address the logical address + */ + public void localDeltaScheduleWorkRejected(Address address) + { + log.tracef("LOCAL_DELTA_SCHEDULEWORK_REJECTED(%s)", address); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(address); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.deltaScheduleWorkRejected(); + } + } + } + + /** + * Local delta work successful + * @param address the logical address + */ + public void localDeltaWorkSuccessful(Address address) + { + log.tracef("LOCAL_DELTA_WORK_SUCCESSFUL(%s)", address); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(address); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.deltaWorkSuccessful(); + } + } + } + + /** + * Local delta work failed + * @param address the logical address + */ + public void localDeltaWorkFailed(Address address) + { + log.tracef("LOCAL_DELTA_WORK_FAILED(%s)", address); + + WorkManagerCoordinator wmc = WorkManagerCoordinator.getInstance(); + DistributedWorkManager dwm = wmc.resolveDistributedWorkManager(address); + + if (dwm != null) + { + Collection copy = + new ArrayList(dwm.getNotificationListeners()); + for (NotificationListener nl : copy) + { + nl.deltaWorkFailed(); + } + } + } + + /** + * Get the own address + * @return The value + */ + protected abstract T getOwnAddress(); + + /** + * send a messagge using specific protocol. Method overridden in specific protocol implementation classes + * + * @param physicalAddress the physical address + * @param request the request + * @param parameters the parameters + * @return the returned value. Can be null if requested operation return a void + * @throws WorkException in case of problem with the work + */ + protected abstract Serializable sendMessage(T physicalAddress, Request request, Serializable... parameters) + throws WorkException; +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/ProtocolMessages.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/ProtocolMessages.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/ProtocolMessages.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,281 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.workmanager.transport.remote; + +import org.jboss.jca.core.spi.workmanager.Address; +import org.jboss.jca.core.workmanager.ClassBundle; + +import java.io.Serializable; +import java.util.Arrays; + +import javax.resource.spi.work.DistributableWork; +import javax.resource.spi.work.WorkException; + +/** + * A ProtocolMessages. + * + * @author Stefano Maestri + * @author Jesper Pedersen + */ +public class ProtocolMessages +{ + /** + * A Command of DistributedWorkManager to through network transport + * + * @author Stefano Maestri + */ + public static enum Request + { + /** join*/ + JOIN(1, Serializable.class), + /** leave */ + LEAVE(1, Serializable.class), + /** get workmanagers */ + GET_WORKMANAGERS(0), + /** workmanager add */ + WORKMANAGER_ADD(2, Address.class, Serializable.class), + /** workmanager remove */ + WORKMANAGER_REMOVE(1, Address.class), + /** update short running free */ + UPDATE_SHORTRUNNING_FREE(2, Address.class, Long.class), + /** update long running free */ + UPDATE_LONGRUNNING_FREE(2, Address.class, Long.class), + /** get short running free */ + GET_SHORTRUNNING_FREE(1, Address.class), + /** get long running free */ + GET_LONGRUNNING_FREE(1, Address.class), + + /** GET_DISTRIBUTED_STATISTICS */ + GET_DISTRIBUTED_STATISTICS(1, Address.class), + /** CLEAR_DISTRIBUTED_STATISTICS */ + CLEAR_DISTRIBUTED_STATISTICS(1, Address.class), + /** DELTA_DOWORK_ACCEPTED */ + DELTA_DOWORK_ACCEPTED(1, Address.class), + /** DELTA_DOWORK_REJECTED */ + DELTA_DOWORK_REJECTED(1, Address.class), + /** DELTA_STARTWORK_ACCEPTED */ + DELTA_STARTWORK_ACCEPTED(1, Address.class), + /** DELTA_STARTWORK_REJECTED */ + DELTA_STARTWORK_REJECTED(1, Address.class), + /** DELTA_SCHEDULEWORK_ACCEPTED */ + DELTA_SCHEDULEWORK_ACCEPTED(1, Address.class), + /** DELTA_SCHEDULEWORK_REJECTED */ + DELTA_SCHEDULEWORK_REJECTED(1, Address.class), + /** DELTA_WORK_SUCCESSFUL */ + DELTA_WORK_SUCCESSFUL(1, Address.class), + /** DELTA_WORK_FAILED */ + DELTA_WORK_FAILED(1, Address.class), + + /** PING */ + PING(0), + /** do work */ + DO_WORK(3, Address.class, ClassBundle.class, DistributableWork.class), + /** schedule work */ + SCHEDULE_WORK(3, Address.class, ClassBundle.class, DistributableWork.class), + /** start work */ + START_WORK(3, Address.class, ClassBundle.class, DistributableWork.class); + + private final int numberOfParameter; + + private final Class[] typeOfParameters; + + private Request(final int numberOfParameter, final Class... typeOfParameters) + { + this.numberOfParameter = numberOfParameter; + this.typeOfParameters = typeOfParameters; + } + + /** + * Get the numberOfParameter. + * + * @return the numberOfParameter. + */ + public int getNumberOfParameter() + { + return numberOfParameter; + } + + /** + * Get the typeOfParameters. + * + * @return the typeOfParameters. + */ + public Class[] getTypeOfParameters() + { + return Arrays.copyOf(typeOfParameters, typeOfParameters.length); + } + + } + + /** + * + * A Command of DistributedWorkManager to through network transport + * + * @author Stefano Maestri + * + */ + public enum Response + { + /** OK_VOID */ + OK_VOID(0), + /** OK_SERIALIZABLE */ + OK_SERIALIZABLE(1, Serializable.class), + /** WORK_EXCEPTION */ + WORK_EXCEPTION(1, WorkException.class), + /** GENERIC_EXCEPTION */ + GENERIC_EXCEPTION(1, Throwable.class); + + private final int numberOfParameter; + + private final Class[] typeOfParameters; + + private Response(final int numberOfParameter, final Class... typeOfParameters) + { + this.numberOfParameter = numberOfParameter; + this.typeOfParameters = typeOfParameters; + } + + /** + * Get the numberOfParameter. + * + * @return the numberOfParameter. + */ + public int getNumberOfParameter() + { + return numberOfParameter; + } + + /** + * Get the typeOfParameters. + * + * @return the typeOfParameters. + */ + public Class[] getTypeOfParameters() + { + return Arrays.copyOf(typeOfParameters, typeOfParameters.length); + } + } + + /** + * + * A ResponseValue. + * + * @author Stefano Maestri + * + */ + public static class ResponseValues implements Serializable + { + /** Serial version uid */ + private static final long serialVersionUID = 1L; + + private final Response response; + + private final Serializable[] values; + + /** + * Create a new ResponseValue. + * + * @param response the response + * @param values values to return + */ + public ResponseValues(Response response, Serializable... values) + { + super(); + this.response = response; + this.values = values; + } + + /** + * Get the response. + * + * @return the response. + */ + public final Response getResponse() + { + return response; + } + + /** + * Get the value. + * + * @return the value. + */ + public final Serializable[] getValues() + { + return values; + } + } + + /** + * + * A ResponseValue. + * + * @author Stefano Maestri + * + */ + public static class RequestValues implements Serializable + { + /** Serial version uid */ + private static final long serialVersionUID = 1L; + + private final Request request; + + private final Serializable[] values; + + /** + * Create a new RequestValue. + * + * @param request the request + * @param values params to send with request + */ + public RequestValues(Request request, Serializable... values) + { + super(); + this.request = request; + this.values = values; + } + + /** + * Get the value. + * + * @return the value. + */ + public final Serializable[] getValues() + { + return values; + } + + /** + * Get the request. + * + * @return the request. + */ + public final Request getRequest() + { + return request; + } + + } + + + +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/jgroups/JGroupsConfiguration.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/jgroups/JGroupsConfiguration.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/jgroups/JGroupsConfiguration.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,114 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.jca.core.workmanager.transport.remote.jgroups; + +import org.jgroups.JChannel; + +/** + * + * A JGroupsConfiguration. + * + * @author Stefano Maestri + * + */ +public class JGroupsConfiguration +{ + /** the configuration **/ + private String configuration; + + /** the channel **/ + private JChannel channel; + + /** + * + * Create a new JGroupsConfiguration. + * + */ + public JGroupsConfiguration() + { + + } + + /** + * Start method for bean lifecycle + * + * @throws Throwable in case of error + */ + public void start() throws Throwable + { + + if (configuration == null) + { + channel = new JChannel(); + } + else + { + channel = new JChannel(configuration); + } + + + } + + /** + * Stop method for bean lifecycle + * + * @throws Throwable in case of error + */ + public void stop() throws Throwable + { + + } + + /** + * Get the configuration. + * + * @return the configuration. + */ + public final String getConfiguration() + { + return configuration; + } + + /** + * Set the configuration. + * + * @param configuration The configuration to set. + */ + public final void setConfiguration(String configuration) + { + this.configuration = configuration; + + } + + /** + * Get the channel. + * + * @return the channel. + */ + public final JChannel getChannel() + { + + return channel; + + } + +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/jgroups/JGroupsTransport.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/jgroups/JGroupsTransport.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/jgroups/JGroupsTransport.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,1206 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager.transport.remote.jgroups; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.lang.reflect.Method; +import java.rmi.RemoteException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.resource.spi.work.DistributableWork; +import javax.resource.spi.work.WorkException; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.api.workmanager.DistributedWorkManagerStatisticsValues; +import org.jboss.jca.core.spi.workmanager.Address; +import org.jboss.jca.core.workmanager.ClassBundle; +import org.jboss.jca.core.workmanager.WorkClassLoader; +import org.jboss.jca.core.workmanager.WorkObjectInputStream; +import org.jboss.jca.core.workmanager.transport.remote.AbstractRemoteTransport; +import org.jboss.jca.core.workmanager.transport.remote.ProtocolMessages.Request; +import org.jboss.jca.core.workmanager.transport.remote.ProtocolMessages.ResponseValues; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +import org.jgroups.Channel; +import org.jgroups.MembershipListener; +import org.jgroups.Message; +import org.jgroups.View; +import org.jgroups.blocks.MethodCall; +import org.jgroups.blocks.MethodLookup; +import org.jgroups.blocks.RequestOptions; +import org.jgroups.blocks.ResponseMode; +import org.jgroups.blocks.RpcDispatcher; +import org.jgroups.util.Rsp; +import org.jgroups.util.RspList; + +/** + * The socket transport + * + * @author Stefano Maestri + * @author Jesper Pedersen + */ +public class JGroupsTransport extends AbstractRemoteTransport implements MembershipListener +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, JGroupsTransport.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** The Channel used by this transport **/ + private Channel channel; + + /** Timeout */ + private long timeout; + + /** the cluster name to join **/ + private String clusterName; + + private RpcDispatcher disp; + + private boolean initialized; + + private static final short JOIN_METHOD = 1; + + private static final short LEAVE_METHOD = 2; + + private static final short PING_METHOD = 3; + + private static final short GET_WORKMANAGERS_METHOD = 4; + + private static final short WORKMANAGER_ADD_METHOD = 5; + + private static final short WORKMANAGER_REMOVE_METHOD = 6; + + private static final short DO_WORK_METHOD = 7; + + private static final short START_WORK_METHOD = 8; + + private static final short SCHEDULE_WORK_METHOD = 9; + + private static final short GET_SHORTRUNNING_FREE_METHOD = 10; + + private static final short GET_LONGRUNNING_FREE_METHOD = 11; + + private static final short UPDATE_SHORTRUNNING_FREE_METHOD = 12; + + private static final short UPDATE_LONGRUNNING_FREE_METHOD = 13; + + private static final short GET_DISTRIBUTED_STATISTICS_METHOD = 14; + + private static final short CLEAR_DISTRIBUTED_STATISTICS_METHOD = 15; + + private static final short DELTA_DOWORK_ACCEPTED_METHOD = 16; + + private static final short DELTA_DOWORK_REJECTED_METHOD = 17; + + private static final short DELTA_STARTWORK_ACCEPTED_METHOD = 18; + + private static final short DELTA_STARTWORK_REJECTED_METHOD = 19; + + private static final short DELTA_SCHEDULEWORK_ACCEPTED_METHOD = 20; + + private static final short DELTA_SCHEDULEWORK_REJECTED_METHOD = 21; + + private static final short DELTA_WORK_SUCCESSFUL_METHOD = 22; + + private static final short DELTA_WORK_FAILED_METHOD = 23; + + private static Map methods = new HashMap(); + + static + { + try + { + methods.put(JOIN_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "join", + Map.class, + org.jgroups.Address.class)); + + methods.put(LEAVE_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "leave", + org.jgroups.Address.class)); + + methods.put(PING_METHOD, + SecurityActions.getMethod(AbstractRemoteTransport.class, "localPing")); + + methods.put(GET_WORKMANAGERS_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "getWorkManagers")); + + methods.put(WORKMANAGER_ADD_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "addWorkManager", + Map.class, + org.jgroups.Address.class)); + + methods.put(WORKMANAGER_REMOVE_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "workManagerRemove", + Map.class)); + + methods.put(DO_WORK_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "executeDoWork", + Map.class, + List.class, + byte[].class)); + + methods.put(START_WORK_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "executeStartWork", + Map.class, + List.class, + byte[].class)); + + methods.put(SCHEDULE_WORK_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "executeScheduleWork", + Map.class, + List.class, + byte[].class)); + + methods.put(GET_SHORTRUNNING_FREE_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "getShortRunningFree", + Map.class)); + + methods.put(GET_LONGRUNNING_FREE_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "getLongRunningFree", + Map.class)); + + methods.put(UPDATE_SHORTRUNNING_FREE_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "updateShortRunningFree", + Map.class, + Long.class)); + + methods.put(UPDATE_LONGRUNNING_FREE_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "updateLongRunningFree", + Map.class, + Long.class)); + + methods.put(GET_DISTRIBUTED_STATISTICS_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "getDistributedStatistics", + Map.class)); + + methods.put(CLEAR_DISTRIBUTED_STATISTICS_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "clearDistributedStatistics", + Map.class)); + + methods.put(DELTA_DOWORK_ACCEPTED_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "deltaDoWorkAccepted", + Map.class)); + + methods.put(DELTA_DOWORK_REJECTED_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "deltaDoWorkRejected", + Map.class)); + + methods.put(DELTA_STARTWORK_ACCEPTED_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "deltaStartWorkAccepted", + Map.class)); + + methods.put(DELTA_STARTWORK_REJECTED_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "deltaStartWorkRejected", + Map.class)); + + methods.put(DELTA_SCHEDULEWORK_ACCEPTED_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "deltaScheduleWorkAccepted", + Map.class)); + + methods.put(DELTA_SCHEDULEWORK_REJECTED_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "deltaScheduleWorkRejected", + Map.class)); + + methods.put(DELTA_WORK_SUCCESSFUL_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "deltaWorkSuccessful", + Map.class)); + + methods.put(DELTA_WORK_FAILED_METHOD, + SecurityActions.getMethod(JGroupsTransport.class, "deltaWorkFailed", + Map.class)); + } + catch (NoSuchMethodException e) + { + throw new RuntimeException(e); + } + } + + /** + * Constructor + */ + public JGroupsTransport() + { + super(); + this.channel = null; + this.clusterName = null; + this.disp = null; + this.initialized = false; + this.timeout = 10000L; + } + + /** + * Delegator + * @param logicalAddress The logical address + * @param address The address + */ + public void join(Map logicalAddress, org.jgroups.Address address) + { + Address logicalAddressObj = Address.fromMap(logicalAddress); + super.join(logicalAddressObj, address); + } + + /** + * Delegator + * @param address The address + */ + public void leave(org.jgroups.Address address) + { + super.leave(address); + } + + /** + * Get WorkManagers + * @return The value + */ + public Set> getWorkManagers() + { + Set> setOfMaps = new HashSet>(); + for (Address address : getAddresses(channel.getAddress())) + { + setOfMaps.add(address.toMap()); + } + return setOfMaps; + } + + /** + * Delegator + * @param logicalAddressMap The logical address + * @param address The address + */ + public void addWorkManager(Map logicalAddressMap, org.jgroups.Address address) + { + Address logicalAddress = Address.fromMap(logicalAddressMap); + super.localWorkManagerAdd(logicalAddress, address); + Long shortRunning = getShortRunningFree(logicalAddress); + Long longRunning = getLongRunningFree(logicalAddress); + + localUpdateShortRunningFree(logicalAddress, shortRunning); + localUpdateLongRunningFree(logicalAddress, longRunning); + + } + + /** + * Delegator + * @param logicalAddressMap The logical address + */ + public void workManagerRemove(Map logicalAddressMap) + { + super.localWorkManagerRemove(Address.fromMap(logicalAddressMap)); + } + + /** + * Delegator + * @param logicalAddressMap The logical address + * @return the free count + */ + public long getShortRunningFree(Map logicalAddressMap) + { + return super.localGetShortRunningFree(Address.fromMap(logicalAddressMap)); + } + + + /** + * Delegator + * @param logicalAddressMap The logical address + * @return the free count + */ + public long getLongRunningFree(Map logicalAddressMap) + { + return super.localGetLongRunningFree(Address.fromMap(logicalAddressMap)); + } + + /** + * Delegator + * + * @param logicalAddressMap The logical address + * @param freeCount freeCount + */ + public void updateShortRunningFree(Map logicalAddressMap, Long freeCount) + { + super.localUpdateShortRunningFree(Address.fromMap(logicalAddressMap), freeCount); + } + + /** + * Delegator + * + * @param logicalAddressMap The logical address + * @param freeCount freeCount + */ + public void updateLongRunningFree(Map logicalAddressMap, Long freeCount) + { + super.localUpdateLongRunningFree(Address.fromMap(logicalAddressMap), freeCount); + } + + /** + * Delegator + * @param logicalAddressMap The logical address + * @return The value + */ + public Map getDistributedStatistics(Map logicalAddressMap) + { + return super.localGetDistributedStatistics(Address.fromMap(logicalAddressMap)).toMap(); + } + + /** + * Delegator + * @param logicalAddressMap The logical address + */ + public void clearDistributedStatistics(Map logicalAddressMap) + { + super.localClearDistributedStatistics(Address.fromMap(logicalAddressMap)); + } + + /** + * Delegator + * @param logicalAddressMap The logical address + */ + public void deltaDoWorkAccepted(Map logicalAddressMap) + { + super.localDeltaDoWorkAccepted(Address.fromMap(logicalAddressMap)); + } + + /** + * Delegator + * @param logicalAddressMap The logical address + */ + public void deltaDoWorkRejected(Map logicalAddressMap) + { + super.localDeltaDoWorkRejected(Address.fromMap(logicalAddressMap)); + } + + + /** + * Delegator + * + * @param logicalAddressMap The logical address + */ + public void deltaStartWorkAccepted(Map logicalAddressMap) + { + super.localDeltaStartWorkAccepted(Address.fromMap(logicalAddressMap)); + } + + + /** + * Delegator + * + * @param logicalAddressMap The logical address + */ + public void deltaStartWorkRejected(Map logicalAddressMap) + { + super.localDeltaStartWorkRejected(Address.fromMap(logicalAddressMap)); + } + + + + /** + * Delegator + * + * @param logicalAddressMap The logical address + */ + public void deltaScheduleWorkAccepted(Map logicalAddressMap) + { + super.localDeltaScheduleWorkAccepted(Address.fromMap(logicalAddressMap)); + } + + /** + * Delegator + * + * @param logicalAddressMap The logical address + */ + public void deltaScheduleWorkRejected(Map logicalAddressMap) + { + super.localDeltaScheduleWorkRejected(Address.fromMap(logicalAddressMap)); + } + + /** + * Delegator + * + * @param logicalAddressMap The logical address + */ + public void deltaWorkSuccessful(Map logicalAddressMap) + { + super.localDeltaWorkSuccessful(Address.fromMap(logicalAddressMap)); + } + + /** + * Delegator + * + * @param logicalAddressMap The logical address + */ + public void deltaWorkFailed(Map logicalAddressMap) + { + super.localDeltaWorkSuccessful(Address.fromMap(logicalAddressMap)); + } + + + /** + * Execute doWork + * @param logicalAddressMap The logical address + * @param classBundle The class bundle + * @param b The bytes + * @throws RemoteException in case of error + */ + public void executeDoWork(Map logicalAddressMap, + List> classBundle, byte[] b) + throws RemoteException + { + ByteArrayInputStream bias = new ByteArrayInputStream(b); + WorkObjectInputStream wois = null; + try + { + WorkClassLoader wcl = SecurityActions.createWorkClassLoader(ClassBundle.fromListOfMaps(classBundle)); + + wois = new WorkObjectInputStream(bias, wcl); + + DistributableWork dw = (DistributableWork)wois.readObject(); + + localDoWork(Address.fromMap(logicalAddressMap), dw); + } + catch (Throwable t) + { + throw new RemoteException("Error during doWork: " + t.getMessage()); + } + finally + { + if (wois != null) + { + try + { + wois.close(); + } + catch (IOException ioe) + { + // Ignore + } + } + } + } + + /** + * Execute startWork + * @param logicalAddressMap The logical address + * @param classBundle The class bundle + * @param b The bytes + * @return the start value + * @throws RemoteException in case of error + */ + public long executeStartWork(Map logicalAddressMap, + List> classBundle, byte[] b) + throws RemoteException + { + ByteArrayInputStream bias = new ByteArrayInputStream(b); + WorkObjectInputStream wois = null; + try + { + WorkClassLoader wcl = SecurityActions.createWorkClassLoader(ClassBundle.fromListOfMaps(classBundle)); + + wois = new WorkObjectInputStream(bias, wcl); + + DistributableWork dw = (DistributableWork)wois.readObject(); + + return localStartWork(Address.fromMap(logicalAddressMap), dw); + } + catch (Throwable t) + { + throw new RemoteException("Error during doWork: " + t.getMessage()); + } + finally + { + if (wois != null) + { + try + { + wois.close(); + } + catch (IOException ioe) + { + // Ignore + } + } + } + } + + /** + * Execute scheduleWork + * @param logicalAddress The logical address + * @param classBundle The class bundle + * @param b The bytes + * @throws RemoteException in case of error + */ + public void executeScheduleWork(Map logicalAddress, List> classBundle, byte[] b) + throws RemoteException + { + ByteArrayInputStream bias = new ByteArrayInputStream(b); + WorkObjectInputStream wois = null; + try + { + WorkClassLoader wcl = SecurityActions.createWorkClassLoader(ClassBundle.fromListOfMaps(classBundle)); + + wois = new WorkObjectInputStream(bias, wcl); + + DistributableWork dw = (DistributableWork)wois.readObject(); + + localScheduleWork(Address.fromMap(logicalAddress), dw); + } + catch (Throwable t) + { + throw new RemoteException("Error during doWork: " + t.getMessage()); + } + finally + { + if (wois != null) + { + try + { + wois.close(); + } + catch (IOException ioe) + { + // Ignore + } + } + } + } + + /** + * {@inheritDoc} + */ + public void startup() throws Throwable + { + disp = createRpcDispatcher(); + + if (clusterName == null) + clusterName = "jca"; + + channel.connect(clusterName); + } + + /** + * Creates an rpc dispatcher used by this transport + * @return an rpc dispatcher + */ + protected RpcDispatcher createRpcDispatcher() + { + RpcDispatcher dispatcher = new RpcDispatcher(channel, null, this, this); + + dispatcher.setMethodLookup(new MethodLookup() + { + @Override + public Method findMethod(short key) + { + return methods.get(key); + } + }); + return dispatcher; + } + + /** + * {@inheritDoc} + */ + public boolean isInitialized() + { + return initialized; + } + + /** + * {@inheritDoc} + */ + public void initialize() throws Throwable + { + initialized = true; + } + + /** + * {@inheritDoc} + */ + public void shutdown() throws Throwable + { + if (disp != null) + { + try + { + disp.stop(); + } + catch (Throwable t) + { + if (log.isTraceEnabled()) + log.tracef("Throwable during disp.stop(): %s", t.getMessage()); + } + + disp = null; + } + + if (channel != null) + { + try + { + channel.disconnect(); + } + catch (Throwable t) + { + if (log.isTraceEnabled()) + log.tracef("Throwable during channel.disconnect(): %s", t.getMessage()); + } + + try + { + channel.close(); + } + catch (Throwable t) + { + if (log.isTraceEnabled()) + log.tracef("Throwable during channel.close(): %s", t.getMessage()); + } + + channel = null; + } + } + + @Override + public Serializable sendMessage(org.jgroups.Address destAddress, Request request, Serializable... parameters) + throws WorkException + { + Serializable returnValue = null; + if (log.isTraceEnabled()) + log.tracef("%s: sending message=%s to %s", channel.getAddress(), request, destAddress); + + if (channel == null || !channel.isOpen() || !channel.isConnected()) + { + if (log.isTraceEnabled()) + log.tracef("%s: channel not connected", channel != null ? channel.getAddress() : ""); + + return null; + } + // Set request optiuons. + // Note we are settings OOB flag for for the sync calls, to avoid the deadlocks. + // The only diff to regular messages is that OOB RPCs are not ordered, but we don't need this anyway + // as we're sending the next RPC only *after* we've received the response(s). + RequestOptions opts = new RequestOptions(ResponseMode.GET_ALL, timeout).setFlags(Message.Flag.OOB); + + //RequestOptions opts = new RequestOptions(ResponseMode.GET_ALL, timeout); + try + { + switch (request) + { + case JOIN : { + org.jgroups.Address joiningAddress = (org.jgroups.Address) parameters[0]; + List dests = destAddress == null ? null : Arrays.asList(destAddress); + + RspList rspList = disp.callRemoteMethods(dests, new MethodCall(JOIN_METHOD, + joiningAddress), + opts); + throwWorkExceptionIfHasExption(rspList); + break; + } + case LEAVE : { + org.jgroups.Address leavingAddress = (org.jgroups.Address) parameters[0]; + + List dests = destAddress == null ? null : Arrays.asList(destAddress); + + RspList rspList = disp.callRemoteMethods(dests, new MethodCall(LEAVE_METHOD, + leavingAddress), opts); + throwWorkExceptionIfHasExption(rspList); + break; + } + case GET_WORKMANAGERS : { + try + { + Set> setOfMaps = disp.callRemoteMethod(destAddress, + new MethodCall(GET_WORKMANAGERS_METHOD), + opts); + if (setOfMaps != null) + { + Set
setOfAddress = new HashSet
(setOfMaps.size()); + for (Map map : setOfMaps) + { + if (map != null) + setOfAddress.add(Address.fromMap(map)); + } + returnValue = (Serializable) setOfAddress; + } + } + catch (Exception e) + { + throw new WorkException(e); + } + + break; + } + case WORKMANAGER_ADD : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + org.jgroups.Address physicalAddress = (org.jgroups.Address) parameters[1]; + + disp.callRemoteMethod(destAddress, + new MethodCall(WORKMANAGER_ADD_METHOD, address, physicalAddress), opts); + + break; + } + case WORKMANAGER_REMOVE : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + + disp.callRemoteMethod(destAddress, + new MethodCall(WORKMANAGER_REMOVE_METHOD, address), opts); + + break; + } + case PING : { + try + { + returnValue = (Long) disp.callRemoteMethod(destAddress, new MethodCall(PING_METHOD), + opts); + } + catch (WorkException we) + { + throw we; + } + catch (Exception e) + { + throw new WorkException(e); + } + + break; + } + case DO_WORK : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + List> cb = ((ClassBundle)parameters[1]).toListOfMaps(); + DistributableWork work = (DistributableWork) parameters[2]; + try + { + disp.callRemoteMethod(destAddress, + new MethodCall(DO_WORK_METHOD, address, cb, getBytes(work)), opts); + } + catch (WorkException we) + { + throw we; + } + catch (Exception e) + { + throw new WorkException(e); + } + break; + } + case START_WORK : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + List> cb = ((ClassBundle)parameters[1]).toListOfMaps(); + DistributableWork work = (DistributableWork) parameters[2]; + + returnValue = (Long) disp.callRemoteMethod(destAddress, + new MethodCall(START_WORK_METHOD, address, cb, + getBytes(work)), opts); + + break; + } + case SCHEDULE_WORK : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + List> cb = ((ClassBundle)parameters[1]).toListOfMaps(); + DistributableWork work = (DistributableWork) parameters[2]; + + disp.callRemoteMethod(destAddress, + new MethodCall(SCHEDULE_WORK_METHOD, address, cb, getBytes(work)), opts); + + break; + } + case GET_SHORTRUNNING_FREE : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + + returnValue = (Long) disp.callRemoteMethod(destAddress, + new MethodCall(GET_SHORTRUNNING_FREE_METHOD, + address), opts); + + break; + } + case GET_LONGRUNNING_FREE : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + + returnValue = (Long) disp.callRemoteMethod(destAddress, + new MethodCall(GET_LONGRUNNING_FREE_METHOD, + address), opts); + break; + } + case UPDATE_SHORTRUNNING_FREE : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + Long freeCount = (Long) parameters[1]; + + disp.callRemoteMethod(destAddress, + new MethodCall(UPDATE_SHORTRUNNING_FREE_METHOD, address, freeCount), opts); + + break; + } + case UPDATE_LONGRUNNING_FREE : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + Long freeCount = (Long) parameters[1]; + + disp.callRemoteMethod(destAddress, + new MethodCall(UPDATE_LONGRUNNING_FREE_METHOD, address, freeCount), opts); + + break; + } + case GET_DISTRIBUTED_STATISTICS : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + + Map statisticsMap = disp.callRemoteMethod(destAddress, + new MethodCall(GET_DISTRIBUTED_STATISTICS_METHOD, address), + opts); + returnValue = DistributedWorkManagerStatisticsValues.fromMap(statisticsMap); + + break; + } + case CLEAR_DISTRIBUTED_STATISTICS : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + + disp.callRemoteMethod(destAddress, + new MethodCall(CLEAR_DISTRIBUTED_STATISTICS_METHOD, address), + opts); + + break; + } + case DELTA_DOWORK_ACCEPTED : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + + disp.callRemoteMethod(destAddress, new MethodCall(DELTA_DOWORK_ACCEPTED_METHOD, address), + opts); + + break; + } + case DELTA_DOWORK_REJECTED : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + + disp.callRemoteMethod(destAddress, new MethodCall(DELTA_DOWORK_REJECTED_METHOD, address), + opts); + + break; + } + case DELTA_STARTWORK_ACCEPTED : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + + disp.callRemoteMethod(destAddress, new MethodCall(DELTA_STARTWORK_ACCEPTED_METHOD, address), + opts); + + break; + } + case DELTA_STARTWORK_REJECTED : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + + disp.callRemoteMethod(destAddress, new MethodCall(DELTA_STARTWORK_REJECTED_METHOD, address), + opts); + + break; + } + case DELTA_SCHEDULEWORK_ACCEPTED : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + + disp.callRemoteMethod(destAddress, new MethodCall(DELTA_SCHEDULEWORK_ACCEPTED_METHOD, address), + opts); + + break; + } + case DELTA_SCHEDULEWORK_REJECTED : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + + disp.callRemoteMethod(destAddress, new MethodCall(DELTA_SCHEDULEWORK_REJECTED_METHOD, address), + opts); + + break; + } + case DELTA_WORK_SUCCESSFUL : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + + disp.callRemoteMethod(destAddress, new MethodCall(DELTA_WORK_SUCCESSFUL_METHOD, address), + opts); + + break; + } + case DELTA_WORK_FAILED : { + Map address = + ((org.jboss.jca.core.spi.workmanager.Address) parameters[0]).toMap(); + + disp.callRemoteMethod(destAddress, new MethodCall(DELTA_WORK_FAILED_METHOD, address), + opts); + + break; + } + default : + if (log.isDebugEnabled()) + { + log.debug("Unknown command received on socket Transport"); + } + break; + } + } + catch (WorkException we) + { + throw we; + } + catch (Throwable t) + { + WorkException we = new WorkException(t.getMessage()); + we.initCause(t); + throw we; + } + + return returnValue; + } + + private void throwWorkExceptionIfHasExption(RspList rspList) throws WorkException + { + if (rspList != null && rspList.getFirst() != null) + { + for (Rsp rsp : rspList) + { + if (rsp.hasException()) + { + Throwable t = rsp.getException(); + if (t instanceof WorkException) + { + throw (WorkException)t; + } + else + { + WorkException we = new WorkException(rsp.getException().getMessage()); + we.initCause(rsp.getException()); + throw we; + } + } + } + } + } + + /** + * Get the physical address + * @return The value + */ + public org.jgroups.Address getOwnAddress() + { + return channel.getAddress(); + } + + /** + * Get the channel. + * + * @return the channel. + */ + public Channel getChannel() + { + return channel; + } + + /** + * Set the channel. + * + * @param channel The channel to set. + */ + public void setChannel(Channel channel) + { + this.channel = channel; + } + + /** + * Get the clustername. + * + * @return the clustername. + */ + public String getClusterName() + { + return clusterName; + } + + /** + * Set the clustername. + * + * @param clustername The clustername to set. + */ + public void setClusterName(String clustername) + { + this.clusterName = clustername; + } + + /** + * Get the timeout + * @return The value + */ + public long getTimeout() + { + return timeout; + } + + /** + * Set the timeout + * @param v The value + */ + public void setTimeout(long v) + { + timeout = v; + } + + @Override + public void viewAccepted(View view) + { + if (log.isTraceEnabled()) + { + log.tracef("java.net.preferIPv4Stack=%s", SecurityActions.getSystemProperty("java.net.preferIPv4Stack")); + log.tracef("viewAccepted called w/ View=%s", view); + log.tracef("viewAccepted called w/ physicalAdresses=%s", nodes.values()); + log.tracef("viewAccepted called w/ members=%s", view.getMembers()); + log.tracef("viewAccepted called w/ channels=%s", channel); + + } + + synchronized (this) + { + List physicalAddresses = new ArrayList(nodes.values().size()); + physicalAddresses.addAll(nodes.values()); + for (org.jgroups.Address physicalAddress : physicalAddresses) + { + if (physicalAddress != null && !view.containsMember(physicalAddress)) + { + leave(physicalAddress); + } + } + for (org.jgroups.Address address : view.getMembers()) + { + if (channel != null && !channel.getAddress().equals(address) && !nodes.containsValue(address)) + { + try + { + Set logicalAddresses = + (Set)sendMessage(address, Request.GET_WORKMANAGERS); + + if (logicalAddresses != null && logicalAddresses.size() > 0) + { + for (org.jboss.jca.core.spi.workmanager.Address logicalAddress : logicalAddresses) + { + join(logicalAddress, address); + + Long shortRunning = getShortRunningFree(logicalAddress); + Long longRunning = getLongRunningFree(logicalAddress); + + localUpdateShortRunningFree(logicalAddress, shortRunning); + localUpdateLongRunningFree(logicalAddress, longRunning); + } + } + } + catch (Throwable t) + { + log.error("ViewAccepted: " + t.getMessage(), t); + } + } + } + } + } + + @Override + public void block() + { + log.tracef("block called"); + } + + @Override + public void suspect(org.jgroups.Address address) + { + log.tracef("suspect called w/ Address=%s", address); + } + + @Override + public void unblock() + { + log.tracef("unblock called"); + } + + /** + * Get the byte[] of a DistributableWork instance + * @param dw The instance + * @return The value + */ + private byte[] getBytes(DistributableWork dw) + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = null; + try + { + oos = new ObjectOutputStream(baos); + oos.writeObject(dw); + oos.flush(); + return baos.toByteArray(); + } + catch (Throwable t) + { + log.error("Error during getBytes: " + t.getMessage(), t); + } + finally + { + if (oos != null) + { + try + { + oos.close(); + } + catch (IOException ioe) + { + // Ignore + } + } + } + + return null; + } + + @Override + public String toString() + { + return "JGroupsTransport [channel=" + channel + ", clustername=" + clusterName + "]"; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/jgroups/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/jgroups/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/jgroups/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,111 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager.transport.remote.jgroups; + +import org.jboss.jca.core.workmanager.ClassBundle; +import org.jboss.jca.core.workmanager.WorkClassLoader; + +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Constructor + */ + private SecurityActions() + { + } + + /** + * Get a system property + * @param name The property name + * @return The property value + */ + static String getSystemProperty(final String name) + { + return AccessController.doPrivileged(new PrivilegedAction() + { + public String run() + { + return System.getProperty(name); + } + }); + } + + /** + * Create a WorkClassLoader + * @param cb The class bundle + * @return The class loader + */ + static WorkClassLoader createWorkClassLoader(final ClassBundle cb) + { + return AccessController.doPrivileged(new PrivilegedAction() + { + public WorkClassLoader run() + { + return new WorkClassLoader(cb); + } + }); + } + + /** + * Get the method + * @param c The class + * @param name The name + * @param params The parameters + * @return The method + * @exception NoSuchMethodException If a matching method is not found. + */ + static Method getMethod(final Class c, final String name, final Class... params) + throws NoSuchMethodException + { + if (System.getSecurityManager() == null) + return c.getMethod(name, params); + + Method result = AccessController.doPrivileged(new PrivilegedAction() + { + public Method run() + { + try + { + return c.getMethod(name, params); + } + catch (NoSuchMethodException e) + { + return null; + } + } + }); + + if (result != null) + return result; + + throw new NoSuchMethodException(); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/jgroups/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/jgroups/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/jgroups/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the jgroups transport + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the protocol common classes for remote transports (socket and jgroups) + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/socket/Communication.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/socket/Communication.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/socket/Communication.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,570 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2008, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager.transport.remote.socket; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.workmanager.Address; +import org.jboss.jca.core.workmanager.ClassBundle; +import org.jboss.jca.core.workmanager.WorkClassLoader; +import org.jboss.jca.core.workmanager.WorkObjectInputStream; +import org.jboss.jca.core.workmanager.transport.remote.ProtocolMessages.Request; +import org.jboss.jca.core.workmanager.transport.remote.ProtocolMessages.Response; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.net.Socket; +import java.util.Arrays; +import java.util.Set; + +import javax.resource.spi.work.DistributableWork; +import javax.resource.spi.work.WorkException; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * The communication between client and server + * @author Jesper Pedersen + */ +public class Communication implements Runnable +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, Communication.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** The socket */ + private final Socket socket; + + /** The trasport **/ + private final SocketTransport transport; + + /** + * Create a new Communication. + * + * @param socket The socket + * @param transport The Transport + */ + public Communication(SocketTransport transport, Socket socket) + { + this.socket = socket; + this.transport = transport; + } + + /** + * Run + */ + public void run() + { + WorkObjectInputStream wois = null; + ObjectOutputStream oos = null; + Serializable returnValue = null; + Response response = null; + try + { + wois = new WorkObjectInputStream(socket.getInputStream()); + int commandOrdinalPosition = wois.readInt(); + int numberOfParameters = wois.readInt(); + + Request command = Request.values()[commandOrdinalPosition]; + + switch (command) + { + case JOIN : { + if (numberOfParameters != 1) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, "JOIN")); + + String address = (String)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: JOIN(%s)", socket.getInetAddress(), address); + + Set
workManagers = + (Set
)transport.sendMessage(address, Request.GET_WORKMANAGERS); + if (workManagers != null) + { + for (Address a : workManagers) + { + transport.join(a, address); + + long shortRunningFree = + (long)transport.sendMessage(address, Request.GET_SHORTRUNNING_FREE, a); + long longRunningFree = + (long)transport.sendMessage(address, Request.GET_LONGRUNNING_FREE, a); + + transport.localUpdateShortRunningFree(a, shortRunningFree); + transport.localUpdateLongRunningFree(a, longRunningFree); + } + } + + response = Response.OK_VOID; + break; + } + case LEAVE : { + if (numberOfParameters != 1) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, "LEAVE")); + + String address = (String)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: LEAVE(%s)", socket.getInetAddress(), address); + + transport.leave(address); + response = Response.OK_VOID; + break; + } + case GET_WORKMANAGERS : { + if (numberOfParameters != 0) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "GET_WORKMANAGERS")); + + if (log.isTraceEnabled()) + log.tracef("%s: GET_WORKMANAGERS()", socket.getInetAddress()); + + returnValue = (Serializable)transport.getAddresses(transport.getOwnAddress()); + response = Response.OK_SERIALIZABLE; + + break; + } + case WORKMANAGER_ADD : { + if (numberOfParameters != 2) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "WORKMANAGER_ADD")); + + Address id = (Address)wois.readObject(); + String address = (String)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: WORKMANAGER_ADD(%s, %s)", socket.getInetAddress(), id, address); + + transport.localWorkManagerAdd(id, address); + response = Response.OK_VOID; + + break; + } + case WORKMANAGER_REMOVE : { + if (numberOfParameters != 1) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "WORKMANAGER_REMOVE")); + + Address id = (Address)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: WORKMANAGER_REMOVE(%s)", socket.getInetAddress(), id); + + transport.localWorkManagerRemove(id); + response = Response.OK_VOID; + + break; + } + case PING : { + if (numberOfParameters != 0) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "PING")); + + if (log.isTraceEnabled()) + log.tracef("%s: PING()", socket.getInetAddress()); + + transport.localPing(); + response = Response.OK_VOID; + + break; + } + case DO_WORK : { + if (numberOfParameters != 3) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "DO_WORK")); + + Address id = (Address)wois.readObject(); + ClassBundle cb = (ClassBundle)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("DO_WORK/ClassBundle: %s", cb); + + WorkClassLoader wcl = SecurityActions.createWorkClassLoader(cb); + wois.setWorkClassLoader(wcl); + + DistributableWork work = (DistributableWork)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: DO_WORK(%s, %s)", socket.getInetAddress(), id, work); + + transport.localDoWork(id, work); + response = Response.OK_VOID; + + break; + } + case START_WORK : { + if (numberOfParameters != 3) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "START_WORK")); + + Address id = (Address)wois.readObject(); + ClassBundle cb = (ClassBundle)wois.readObject(); + + log.tracef("START_WORK/ClassBundle: %s", cb); + + WorkClassLoader wcl = SecurityActions.createWorkClassLoader(cb); + wois.setWorkClassLoader(wcl); + + DistributableWork work = (DistributableWork)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: START_WORK(%s, %s)", socket.getInetAddress(), id, work); + + returnValue = transport.localStartWork(id, work); + response = Response.OK_SERIALIZABLE; + + break; + } + case SCHEDULE_WORK : { + if (numberOfParameters != 3) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "SCHEDULE_WORK")); + + Address id = (Address)wois.readObject(); + ClassBundle cb = (ClassBundle)wois.readObject(); + + log.tracef("SCHEDULE_WORK/ClassBundle: %s", cb); + + WorkClassLoader wcl = SecurityActions.createWorkClassLoader(cb); + wois.setWorkClassLoader(wcl); + + DistributableWork work = (DistributableWork)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: SCHEDULE_WORK(%s, %s)", socket.getInetAddress(), id, work); + + transport.localScheduleWork(id, work); + response = Response.OK_VOID; + + break; + } + case GET_SHORTRUNNING_FREE : { + if (numberOfParameters != 1) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "GET_SHORTRUNNING_FREE")); + + Address id = (Address)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: GET_SHORTRUNNING_FREE(%s)", socket.getInetAddress(), id); + + returnValue = transport.localGetShortRunningFree(id); + response = Response.OK_SERIALIZABLE; + + break; + } + case GET_LONGRUNNING_FREE : { + if (numberOfParameters != 1) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "GET_LONGRUNNING_FREE")); + + Address id = (Address)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: GET_LONGRUNNING_FREE(%s)", socket.getInetAddress(), id); + + returnValue = transport.localGetLongRunningFree(id); + response = Response.OK_SERIALIZABLE; + + break; + } + case UPDATE_SHORTRUNNING_FREE : { + if (numberOfParameters != 2) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "UPDATE_SHORTRUNNING_FREE")); + + Address id = (Address)wois.readObject(); + Long freeCount = (Long)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: UPDATE_SHORTRUNNING_FREE(%s, %d)", socket.getInetAddress(), id, freeCount); + + transport.localUpdateShortRunningFree(id, freeCount); + response = Response.OK_VOID; + + break; + } + case UPDATE_LONGRUNNING_FREE : { + if (numberOfParameters != 2) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "UPDATE_LONGRUNNING_FREE")); + + Address id = (Address)wois.readObject(); + Long freeCount = (Long)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: UPDATE_LONGRUNNING_FREE(%s, %d)", socket.getInetAddress(), id, freeCount); + + transport.localUpdateLongRunningFree(id, freeCount); + response = Response.OK_VOID; + + break; + } + case GET_DISTRIBUTED_STATISTICS : { + if (numberOfParameters != 1) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "GET_DISTRIBUTED_STATISTICS")); + + Address id = (Address)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: GET_DISTRIBUTED_STATISTICS(%s)", socket.getInetAddress(), id); + + returnValue = transport.localGetDistributedStatistics(id); + response = Response.OK_SERIALIZABLE; + + break; + } + case CLEAR_DISTRIBUTED_STATISTICS : { + if (numberOfParameters != 1) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "CLEAR_DISTRIBUTED_STATISTICS")); + + Address id = (Address)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: CLEAR_DISTRIBUTED_STATISTICS(%s)", socket.getInetAddress(), id); + + transport.localClearDistributedStatistics(id); + response = Response.OK_VOID; + + break; + } + case DELTA_DOWORK_ACCEPTED : { + if (numberOfParameters != 1) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "DELTA_DOWORK_ACCEPTED")); + + Address id = (Address)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: DELTA_DOWORK_ACCEPTED(%s)", socket.getInetAddress(), id); + + transport.localDeltaDoWorkAccepted(id); + response = Response.OK_VOID; + + break; + } + case DELTA_DOWORK_REJECTED : { + if (numberOfParameters != 1) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "DELTA_DOWORK_REJECTED")); + + Address id = (Address)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: DELTA_DOWORK_REJECTED(%s)", socket.getInetAddress(), id); + + transport.localDeltaDoWorkRejected(id); + response = Response.OK_VOID; + + break; + } + case DELTA_STARTWORK_ACCEPTED : { + if (numberOfParameters != 1) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "DELTA_STARTWORK_ACCEPTED")); + + Address id = (Address)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: DELTA_STARTWORK_ACCEPTED(%s)", socket.getInetAddress(), id); + + transport.localDeltaStartWorkAccepted(id); + response = Response.OK_VOID; + + break; + } + case DELTA_STARTWORK_REJECTED : { + if (numberOfParameters != 1) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "DELTA_STARTWORK_REJECTED")); + + Address id = (Address)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: DELTA_STARTWORK_REJECTED(%s)", socket.getInetAddress(), id); + + transport.localDeltaStartWorkRejected(id); + response = Response.OK_VOID; + + break; + } + case DELTA_SCHEDULEWORK_ACCEPTED : { + if (numberOfParameters != 1) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "DELTA_SCHEDULEWORK_ACCEPTED")); + + Address id = (Address)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: DELTA_SCHEDULEWORK_ACCEPTED(%s)", socket.getInetAddress(), id); + + transport.localDeltaScheduleWorkAccepted(id); + response = Response.OK_VOID; + + break; + } + case DELTA_SCHEDULEWORK_REJECTED : { + if (numberOfParameters != 1) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "DELTA_SCHEDULEWORK_REJECTED")); + + Address id = (Address)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: DELTA_SCHEDULEWORK_REJECTED(%s)", socket.getInetAddress(), id); + + transport.localDeltaScheduleWorkRejected(id); + response = Response.OK_VOID; + + break; + } + case DELTA_WORK_SUCCESSFUL : { + if (numberOfParameters != 1) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "DELTA_WORK_SUCCESSFUL")); + + Address id = (Address)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: DELTA_WORK_SUCCESSFUL(%s)", socket.getInetAddress(), id); + + transport.localDeltaWorkSuccessful(id); + response = Response.OK_VOID; + + break; + } + case DELTA_WORK_FAILED : { + if (numberOfParameters != 1) + throw new IllegalArgumentException(bundle.invalidNumberOfParameters(numberOfParameters, + "DELTA_WORK_FAILED")); + + Address id = (Address)wois.readObject(); + + if (log.isTraceEnabled()) + log.tracef("%s: DELTA_WORK_FAILED(%s)", socket.getInetAddress(), id); + + transport.localDeltaWorkFailed(id); + response = Response.OK_VOID; + + break; + } + default : + if (log.isDebugEnabled()) + { + log.debug("Unknown command received on socket Transport"); + } + break; + } + + if (response != null) + { + sendResponse(response, returnValue); + } + else + { + sendResponse(Response.GENERIC_EXCEPTION, new Exception("Unknown command: " + commandOrdinalPosition)); + } + } + catch (WorkException we) + { + if (log.isTraceEnabled()) + log.tracef("%s: WORK_EXCEPTION(%s)", socket.getInetAddress(), we.getMessage()); + + sendResponse(Response.WORK_EXCEPTION, we); + } + catch (Throwable t) + { + if (log.isTraceEnabled()) + log.tracef("%s: THROWABLE(%s)", socket.getInetAddress(), t.getMessage()); + + sendResponse(Response.GENERIC_EXCEPTION, t); + } + finally + { + if (wois != null) + { + try + { + wois.close(); + } + catch (IOException e) + { + //ignore it + } + } + } + } + + private void sendResponse(Response response, Serializable... parameters) + { + if (log.isTraceEnabled()) + log.tracef("Sending response: %s with %s", response, + parameters != null ? Arrays.toString(parameters) : "null"); + + ObjectOutputStream oos = null; + try + { + oos = new ObjectOutputStream(socket.getOutputStream()); + oos.writeInt(response.ordinal()); + oos.writeInt(response.getNumberOfParameter()); + if (response.getNumberOfParameter() > 0 && parameters != null) + { + for (Serializable o : parameters) + { + oos.writeObject(o); + } + } + + oos.flush(); + + } + catch (Throwable t) + { + if (log.isDebugEnabled()) + { + log.debugf("Error sending response: %s", t.getMessage()); + } + } + finally + { + if (oos != null) + { + try + { + oos.close(); + } + catch (IOException e) + { + //ignore it + } + } + } + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/socket/SecurityActions.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/socket/SecurityActions.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/socket/SecurityActions.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,59 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager.transport.remote.socket; + +import org.jboss.jca.core.workmanager.ClassBundle; +import org.jboss.jca.core.workmanager.WorkClassLoader; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Privileged Blocks + * @author Jesper Pedersen + */ +class SecurityActions +{ + /** + * Constructor + */ + private SecurityActions() + { + } + + /** + * Create a WorkClassLoader + * @param cb The class bundle + * @return The class loader + */ + static WorkClassLoader createWorkClassLoader(final ClassBundle cb) + { + return AccessController.doPrivileged(new PrivilegedAction() + { + public WorkClassLoader run() + { + return new WorkClassLoader(cb); + } + }); + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/socket/SocketTransport.java =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/socket/SocketTransport.java (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/socket/SocketTransport.java (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,374 @@ +/* + * IronJacamar, a Java EE Connector Architecture implementation + * Copyright 2012, Red Hat Inc, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.jca.core.workmanager.transport.remote.socket; + +import org.jboss.jca.core.CoreBundle; +import org.jboss.jca.core.CoreLogger; +import org.jboss.jca.core.spi.workmanager.Address; +import org.jboss.jca.core.workmanager.transport.remote.AbstractRemoteTransport; +import org.jboss.jca.core.workmanager.transport.remote.ProtocolMessages.Request; +import org.jboss.jca.core.workmanager.transport.remote.ProtocolMessages.Response; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.resource.spi.work.WorkException; + +import org.jboss.logging.Logger; +import org.jboss.logging.Messages; + +/** + * The socket transport + * + * @author Jesper Pedersen + */ +public class SocketTransport extends AbstractRemoteTransport implements Runnable +{ + /** The logger */ + private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, SocketTransport.class.getName()); + + /** The bundle */ + private static CoreBundle bundle = Messages.getBundle(CoreBundle.class); + + /** The bind address */ + private String host; + + /** The bind port */ + private int port; + + /** The peers */ + private Set peers; + + /** Is the server running ? */ + private AtomicBoolean running; + + /** The server socket */ + private ServerSocket ss; + + /** Is the transport initialized */ + private boolean initialized; + + /** + * Constructor + */ + public SocketTransport() + { + super(); + this.host = null; + this.port = 0; + this.peers = null; + this.running = new AtomicBoolean(false); + this.ss = null; + this.initialized = false; + } + + /** + * {@inheritDoc} + */ + public void startup() throws Throwable + { + if (!running.get()) + { + InetSocketAddress address = new InetSocketAddress(host, port); + + ss = new ServerSocket(); + ss.bind(address); + + running.set(true); + + getExecutorService().submit(this); + } + } + + /** + * {@inheritDoc} + */ + public boolean isInitialized() + { + return initialized; + } + + /** + * {@inheritDoc} + */ + public void initialize() throws Throwable + { + if (peers != null && !initialized) + { + for (String addr : peers) + { + log.tracef("Peer: %s", addr); + + try + { + // Let other node know of us + sendMessage(addr, Request.JOIN, getOwnAddress()); + + // Update the local information + Set
workManagers = (Set
)sendMessage(addr, Request.GET_WORKMANAGERS); + + log.tracef("Peer WorkManagers: %s", workManagers); + + if (workManagers != null) + { + for (Address a : workManagers) + { + join(a, addr); + + long shortRunningFree = + (long)sendMessage(addr, Request.GET_SHORTRUNNING_FREE, a); + long longRunningFree = + (long)sendMessage(addr, Request.GET_LONGRUNNING_FREE, a); + + localUpdateShortRunningFree(a, shortRunningFree); + localUpdateLongRunningFree(a, longRunningFree); + } + } + } + catch (Throwable t) + { + log.error(t.getMessage(), t); + } + } + } + + initialized = true; + } + + /** + * {@inheritDoc} + */ + public void shutdown() throws Throwable + { + running.set(false); + + if (ss != null) + ss.close(); + } + + @Override + protected Serializable sendMessage(String address, Request request, Serializable... parameters) + throws WorkException + { + String[] addressPart = address.split(":"); + Socket socket = null; + ObjectOutputStream oos = null; + + if (log.isTraceEnabled()) + log.tracef("%s:%d: sending message=%s to %s:%s", ss.getInetAddress().getHostName(), + ss.getLocalPort(), request, addressPart[0], addressPart[1]); + + try + { + socket = new Socket(addressPart[0], Integer.valueOf(addressPart[1])); + + oos = new ObjectOutputStream(socket.getOutputStream()); + oos.writeInt(request.ordinal()); + oos.writeInt(request.getNumberOfParameter()); + if (parameters != null) + { + for (Serializable o : parameters) + { + oos.writeObject(o); + } + } + + oos.flush(); + + return parseResponse(socket); + } + catch (Throwable t) + { + if (log.isDebugEnabled()) + { + log.debug("Error sending command: " + t.getMessage(), t); + } + if (t instanceof WorkException) + { + throw (WorkException) t; + } + else + { + WorkException we = new WorkException(t.getMessage()); + we.initCause(t); + throw we; + } + } + finally + { + if (oos != null) + { + try + { + oos.close(); + } + catch (IOException e) + { + //ignore it + } + } + if (socket != null) + { + try + { + socket.close(); + } + catch (IOException e) + { + //ignore it + } + } + } + } + + private Serializable parseResponse(Socket socket) throws Throwable + { + ObjectInputStream ois = null; + + try + { + ois = new ObjectInputStream(socket.getInputStream()); + + int commandOrdinalPosition = ois.readInt(); + int numberOfParameters = ois.readInt(); + Serializable[] parameters = new Serializable[numberOfParameters]; + + for (int i = 0; i < numberOfParameters; i++) + { + Serializable parameter = (Serializable)ois.readObject(); + parameters[i] = parameter; + } + + Response response = Response.values()[commandOrdinalPosition]; + + switch (response) + { + case OK_VOID : { + return null; + } + case OK_SERIALIZABLE : { + return parameters[0]; + } + case WORK_EXCEPTION : { + WorkException we = (WorkException)parameters[0]; + throw we; + } + case GENERIC_EXCEPTION : { + Throwable t = (Throwable)parameters[0]; + throw t; + } + default : + if (log.isDebugEnabled()) + { + log.debug("Unknown response received on socket Transport"); + } + throw new WorkException("Unknown response received on socket Transport"); + } + } + finally + { + if (ois != null) + { + try + { + ois.close(); + } + catch (IOException e) + { + //ignore it + } + } + } + } + + /** + * Set the host. + * + * @param host The host to set. + */ + public void setHost(String host) + { + this.host = host; + } + + /** + * Set the port. + * + * @param port The port to set. + */ + public void setPort(int port) + { + this.port = port; + } + + /** + * Set the peers + * @param peers The peers + */ + public void setPeers(Set peers) + { + this.peers = peers; + } + + /** + * Get the physical address + * @return The value + */ + public String getOwnAddress() + { + return host + ":" + port; + } + + @Override + public void run() + { + while (running.get()) + { + try + { + java.net.Socket socket = ss.accept(); + + Runnable r = new Communication(this, socket); + this.getExecutorService().submit(r); + } + catch (Exception e) + { + if (log.isTraceEnabled()) + log.trace(e.getMessage()); + } + } + } + + @Override + public String toString() + { + return "SocketTransport [host=" + host + ", port=" + port + ", running=" + running + ", ss=" + ss + "]"; + } +} Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/socket/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/socket/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/workmanager/transport/remote/socket/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +This package contains the socket transport + Index: 3rdParty_sources/ironjacamar/org/jboss/jca/package.html =================================================================== diff -u --- 3rdParty_sources/ironjacamar/org/jboss/jca/package.html (revision 0) +++ 3rdParty_sources/ironjacamar/org/jboss/jca/package.html (revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9) @@ -0,0 +1,3 @@ + +The IronJacamar project +