Package ognl.helperfunction

Source Code of ognl.helperfunction.WOHelperFunctionClassKeyValueCoding$DefaultImplementation

package ognl.helperfunction;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import com.webobjects.foundation.NSKeyValueCoding;
import com.webobjects.foundation.NSKeyValueCoding.ValueAccessor;
import com.webobjects.foundation.NSKeyValueCoding._BooleanFieldBinding;
import com.webobjects.foundation.NSKeyValueCoding._BooleanMethodBinding;
import com.webobjects.foundation.NSKeyValueCoding._FieldBinding;
import com.webobjects.foundation.NSKeyValueCoding._KeyBinding;
import com.webobjects.foundation.NSKeyValueCoding._MethodBinding;
import com.webobjects.foundation.NSKeyValueCoding._NumberFieldBinding;
import com.webobjects.foundation.NSKeyValueCoding._NumberMethodBinding;
import com.webobjects.foundation.NSKeyValueCoding._ReflectionKeyBindingCreation.Callback;
import com.webobjects.foundation.NSLog;
import com.webobjects.foundation.NSMutableDictionary;
import com.webobjects.foundation.NSMutableSet;
import com.webobjects.foundation._NSReflectionUtilities;
import com.webobjects.foundation._NSThreadsafeMutableDictionary;
import com.webobjects.foundation._NSThreadsafeMutableSet;
import com.webobjects.foundation._NSUtilities;

/**
* WOHelperFunctionClassKeyValueCoding is basically just like NSKVC except that
* it operates ONLY on Classes, and not on Objects.  This is required if you have
* a keypath with evaluates to null, and you need to figure out the type of the
* Helper to pass the null value to.
*
* @author mschrag
*/
public class WOHelperFunctionClassKeyValueCoding {
  public static class _ReflectionKeyBindingCreation {
    public static _KeyBinding _NotAvailableIndicator = new _KeyBinding(null, null);
    private static final _NSThreadsafeMutableDictionary _bindingStorageMapTable = new _NSThreadsafeMutableDictionary(new NSMutableDictionary(256));
    public static final int _ValueForKeyLookupOrder[] = { 0, 1, 3, 2, 4 };
    public static final int _StoredValueForKeyLookupOrder[] = { 1, 3, 2, 4, 0 };

    private static class _BindingStorage {
      _KeyBinding _keyGetBindings[];
      _KeyBinding _keySetBindings[];

      public _BindingStorage() {

        _keyGetBindings = new _KeyBinding[4];
        _keySetBindings = new _KeyBinding[4];
      }
    }

    public static _KeyBinding _fieldKeyBinding(Class objectClass, String key, String fieldName) {
      ValueAccessor valueAccessor = ValueAccessor._valueAccessorForClass(objectClass);
      boolean publicFieldOnly = valueAccessor == null;
      Field field = _NSReflectionUtilities._fieldForClass(objectClass, fieldName, publicFieldOnly);
      if (field != null) {
        Class valueClass = _NSUtilities.classObjectForClass(field.getType());
        if (_NSUtilities._isClassANumber(valueClass)) {
          return new _NumberFieldBinding(objectClass, key, field, valueClass, valueAccessor);
        }
        if (_NSUtilities._isClassABoolean(valueClass)) {
          return new _BooleanFieldBinding(objectClass, key, field, valueAccessor);
        }
        return new _FieldBinding(objectClass, key, field, valueAccessor);
      }
      return null;
    }

      private static final Class _noArgumentTypes[] = new Class[0];

      // MS: slurped in from _NSReflectionUtilities because the original won't return a typed keypath for an abstract method, which
      // means you don't get type information when you bind a helper function to an interface method
      public static Method _methodForClass(Class objectClass, String methodName, Class argumentTypes[], boolean publicMethodOnly) {
        Method method = null;
        if (publicMethodOnly) {
          try {
            method = objectClass.getMethod(methodName, argumentTypes == null ? _noArgumentTypes : argumentTypes);
          }
          catch (NoSuchMethodException exception) {
            NSLog._conditionallyLogPrivateException(exception);
          }
          catch (SecurityException exception) {
            NSLog._conditionallyLogPrivateException(exception);
            method = null;
          }
        }
        else {
          do {
            if (objectClass == _NSUtilities._ObjectClass || method != null) {
              break;
            }
            try {
              method = objectClass.getDeclaredMethod(methodName, argumentTypes == null ? _noArgumentTypes : argumentTypes);
            }
            catch (NoSuchMethodException exception) {
              NSLog._conditionallyLogPrivateException(exception);
            }
            catch (SecurityException exception) {
              NSLog._conditionallyLogPrivateException(exception);
              method = null;
            }
            if (method == null) {
              objectClass = objectClass.getSuperclass();
            }
          } while (true);
        }
        if (method != null) {
          int modifiers = method.getModifiers();
          if (Modifier.isPrivate(modifiers) || Modifier.isStatic(modifiers)/* || Modifier.isAbstract(modifiers)*/) {
            return null;
          }
        }
        return method;
      }
 
