Beispiel #1
0
  /**
   * Does the given method info override an existing method registered before (from a subclass)
   *
   * @param methodInfo the method to test
   * @return the already registered method to use, null if not overriding any
   */
  private MethodInfo overridesExistingMethod(MethodInfo methodInfo) {
    for (MethodInfo info : methodMap.values()) {
      Method source = info.getMethod();
      Method target = methodInfo.getMethod();

      boolean override = ObjectHelper.isOverridingMethod(source, target);
      if (override) {
        // same name, same parameters, then its overrides an existing class
        return info;
      }
    }

    return null;
  }
Beispiel #2
0
  /**
   * Validates whether the given method is a valid candidate for Camel Bean Binding.
   *
   * @param clazz the class
   * @param method the method
   * @return true if valid, false to skip the method
   */
  protected boolean isValidMethod(Class<?> clazz, Method method) {
    // must not be in the excluded list
    for (Method excluded : EXCLUDED_METHODS) {
      if (ObjectHelper.isOverridingMethod(excluded, method)) {
        // the method is overriding an excluded method so its not valid
        return false;
      }
    }

    // must be a public method
    if (!Modifier.isPublic(method.getModifiers())) {
      return false;
    }

    // return type must not be an Exchange and it should not be a bridge method
    if ((method.getReturnType() != null && Exchange.class.isAssignableFrom(method.getReturnType()))
        || method.isBridge()) {
      return false;
    }

    return true;
  }
Beispiel #3
0
  /**
   * Returns the {@link MethodInfo} for the given method if it exists or null if there is no
   * metadata available for the given method
   */
  public MethodInfo getMethodInfo(Method method) {
    MethodInfo answer = methodMap.get(method);
    if (answer == null) {
      // maybe the method overrides, and the method map keeps info of the source override we can use
      for (Method source : methodMap.keySet()) {
        if (ObjectHelper.isOverridingMethod(source, method, false)) {
          answer = methodMap.get(source);
          break;
        }
      }
    }

    if (answer == null) {
      // maybe the method is defined on a base class?
      if (type != Object.class) {
        Class<?> superclass = type.getSuperclass();
        if (superclass != null && superclass != Object.class) {
          BeanInfo superBeanInfo = new BeanInfo(camelContext, superclass, strategy);
          return superBeanInfo.getMethodInfo(method);
        }
      }
    }
    return answer;
  }
Beispiel #4
0
  /**
   * Introspects the given class
   *
   * @param clazz the class
   */
  private void introspect(Class<?> clazz) {
    // get the target clazz as it could potentially have been enhanced by CGLIB etc.
    clazz = getTargetClass(clazz);
    ObjectHelper.notNull(clazz, "clazz", this);

    LOG.trace("Introspecting class: {}", clazz);

    // does the class have any public constructors?
    publicConstructors = clazz.getConstructors().length > 0;

    // favor declared methods, and then filter out duplicate interface methods
    List<Method> methods;
    if (Modifier.isPublic(clazz.getModifiers())) {
      LOG.trace("Preferring class methods as class: {} is public accessible", clazz);
      methods = new ArrayList<Method>(Arrays.asList(clazz.getDeclaredMethods()));
    } else {
      LOG.trace("Preferring interface methods as class: {} is not public accessible", clazz);
      methods = getInterfaceMethods(clazz);
      // and then we must add its declared methods as well
      List<Method> extraMethods = Arrays.asList(clazz.getDeclaredMethods());
      methods.addAll(extraMethods);
    }

    Set<Method> overrides = new HashSet<Method>();
    Set<Method> bridges = new HashSet<Method>();

    // do not remove duplicates form class from the Java itself as they have some "duplicates" we
    // need
    boolean javaClass = clazz.getName().startsWith("java.") || clazz.getName().startsWith("javax.");
    if (!javaClass) {
      // it may have duplicate methods already, even from declared or from interfaces + declared
      for (Method source : methods) {
        for (Method target : methods) {
          // skip ourselves
          if (ObjectHelper.isOverridingMethod(source, target, true)) {
            continue;
          }
          // skip duplicates which may be assign compatible (favor keep first added method when
          // duplicate)
          if (ObjectHelper.isOverridingMethod(source, target, false)) {
            overrides.add(target);
          }
        }
      }
      methods.removeAll(overrides);
      overrides.clear();
    }

    // if we are a public class, then add non duplicate interface classes also
    if (Modifier.isPublic(clazz.getModifiers())) {
      // add additional interface methods
      List<Method> extraMethods = getInterfaceMethods(clazz);
      for (Method target : extraMethods) {
        for (Method source : methods) {
          if (ObjectHelper.isOverridingMethod(source, target, false)) {
            overrides.add(target);
          }
        }
      }
      // remove all the overrides methods
      extraMethods.removeAll(overrides);
      methods.addAll(extraMethods);
    }

    // now introspect the methods and filter non valid methods
    for (Method method : methods) {
      boolean valid = isValidMethod(clazz, method);
      LOG.trace("Method: {} is valid: {}", method, valid);
      if (valid) {
        introspect(clazz, method);
      }
    }

    Class<?> superclass = clazz.getSuperclass();
    if (superclass != null && !superclass.equals(Object.class)) {
      introspect(superclass);
    }
  }