3
3
import java .io .IOException ;
4
4
import java .util .*;
5
5
6
- import com .fasterxml .jackson .annotation .JsonTypeInfo ;
7
-
8
6
import com .fasterxml .jackson .core .JsonParser ;
9
7
import com .fasterxml .jackson .core .JsonToken ;
10
8
11
9
import com .fasterxml .jackson .databind .*;
12
- import com .fasterxml .jackson .databind .exc .InvalidTypeIdException ;
13
10
import com .fasterxml .jackson .databind .introspect .BeanPropertyDefinition ;
14
11
import com .fasterxml .jackson .databind .jsontype .NamedType ;
15
12
import com .fasterxml .jackson .databind .jsontype .TypeDeserializer ;
21
18
* A {@link TypeDeserializer} capable of deducing polymorphic types based on the fields available. Deduction
22
19
* is limited to the <i>names</i> of child fields (not their values or, consequently, any nested descendants).
23
20
* Exceptions will be thrown if not enough unique information is present to select a single subtype.
21
+ * <p>
22
+ * The current deduction process <b>does not</b> support pojo-hierarchies such that the
23
+ * absence of child fields infers a parent type. That is, every deducible subtype
24
+ * MUST have some unique fields and the input data MUST contain said unique fields
25
+ * to provide a <i>positive match</i>.
24
26
*/
25
27
public class AsDeductionTypeDeserializer extends AsPropertyTypeDeserializer
26
28
{
@@ -32,7 +34,7 @@ public class AsDeductionTypeDeserializer extends AsPropertyTypeDeserializer
32
34
private final Map <BitSet , String > subtypeFingerprints ;
33
35
34
36
public AsDeductionTypeDeserializer (JavaType bt , TypeIdResolver idRes , JavaType defaultImpl , DeserializationConfig config , Collection <NamedType > subtypes ) {
35
- super (bt , idRes , null , false , defaultImpl );
37
+ super (bt , idRes , null , false , defaultImpl , null );
36
38
fieldBitIndex = new HashMap <>();
37
39
subtypeFingerprints = buildFingerprints (config , subtypes );
38
40
}
@@ -43,11 +45,6 @@ public AsDeductionTypeDeserializer(AsDeductionTypeDeserializer src, BeanProperty
43
45
subtypeFingerprints = src .subtypeFingerprints ;
44
46
}
45
47
46
- @ Override
47
- public JsonTypeInfo .As getTypeInclusion () {
48
- return null ;
49
- }
50
-
51
48
@ Override
52
49
public TypeDeserializer forProperty (BeanProperty prop ) {
53
50
return (prop == _property ) ? this : new AsDeductionTypeDeserializer (this , prop );
@@ -93,15 +90,15 @@ public Object deserializeTypedFromObject(JsonParser p, DeserializationContext ct
93
90
JsonToken t = p .currentToken ();
94
91
if (t == JsonToken .START_OBJECT ) {
95
92
t = p .nextToken ();
96
- } else {
93
+ } else if ( /*t == JsonToken.START_ARRAY ||*/ t != JsonToken . FIELD_NAME ) {
97
94
/* This is most likely due to the fact that not all Java types are
98
95
* serialized as JSON Objects; so if "as-property" inclusion is requested,
99
96
* serialization of things like Lists must be instead handled as if
100
97
* "as-wrapper-array" was requested.
101
98
* But this can also be due to some custom handling: so, if "defaultImpl"
102
99
* is defined, it will be asked to handle this case.
103
100
*/
104
- return _deserializeTypedUsingDefaultImpl (p , ctxt , null );
101
+ return _deserializeTypedUsingDefaultImpl (p , ctxt , null , "Unexpected input" );
105
102
}
106
103
107
104
List <BitSet > candidates = new LinkedList <>(subtypeFingerprints .keySet ());
@@ -127,13 +124,9 @@ public Object deserializeTypedFromObject(JsonParser p, DeserializationContext ct
127
124
}
128
125
}
129
126
130
- throw new InvalidTypeIdException (p ,
131
- String .format ("Cannot deduce unique subtype of %s (%d candidates match)" ,
132
- ClassUtil .getTypeDescription (_baseType ),
133
- candidates .size ()),
134
- _baseType
135
- , "DEDUCED"
136
- );
127
+ // We have zero or multiple candidates, deduction has failed
128
+ String msgToReportIfDefaultImplFailsToo = String .format ("Cannot deduce unique subtype of %s (%d candidates match)" , ClassUtil .getTypeDescription (_baseType ), candidates .size ());
129
+ return _deserializeTypedUsingDefaultImpl (p , ctxt , tb , msgToReportIfDefaultImplFailsToo );
137
130
}
138
131
139
132
// Keep only fingerprints containing this field
0 commit comments