/**
*
* Copyright 2003-2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geronimo.connector.outbound;
import java.util.Collection;
import java.util.Iterator;
import javax.resource.ResourceException;
import javax.resource.spi.DissociatableManagedConnection;
import javax.resource.spi.ManagedConnection;
import org.apache.geronimo.connector.outbound.connectiontracking.ConnectionTracker;
/**
* ConnectionTrackingInterceptor.java handles communication with the
* CachedConnectionManager. On method call entry, cached handles are
* checked for the correct Subject. On method call exit, cached
* handles are disassociated if possible. On getting or releasing
* a connection the CachedConnectionManager is notified.
*
*
* @version $Rev$ $Date$
*/
public class ConnectionTrackingInterceptor implements ConnectionInterceptor {
private final ConnectionInterceptor next;
private final String key;
private final ConnectionTracker connectionTracker;
public ConnectionTrackingInterceptor(
final ConnectionInterceptor next,
final String key,
final ConnectionTracker connectionTracker
) {
this.next = next;
this.key = key;
this.connectionTracker = connectionTracker;
}
/**
* called by: GenericConnectionManager.allocateConnection, GenericConnectionManager.associateConnection, and enter.
* in: connectionInfo is non-null, and has non-null ManagedConnectionInfo with non-null managedConnectionfactory.
* connection handle may or may not be null.
* out: connectionInfo has non-null connection handle, non null ManagedConnectionInfo with non-null ManagedConnection and GeronimoConnectionEventListener.
* connection tracker has been notified of handle-managed connection association.
* @param connectionInfo
* @throws ResourceException
*/
public void getConnection(ConnectionInfo connectionInfo) throws ResourceException {
connectionTracker.setEnvironment(connectionInfo, key);
next.getConnection(connectionInfo);
connectionTracker.handleObtained(this, connectionInfo);
}
/**
* called by: GeronimoConnectionEventListener.connectionClosed, GeronimoConnectionEventListener.connectionErrorOccurred, exit
* in: handle has already been dissociated from ManagedConnection. connectionInfo not null, has non-null ManagedConnectionInfo, ManagedConnectionInfo has non-null ManagedConnection
* handle can be null if called from error in ManagedConnection in pool.
* out: connectionTracker has been notified, ManagedConnectionInfo null.
* @param connectionInfo
* @param connectionReturnAction
*/
public void returnConnection(
ConnectionInfo connectionInfo,
ConnectionReturnAction connectionReturnAction) {
connectionTracker.handleReleased(this, connectionInfo);
next.returnConnection(connectionInfo, connectionReturnAction);
}
public void destroy() {
next.destroy();
}
public void enter(Collection connectionInfos)
throws ResourceException {
for (Iterator i = connectionInfos.iterator(); i.hasNext();) {
ConnectionInfo connectionInfo = (ConnectionInfo) i.next();
next.getConnection(connectionInfo);
}
}
public void exit(Collection connectionInfos)
throws ResourceException {
for (Iterator i = connectionInfos.iterator(); i.hasNext();) {
ConnectionInfo connectionInfo = (ConnectionInfo) i.next();
if (connectionInfo.isUnshareable()) {
//if one is, they all are
return;
}
ManagedConnectionInfo managedConnectionInfo = connectionInfo.getManagedConnectionInfo();
ManagedConnection managedConnection = managedConnectionInfo.getManagedConnection();
if (managedConnection instanceof DissociatableManagedConnection
&& managedConnectionInfo.isFirstConnectionInfo(connectionInfo)) {
int size = connectionInfos.size();
i.remove();
assert size - 1 == connectionInfos.size();
((DissociatableManagedConnection) managedConnection).dissociateConnections();
managedConnectionInfo.clearConnectionHandles();
//todo this needs some kind of check so cx isn't returned more than once
//in case dissociate calls connection closed event and returns cx to pool.
returnConnection(connectionInfo, ConnectionReturnAction.RETURN_HANDLE);
}
}
}
}