    public static _KeyBinding _methodKeyGetBinding(Class objectClass, String key, String methodName) {
      ValueAccessor valueAccessor = ValueAccessor._valueAccessorForClass(objectClass);
      boolean publicMethodOnly = valueAccessor == null;
      Method method = WOHelperFunctionClassKeyValueCoding._ReflectionKeyBindingCreation._methodForClass(objectClass, methodName, null, publicMethodOnly);
      if (method != null) {
        Class valueClass = _NSUtilities.classObjectForClass(method.getReturnType());
        if (_NSUtilities._isClassANumber(valueClass)) {
          return new _NumberMethodBinding(objectClass, key, method, valueClass, valueAccessor);
        }
        if (_NSUtilities._isClassABoolean(valueClass)) {
          return new _BooleanMethodBinding(objectClass, key, method, valueAccessor);
        }
        return new _MethodBinding(objectClass, key, method, valueAccessor);
      }
      return null;
    }

    public static _KeyBinding _methodKeySetBinding(Class objectClass, String key, String methodName) {
      ValueAccessor valueAccessor = ValueAccessor._valueAccessorForClass(objectClass);
      boolean publicMethodOnly = valueAccessor == null;
      Method method = _NSReflectionUtilities._methodWithOneArgumentOfUnknownType(objectClass, methodName, key, publicMethodOnly, true, null, true);
      if (method != null) {
        Class valueClass = _NSUtilities.classObjectForClass(method.getParameterTypes()[0]);
        if (_NSUtilities._isClassANumber(valueClass)) {
          return new _NumberMethodBinding(objectClass, key, method, valueClass, valueAccessor);
        }
        if (_NSUtilities._isClassABoolean(valueClass)) {
          return new _BooleanMethodBinding(objectClass, key, method, valueAccessor);
        }
        return new _MethodBinding(objectClass, key, method, valueAccessor);
      }
      return null;
    }

