Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » proxy » [javadoc | source]
    1   //$Id: CGLIBLazyInitializer.java,v 1.9 2005/03/21 16:08:28 oneovthafew Exp $
    2   package org.hibernate.proxy;
    3   
    4   import java.io.Serializable;
    5   import java.lang.reflect.Method;
    6   
    7   import net.sf.cglib.proxy.Enhancer;
    8   import net.sf.cglib.proxy.Factory;
    9   import net.sf.cglib.proxy.MethodInterceptor;
   10   import net.sf.cglib.proxy.MethodProxy;
   11   import org.hibernate.HibernateException;
   12   import org.hibernate.engine.SessionImplementor;
   13   import org.hibernate.type.AbstractComponentType;
   14   import org.hibernate.util.ReflectHelper;
   15   
   16   import org.apache.commons.logging.LogFactory;
   17   
   18   
   19   /**
   20    * A <tt>LazyInitializer</tt> implemented using the CGLIB bytecode generation library
   21    */
   22   public final class CGLIBLazyInitializer extends BasicLazyInitializer implements MethodInterceptor {
   23   
   24   	private Class[] interfaces;
   25   	private boolean constructed = false;
   26   
   27   	static HibernateProxy getProxy(
   28   		final String entityName,
   29   		final Class persistentClass,
   30   		final Class[] interfaces,
   31   		final Method getIdentifierMethod,
   32   		final Method setIdentifierMethod,
   33   		AbstractComponentType componentIdType,
   34   		final Serializable id,
   35   		final SessionImplementor session)
   36   	throws HibernateException {
   37   		//note: interfaces is assumed to already contain HibernateProxy.class
   38   		try {
   39   			final CGLIBLazyInitializer instance = new CGLIBLazyInitializer(
   40   				entityName, 
   41   				persistentClass, 
   42   				interfaces, 
   43   				id, 
   44   				getIdentifierMethod, 
   45   				setIdentifierMethod, 
   46   				componentIdType,
   47   				session
   48   			);
   49   			final HibernateProxy proxy = (HibernateProxy) Enhancer.create(
   50   				(interfaces.length==1) ?
   51   					persistentClass :
   52   					null,
   53   				interfaces,
   54   				instance
   55   			);
   56   			instance.constructed = true;
   57   			return proxy;
   58   		}
   59   		catch (Throwable t) {
   60   			LogFactory.getLog(BasicLazyInitializer.class).error("CGLIB Enhancement failed: " + entityName, t);
   61   			throw new HibernateException( "CGLIB Enhancement failed: " + entityName, t );
   62   		}
   63   	}
   64   
   65   	public static HibernateProxy getProxy(
   66   		final Factory factory,
   67   		final String entityName,
   68   		final Class persistentClass,
   69   		final Class[] interfaces,
   70   		final Method getIdentifierMethod,
   71   		final Method setIdentifierMethod,
   72   		AbstractComponentType componentIdType,
   73   		final Serializable id,
   74   		final SessionImplementor session)
   75   	throws HibernateException {
   76   		final CGLIBLazyInitializer instance = new CGLIBLazyInitializer(
   77   			entityName, 
   78   			persistentClass, 
   79   			interfaces, 
   80   			id, 
   81   			getIdentifierMethod, 
   82   			setIdentifierMethod,
   83   			componentIdType,
   84   			session
   85   		);
   86   		final HibernateProxy proxy = (HibernateProxy) factory.newInstance(instance);
   87   		instance.constructed = true;
   88   		return proxy;
   89   	}
   90   
   91   	public static Factory getProxyFactory(Class persistentClass, Class[] interfaces) throws HibernateException {
   92   		//note: interfaces is assumed to already contain HibernateProxy.class
   93   		try {
   94   			return (Factory) Enhancer.create(
   95   				(interfaces.length==1) ?
   96   					persistentClass :
   97   					null,
   98   				interfaces,
   99   				NULL_METHOD_INTERCEPTOR
  100   			);
  101   		}
  102   		catch (Throwable t) {
  103   			LogFactory.getLog(BasicLazyInitializer.class).error(
  104   					"CGLIB Enhancement failed: " + 
  105   					persistentClass.getName(), 
  106   					t
  107   			);
  108   			throw new HibernateException( "CGLIB Enhancement failed: " + persistentClass.getName(), t );
  109   		}
  110   	}
  111   
  112   	private CGLIBLazyInitializer(
  113   		final String entityName,
  114   		final Class persistentClass,
  115   		final Class[] interfaces,
  116   		final Serializable id,
  117   		final Method getIdentifierMethod,
  118   		final Method setIdentifierMethod,
  119   		AbstractComponentType componentIdType,
  120   		final SessionImplementor session) {
  121   		super(entityName, persistentClass, id, getIdentifierMethod, setIdentifierMethod, componentIdType, session);
  122   		this.interfaces = interfaces;
  123   	}
  124   
  125   	public Object intercept(
  126   		final Object proxy,
  127   		final Method method,
  128   		final Object[] args,
  129   		final MethodProxy methodProxy)
  130   	throws Throwable {
  131   		if (constructed) {
  132   			Object result = invoke(method, args, proxy);
  133   			if (result==INVOKE_IMPLEMENTATION) {
  134   				Object target = getImplementation();
  135   				final Object returnValue;
  136   				if ( ReflectHelper.isPublic(persistentClass, method) ) {
  137   					returnValue = methodProxy.invoke(target, args);
  138   				}
  139   				else {
  140   					if ( !method.isAccessible() ) method.setAccessible(true);
  141   					returnValue = method.invoke(target, args);
  142   				}
  143   				return returnValue==target ? proxy : returnValue;
  144   			}
  145   			else {
  146   				return result;
  147   			}
  148   		}
  149   		else {
  150   			//while constructor is running
  151   			if( method.getName().equals("getHibernateLazyInitializer") ) {
  152   				return this;
  153   			}
  154   			else {
  155   				return methodProxy.invokeSuper(proxy, args);
  156   			}
  157   		}
  158   	}
  159   
  160   	protected Object serializableProxy() {
  161   		return new SerializableProxy( 
  162   			getEntityName(), 
  163   			persistentClass, 
  164   			interfaces, 
  165   			getIdentifier(), 
  166   			getIdentifierMethod, 
  167   			setIdentifierMethod,
  168   			componentIdType
  169   		);
  170   	}
  171   
  172   	private static final MethodInterceptor NULL_METHOD_INTERCEPTOR = new MethodInterceptor() {
  173   		public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
  174   			return proxy.invokeSuper(obj, args);
  175   		}
  176   	};
  177   }

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