aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorTatu Saloranta <tatu.saloranta@iki.fi>2020-06-29 17:09:42 -0700
committerTatu Saloranta <tatu.saloranta@iki.fi>2020-06-29 17:09:42 -0700
commit40701f15a81c1f2ed7aae2a43173f97ab7403af9 (patch)
tree1089c78bf1cfde4cd782ba393048112ce2603478 /src/main/java
parent7b9e7ddec3722b4b97dff76d41b3cbaa4685e577 (diff)
downloadjackson-databind-40701f15a81c1f2ed7aae2a43173f97ab7403af9.tar.gz
Add Object-to-Scalar support for some String/String-like types
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java78
-rw-r--r--src/main/java/com/fasterxml/jackson/databind/deser/std/StringDeserializer.java4
2 files changed, 48 insertions, 34 deletions
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java
index a750550b4..52e52832d 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java
@@ -142,33 +142,49 @@ public abstract class FromStringDeserializer<T> extends StdScalarDeserializer<T>
{
// 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) {
- // 09-Jun-2020, tatu: Commonly `null` but may coerce to "empty" as well
- return (T) _deserializeFromEmptyString(ctxt);
+ if (text == null) {
+ JsonToken t = p.currentToken();
+ if (t != JsonToken.START_OBJECT) {
+ return (T) _deserializeFromOther(p, ctxt, t);
}
- 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
+ // 29-Jun-2020, tatu: New! "Scalar from Object" (mostly for XML)
+ text = ctxt.extractScalarFromObject(p, this, _valueClass);
+ }
+ if (text.length() == 0 || (text = text.trim()).length() == 0) {
+ // 09-Jun-2020, tatu: Commonly `null` but may coerce to "empty" as well
+ return (T) _deserializeFromEmptyString(ctxt);
+ }
+ 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;
}
- JsonToken t = p.currentToken();
+ // 05-May-2016, tatu: Unlike most usage, this seems legit, so...
+ JsonMappingException e = ctxt.weirdStringException(text, _valueClass, msg);
+ e.initCause(cause);
+ throw e;
+ }
+
+ /**
+ * Main method from trying to deserialize actual value from non-empty
+ * String.
+ */
+ protected abstract T _deserialize(String value, DeserializationContext ctxt) throws IOException;
+
+ // @since 2.12
+ protected Object _deserializeFromOther(JsonParser p, DeserializationContext ctxt,
+ JsonToken t) throws IOException
+ {
// [databind#381]
if (t == JsonToken.START_ARRAY) {
return _deserializeFromArray(p, ctxt);
@@ -180,20 +196,14 @@ public abstract class FromStringDeserializer<T> extends StdScalarDeserializer<T>
return null;
}
if (_valueClass.isAssignableFrom(ob.getClass())) {
- return (T) ob;
+ return ob;
}
- return (T) _deserializeEmbedded(ob, ctxt);
+ return _deserializeEmbedded(ob, ctxt);
}
- return (T) ctxt.handleUnexpectedToken(_valueClass, p);
+ return ctxt.handleUnexpectedToken(_valueClass, p);
}
/**
- * Main method from trying to deserialize actual value from non-empty
- * String.
- */
- protected abstract T _deserialize(String value, DeserializationContext ctxt) throws IOException;
-
- /**
* Overridable method to allow coercion from embedded value that is neither
* {@code null} nor directly assignable to target type.
* Used, for example, by {@link UUIDDeserializer} to coerce from {@code byte[]}.
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/StringDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/StringDeserializer.java
index 41850051a..2cdf67a1d 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/std/StringDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/StringDeserializer.java
@@ -57,6 +57,10 @@ public class StringDeserializer extends StdScalarDeserializer<String> // non-fin
// otherwise, try conversion using toString()...
return ob.toString();
}
+ // 29-Jun-2020, tatu: New! "Scalar from Object" (mostly for XML)
+ if (t == JsonToken.START_OBJECT) {
+ return ctxt.extractScalarFromObject(p, this, _valueClass);
+ }
// allow coercions for other scalar types
// 17-Jan-2018, tatu: Related to [databind#1853] avoid FIELD_NAME by ensuring it's
// "real" scalar