    private static _KeyBinding _createKeyBindingForKey(Class objectClass, String key, int lookupOrder[], boolean trueForSetAndFalseForGet) {
      if (key == null || key.length() == 0) {
        return null;
      }
      boolean canAccessFieldsDirectlyTestPerformed = false;
      boolean canAccessFieldsDirectly = false;
      _KeyBinding lookupBinding = new _KeyBinding(objectClass, key);
      _BindingStorage bindingStorage = (_BindingStorage) _bindingStorageMapTable.objectForKey(lookupBinding);
      if (bindingStorage == null) {
        bindingStorage = new _BindingStorage();
        _bindingStorageMapTable.setObjectForKey(bindingStorage, lookupBinding);
      }
      // MS: We just can't support callbacks without the original object
      // ... I think this is PROBABLY OK for our purposes.
      Callback keyBindingCreationCallbackObject = null;
      // (object instanceof Callback) ? (Callback) object : null;
      _KeyBinding keyBindings[] = trueForSetAndFalseForGet ? bindingStorage._keySetBindings : bindingStorage._keyGetBindings;
      for (int i = 0; i < lookupOrder.length; i++) {
        int lookup = lookupOrder[i];
        _KeyBinding keyBinding = lookup < 0 || lookup > 3 ? null : keyBindings[lookup];
        if (keyBinding == null) {
          switch (lookup) {
          case 0:

            StringBuilder methodNameBuffer = new StringBuilder(key.length() + 3);

            methodNameBuffer.append(trueForSetAndFalseForGet ? "set" : "get");

            methodNameBuffer.append(Character.toUpperCase(key.charAt(0)));

            methodNameBuffer.append(key.substring(1));

            String methodName = methodNameBuffer.toString();

            if (trueForSetAndFalseForGet) {
              keyBinding = keyBindingCreationCallbackObject == null ? _methodKeySetBinding(objectClass, key, methodName) : keyBindingCreationCallbackObject._methodKeySetBinding(key, methodName);
            }
            else {
              keyBinding = keyBindingCreationCallbackObject == null ? _methodKeyGetBinding(objectClass, key, methodName) : keyBindingCreationCallbackObject._methodKeyGetBinding(key, methodName);
              if (keyBinding == null) {
                keyBinding = keyBindingCreationCallbackObject == null ? _methodKeyGetBinding(objectClass, key, key) : keyBindingCreationCallbackObject._methodKeyGetBinding(key, key);
              }
              if (keyBinding == null) {
                methodNameBuffer.setLength(0);
                methodNameBuffer.append("is");
                methodNameBuffer.append(Character.toUpperCase(key.charAt(0)));
                methodNameBuffer.append(key.substring(1));
                methodName = methodNameBuffer.toString();
                keyBinding = keyBindingCreationCallbackObject == null ? _methodKeyGetBinding(objectClass, key, methodName) : keyBindingCreationCallbackObject._methodKeyGetBinding(key, methodName);
              }
            }
            break;
          case 1:

            StringBuilder underbarMethodNameBuffer = new StringBuilder(key.length() + 4);

            underbarMethodNameBuffer.append(trueForSetAndFalseForGet ? "_set" : "_get");

            underbarMethodNameBuffer.append(Character.toUpperCase(key.charAt(0)));

            underbarMethodNameBuffer.append(key.substring(1));

            String underbarMethodName = underbarMethodNameBuffer.toString();

            if (trueForSetAndFalseForGet) {
              keyBinding = keyBindingCreationCallbackObject == null ? _methodKeySetBinding(objectClass, key, underbarMethodName) : keyBindingCreationCallbackObject._methodKeySetBinding(key, underbarMethodName);
            }
            else {
              keyBinding = keyBindingCreationCallbackObject == null ? _methodKeyGetBinding(objectClass, key, underbarMethodName) : keyBindingCreationCallbackObject._methodKeyGetBinding(key, underbarMethodName);
              if (keyBinding == null) {
                underbarMethodNameBuffer.setLength(0);
                underbarMethodNameBuffer.append('_');
                underbarMethodNameBuffer.append(key);
                underbarMethodName = underbarMethodNameBuffer.toString();
                keyBinding = keyBindingCreationCallbackObject == null ? _methodKeyGetBinding(objectClass, key, underbarMethodName) : keyBindingCreationCallbackObject._methodKeyGetBinding(key, underbarMethodName);
              }
              if (keyBinding == null) {
                underbarMethodNameBuffer.setLength(0);
                underbarMethodNameBuffer.append("_is");
                underbarMethodNameBuffer.append(Character.toUpperCase(key.charAt(0)));
                underbarMethodNameBuffer.append(key.substring(1));
                underbarMethodName = underbarMethodNameBuffer.toString();
                keyBinding = keyBindingCreationCallbackObject == null ? _methodKeyGetBinding(objectClass, key, underbarMethodName) : keyBindingCreationCallbackObject._methodKeyGetBinding(key, underbarMethodName);
              }
            }
            break;
          case 2:

            if (!canAccessFieldsDirectlyTestPerformed) {
              canAccessFieldsDirectlyTestPerformed = true;
              canAccessFieldsDirectly = NSKeyValueCoding._ReflectionKeyBindingCreation._canAccessFieldsDirectlyForClass(objectClass);
            }

            if (canAccessFieldsDirectly) {
              keyBinding = keyBindingCreationCallbackObject == null ? _fieldKeyBinding(objectClass, key, key) : keyBindingCreationCallbackObject._fieldKeyBinding(key, key);
              if (keyBinding == null) {
                StringBuilder fieldNameBuffer = new StringBuilder(key.length() + 2);
                fieldNameBuffer.append("is");
                fieldNameBuffer.append(Character.toUpperCase(key.charAt(0)));
                fieldNameBuffer.append(key.substring(1));
                String fieldName = fieldNameBuffer.toString();
                keyBinding = keyBindingCreationCallbackObject == null ? _fieldKeyBinding(objectClass, key, fieldName) : keyBindingCreationCallbackObject._fieldKeyBinding(key, fieldName);
              }
            }
            break;
          case 3:

            if (!canAccessFieldsDirectlyTestPerformed) {
              canAccessFieldsDirectlyTestPerformed = true;
              canAccessFieldsDirectly = NSKeyValueCoding._ReflectionKeyBindingCreation._canAccessFieldsDirectlyForClass(objectClass);
            }

            if (canAccessFieldsDirectly) {
              StringBuilder underbarFieldNameBuffer = new StringBuilder(key.length() + 3);
              underbarFieldNameBuffer.append('_');
              underbarFieldNameBuffer.append(key);
              String underbarFieldName = underbarFieldNameBuffer.toString();
              keyBinding = keyBindingCreationCallbackObject == null ? _fieldKeyBinding(objectClass, key, underbarFieldName) : keyBindingCreationCallbackObject._fieldKeyBinding(key, underbarFieldName);
              if (keyBinding == null) {
                underbarFieldNameBuffer.setLength(0);
                underbarFieldNameBuffer.append("_is");
                underbarFieldNameBuffer.append(Character.toUpperCase(key.charAt(0)));
                underbarFieldNameBuffer.append(key.substring(1));
                underbarFieldName = underbarFieldNameBuffer.toString();
                keyBinding = keyBindingCreationCallbackObject == null ? _fieldKeyBinding(objectClass, key, underbarFieldName) : keyBindingCreationCallbackObject._fieldKeyBinding(key, underbarFieldName);
              }
            }
            break;
          case 4:

            keyBinding = keyBindingCreationCallbackObject == null ? null : keyBindingCreationCallbackObject._otherStorageBinding(key);
            break;
          }
          if (keyBinding == null) {
            keyBinding = _NotAvailableIndicator;
          }
          if (lookup == 2 || lookup == 3) {
            bindingStorage._keySetBindings[lookup] = bindingStorage._keyGetBindings[lookup] = keyBinding;
          }
          else if (lookup == 0 || lookup == 1) {
            keyBindings[lookup] = keyBinding;
          }
        }
        if (keyBinding != null && keyBinding != _NotAvailableIndicator) {
          return keyBinding;
        }
      }
      return null;
    }

