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

com.fasterxml.jackson.databind.deser.ValueInstantiator Maven / Gradle / Ivy

The newest version!
package com.fasterxml.jackson.databind.deser;

import java.io.IOException;

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.cfg.CoercionAction;
import com.fasterxml.jackson.databind.cfg.CoercionInputShape;
import com.fasterxml.jackson.databind.deser.impl.PropertyValueBuffer;
import com.fasterxml.jackson.databind.introspect.AnnotatedWithParams;
import com.fasterxml.jackson.databind.type.LogicalType;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * Class that defines simple API implemented by objects that create value
 * instances.  Some or all of properties of value instances may
 * be initialized by instantiator, rest being populated by deserializer,
 * to which value instance is passed.
 * Since different kinds of JSON values (structured and scalar)
 * may be bound to Java values, in some cases instantiator
 * fully defines resulting value; this is the case when JSON value
 * is a scalar value (String, number, boolean).
 *

* Note that this type is not parameterized (even though it would seemingly * make sense), because such type information cannot be use effectively * during runtime: access is always using either wildcard type, or just * basic {@link java.lang.Object}; and so adding type parameter seems * like unnecessary extra work. *

* Actual implementations are strongly recommended to be based on * {@link com.fasterxml.jackson.databind.deser.std.StdValueInstantiator} * which implements all methods, and as such will be compatible * across versions even if new methods were added to this interface. */ public abstract class ValueInstantiator { /* /********************************************************** /* Introspection /********************************************************** */ /** * @since 2.9 */ public interface Gettable { public ValueInstantiator getValueInstantiator(); } /* /********************************************************** /* Life-cycle /********************************************************** */ /** * "Contextualization" method that is called after construction but before first * use, to allow instantiator access to context needed to possible resolve its * dependencies. * * @param ctxt Currently active deserialization context: needed to (for example) * resolving {@link com.fasterxml.jackson.databind.jsontype.TypeDeserializer}s. * * @return This instance, if no change, or newly constructed instance * * @throws JsonMappingException If there are issues with contextualization * * @since 2.12 */ public ValueInstantiator createContextual(DeserializationContext ctxt, BeanDescription beanDesc) throws JsonMappingException { return this; } /* /********************************************************** /* Metadata accessors /********************************************************** */ /** * Accessor for raw (type-erased) type of instances to create. *

* NOTE: since this method has not existed since beginning of * Jackson 2.0 series, default implementation will just return * Object.class; implementations are expected * to override it with real value. * * @since 2.8 */ public Class getValueClass() { return Object.class; } /** * Method that returns description of the value type this instantiator * handles. Used for error messages, diagnostics. */ public String getValueTypeDesc() { Class cls = getValueClass(); if (cls == null) { return "UNKNOWN"; } return cls.getName(); } /** * Method that will return true if any of {@code canCreateXxx} method * returns true: that is, if there is any way that an instance could * be created. */ public boolean canInstantiate() { return canCreateUsingDefault() || canCreateUsingDelegate() || canCreateUsingArrayDelegate() || canCreateFromObjectWith() || canCreateFromString() || canCreateFromInt() || canCreateFromLong() || canCreateFromDouble() || canCreateFromBoolean(); } /** * Method that can be called to check whether a String-based creator * is available for this instantiator. *

* NOTE: does NOT include possible case of fallbacks, or coercion; only * considers explicit creator. */ public boolean canCreateFromString() { return false; } /** * Method that can be called to check whether an integer (int, Integer) based * creator is available to use (to call {@link #createFromInt}). */ public boolean canCreateFromInt() { return false; } /** * Method that can be called to check whether a long (long, Long) based * creator is available to use (to call {@link #createFromLong}). */ public boolean canCreateFromLong() { return false; } /** * Method that can be called to check whether a BigInteger based creator is available * to use (to call {@link #createFromBigInteger}). + */ public boolean canCreateFromBigInteger() { return false; } /** * Method that can be called to check whether a double (double / Double) based * creator is available to use (to call {@link #createFromDouble}). */ public boolean canCreateFromDouble() { return false; } /** * Method that can be called to check whether a BigDecimal based creator is available * to use (to call {@link #createFromBigDecimal}). */ public boolean canCreateFromBigDecimal() { return false; } /** * Method that can be called to check whether a double (boolean / Boolean) based * creator is available to use (to call {@link #createFromDouble}). */ public boolean canCreateFromBoolean() { return false; } /** * Method that can be called to check whether a default creator (constructor, * or no-arg static factory method) * is available for this instantiator */ public boolean canCreateUsingDefault() { return getDefaultCreator() != null; } /** * Method that can be called to check whether a delegate-based creator (single-arg * constructor or factory method) * is available for this instantiator */ public boolean canCreateUsingDelegate() { return false; } /** * Method that can be called to check whether a array-delegate-based creator * (single-arg constructor or factory method) * is available for this instantiator * * @since 2.7 */ public boolean canCreateUsingArrayDelegate() { return false; } /** * Method that can be called to check whether a property-based creator * (argument-taking constructor or factory method) * is available to instantiate values from JSON Object */ public boolean canCreateFromObjectWith() { return false; } /** * Method called to determine types of instantiation arguments * to use when creating instances with creator arguments * (when {@link #canCreateFromObjectWith()} returns true). * These arguments are bound from JSON, using specified * property types to locate deserializers. *

* NOTE: all properties will be of type * {@link com.fasterxml.jackson.databind.deser.CreatorProperty}. */ public SettableBeanProperty[] getFromObjectArguments(DeserializationConfig config) { return null; } /** * Method that can be used to determine what is the type of delegate * type to use, if any; if no delegates are used, will return null. * If non-null type is returned, deserializer will bind JSON into * specified type (using standard deserializer for that type), and * pass that to instantiator. */ public JavaType getDelegateType(DeserializationConfig config) { return null; } /** * Method that can be used to determine what is the type of array delegate * type to use, if any; if no delegates are used, will return null. If * non-null type is returned, deserializer will bind JSON into specified * type (using standard deserializer for that type), and pass that to * instantiator. * * @since 2.7 */ public JavaType getArrayDelegateType(DeserializationConfig config) { return null; } /* /********************************************************** /* Instantiation methods for JSON Object /********************************************************** */ /** * Method called to create value instance from a JSON value when * no data needs to passed to creator (constructor, factory method); * typically this will call the default constructor of the value object. * It will only be used if more specific creator methods are not * applicable; hence "default". *

* This method is called if {@link #getFromObjectArguments} returns * null or empty List. */ public Object createUsingDefault(DeserializationContext ctxt) throws IOException { return ctxt.handleMissingInstantiator(getValueClass(), this, null, "no default no-arguments constructor found"); } /** * Method called to create value instance from JSON Object when * instantiation arguments are passed; this is done, for example when passing information * specified with "Creator" annotations. *

* This method is called if {@link #getFromObjectArguments} returns * a non-empty List of arguments. */ public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) throws IOException { // sanity check; shouldn't really get called if no Creator specified return ctxt.handleMissingInstantiator(getValueClass(), this, null, "no creator with arguments specified"); } /** * Combination of {@link #createUsingDefault} and {@link #createFromObjectWith(DeserializationContext, Object[])} * which will call former first, if possible; or latter if possible (with {@code null} * arguments); and if neither works throw an exception. * * @since 2.15 */ //public abstract Object createUsingDefaultOrWithoutArguments(DeserializationContext ctxt) throws IOException; public Object createUsingDefaultOrWithoutArguments(DeserializationContext ctxt) throws IOException { return ctxt.handleMissingInstantiator(getValueClass(), this, null, "neither default (no-arguments) nor with-arguments Creator found"); } /** * Method that delegates to * {@link #createFromObjectWith(DeserializationContext, Object[])} by * default, but can be overridden if the application should have customized * behavior with respect to missing properties. *

* The default implementation of this method uses * {@link PropertyValueBuffer#getParameters(SettableBeanProperty[])} to read * and validate all properties in bulk, possibly substituting defaults for * missing properties or throwing exceptions for missing properties. An * overridden implementation of this method could, for example, use * {@link PropertyValueBuffer#hasParameter(SettableBeanProperty)} and * {@link PropertyValueBuffer#getParameter(SettableBeanProperty)} to safely * read the present properties only, and to have some other behavior for the * missing properties. * * @since 2.8 */ public Object createFromObjectWith(DeserializationContext ctxt, SettableBeanProperty[] props, PropertyValueBuffer buffer) throws IOException { return createFromObjectWith(ctxt, buffer.getParameters(props)); } /** * Method to called to create value instance from JSON Object using * an intermediate "delegate" value to pass to createor method */ public Object createUsingDelegate(DeserializationContext ctxt, Object delegate) throws IOException { return ctxt.handleMissingInstantiator(getValueClass(), this, null, "no delegate creator specified"); } /** * Method to called to create value instance from JSON Array using * an intermediate "delegate" value to pass to createor method */ public Object createUsingArrayDelegate(DeserializationContext ctxt, Object delegate) throws IOException { return ctxt.handleMissingInstantiator(getValueClass(), this, null, "no array delegate creator specified"); } /* /********************************************************** /* Instantiation methods for JSON scalar types (String, Number, Boolean) /********************************************************** */ @SuppressWarnings("resource") public Object createFromString(DeserializationContext ctxt, String value) throws IOException { return ctxt.handleMissingInstantiator(getValueClass(), this, ctxt.getParser(), "no String-argument constructor/factory method to deserialize from String value ('%s')", value); } public Object createFromInt(DeserializationContext ctxt, int value) throws IOException { return ctxt.handleMissingInstantiator(getValueClass(), this, null, "no int/Int-argument constructor/factory method to deserialize from Number value (%s)", value); } public Object createFromLong(DeserializationContext ctxt, long value) throws IOException { return ctxt.handleMissingInstantiator(getValueClass(), this, null, "no long/Long-argument constructor/factory method to deserialize from Number value (%s)", value); } public Object createFromBigInteger(DeserializationContext ctxt, BigInteger value) throws IOException { return ctxt.handleMissingInstantiator(getValueClass(),this,null, "no BigInteger-argument constructor/factory method to deserialize from Number value (%s)", value ); } public Object createFromDouble(DeserializationContext ctxt, double value) throws IOException { return ctxt.handleMissingInstantiator(getValueClass(), this, null, "no double/Double-argument constructor/factory method to deserialize from Number value (%s)", value); } public Object createFromBigDecimal(DeserializationContext ctxt, BigDecimal value) throws IOException { return ctxt.handleMissingInstantiator(getValueClass(),this,null, "no BigDecimal/double/Double-argument constructor/factory method to deserialize from Number value (%s)", value ); } public Object createFromBoolean(DeserializationContext ctxt, boolean value) throws IOException { return ctxt.handleMissingInstantiator(getValueClass(), this, null, "no boolean/Boolean-argument constructor/factory method to deserialize from boolean value (%s)", value); } /* /********************************************************** /* Accessors for underlying creator objects (optional) /********************************************************** */ /** * Method that can be called to try to access member (constructor, * static factory method) that is used as the "default creator" * (creator that is called without arguments; typically default * [zero-argument] constructor of the type). * Note that implementations not required to return actual object * they use (or, they may use some other instantiation) method. * That is, even if {@link #canCreateUsingDefault()} returns true, * this method may return null . */ public AnnotatedWithParams getDefaultCreator() { return null; } /** * Method that can be called to try to access member (constructor, * static factory method) that is used as the "delegate creator". * Note that implementations not required to return actual object * they use (or, they may use some other instantiation) method. * That is, even if {@link #canCreateUsingDelegate()} returns true, * this method may return null . */ public AnnotatedWithParams getDelegateCreator() { return null; } /** * Method that can be called to try to access member (constructor, * static factory method) that is used as the "array delegate creator". * Note that implementations not required to return actual object * they use (or, they may use some other instantiation) method. * That is, even if {@link #canCreateUsingArrayDelegate()} returns true, * this method may return null . */ public AnnotatedWithParams getArrayDelegateCreator() { return null; } /** * Method that can be called to try to access member (constructor, * static factory method) that is used as the "non-default creator" * (constructor or factory method that takes one or more arguments). * Note that implementations not required to return actual object * they use (or, they may use some other instantiation) method. * That is, even if {@link #canCreateFromObjectWith()} returns true, * this method may return null . */ public AnnotatedWithParams getWithArgsCreator() { return null; } /* /********************************************************** /* Helper methods /********************************************************** */ /** * @since 2.4 (demoted from StdValueInstantiator) * @deprecated Since 2.12 should not handle coercions here */ @Deprecated // since 2.12 @SuppressWarnings("resource") protected Object _createFromStringFallbacks(DeserializationContext ctxt, String value) throws IOException { // also, empty Strings might be accepted as null Object... if (value.isEmpty()) { if (ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) { return null; } } /* 28-Sep-2011, tatu: Ok this is not clean at all; but since there are legacy * systems that expect conversions in some cases, let's just add a minimal * patch (note: same could conceivably be used for numbers too). */ if (canCreateFromBoolean()) { // 29-May-2020, tatu: With 2.12 can and should use CoercionConfig so: if (ctxt.findCoercionAction(LogicalType.Boolean, Boolean.class, CoercionInputShape.String) == CoercionAction.TryConvert) { String str = value.trim(); if ("true".equals(str)) { return createFromBoolean(ctxt, true); } if ("false".equals(str)) { return createFromBoolean(ctxt, false); } } } return ctxt.handleMissingInstantiator(getValueClass(), this, ctxt.getParser(), "no String-argument constructor/factory method to deserialize from String value ('%s')", value); } /* /********************************************************** /* Standard Base implementation (since 2.8) /********************************************************** */ /** * Partial {@link ValueInstantiator} implementation that is strongly recommended * to be used instead of directly extending {@link ValueInstantiator} itself. */ public static class Base extends ValueInstantiator implements java.io.Serializable // just because used as base for "standard" variants { private static final long serialVersionUID = 1L; protected final Class _valueType; public Base(Class type) { _valueType = type; } public Base(JavaType type) { _valueType = type.getRawClass(); } @Override public String getValueTypeDesc() { return _valueType.getName(); } @Override public Class getValueClass() { return _valueType; } } /** * Delegating {@link ValueInstantiator} implementation meant as a base type * that by default delegates methods to specified fallback instantiator. * * @since 2.12 */ public static class Delegating extends ValueInstantiator implements java.io.Serializable { private static final long serialVersionUID = 1L; protected final ValueInstantiator _delegate; protected Delegating(ValueInstantiator delegate) { _delegate = delegate; } @Override public ValueInstantiator createContextual(DeserializationContext ctxt, BeanDescription beanDesc) throws JsonMappingException { ValueInstantiator d = _delegate.createContextual(ctxt, beanDesc); return (d == _delegate) ? this : new Delegating(d); } protected ValueInstantiator delegate() { return _delegate; } @Override public Class getValueClass() { return delegate().getValueClass(); } @Override public String getValueTypeDesc() { return delegate().getValueTypeDesc(); } @Override public boolean canInstantiate() { return delegate().canInstantiate(); } @Override public boolean canCreateFromString() { return delegate().canCreateFromString(); } @Override public boolean canCreateFromInt() { return delegate().canCreateFromInt(); } @Override public boolean canCreateFromLong() { return delegate().canCreateFromLong(); } @Override public boolean canCreateFromDouble() { return delegate().canCreateFromDouble(); } @Override public boolean canCreateFromBoolean() { return delegate().canCreateFromBoolean(); } @Override public boolean canCreateUsingDefault() { return delegate().canCreateUsingDefault(); } @Override public boolean canCreateUsingDelegate() { return delegate().canCreateUsingDelegate(); } @Override public boolean canCreateUsingArrayDelegate() { return delegate().canCreateUsingArrayDelegate(); } @Override public boolean canCreateFromObjectWith() { return delegate().canCreateFromObjectWith(); } @Override public SettableBeanProperty[] getFromObjectArguments(DeserializationConfig config) { return delegate().getFromObjectArguments(config); } @Override public JavaType getDelegateType(DeserializationConfig config) { return delegate().getDelegateType(config); } @Override public JavaType getArrayDelegateType(DeserializationConfig config) { return delegate().getArrayDelegateType(config); } /* /********************************************************** /* Creation methods /********************************************************** */ @Override public Object createUsingDefault(DeserializationContext ctxt) throws IOException { return delegate().createUsingDefault(ctxt); } @Override public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) throws IOException { return delegate().createFromObjectWith(ctxt, args); } @Override public Object createFromObjectWith(DeserializationContext ctxt, SettableBeanProperty[] props, PropertyValueBuffer buffer) throws IOException { return delegate().createFromObjectWith(ctxt, props, buffer); } @Override public Object createUsingDelegate(DeserializationContext ctxt, Object delegate) throws IOException { return delegate().createUsingDelegate(ctxt, delegate); } @Override public Object createUsingArrayDelegate(DeserializationContext ctxt, Object delegate) throws IOException { return delegate().createUsingArrayDelegate(ctxt, delegate); } @Override public Object createFromString(DeserializationContext ctxt, String value) throws IOException { return delegate().createFromString(ctxt, value); } @Override public Object createFromInt(DeserializationContext ctxt, int value) throws IOException { return delegate().createFromInt(ctxt, value); } @Override public Object createFromLong(DeserializationContext ctxt, long value) throws IOException { return delegate().createFromLong(ctxt, value); } @Override public Object createFromBigInteger(DeserializationContext ctxt, BigInteger value) throws IOException { return delegate().createFromBigInteger(ctxt, value); } @Override public Object createFromDouble(DeserializationContext ctxt, double value) throws IOException { return delegate().createFromDouble(ctxt, value); } @Override public Object createFromBigDecimal(DeserializationContext ctxt, BigDecimal value) throws IOException { return delegate().createFromBigDecimal(ctxt, value); } @Override public Object createFromBoolean(DeserializationContext ctxt, boolean value) throws IOException { return delegate().createFromBoolean(ctxt, value); } /* /********************************************************** /* Accessors for underlying creator objects (optional) /********************************************************** */ @Override public AnnotatedWithParams getDefaultCreator() { return delegate().getDefaultCreator(); } @Override public AnnotatedWithParams getDelegateCreator() { return delegate().getDelegateCreator(); } @Override public AnnotatedWithParams getArrayDelegateCreator() { return delegate().getArrayDelegateCreator(); } @Override public AnnotatedWithParams getWithArgsCreator() { return delegate().getWithArgsCreator(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy