Package ognl.helperfunction

Source Code of ognl.helperfunction.WOHelperFunctionRegistry

package ognl.helperfunction;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;

import org.apache.log4j.Logger;

import com.webobjects.foundation.NSKeyValueCoding._KeyBinding;
import com.webobjects.foundation.NSKeyValueCodingAdditions;
import com.webobjects.foundation._NSUtilities;

/**
* HelperFunctionRegistry provides a central point for registering and resolving helper functions.
*
* @author mschrag
*/
public class WOHelperFunctionRegistry {
  public static Logger log = Logger.getLogger(WOHelperFunctionRegistry.class);

  public static final String APP_FRAMEWORK_NAME = "app";

  private static WOHelperFunctionRegistry _instance;
  private Map _applicationHelperInstanceCache;
   
  private WOHelperFunctionRegistry() {
    _applicationHelperInstanceCache = new HashMap();
  }

  public static synchronized WOHelperFunctionRegistry registry() {
    if (_instance == null) {
      _instance = new WOHelperFunctionRegistry();
    }
    return _instance;
  }

  /**
   * Sets the helper object to use for the given class.
   *
   * @param helperInstance
   *            an instance of the helper class (i.e. PersonHelper)
   * @param targetObjectClass
   *            the class that maps to this helper instance (i.e. Person.class)
   * @param frameworkName
   *            the scoping of the helper instance (null, or "app" = global)
   */
  public synchronized void setHelperInstanceForClassInFrameworkNamed(Object helperInstance, Class targetObjectClass, String frameworkName) {
    setHelperInstanceForClassInFrameworkNamed(helperInstance, null, targetObjectClass, frameworkName);
  }
 
  /**
   * Sets the helper object to use for the given class.
   *
   * @param helperInstance
   *            an instance of the helper class (i.e. PersonHelper)
   * @param helperFunction
   *         the helper function being requested (i.e. formattedName)
   * @param targetObjectClass
   *            the class that maps to this helper instance (i.e. Person.class)
   * @param frameworkName
   *            the scoping of the helper instance (null, or "app" = global)
   */
  protected synchronized void setHelperInstanceForClassInFrameworkNamed(Object helperInstance, String helperFunction, Class targetObjectClass, String frameworkName) {
    if (frameworkName == null) {
      frameworkName = WOHelperFunctionRegistry.APP_FRAMEWORK_NAME;
    }
    Map frameworkHelperInstanceCache = (Map) _applicationHelperInstanceCache.get(frameworkName);
    if (frameworkHelperInstanceCache == null) {
      frameworkHelperInstanceCache = new HashMap();
      _applicationHelperInstanceCache.put(frameworkName, frameworkHelperInstanceCache);
    }
    frameworkHelperInstanceCache.put(targetObjectClass, helperInstance);
   
    if (helperFunction != null) {
      frameworkHelperInstanceCache.put(targetObjectClass.getName() + helperFunction, helperInstance);
    }
  }

  protected synchronized Object _cachedHelperInstanceForFrameworkNamed(Class targetClass, String frameworkName) {
    return __cachedHelperInstanceForFrameworkNamed(targetClass, frameworkName);
  }

  protected synchronized Object _cachedHelperInstanceForFrameworkNamed(Class targetClass, String helperFunction, String frameworkName) {
    return __cachedHelperInstanceForFrameworkNamed(targetClass.getName() + "." + helperFunction, frameworkName);
  }
 
  protected synchronized Object __cachedHelperInstanceForFrameworkNamed(Object key, String frameworkName)  {
    Object helperInstance = null;
    Map frameworkHelperInstanceCache = (Map) _applicationHelperInstanceCache.get(frameworkName);
    if (frameworkHelperInstanceCache != null) {
      helperInstance = frameworkHelperInstanceCache.get(key);
    }
    return helperInstance;
  }
 
  public synchronized Object _helperInstanceForFrameworkNamed(Object targetObject, String helperFunction, String keyPath, String frameworkName) throws SecurityException, IllegalArgumentException, InstantiationException, IllegalAccessException {
    if (frameworkName == null) {
      frameworkName = WOHelperFunctionRegistry.APP_FRAMEWORK_NAME;
    }

    if (targetObject == null) {
      throw new IllegalArgumentException("The target of a helper keypath must not be null.");
    }
    if (keyPath == null) {
      throw new NullPointerException("You must specify a keypath to use helper functions.");
    }

    Object helpedObject = NSKeyValueCodingAdditions.Utility.valueForKeyPath(targetObject, keyPath);
    Class helpedClass;
    if (helpedObject != null) {
      helpedClass = helpedObject.getClass();
    }
    else {
      _KeyBinding keyBinding = WOHelperFunctionClassKeyValueCoding.DefaultImplementation.keyGetBindingForKeyPath(targetObject.getClass(), keyPath);
      if (keyBinding != null) {
        helpedClass = keyBinding.valueType();
      }
      else {
        WOHelperFunctionRegistry.log.warn("Unable to determine the value class of the keypath '" + keyPath + "' for the object " + targetObject);
        helpedClass = Object.class;
      }
    }

    Object helperInstance = null;
    helperInstance = _cachedHelperInstanceForFrameworkNamed(helpedClass, helperFunction, frameworkName);
    if (helperInstance == null && !WOHelperFunctionRegistry.APP_FRAMEWORK_NAME.equals(frameworkName)) {
      helperInstance = _cachedHelperInstanceForFrameworkNamed(helpedClass, helperFunction, WOHelperFunctionRegistry.APP_FRAMEWORK_NAME);
    }
    if (helperInstance == null) {
      //see if we have a cached helper, but we haven't cached it for the helperFunction
      helperInstance = _cachedHelperInstanceForFrameworkNamed(helpedClass, frameworkName);
      if (helperInstance == null && !WOHelperFunctionRegistry.APP_FRAMEWORK_NAME.equals(frameworkName)) {
        helperInstance = _cachedHelperInstanceForFrameworkNamed(helpedClass, WOHelperFunctionRegistry.APP_FRAMEWORK_NAME);
      }
      if (helperInstance != null) {
        if (classImplementsMethod(helperInstance.getClass(), helperFunction)) {
          setHelperInstanceForClassInFrameworkNamed(helperInstance, helperFunction, helpedClass, frameworkName);
        } else {
          helperInstance = null;
        }
      }
    }
   
    if (helperInstance == null) {
      Class targetHelperClass = helperClassForClass(helpedClass, helperFunction);
      if (targetHelperClass == null) {
        throw new NoSuchElementException("Could not find a helper class for '" + helpedClass.getName() + " implementing " + helperFunction + "'.");
      }
      helperInstance = targetHelperClass.newInstance();
      setHelperInstanceForClassInFrameworkNamed(helperInstance, helperFunction, helpedClass, frameworkName);
    }

    return helperInstance;
  }
 
  /**
   * Attempts to locate a helper class for helpedClass that implements helperFunction.
   * If it cannot find a class called <className>Helper implementing helperFunction,
   * it looks for a helper for each of the interfaces implemented by the class, and starts the
   * process over with the superclass if that fails.
   * @param helpedClass
   * @param helperFunction
   * @return
   */
  protected Class helperClassForClass(Class helpedClass, String helperFunction) {
    String targetClassName = helpedClass.getName();
    int lastDotIndex = targetClassName.lastIndexOf('.');
    if (lastDotIndex != -1) {
      targetClassName = targetClassName.substring(lastDotIndex + 1);
    }
   
    String targetHelperName = targetClassName + "Helper";
    Class helperClass = _NSUtilities.classWithName(targetHelperName);
    if (helperClass != null && classImplementsMethod(helperClass, helperFunction)) {
      return helperClass;
    }
   
    //check for a helper for the interfaces
    Class[] interfaces = helpedClass.getInterfaces();
    for(int i = 0; i < interfaces.length; i++) {
      helperClass = helperClassForClass(interfaces[i], helperFunction);
      if ( helperClass != null && classImplementsMethod(helperClass, helperFunction)) {
        return helperClass;
      }
    }
   
    //if that fails, try the super class
    Class superClass = helpedClass.getSuperclass();
    if (superClass != null) {
      return helperClassForClass(superClass, helperFunction);
    }
   
    return null;
  }
 
  protected boolean classImplementsMethod(Class theClass, String methodName) {
    Method[] methods = theClass.getMethods();
    for(int i = 0; i < methods.length; i++) {
      if (methods[i].getName().equals(methodName)) {
        return true;
      }
    }
    return false;
  }
}
TOP

Related Classes of ognl.helperfunction.WOHelperFunctionRegistry

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.