NullElementHelper.java
package tools.jackson.datatype.guava.util;
import java.util.function.Function;
import tools.jackson.core.JacksonException;
import tools.jackson.core.JsonParser;
import tools.jackson.core.JsonToken;
import tools.jackson.databind.DeserializationContext;
import tools.jackson.databind.JavaType;
/**
* Shared helper for adding {@code null} elements (or values) into Guava containers,
* many of which do not accept them.
*<p>
* NOTE: internal helper; package not exported by module, not part of
* the public API.
*/
public final class NullElementHelper
{
private NullElementHelper() { }
/**
* Method that applies given "adder" to given value. If value is {@code null}
* and adder fails with {@link NullPointerException} (container does not accept
* {@code null}s), problem is reported via
* {@link DeserializationContext#handleUnexpectedToken}: this allows a
* {@link tools.jackson.databind.deser.DeserializationProblemHandler} to provide
* a replacement value (which is then added), or to drop the element by returning
* {@code null}; without a handler, a
* {@link tools.jackson.databind.exc.MismatchedInputException} is thrown.
*<p>
* Callers must pass the token parser is currently positioned at
* ({@code p.currentToken()}), not the token value started at: for structured
* values, value deserializer has already advanced parser to the matching
* {@code END_OBJECT} / {@code END_ARRAY}, and a problem handler may want to
* access the parser.
*
* @param t Token parser is currently positioned at (for structured values,
* the matching {@code END_OBJECT} / {@code END_ARRAY}, not the start token)
* @param elementType Type of elements (or values) of container
* @param containerDesc Description of the container for the error message
*
* @return Result of adder, or {@code null} if element was dropped
*/
public static <R> R addElement(JsonParser p, DeserializationContext ctxt, JsonToken t,
JavaType elementType, String containerDesc,
Object value, Function<Object, R> adder)
throws JacksonException
{
if (value == null) {
try {
return adder.apply(null);
} catch (NullPointerException e) {
value = handleNull(p, ctxt, t, elementType, containerDesc);
if (value == null) {
return null;
}
}
}
return adder.apply(value);
}
/**
* Method for reporting a {@code null} element (or value) that the container
* does not accept, for cases where caller knows this without trying to add it.
*
* @param t Token parser is currently positioned at; see
* {@link #addElement} for details
* @return Replacement value given by a problem handler, or {@code null} if
* element is to be dropped
*/
public static Object handleNull(JsonParser p, DeserializationContext ctxt, JsonToken t,
JavaType elementType, String containerDesc)
throws JacksonException
{
return ctxt.handleUnexpectedToken(elementType, t, p,
"%s does not accept `null` values", containerDesc);
}
}