javassistlazyinitializer.java

来自「好东西,hibernate-3.2.0,他是一开元的树杖hibernate-3.」· Java 代码 · 共 246 行

JAVA
246
字号
package org.hibernate.proxy.pojo.javassist;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javassist.util.proxy.MethodFilter;
import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyFactory;
import javassist.util.proxy.ProxyObject;

import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.proxy.pojo.BasicLazyInitializer;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.type.AbstractComponentType;
import org.hibernate.util.ReflectHelper;

/**
 * A Javassist-based lazy initializer proxy.
 *
 * @author Muga Nishizawa
 */
public class JavassistLazyInitializer extends BasicLazyInitializer implements MethodHandler {

	private static final MethodFilter FINALIZE_FILTER = new MethodFilter() {
		public boolean isHandled(Method m) {
			// skip finalize methods
			return !( m.getParameterTypes().length == 0 && m.getName().equals( "finalize" ) );
		}
	};

	private Class[] interfaces;
	private boolean constructed = false;

	private JavassistLazyInitializer(
			final String entityName,
	        final Class persistentClass,
	        final Class[] interfaces,
	        final Serializable id,
	        final Method getIdentifierMethod,
	        final Method setIdentifierMethod,
	        final AbstractComponentType componentIdType,
	        final SessionImplementor session) {
		super( entityName, persistentClass, id, getIdentifierMethod, setIdentifierMethod, componentIdType, session );
		this.interfaces = interfaces;
	}

	public static HibernateProxy getProxy(
			final String entityName,
	        final Class persistentClass,
	        final Class[] interfaces,
	        final Method getIdentifierMethod,
	        final Method setIdentifierMethod,
	        AbstractComponentType componentIdType,
	        final Serializable id,
	        final SessionImplementor session) throws HibernateException {
		// note: interface is assumed to already contain HibernateProxy.class
		try {
			final JavassistLazyInitializer instance = new JavassistLazyInitializer(
					entityName,
			        persistentClass,
			        interfaces,
			        id,
			        getIdentifierMethod,
			        setIdentifierMethod,
			        componentIdType,
			        session
			);
			ProxyFactory factory = new ProxyFactory();
			factory.setSuperclass( interfaces.length == 1 ? persistentClass : null );
			factory.setInterfaces( interfaces );
			factory.setFilter( FINALIZE_FILTER );
			factory.setHandler( instance );
			Class cl = factory.createClass();
			final HibernateProxy proxy = ( HibernateProxy ) cl.newInstance();
			instance.constructed = true;
			return proxy;
		}
		catch ( Throwable t ) {
			LogFactory.getLog( BasicLazyInitializer.class ).error(
					"Javassist Enhancement failed: " + entityName, t
			);
			throw new HibernateException(
					"Javassist Enhancement failed: "
					+ entityName, t
			);
		}
	}

	public static HibernateProxy getProxy(
			final Class factory,
	        final String entityName,
	        final Class persistentClass,
	        final Class[] interfaces,
	        final Method getIdentifierMethod,
	        final Method setIdentifierMethod,
	        final AbstractComponentType componentIdType,
	        final Serializable id,
	        final SessionImplementor session) throws HibernateException {

		final JavassistLazyInitializer instance = new JavassistLazyInitializer(
				entityName,
		        persistentClass,
		        interfaces, id,
		        getIdentifierMethod,
		        setIdentifierMethod,
		        componentIdType,
		        session
		);

		final HibernateProxy proxy;
		try {
			proxy = ( HibernateProxy ) factory.newInstance();
		}
		catch ( Exception e ) {
			throw new HibernateException(
					"Javassist Enhancement failed: "
					+ persistentClass.getName(), e
			);
		}
		( ( ProxyObject ) proxy ).setHandler( instance );
		instance.constructed = true;
		return proxy;
	}

	public static Class getProxyFactory(
			Class persistentClass,
	        Class[] interfaces) throws HibernateException {
		// note: interfaces is assumed to already contain HibernateProxy.class

		try {
			ProxyFactory factory = new ProxyFactory();
			factory.setSuperclass( interfaces.length == 1 ? persistentClass : null );
			factory.setInterfaces( interfaces );
			factory.setFilter( FINALIZE_FILTER );
			return factory.createClass();
			// TODO
		}
		catch ( Throwable t ) {
			LogFactory.getLog( BasicLazyInitializer.class ).error(
					"Javassist Enhancement failed: "
					+ persistentClass.getName(), t
			);
			throw new HibernateException(
					"Javassist Enhancement failed: "
					+ persistentClass.getName(), t
			);
		}
	}

	private static boolean isCastable(Class caster, Class castee) {
		if ( castee.equals( caster ) ) {
			return true;
		}
		List list = addCheckingTypes( caster, new ArrayList() );
		for ( Iterator iter = list.iterator(); iter.hasNext(); ) {
			Class cl = ( Class ) iter.next();
			if ( castee.equals( cl ) ) {
				return true;
			}
		}
		return false;
	}

	private static List addCheckingTypes(final Class type, final List list) {
		Class superclass = type.getSuperclass();
		if ( superclass != null ) {
			list.add( superclass );
			addCheckingTypes( superclass, list );
		}
		Class[] interfaces = type.getInterfaces();
		for ( int i = 0; i < interfaces.length; ++i ) {
			list.add( interfaces[i] );
			addCheckingTypes( interfaces[i], list );
		}
		return list;
	}

	public Object invoke(
			final Object proxy,
			final Method thisMethod,
			final Method proceed,
			final Object[] args) throws Throwable {
		if ( this.constructed ) {
			Object result;
			try {
				result = this.invoke( thisMethod, args, proxy );
			}
			catch ( Throwable t ) {
				throw new Exception( t.getCause() );
			}
			if ( result == INVOKE_IMPLEMENTATION ) {
				Object target = getImplementation();
				final Object returnValue;
				try {
                    if ( ReflectHelper.isPublic( persistentClass, thisMethod ) ) {
                    	if ( !isCastable( target.getClass(), thisMethod.getDeclaringClass()) ) {
                    		throw new ClassCastException( target.getClass().getName() );
                    	}
                    	returnValue = thisMethod.invoke( target, args );
                    }
                    else {
                    	if ( !thisMethod.isAccessible() ) {
                    		thisMethod.setAccessible( true );
                    	}
                    	returnValue = thisMethod.invoke( target, args );
                    }
                    return returnValue == target ? proxy : returnValue;
                }
				catch ( InvocationTargetException ite ) {
                    throw ite.getTargetException();
                }
			}
			else {
				return result;
			}
		}
		else {
			// while constructor is running
			if ( thisMethod.getName().equals( "getHibernateLazyInitializer" ) ) {
				return this;
			}
			else {
				return proceed.invoke( proxy, args );
			}
		}
	}

	protected Object serializableProxy() {
		return new SerializableProxy(
				getEntityName(),
		        persistentClass,
		        interfaces,
		        getIdentifier(),
		        getIdentifierMethod,
		        setIdentifierMethod,
		        componentIdType
		);
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?