Package com.compoundtheory.coldfusion.cfc

Source Code of com.compoundtheory.coldfusion.cfc.CFCDynamicProxy

/**
*
*/
package com.compoundtheory.coldfusion.cfc;

import java.io.File;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import coldfusion.filter.FusionContext;
import coldfusion.runtime.TemplateProxy;
import coldfusion.runtime.TemplateProxyFactory;

/**
* This is a dynamic proxy for ColdFusion components, for complete
* interoperability between CFCs and Java objects,.
*
* Creation of the Proxy is done through one of the several createInstance() methods.
*
* @author Mark Mandel
*
*/
public class CFCDynamicProxy implements InvocationHandler
{
  private TemplateProxy cfc;
 
  private static enum ObjectMethod {
   
    HASHCODE("hashCode");
   
    public final String name;
    private ObjectMethod(String name)
    {
      this.name = name;
    }
  }
 
  private static final Map<String, ObjectMethod> METHOD_MAP = new HashMap<String, ObjectMethod>();
  static {
    for(ObjectMethod method : ObjectMethod.values())
    {
      METHOD_MAP.put(method.name, method);
    }
  }
 
  /**
   * Private constructor
   * @param cfc the CFC that this Proxy wraps
   */
  private CFCDynamicProxy(TemplateProxy cfc)
  {
    setCFC(cfc);
  }
 
  /**
   * Private constructor
   * @param path the path to the CFC that this proxy wraps.
   * @throws Throwable
   */
  private CFCDynamicProxy(String path) throws Throwable
  {
    TemplateProxy cfc = TemplateProxyFactory.resolveFile(FusionContext.getCurrent().pageContext, new File(path), null);
   
    setCFC(cfc);
  }
 
  /**
   * Private constructor
   * @param file A file that points to the CFC this proxy will wrap.
   * @throws Throwable
   */
  private CFCDynamicProxy(File file) throws Throwable
  {
    TemplateProxy cfc = TemplateProxyFactory.resolveFile(FusionContext.getCurrent().pageContext, file, null);
   
    setCFC(cfc);
  }
 
  /**
   * Create a proxy instance
   * @param path The File that points to the CFC
   * @param interfaces the proxy will implement
   * @return the proxy that implements the interfaces given
   * @throws Throwable if there is an error in the CFC
   */
  public static Object createInstance(File path, Class<?>[] interfaces) throws Throwable
  {
    CFCDynamicProxy proxy = new CFCDynamicProxy(path);
   
    return createInstance(proxy, interfaces);
  }
 
  /**
   * Create a proxy instance
   * @param path Absolute path to the CFC we want to proxy
   * @param interfaces the proxy will implement
   * @return the proxy that implements the interfaces given
   * @throws Throwable if there is an error in the CFC
   */
  public static Object createInstance(String path, Class<?>[] interfaces) throws Throwable
  {
    CFCDynamicProxy proxy = new CFCDynamicProxy(path);
   
    return createInstance(proxy, interfaces);
  }

  /**
   * Create a proxy instance
   * @param path The File that points to the CFC
   * @param interfaces An array of the names of the classes that this proxy will implement.
   * @return the proxy that implements the interfaces given
   * @throws Throwable if there is an error in the CFC
   */
  public static Object createInstance(File path, String[] interfaces) throws Throwable
  {
    Class<?>[] resolvedInterfaces = resolveInterfaces(interfaces);
   
    CFCDynamicProxy proxy = new CFCDynamicProxy(path);
   
    return createInstance(proxy, resolvedInterfaces);
  }
 
  /**
   * Create a proxy instance
   * @param path Absolute path to the CFC we want to proxy
   * @param interfaces An array of the names of the classes that this proxy will implement.
   * @return the proxy that implements the interfaces given
   * @throws Throwable if there is an error in the CFC
   */
  public static Object createInstance(String path, String[] interfaces) throws Throwable
  {
    Class<?>[] resolvedInterfaces = resolveInterfaces(interfaces);
   
    CFCDynamicProxy proxy = new CFCDynamicProxy(path);
   
    return createInstance(proxy, resolvedInterfaces);
  }

