001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    
018    package org.apache.geronimo.connector.outbound;
019    
020    import java.util.Collections;
021    
022    import javax.resource.ResourceException;
023    
024    /**
025     *
026     *
027     * @version $Rev: 585608 $ $Date: 2007-10-17 19:56:54 +0200 (Wed, 17 Oct 2007) $
028     *
029     * */
030    public class ThreadLocalCachingConnectionInterceptor implements ConnectionInterceptor {
031    
032        private final ConnectionInterceptor next;
033    
034        private final ThreadLocal<ManagedConnectionInfo> connections = new ThreadLocal<ManagedConnectionInfo>();
035        private final boolean matchConnections;
036    
037        public ThreadLocalCachingConnectionInterceptor(final ConnectionInterceptor next, final boolean matchConnections) {
038            this.next = next;
039            this.matchConnections = matchConnections;
040        }
041    
042    
043        public void getConnection(ConnectionInfo connectionInfo) throws ResourceException {
044            if (connectionInfo.isUnshareable()) {
045                next.getConnection(connectionInfo);
046                return;
047            }
048            ManagedConnectionInfo managedConnectionInfo = connections.get();
049            if (managedConnectionInfo != null) {
050                if (matchConnections) {
051                    ManagedConnectionInfo mciRequest = connectionInfo.getManagedConnectionInfo();
052                    if (null != managedConnectionInfo.getManagedConnectionFactory().matchManagedConnections(
053                            Collections.singleton(managedConnectionInfo.getManagedConnection()),
054                            mciRequest.getSubject(),
055                            mciRequest.getConnectionRequestInfo()
056                    )) {
057                        connectionInfo.setManagedConnectionInfo(managedConnectionInfo);
058                        return;
059                    } else {
060                        //match failed, get a new cx after returning this one
061                        connections.set(null);
062                        next.returnConnection(connectionInfo, ConnectionReturnAction.RETURN_HANDLE);
063                    }
064                } else {
065                    connectionInfo.setManagedConnectionInfo(managedConnectionInfo);
066                    return;
067                }
068            }
069            //nothing for this thread or match failed
070            next.getConnection(connectionInfo);
071            connections.set(connectionInfo.getManagedConnectionInfo());
072        }
073    
074        public void returnConnection(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction) {
075            if (connectionReturnAction == ConnectionReturnAction.DESTROY || connectionInfo.isUnshareable()) {
076                next.returnConnection(connectionInfo, connectionReturnAction);
077            }
078        }
079        
080        public void destroy() {
081            next.destroy();
082        }
083    }