io.honeybadger.com.fasterxml.jackson.databind.deser.std.FromStringDeserializer Maven / Gradle / Ivy
package com.fasterxml.jackson.databind.deser.std;
import java.io.*;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Currency;
import java.util.Locale;
import java.util.TimeZone;
import java.util.regex.Pattern;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.util.VersionUtil;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.fasterxml.jackson.databind.util.ClassUtil;
/**
* Base class for simple deserializers that serialize values from String
* representation: this includes JSON Strings and other Scalar values that
* can be coerced into text, like Numbers and Booleans).
* Simple JSON String values are trimmed using {@link java.lang.String#trim}.
* Partial deserializer implementation will try to first access current token as
* a String, calls {@link #_deserialize(String,DeserializationContext)} and
* returns return value.
* If this does not work (current token not a simple scalar type), attempts
* are made so that:
*
* - Embedded values ({@link JsonToken#VALUE_EMBEDDED_OBJECT}) are returned as-is
* if they are of compatible type
*
* - Arrays may be "unwrapped" if (and only if) {@link DeserializationFeature#UNWRAP_SINGLE_VALUE_ARRAYS}
* is enabled, and array contains just a single scalar value that can be deserialized
* (for example, JSON Array with single JSON String element).
*
*
*
* Special handling includes:
*
* - Null values ({@link JsonToken#VALUE_NULL}) are handled by returning value
* returned by {@link JsonDeserializer#getNullValue(DeserializationContext)}: default
* implementation simply returns Java `null` but this may be overridden.
*
* - Empty String (after trimming) will result in {@link #_deserializeFromEmptyString}
* getting called, and return value being returned as deserialization: default implementation
* simply returns `null`.
*
*
*/
@SuppressWarnings("serial")
public abstract class FromStringDeserializer extends StdScalarDeserializer
{
public static Class>[] types() {
return new Class>[] {
File.class,
URL.class,
URI.class,
Class.class,
JavaType.class,
Currency.class,
Pattern.class,
Locale.class,
Charset.class,
TimeZone.class,
InetAddress.class,
InetSocketAddress.class,
StringBuilder.class,
};
}
/*
/**********************************************************
/* Deserializer implementations
/**********************************************************
*/
protected FromStringDeserializer(Class> vc) {
super(vc);
}
/**
* Factory method for trying to find a deserializer for one of supported
* types that have simple from-String serialization.
*/
public static Std findDeserializer(Class> rawType)
{
int kind = 0;
if (rawType == File.class) {
kind = Std.STD_FILE;
} else if (rawType == URL.class) {
kind = Std.STD_URL;
} else if (rawType == URI.class) {
kind = Std.STD_URI;
} else if (rawType == Class.class) {
kind = Std.STD_CLASS;
} else if (rawType == JavaType.class) {
kind = Std.STD_JAVA_TYPE;
} else if (rawType == Currency.class) {
kind = Std.STD_CURRENCY;
} else if (rawType == Pattern.class) {
kind = Std.STD_PATTERN;
} else if (rawType == Locale.class) {
kind = Std.STD_LOCALE;
} else if (rawType == Charset.class) {
kind = Std.STD_CHARSET;
} else if (rawType == TimeZone.class) {
kind = Std.STD_TIME_ZONE;
} else if (rawType == InetAddress.class) {
kind = Std.STD_INET_ADDRESS;
} else if (rawType == InetSocketAddress.class) {
kind = Std.STD_INET_SOCKET_ADDRESS;
} else if (rawType == StringBuilder.class) {
kind = Std.STD_STRING_BUILDER;
} else {
return null;
}
return new Std(rawType, kind);
}
/*
/**********************************************************
/* Deserializer implementations
/**********************************************************
*/
@SuppressWarnings("unchecked")
@Override
public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
{
// Let's get textual value, possibly via coercion from other scalar types
String text = p.getValueAsString();
if (text != null) { // has String representation
if (text.length() == 0 || (text = text.trim()).length() == 0) {
// Usually should become null; but not always
return _deserializeFromEmptyString();
}
Exception cause = null;
try {
// 19-May-2017, tatu: Used to require non-null result (assuming `null`
// indicated error; but that seems wrong. Should be able to return
// `null` as value.
return _deserialize(text, ctxt);
} catch (IllegalArgumentException | MalformedURLException e) {
cause = e;
}
// note: `cause` can't be null
String msg = "not a valid textual representation";
String m2 = cause.getMessage();
if (m2 != null) {
msg = msg + ", problem: "+m2;
}
// 05-May-2016, tatu: Unlike most usage, this seems legit, so...
JsonMappingException e = ctxt.weirdStringException(text, _valueClass, msg);
e.initCause(cause);
throw e;
// nothing to do here, yet? We'll fail anyway
}
JsonToken t = p.getCurrentToken();
// [databind#381]
if (t == JsonToken.START_ARRAY) {
return _deserializeFromArray(p, ctxt);
}
if (t == JsonToken.VALUE_EMBEDDED_OBJECT) {
// Trivial cases; null to null, instance of type itself returned as is
Object ob = p.getEmbeddedObject();
if (ob == null) {
return null;
}
if (_valueClass.isAssignableFrom(ob.getClass())) {
return (T) ob;
}
return _deserializeEmbedded(ob, ctxt);
}
return (T) ctxt.handleUnexpectedToken(_valueClass, p);
}
protected abstract T _deserialize(String value, DeserializationContext ctxt) throws IOException;
protected T _deserializeEmbedded(Object ob, DeserializationContext ctxt) throws IOException {
// default impl: error out
ctxt.reportInputMismatch(this,
"Don't know how to convert embedded Object of type %s into %s",
ob.getClass().getName(), _valueClass.getName());
return null;
}
protected T _deserializeFromEmptyString() throws IOException {
return null;
}
/*
/**********************************************************
/* A general-purpose implementation
/**********************************************************
*/
/**
* "Chameleon" deserializer that works on simple types that are deserialized
* from a simple String.
*
* @since 2.4
*/
public static class Std extends FromStringDeserializer