Open Source Repository

Home /hibernate/hibernate-3.2.7.ga | Repository Home



org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java
package org.hibernate.proxy.pojo.javassist;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

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 == && 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) {
    superentityName, 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 sessionthrows 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.setSuperclassinterfaces.length == ? persistentClass : null );
      factory.setInterfacesinterfaces );
      factory.setFilterFINALIZE_FILTER );
      Class cl = factory.createClass();
      final HibernateProxy proxy = HibernateProxy cl.newInstance();
      ( ( ProxyObject proxy ).setHandlerinstance );
      instance.constructed = true;
      return proxy;
    }
    catch Throwable t ) {
      LogFactory.getLogBasicLazyInitializer.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 sessionthrows 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 ).setHandlerinstance );
    instance.constructed = true;
    return proxy;
  }

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

    try {
      ProxyFactory factory = new ProxyFactory();
      factory.setSuperclassinterfaces.length == ? persistentClass : null );
      factory.setInterfacesinterfaces );
      factory.setFilterFINALIZE_FILTER );
      return factory.createClass();
    }
    catch Throwable t ) {
      LogFactory.getLogBasicLazyInitializer.class ).error(
          "Javassist Enhancement failed: "
          + persistentClass.getName(), t
      );
      throw new HibernateException(
          "Javassist Enhancement failed: "
          + persistentClass.getName(), t
      );
    }
  }

  public Object invoke(
      final Object proxy,
      final Method thisMethod,
      final Method proceed,
      final Object[] argsthrows Throwable {
    if this.constructed ) {
      Object result;
      try {
        result = this.invokethisMethod, args, proxy );
      }
      catch Throwable t ) {
        throw new Exceptiont.getCause() );
      }
      if result == INVOKE_IMPLEMENTATION ) {
        Object target = getImplementation();
        final Object returnValue;
        try {
                    if ReflectHelper.isPublicpersistentClass, thisMethod ) ) {
            if ! thisMethod.getDeclaringClass().isInstancetarget ) ) {
                        throw new ClassCastExceptiontarget.getClass().getName() );
            }
                      returnValue = thisMethod.invoketarget, args );
                    }
                    else {
                      if !thisMethod.isAccessible() ) {
                        thisMethod.setAccessibletrue );
                      }
                      returnValue = thisMethod.invoketarget, 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.invokeproxy, args );
      }
    }
  }

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