Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » jdbc » [javadoc | source]
    1   /*
    2    * Hibernate, Relational Persistence for Idiomatic Java
    3    *
    4    * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
    5    * indicated by the @author tags or express copyright attribution
    6    * statements applied by the authors.  All third-party contributions are
    7    * distributed under license by Red Hat Middleware LLC.
    8    *
    9    * This copyrighted material is made available to anyone wishing to use, modify,
   10    * copy, or redistribute it subject to the terms and conditions of the GNU
   11    * Lesser General Public License, as published by the Free Software Foundation.
   12    *
   13    * This program is distributed in the hope that it will be useful,
   14    * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   15    * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
   16    * for more details.
   17    *
   18    * You should have received a copy of the GNU Lesser General Public License
   19    * along with this distribution; if not, write to:
   20    * Free Software Foundation, Inc.
   21    * 51 Franklin Street, Fifth Floor
   22    * Boston, MA  02110-1301  USA
   23    *
   24    */
   25   package org.hibernate.jdbc;
   26   
   27   import org.hibernate.HibernateException;
   28   
   29   import java.lang.reflect.InvocationHandler;
   30   import java.lang.reflect.Method;
   31   import java.lang.reflect.Proxy;
   32   import java.lang.reflect.InvocationTargetException;
   33   import java.sql.Connection;
   34   
   35   /**
   36    * A proxy for <i>borrowed</i> connections which funnels all requests back
   37    * into the ConnectionManager from which it was borrowed to be properly
   38    * handled (in terms of connection release modes).
   39    * <p/>
   40    * Note: the term borrowed here refers to connection references obtained
   41    * via {@link org.hibernate.Session#connection()} for application usage.
   42    *
   43    * @author Steve Ebersole
   44    */
   45   public class BorrowedConnectionProxy implements InvocationHandler {
   46   
   47   	private static final Class[] PROXY_INTERFACES = new Class[] { Connection.class, ConnectionWrapper.class };
   48   
   49   	private final ConnectionManager connectionManager;
   50   	private boolean useable = true;
   51   
   52   	public BorrowedConnectionProxy(ConnectionManager connectionManager) {
   53   		this.connectionManager = connectionManager;
   54   	}
   55   
   56   	/**
   57   	 * {@inheritDoc}
   58   	 */
   59   	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   60   		if ( "close".equals( method.getName() ) ) {
   61   			connectionManager.releaseBorrowedConnection();
   62   			return null;
   63   		}
   64   		// should probably no-op commit/rollback here, at least in JTA scenarios
   65   		if ( !useable ) {
   66   			throw new HibernateException( "connnection proxy not usable after transaction completion" );
   67   		}
   68   
   69   		if ( "getWrappedConnection".equals( method.getName() ) ) {
   70   			return connectionManager.getConnection();
   71   		}
   72   
   73   		try {
   74   			return method.invoke( connectionManager.getConnection(), args );
   75   		}
   76   		catch( InvocationTargetException e ) {
   77   			throw e.getTargetException();
   78   		}
   79   	}
   80   
   81   	/**
   82   	 * Generates a Connection proxy wrapping the connection managed by the passed
   83   	 * connection manager.
   84   	 *
   85   	 * @param connectionManager The connection manager to wrap with the
   86   	 * connection proxy.
   87   	 * @return The generated proxy.
   88   	 */
   89   	public static Connection generateProxy(ConnectionManager connectionManager) {
   90   		BorrowedConnectionProxy handler = new BorrowedConnectionProxy( connectionManager );
   91   		return ( Connection ) Proxy.newProxyInstance(
   92   				getProxyClassLoader(),
   93   		        PROXY_INTERFACES,
   94   		        handler
   95   		);
   96   	}
   97   
   98   	/**
   99   	 * Marks a borrowed connection as no longer usable.
  100   	 *
  101   	 * @param connection The connection (proxy) to be marked.
  102   	 */
  103   	public static void renderUnuseable(Connection connection) {
  104   		if ( connection != null && Proxy.isProxyClass( connection.getClass() ) ) {
  105   			InvocationHandler handler = Proxy.getInvocationHandler( connection );
  106   			if ( BorrowedConnectionProxy.class.isAssignableFrom( handler.getClass() ) ) {
  107   				( ( BorrowedConnectionProxy ) handler ).useable = false;
  108   			}
  109   		}
  110   	}
  111   
  112   	/**
  113   	 * Convience method for unwrapping a connection proxy and getting a
  114   	 * handle to an underlying connection.
  115   	 *
  116   	 * @param connection The connection (proxy) to be unwrapped.
  117   	 * @return The unwrapped connection.
  118   	 */
  119   	public static Connection getWrappedConnection(Connection connection) {
  120   		if ( connection != null && connection instanceof ConnectionWrapper ) {
  121   			return ( ( ConnectionWrapper ) connection ).getWrappedConnection();
  122   		}
  123   		else {
  124   			return connection;
  125   		}
  126   	}
  127   
  128   	/**
  129   	 * Determines the appropriate class loader to which the generated proxy
  130   	 * should be scoped.
  131   	 *
  132   	 * @return The class loader appropriate for proxy construction.
  133   	 */
  134   	public static ClassLoader getProxyClassLoader() {
  135   		ClassLoader cl = Thread.currentThread().getContextClassLoader();
  136   		if ( cl == null ) {
  137   			cl = BorrowedConnectionProxy.class.getClassLoader();
  138   		}
  139   		return cl;
  140   	}
  141   }

Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » jdbc » [javadoc | source]