  /**
   * Create a proxy instance
   * @param path Absolute path to the CFC we want to proxy
   * @param interfaces A List of the names of the classes that this proxy will implement.
   * @return the proxy that implements the interfaces given
   * @throws Throwable if there is an error in the CFC
   */
  public static Object createInstance(String path, List<String> interfaces) throws Throwable
  {
    Class<?>[] resolvedInterfaces = resolveInterfaces(interfaces.toArray(new String[0]));
   
    CFCDynamicProxy proxy = new CFCDynamicProxy(path);
   
    return createInstance(proxy, resolvedInterfaces);
 
 
  /**
   * Create a proxy instance
   * @param cfc An actual CFC to pass in to the proxy.
   * @param interfaces the proxy will implement
   * @return the proxy that implements the interfaces given
   */
  public static Object createInstance(TemplateProxy cfc, Class<?>[] interfaces)
  {
    CFCDynamicProxy proxy = new CFCDynamicProxy(cfc);
   
    return createInstance(proxy, interfaces);
  }

  /**
   * Create a proxy instance
   * @param cfc An actual CFC to pass in to the proxy.
   * @param interfaces An array of the names of the classes that this proxy will implement.
   * @return the proxy that implements the interfaces given
   * @throws Throwable if there is an error in the CFC
   */
  public static Object createInstance(TemplateProxy cfc, String[] interfaces) throws Throwable
  {
    Class<?>[] resolvedInterfaces = resolveInterfaces(interfaces);
   
    CFCDynamicProxy proxy = new CFCDynamicProxy(cfc);
   
    return createInstance(proxy, resolvedInterfaces);
 

  /**
   * Create a proxy instance
   * @param cfc An actual CFC to pass in to the proxy.
   * @param interfaces A List of the names of the classes that this proxy will implement.
   * @return the proxy that implements the interfaces given
   * @throws Throwable if there is an error in the CFC
   */
  public static Object createInstance(TemplateProxy cfc, List<String> interfaces) throws Throwable
  {
    Class<?>[] resolvedInterfaces = resolveInterfaces(interfaces.toArray(new String[0]));
   
    CFCDynamicProxy proxy = new CFCDynamicProxy(cfc);
   
    return createInstance(proxy, resolvedInterfaces);
  }
 

  /**
   * utility method to create the actual dynamic proxy instance
   * @param proxy An instance of this class to use as the InvocationHandler
   * @param interfaces class array for the dynamic proxy
   * @return
   */
  private static Object createInstance(CFCDynamicProxy proxy, Class<?>[] interfaces)
  {
    return Proxy.newProxyInstance(proxy.getClass().getClassLoader(), interfaces, proxy);
  }
 
  /**
   * Turns an array of string class names into an array of classes.
   * @param interfaces the array of class names
   * @return an actual class array
   * @throws ClassNotFoundException if the Class cannot be found
   */
  private static Class<?>[] resolveInterfaces(String[] interfaces) throws ClassNotFoundException
  {
    Class<?>[] resolvedInterfaces = new Class<?>[interfaces.length];
   
    ClassLoader classLoader = CFCDynamicProxy.class.getClassLoader();
   
    for(int counter = 0; counter < interfaces.length; counter++)
    {
      resolvedInterfaces[counter] = classLoader.loadClass(interfaces[counter]);
    }
   
    return resolvedInterfaces;
 
 
  /* (non-Javadoc)
   * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
   */
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
  {
    if(args == null)
    {
      args = new Object[0];
    }
   
    try
    {
      return getCFC().invoke(method.getName(), args, FusionContext.getCurrent().pageContext);
    }
    catch(TemplateProxy.InvalidMethodNameException exc)
    {
      /**
       * This is here because when reporting exceptions, CF will ask for the
       * hashCode of the object, so we will have a backup for certain methods
       * if need be.
       */
      String name = method.getName();
      if(METHOD_MAP.containsKey(name))
      {
        ObjectMethod objectMethod = METHOD_MAP.get(name);
       
        switch(objectMethod)
        {
          case HASHCODE:
            return getCFC().hashCode();
         
        }
      }
     
      throw exc;
    }
  }
 
  private TemplateProxy getCFC()
  {
    return cfc;
  }

  private void setCFC(TemplateProxy cfc)
  {
    this.cfc = cfc;
  }
}
TOP

Related Classes of com.compoundtheory.coldfusion.cfc.CFCDynamicProxy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.