/** * * Copyright 2003-2004 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.transaction.context; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.geronimo.transaction.ConnectionReleaser; import org.apache.geronimo.transaction.DoubleKeyedHashMap; import org.apache.geronimo.transaction.InstanceContext; /** * @version $Rev$ $Date$ */ abstract class AbstractTransactionContext implements TransactionContext { protected static final Log log = LogFactory.getLog(AbstractTransactionContext.class); protected Map managedConnections; private InstanceContext currentContext; private final DoubleKeyedHashMap associatedContexts = new DoubleKeyedHashMap(); private final DoubleKeyedHashMap dirtyContexts = new DoubleKeyedHashMap(); private Flushable inTxCache; public final void associate(InstanceContext context) throws Throwable { if (associatedContexts.put(context.getContainerId(), context.getId(), context) == null) { context.associate(); } } public final void unassociate(InstanceContext context) throws Throwable { associatedContexts.remove(context.getContainerId(), context.getId()); context.unassociate(); } public final void unassociate(Object containerId, Object id) throws Throwable { InstanceContext context = (InstanceContext) associatedContexts.remove(containerId, id); if (context != null) { context.unassociate(); } } public final InstanceContext getContext(Object containerId, Object id) { return (InstanceContext) associatedContexts.get(containerId, id); } protected final ArrayList getAssociatedContexts() { return new ArrayList(associatedContexts.values()); } protected final void unassociateAll() { ArrayList toFlush = getAssociatedContexts(); for (Iterator i = toFlush.iterator(); i.hasNext();) { InstanceContext context = (InstanceContext) i.next(); try { context.unassociate(); } catch (Throwable throwable) { log.warn("Error while unassociating instance from transaction context: " + context, throwable); } } } public final InstanceContext beginInvocation(InstanceContext context) throws Throwable { if (context.getId() != null) { associate(context); dirtyContexts.put(context.getContainerId(), context.getId(), context); } context.enter(); InstanceContext caller = currentContext; currentContext = context; return caller; } public final void endInvocation(InstanceContext caller) { if (currentContext != null) { currentContext.exit(); } currentContext = caller; } public final void flushState() throws Throwable { while (dirtyContexts.isEmpty() == false) { ArrayList toFlush = new ArrayList(dirtyContexts.values()); dirtyContexts.clear(); for (Iterator i = toFlush.iterator(); i.hasNext();) { InstanceContext context = (InstanceContext) i.next(); if (!context.isDead()) { context.flush(); } } } if (currentContext != null && currentContext.getId() != null) { dirtyContexts.put(currentContext.getContainerId(), currentContext.getId(), currentContext); } if(inTxCache != null) { inTxCache.flush(); } } public final void setInTxCache(Flushable inTxCache) { this.inTxCache = inTxCache; } public final Flushable getInTxCache() { return inTxCache; } public void setManagedConnectionInfo(ConnectionReleaser key, Object info) { if (managedConnections == null) { managedConnections = new HashMap(); } managedConnections.put(key, info); } public Object getManagedConnectionInfo(ConnectionReleaser key) { if (managedConnections == null) { return null; } return managedConnections.get(key); } }