/* JFox, the OpenSource J2EE Application Server
 *
 * Copyright (C) 2002 huihoo.org
 * Distributable under GNU LGPL license
 * See the GNU Lesser General Public License for more details.
 */

package org.huihoo.jfox.pool;

import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;

/**
 * 
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public class ProxyObjectFactory extends ObjectFactorySupport {

  protected Class invokerClass = null;

  /**
   * 使用 PoolableObjectInvocationHandler 作为默认的 InvocationHandler
   * @param classType PoolableObject 的 Class
   * @throws Exception
   */
  public ProxyObjectFactory(Class classType) throws Exception {
    super(classType);
    this.invokerClass = PoolableObjectInvocationHandler.class;
  }

  public ProxyObjectFactory(Class classType,Class invokerClass) throws Exception {
    super(classType);
    if(PoolableObjectInvocationHandler.class.isAssignableFrom(invokerClass)) {
      this.invokerClass = invokerClass;
    }
    else {
      throw new Exception(invokerClass.getName() + " not implements " + PoolableObjectInvocationHandler.class.getName());
    }
  }

  public boolean validateObject(PoolableObject object) {
    if(Proxy.isProxyClass(object.getClass())) {
      object = ((PoolableObjectInvocationHandler)Proxy.getInvocationHandler(object)).getPoolableObject();
    }
    return super.validateObject(object);
  }

  public PoolableObject makeObject() throws Exception {
    // 生成 PoolableObject
    PoolableObject obj = (PoolableObject)classType.newInstance();
    // 生成 PoolableObjectInvocationHandler
    InvocationHandler handler = (InvocationHandler)invokerClass.getConstructor(new Class[]{PoolableObject.class}).newInstance(new Object[]{obj});

    return (PoolableObject)Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                                                  obj.getClass().getInterfaces(),
                                                  handler);

  }

  public void destroyObject(PoolableObject object) throws Exception {
    if(Proxy.isProxyClass(object.getClass())) {
      object = ((PoolableObjectInvocationHandler)Proxy.getInvocationHandler(object)).getPoolableObject();
    }
    object.passivate();
    super.destroyObject(object);
  }

}
