Пример #1
0
 protected void _addClassMixIns(AnnotationMap annotations, Class<?> toMask, Class<?> mixin) {
   if (mixin == null) {
     return;
   }
   // Ok, first: annotations from mix-in class itself:
   for (Annotation a : mixin.getDeclaredAnnotations()) {
     if (_annotationIntrospector.isHandled(a)) {
       annotations.addIfNotPresent(a);
     }
   }
   /* And then from its supertypes, if any. But note that we will
    *  only consider super-types up until reaching the masked
    * class (if found); this because often mix-in class
    * is a sub-class (for convenience reasons). And if so, we
    * absolutely must NOT include super types of masked class,
    * as that would inverse precedence of annotations.
    */
   for (Class<?> parent : ClassUtil.findSuperTypes(mixin, toMask)) {
     for (Annotation a : parent.getDeclaredAnnotations()) {
       if (_annotationIntrospector.isHandled(a)) {
         annotations.addIfNotPresent(a);
       }
     }
   }
 }
Пример #2
0
  /**
   * Initialization method that will recursively collect Jackson annotations for this class and all
   * super classes and interfaces.
   *
   * <p>Starting with 1.2, it will also apply mix-in annotations, as per [JACKSON-76]
   */
  protected void resolveClassAnnotations() {
    _classAnnotations = new AnnotationMap();
    // add mix-in annotations first (overrides)
    if (_primaryMixIn != null) {
      _addClassMixIns(_classAnnotations, _class, _primaryMixIn);
    }
    // first, annotations from the class itself:
    for (Annotation a : _class.getDeclaredAnnotations()) {
      if (_annotationIntrospector.isHandled(a)) {
        _classAnnotations.addIfNotPresent(a);
      }
    }

    // and then from super types
    for (Class<?> cls : _superTypes) {
      // and mix mix-in annotations in-between
      _addClassMixIns(_classAnnotations, cls);
      for (Annotation a : cls.getDeclaredAnnotations()) {
        if (_annotationIntrospector.isHandled(a)) {
          _classAnnotations.addIfNotPresent(a);
        }
      }
    }

    /* and finally... any annotations there might be for plain
     * old Object.class: separate because for all other purposes
     * it is just ignored (not included in super types)
     */
    /* 12-Jul-2009, tatu: Should this be done for interfaces too?
     *   For now, yes, seems useful for some cases, and not harmful
     *   for any?
     */
    _addClassMixIns(_classAnnotations, Object.class);
  }
Пример #3
0
 /**
  * Method that will add annotations from specified source method to target method, but only if
  * target does not yet have them.
  */
 protected void _addMixUnders(Method src, AnnotatedMethod target) {
   for (Annotation a : src.getDeclaredAnnotations()) {
     if (_annotationIntrospector.isHandled(a)) {
       target.addIfNotPresent(a);
     }
   }
 }
Пример #4
0
  /**
   * Method that will collect all member (non-static) fields that are either public, or have at
   * least a single annotation associated with them.
   *
   * @param collectIgnored Whether to collect list of ignored methods for later retrieval
   */
  public void resolveFields(boolean collectIgnored) {
    LinkedHashMap<String, AnnotatedField> foundFields = new LinkedHashMap<String, AnnotatedField>();
    _addFields(foundFields, _class);

    /* And last but not least: let's remove all fields that are
     * deemed to be ignorable after all annotations have been
     * properly collapsed.
     */
    Iterator<Map.Entry<String, AnnotatedField>> it = foundFields.entrySet().iterator();
    while (it.hasNext()) {
      AnnotatedField f = it.next().getValue();
      if (_annotationIntrospector.isIgnorableField(f)) {
        it.remove();
        if (collectIgnored) {
          _ignoredFields = ArrayBuilders.addToList(_ignoredFields, f);
        }
      } else {

      }
    }
    if (foundFields.isEmpty()) {
      _fields = Collections.emptyList();
    } else {
      _fields = new ArrayList<AnnotatedField>(foundFields.size());
      _fields.addAll(foundFields.values());
    }
  }
Пример #5
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);
        }
      }
    }
  }
Пример #6
0
 protected AnnotationMap _collectRelevantAnnotations(Annotation[] anns) {
   AnnotationMap annMap = new AnnotationMap();
   if (anns != null) {
     for (Annotation a : anns) {
       if (_annotationIntrospector.isHandled(a)) {
         annMap.add(a);
       }
     }
   }
   return annMap;
 }
Пример #7
0
 /** @param addParamAnnotations Whether parameter annotations are to be added as well */
 protected void _addMixOvers(Method mixin, AnnotatedMethod target, boolean addParamAnnotations) {
   for (Annotation a : mixin.getDeclaredAnnotations()) {
     if (_annotationIntrospector.isHandled(a)) {
       target.addOrOverride(a);
     }
   }
   if (addParamAnnotations) {
     Annotation[][] pa = mixin.getParameterAnnotations();
     for (int i = 0, len = pa.length; i < len; ++i) {
       for (Annotation a : pa[i]) {
         target.addOrOverrideParam(i, a);
       }
     }
   }
 }
Пример #8
0
 /**
  * Method called to add field mix-ins from given mix-in class (and its fields) into already
  * collected actual fields (from introspected classes and their super-classes)
  */
 protected void _addFieldMixIns(Class<?> mixin, Map<String, AnnotatedField> fields) {
   for (Field mixinField : mixin.getDeclaredFields()) {
     /* there are some dummy things (static, synthetic); better
      * ignore
      */
     if (!_isIncludableField(mixinField)) {
       continue;
     }
     String name = mixinField.getName();
     // anything to mask? (if not, quietly ignore)
     AnnotatedField maskedField = fields.get(name);
     if (maskedField != null) {
       for (Annotation a : mixinField.getDeclaredAnnotations()) {
         if (_annotationIntrospector.isHandled(a)) {
           maskedField.addOrOverride(a);
         }
       }
     }
   }
 }
Пример #9
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);
          }
        }
      }
    }
  }