예제 #1
0
  /**
   * Method for resolving member method information: aggregating all non-static methods and
   * combining annotations (to implement method-annotation inheritance)
   *
   * @param collectIgnored Whether to collect list of ignored methods for later retrieval
   */
  public void resolveMemberMethods(MethodFilter methodFilter, boolean collectIgnored) {
    _memberMethods = new AnnotatedMethodMap();
    AnnotatedMethodMap mixins = new AnnotatedMethodMap();
    // first: methods from the class itself
    _addMemberMethods(_class, methodFilter, _memberMethods, _primaryMixIn, mixins);

    // and then augment these with annotations from super-types:
    for (Class<?> cls : _superTypes) {
      Class<?> mixin = (_mixInResolver == null) ? null : _mixInResolver.findMixInClassFor(cls);
      _addMemberMethods(cls, methodFilter, _memberMethods, mixin, mixins);
    }
    // Special case: mix-ins for Object.class? (to apply to ALL classes)
    if (_mixInResolver != null) {
      Class<?> mixin = _mixInResolver.findMixInClassFor(Object.class);
      if (mixin != null) {
        _addMethodMixIns(methodFilter, _memberMethods, mixin, mixins);
      }
    }

    /* Any unmatched mix-ins? Most likely error cases (not matching
     * any method); but there is one possible real use case:
     * exposing Object#hashCode (alas, Object#getClass can NOT be
     * exposed, see [JACKSON-140])
     */
    if (!mixins.isEmpty()) {
      Iterator<AnnotatedMethod> it = mixins.iterator();
      while (it.hasNext()) {
        AnnotatedMethod mixIn = it.next();
        try {
          Method m = Object.class.getDeclaredMethod(mixIn.getName(), mixIn.getParameterClasses());
          if (m != null) {
            AnnotatedMethod am = _constructMethod(m);
            _addMixOvers(mixIn.getAnnotated(), am, false);
            _memberMethods.add(am);
          }
        } catch (Exception e) {
        }
      }
    }

    /* And last but not least: let's remove all methods that are
     * deemed to be ignorable after all annotations have been
     * properly collapsed.
     */
    Iterator<AnnotatedMethod> it = _memberMethods.iterator();
    while (it.hasNext()) {
      AnnotatedMethod am = it.next();
      if (_annotationIntrospector.isIgnorableMethod(am)) {
        it.remove();
        if (collectIgnored) {
          _ignoredMethods = ArrayBuilders.addToList(_ignoredMethods, am);
        }
      }
    }
  }
예제 #2
0
  /**
   * Initialization method that will find out all constructors and potential static factory methods
   * the class has.
   *
   * <p>Starting with 1.2, it will also apply mix-in annotations, as per [JACKSON-76]
   *
   * @param includeAll If true, includes all creator methods; if false, will only include the
   *     no-arguments "default" constructor
   */
  public void resolveCreators(boolean includeAll) {
    // Then see which constructors we have
    _constructors = null;
    for (Constructor<?> ctor : _class.getDeclaredConstructors()) {
      switch (ctor.getParameterTypes().length) {
        case 0:
          _defaultConstructor = _constructConstructor(ctor, true);
          break;
        default:
          if (includeAll) {
            if (_constructors == null) {
              _constructors = new ArrayList<AnnotatedConstructor>();
            }
            _constructors.add(_constructConstructor(ctor, false));
          }
      }
    }
    // and if need be, augment with mix-ins
    if (_primaryMixIn != null) {
      if (_defaultConstructor != null || _constructors != null) {
        _addConstructorMixIns(_primaryMixIn);
      }
    }

    /* And then... let's remove all constructors that are
     * deemed to be ignorable after all annotations have been
     * properly collapsed.
     */
    if (_defaultConstructor != null) {
      if (_annotationIntrospector.isIgnorableConstructor(_defaultConstructor)) {
        _defaultConstructor = null;
      }
    }
    if (_constructors != null) {
      // count down to allow safe removal
      for (int i = _constructors.size(); --i >= 0; ) {
        if (_annotationIntrospector.isIgnorableConstructor(_constructors.get(i))) {
          _constructors.remove(i);
        }
      }
    }

    _creatorMethods = null;

    if (includeAll) {
      /* Then static methods which are potential factory
       * methods
       */
      for (Method m : _class.getDeclaredMethods()) {
        if (!Modifier.isStatic(m.getModifiers())) {
          continue;
        }
        int argCount = m.getParameterTypes().length;
        // factory methods take at least one arg:
        if (argCount < 1) {
          continue;
        }
        if (_creatorMethods == null) {
          _creatorMethods = new ArrayList<AnnotatedMethod>();
        }
        _creatorMethods.add(_constructCreatorMethod(m));
      }
      // mix-ins to mix in?
      if (_primaryMixIn != null && _creatorMethods != null) {
        _addFactoryMixIns(_primaryMixIn);
      }
      // anything to ignore at this point?
      if (_creatorMethods != null) {
        // count down to allow safe removal
        for (int i = _creatorMethods.size(); --i >= 0; ) {
          if (_annotationIntrospector.isIgnorableMethod(_creatorMethods.get(i))) {
            _creatorMethods.remove(i);
          }
        }
      }
    }
  }