    public static _KeyBinding _createKeyGetBindingForKey(Class objectClass, String key, int lookupOrder[]) {
      return _createKeyBindingForKey(objectClass, key, lookupOrder, false);
    }

    public static _KeyBinding _createKeySetBindingForKey(Class objectClass, String key, int lookupOrder[]) {
      return _createKeyBindingForKey(objectClass, key, lookupOrder, true);
    }
  }

  public static class DefaultImplementation {
    private static final _NSThreadsafeMutableSet _keyGetBindings = new _NSThreadsafeMutableSet(new NSMutableSet(256));
    private static final _NSThreadsafeMutableSet _keySetBindings = new _NSThreadsafeMutableSet(new NSMutableSet(256));

    public static void _flushCaches() {
      _keyGetBindings.removeAllObjects();
      _keySetBindings.removeAllObjects();
    }

    public static _KeyBinding _keyGetBindingForKey(Class objectClass, String key) {
      _KeyBinding keyBinding = (_KeyBinding) _keyGetBindings.member(new _KeyBinding(objectClass, key));
      if (keyBinding == null) {
        //keyBinding = (object instanceof _KeyBindingCreation) ? ((_KeyBindingCreation) object)._createKeyGetBindingForKey(key) : _createKeyGetBindingForKey(objectClass, key);
        keyBinding = _createKeyGetBindingForKey(objectClass, key);
        if (keyBinding == null) {
          keyBinding = new _KeyBinding(objectClass, key);
        }
        _keyGetBindings.addObject(keyBinding);
      }
      return keyBinding;
    }

    public static _KeyBinding _keySetBindingForKey(Class objectClass, String key) {
      _KeyBinding keyBinding = (_KeyBinding) _keySetBindings.member(new _KeyBinding(objectClass, key));
      if (keyBinding == null) {
        //keyBinding = (object instanceof _KeyBindingCreation) ? ((_KeyBindingCreation) object)._createKeySetBindingForKey(key) : _createKeySetBindingForKey(objectClass, key);
        keyBinding = _createKeySetBindingForKey(objectClass, key);
        if (keyBinding == null) {
          keyBinding = new _KeyBinding(objectClass, key);
        }
        _keySetBindings.addObject(keyBinding);
      }
      return keyBinding;
    }

    public static _KeyBinding _createKeyGetBindingForKey(Class objectClass, String key) {
      _KeyBinding keyBinding = _ReflectionKeyBindingCreation._createKeyGetBindingForKey(objectClass, key, _ReflectionKeyBindingCreation._ValueForKeyLookupOrder);
      return keyBinding;
    }

    public static _KeyBinding _createKeySetBindingForKey(Class objectClass, String key) {
      return _ReflectionKeyBindingCreation._createKeySetBindingForKey(objectClass, key, _ReflectionKeyBindingCreation._ValueForKeyLookupOrder);
    }

    public static _KeyBinding keyGetBindingForKeyPath(Class objectClass, String keyPath) {
      if (keyPath == null) {
        return null;
      }

      int index = keyPath.indexOf('.');
      if (index < 0) {
        return WOHelperFunctionClassKeyValueCoding.DefaultImplementation._keyGetBindingForKey(objectClass, keyPath);
      }
      String key = keyPath.substring(0, index);
      _KeyBinding keyBinding = WOHelperFunctionClassKeyValueCoding.DefaultImplementation._keyGetBindingForKey(objectClass, key);
      return keyBinding != null ? WOHelperFunctionClassKeyValueCoding.DefaultImplementation.keyGetBindingForKeyPath(keyBinding.valueType(), keyPath.substring(index + 1)) : null;
    }

    DefaultImplementation() {
      throw new IllegalStateException("Cannot instantiate an instance of class " + getClass().getName());
    }
  }
}
TOP

Related Classes of ognl.helperfunction.WOHelperFunctionClassKeyValueCoding$DefaultImplementation

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.
iv>