All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fasterxml.jackson.databind.cfg.ConstructorDetector Maven / Gradle / Ivy

There is a newer version: 2.17.0
Show newest version
package com.fasterxml.jackson.databind.cfg;

import com.fasterxml.jackson.databind.util.ClassUtil;

/**
 * Configurable handler used to select aspects of selecting
 * constructor to use as "Creator" for POJOs.
 * Defines the API for handlers, a pre-defined set of standard instances
 * and methods for constructing alternative configurations.
 *
 * @since 2.12
 */
public final class ConstructorDetector
    implements java.io.Serializable
{
    private static final long serialVersionUID = 1L;

    /**
     * Definition of alternate handling modes of single-argument constructors
     * that are annotated with {@link com.fasterxml.jackson.annotation.JsonCreator}
     * but without "mode" definition (or explicit name for the argument):
     * this is the case where two interpretations
     * are possible -- "properties" (in which case the argument is named parameter
     * of a JSON Object) and "delegating (in which case the argument maps to the
     * whole JSON value).
     *

* Default choice is {@code HEURISTIC} (which is Jackson pre-2.12 always uses) *

* NOTE: does NOT have any effect if explicit {@code @JsonCreator}} annotation * is required. * * @since 2.12 */ public enum SingleArgConstructor { /** * Assume "delegating" mode if not explicitly annotated otherwise */ DELEGATING, /** * Assume "properties" mode if not explicitly annotated otherwise */ PROPERTIES, /** * Use heuristics to see if "properties" mode is to be used (POJO has a * property with the same name as the implicit name [if available] of * the constructor argument). * Note: this is the default choice for Jackson versions before 2.12. */ HEURISTIC, /** * Refuse to decide implicit mode and instead throw a * {@link com.fasterxml.jackson.databind.exc.InvalidDefinitionException} * in ambiguous case. */ REQUIRE_MODE; } /* /********************************************************************** /* Global default instances to use /********************************************************************** */ /** * Instance used by default, which: *

    *
  • Uses {@link SingleArgConstructor#HEURISTIC} for single-argument constructor case *
  • *
  • Does not require explicit {@code @JsonCreator} annotations (so allows * auto-detection of Visible constructors} (except for JDK types) *
  • *
  • Does not allow auto-detection of Visible constructors for so-called JDK * types; that is, classes in packages {@code java.*} and {@code javax.*} *
  • *
*/ public final static ConstructorDetector DEFAULT = new ConstructorDetector(SingleArgConstructor.HEURISTIC); /** * Instance similar to {@link #DEFAULT} except that for single-argument case * uses setting of {@link SingleArgConstructor#PROPERTIES}. */ public final static ConstructorDetector USE_PROPERTIES_BASED = new ConstructorDetector(SingleArgConstructor.PROPERTIES); /** * Instance similar to {@link #DEFAULT} except that for single-argument case * uses setting of {@link SingleArgConstructor#DELEGATING}. */ public final static ConstructorDetector USE_DELEGATING = new ConstructorDetector(SingleArgConstructor.DELEGATING); /** * Instance similar to {@link #DEFAULT} except that for single-argument case * uses setting of {@link SingleArgConstructor#REQUIRE_MODE}. */ public final static ConstructorDetector EXPLICIT_ONLY = new ConstructorDetector(SingleArgConstructor.REQUIRE_MODE); /* /********************************************************************** /* Configuration /********************************************************************** */ protected final SingleArgConstructor _singleArgMode; /** * Whether explicit {@link com.fasterxml.jackson.annotation.JsonCreator} * is always required for detecting constructors (even if visible) other * than the default (no argument) constructor. */ protected final boolean _requireCtorAnnotation; /** * Whether auto-detection of constructors of "JDK types" (those in * packages {@code java.} and {@code javax.}) is allowed or not */ protected final boolean _allowJDKTypeCtors; /* /********************************************************************** /* Life-cycle /********************************************************************** */ protected ConstructorDetector(SingleArgConstructor singleArgMode, boolean requireCtorAnnotation, boolean allowJDKTypeCtors) { _singleArgMode = singleArgMode; _requireCtorAnnotation = requireCtorAnnotation; _allowJDKTypeCtors = allowJDKTypeCtors; } /** * Constructors used for default configurations which only varies * by {@code _singleArgMode} */ protected ConstructorDetector(SingleArgConstructor singleArgMode) { this(singleArgMode, false, false); } public ConstructorDetector withSingleArgMode(SingleArgConstructor singleArgMode) { return new ConstructorDetector(singleArgMode, _requireCtorAnnotation, _allowJDKTypeCtors); } public ConstructorDetector withRequireAnnotation(boolean state) { return new ConstructorDetector(_singleArgMode, state, _allowJDKTypeCtors); } public ConstructorDetector withAllowJDKTypeConstructors(boolean state) { return new ConstructorDetector(_singleArgMode, _requireCtorAnnotation, state); } /* /********************************************************************** /* API /********************************************************************** */ public SingleArgConstructor singleArgMode() { return _singleArgMode; } public boolean requireCtorAnnotation() { return _requireCtorAnnotation; } public boolean allowJDKTypeConstructors() { return _allowJDKTypeCtors; } public boolean singleArgCreatorDefaultsToDelegating() { return _singleArgMode == SingleArgConstructor.DELEGATING; } public boolean singleArgCreatorDefaultsToProperties() { return _singleArgMode == SingleArgConstructor.PROPERTIES; } /** * Accessor that combines checks for whether implicit creators are allowed * and, if so, whether JDK type constructors are allowed (if type is JDK type) * to determine whether implicit constructor * detection should be enabled for given type or not. * * @param rawType Value type to consider * * @return True if implicit constructor detection should be enabled; false if not */ public boolean shouldIntrospectorImplicitConstructors(Class rawType) { // May not allow implicit creator introspection at all: if (_requireCtorAnnotation) { return false; } // But if it is allowed, may further limit use for JDK types if (!_allowJDKTypeCtors) { if (ClassUtil.isJDKClass(rawType)) { // 18-Sep-2020, tatu: Looks like must make an exception for Exception // types (ha!) -- at this point, single-String-arg constructor // is to be auto-detected if (!Throwable.class.isAssignableFrom(rawType)) { return false; } } } return true; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy