@Override
 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) {
   if (getControllerMethod.equals(method)) {
     return this.controllerMethod;
   } else if (getArgumentValues.equals(method)) {
     return this.argumentValues;
   } else if (ReflectionUtils.isObjectMethod(method)) {
     return ReflectionUtils.invokeMethod(method, obj, args);
   } else {
     this.controllerMethod = method;
     this.argumentValues = args;
     Class<?> returnType = method.getReturnType();
     return (void.class.equals(returnType)
         ? null
         : returnType.cast(initProxy(returnType, this)));
   }
 }
Пример #2
0
  /**
   * Wrap the given delegate {@link BeanInfo} instance and find any non-void returning setter
   * methods, creating and adding a {@link PropertyDescriptor} for each.
   *
   * <p>The wrapped {@code BeanInfo} is not modified in any way by this process.
   *
   * @see #getPropertyDescriptors()
   * @throws IntrospectionException if any problems occur creating and adding new {@code
   *     PropertyDescriptors}
   */
  public ExtendedBeanInfo(BeanInfo delegate) throws IntrospectionException {
    this.delegate = delegate;

    // PropertyDescriptor instances from the delegate object are never added directly, but always
    // copied to the local collection of #propertyDescriptors and returned by calls to
    // #getPropertyDescriptors(). this algorithm iterates through all methods (method descriptors)
    // in the wrapped BeanInfo object, copying any existing PropertyDescriptor or creating a new
    // one for any non-standard setter methods found.

    ALL_METHODS:
    for (MethodDescriptor md : delegate.getMethodDescriptors()) {
      Method method = md.getMethod();

      // bypass non-getter java.lang.Class methods for efficiency
      if (ReflectionUtils.isObjectMethod(method) && !method.getName().startsWith("get")) {
        continue ALL_METHODS;
      }

      // is the method a NON-INDEXED setter? ignore return type in order to capture non-void
      // signatures
      if (method.getName().startsWith("set") && method.getParameterTypes().length == 1) {
        String propertyName = propertyNameFor(method);
        if (propertyName.length() == 0) {
          continue ALL_METHODS;
        }
        for (PropertyDescriptor pd : delegate.getPropertyDescriptors()) {
          Method readMethod = pd.getReadMethod();
          Method writeMethod = pd.getWriteMethod();
          // has the setter already been found by the wrapped BeanInfo?
          if (writeMethod != null && writeMethod.getName().equals(method.getName())) {
            // yes -> copy it, including corresponding getter method (if any -- may be null)
            this.addOrUpdatePropertyDescriptor(propertyName, readMethod, writeMethod);
            continue ALL_METHODS;
          }
          // has a getter corresponding to this setter already been found by the wrapped BeanInfo?
          if (readMethod != null
              && readMethod.getName().equals(getterMethodNameFor(propertyName))
              && readMethod.getReturnType().equals(method.getParameterTypes()[0])) {
            this.addOrUpdatePropertyDescriptor(propertyName, readMethod, method);
            continue ALL_METHODS;
          }
        }
        // the setter method was not found by the wrapped BeanInfo -> add a new PropertyDescriptor
        // for it
        // no corresponding getter was detected, so the 'read method' parameter is null.
        this.addOrUpdatePropertyDescriptor(propertyName, null, method);
        continue ALL_METHODS;
      }

      // is the method an INDEXED setter? ignore return type in order to capture non-void signatures
      if (method.getName().startsWith("set")
          && method.getParameterTypes().length == 2
          && method.getParameterTypes()[0].equals(int.class)) {
        String propertyName = propertyNameFor(method);
        if (propertyName.length() == 0) {
          continue ALL_METHODS;
        }
        DELEGATE_PD:
        for (PropertyDescriptor pd : delegate.getPropertyDescriptors()) {
          if (!(pd instanceof IndexedPropertyDescriptor)) {
            continue DELEGATE_PD;
          }
          IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
          Method readMethod = ipd.getReadMethod();
          Method writeMethod = ipd.getWriteMethod();
          Method indexedReadMethod = ipd.getIndexedReadMethod();
          Method indexedWriteMethod = ipd.getIndexedWriteMethod();
          // has the setter already been found by the wrapped BeanInfo?
          if (indexedWriteMethod != null && indexedWriteMethod.getName().equals(method.getName())) {
            // yes -> copy it, including corresponding getter method (if any -- may be null)
            this.addOrUpdatePropertyDescriptor(
                propertyName, readMethod, writeMethod, indexedReadMethod, indexedWriteMethod);
            continue ALL_METHODS;
          }
          // has a getter corresponding to this setter already been found by the wrapped BeanInfo?
          if (indexedReadMethod != null
              && indexedReadMethod.getName().equals(getterMethodNameFor(propertyName))
              && indexedReadMethod.getReturnType().equals(method.getParameterTypes()[1])) {
            this.addOrUpdatePropertyDescriptor(
                propertyName, readMethod, writeMethod, indexedReadMethod, method);
            continue ALL_METHODS;
          }
        }
        // the INDEXED setter method was not found by the wrapped BeanInfo -> add a new
        // PropertyDescriptor
        // for it. no corresponding INDEXED getter was detected, so the 'indexed read method'
        // parameter is null.
        this.addOrUpdatePropertyDescriptor(propertyName, null, null, null, method);
        continue ALL_METHODS;
      }

      // the method is not a setter, but is it a getter?
      for (PropertyDescriptor pd : delegate.getPropertyDescriptors()) {
        // have we already copied this read method to a property descriptor locally?
        for (PropertyDescriptor existingPD : this.propertyDescriptors) {
          if (method.equals(pd.getReadMethod()) && existingPD.getName().equals(pd.getName())) {
            if (existingPD.getReadMethod() == null) {
              // no -> add it now
              this.addOrUpdatePropertyDescriptor(pd.getName(), method, pd.getWriteMethod());
            }
            // yes -> do not add a duplicate
            continue ALL_METHODS;
          }
        }
        if (method == pd.getReadMethod()
            || (pd instanceof IndexedPropertyDescriptor
                && method == ((IndexedPropertyDescriptor) pd).getIndexedReadMethod())) {
          // yes -> copy it, including corresponding setter method (if any -- may be null)
          if (pd instanceof IndexedPropertyDescriptor) {
            this.addOrUpdatePropertyDescriptor(
                pd.getName(),
                pd.getReadMethod(),
                pd.getWriteMethod(),
                ((IndexedPropertyDescriptor) pd).getIndexedReadMethod(),
                ((IndexedPropertyDescriptor) pd).getIndexedWriteMethod());
          } else {
            this.addOrUpdatePropertyDescriptor(
                pd.getName(), pd.getReadMethod(), pd.getWriteMethod());
          }
          continue ALL_METHODS;
        }
      }
    }
  }