@@ -954,7 +954,6 @@ public Object handleWeirdNumberValue(Class<?> targetClass, Number value,
954
954
String msg , Object ... msgArgs )
955
955
throws IOException
956
956
{
957
- // but if not handled, just throw exception
958
957
if (msgArgs .length > 0 ) {
959
958
msg = String .format (msg , msgArgs );
960
959
}
@@ -977,46 +976,44 @@ public Object handleWeirdNumberValue(Class<?> targetClass, Number value,
977
976
}
978
977
979
978
/**
980
- * Method that deserializers should call if they encounter a type id
981
- * (for polymorphic deserialization) that can not be resolved to an
982
- * actual type; usually since there is no mapping defined.
983
- * Default implementation will try to call {@link DeserializationProblemHandler#handleUnknownTypeId}
984
- * on configured handlers, if any, to allow for recovery; if recovery does not
985
- * succeed, will throw exception constructed with {@link #unknownTypeIdException}.
986
- *
987
- * @param baseType Base type from which resolution starts
988
- * @param id Type id that could not be converted
989
- * @param extraDesc Additional problem description to add to default exception message,
990
- * if resolution fails.
979
+ * Method that deserializers should call if they fail to instantiate value
980
+ * due to lack of viable instantiator (usually creator, that is, constructor
981
+ * or static factory method). Method should be called at point where value
982
+ * has not been decoded, so that handler has a chance to handle decoding
983
+ * using alternate mechanism, and handle underlying content (possibly by
984
+ * just skipping it) to keep input state valid
991
985
*
992
- * @return {@link JavaType} that id resolves to
986
+ * @param instClass Type that was to be instantiated
987
+ * @param p Parser that points to the JSON value to decode
993
988
*
994
- * @throws IOException To indicate unrecoverable problem, if resolution can not
995
- * be made to work
989
+ * @return Object that should be constructed, if any; has to be of type <code>instClass</code>
996
990
*
997
991
* @since 2.8
998
992
*/
999
- public JavaType handleUnknownTypeId (JavaType baseType , String id ,
1000
- String extraDesc ) throws IOException
993
+ public Object handleMissingInstantiator (Class <?> instClass , JsonParser p ,
994
+ String msg , Object ... msgArgs )
995
+ throws IOException
1001
996
{
997
+ if (msgArgs .length > 0 ) {
998
+ msg = String .format (msg , msgArgs );
999
+ }
1002
1000
LinkedNode <DeserializationProblemHandler > h = _config .getProblemHandlers ();
1003
1001
while (h != null ) {
1004
1002
// Can bail out if it's handled
1005
- JavaType type = h .value ().handleUnknownTypeId (this , baseType , id , extraDesc );
1006
- if (type != null ) {
1007
- if (type .hasRawClass (Void .class )) {
1008
- return null ;
1009
- }
1010
- // But ensure there's type compatibility
1011
- if (type .isTypeOrSubTypeOf (baseType .getRawClass ())) {
1012
- return type ;
1003
+ Object instance = h .value ().handleMissingInstantiator (this ,
1004
+ instClass , p , msg );
1005
+ if (instance != DeserializationProblemHandler .NOT_HANDLED ) {
1006
+ // Sanity check for broken handlers, otherwise nasty to debug:
1007
+ if ((instance == null ) || instClass .isInstance (instance )) {
1008
+ return instance ;
1013
1009
}
1014
- throw unknownTypeIdException (baseType , id ,
1015
- "problem handler tried to resolve into non-subtype: " +type );
1010
+ throw instantiationException (instClass , String .format (
1011
+ "DeserializationProblemHandler.handleMissingInstantiator() for type %s returned value of type %s" ,
1012
+ instClass , instance .getClass ()));
1016
1013
}
1017
1014
h = h .next ();
1018
1015
}
1019
- throw unknownTypeIdException ( baseType , id , extraDesc );
1016
+ throw instantiationException ( instClass , msg );
1020
1017
}
1021
1018
1022
1019
/**
@@ -1062,12 +1059,76 @@ public Object handleInstantiationProblem(Class<?> instClass, Object argument,
1062
1059
throw instantiationException (instClass , t );
1063
1060
}
1064
1061
1062
+ /**
1063
+ * Method that deserializers should call if they encounter a type id
1064
+ * (for polymorphic deserialization) that can not be resolved to an
1065
+ * actual type; usually since there is no mapping defined.
1066
+ * Default implementation will try to call {@link DeserializationProblemHandler#handleUnknownTypeId}
1067
+ * on configured handlers, if any, to allow for recovery; if recovery does not
1068
+ * succeed, will throw exception constructed with {@link #unknownTypeIdException}.
1069
+ *
1070
+ * @param baseType Base type from which resolution starts
1071
+ * @param id Type id that could not be converted
1072
+ * @param extraDesc Additional problem description to add to default exception message,
1073
+ * if resolution fails.
1074
+ *
1075
+ * @return {@link JavaType} that id resolves to
1076
+ *
1077
+ * @throws IOException To indicate unrecoverable problem, if resolution can not
1078
+ * be made to work
1079
+ *
1080
+ * @since 2.8
1081
+ */
1082
+ public JavaType handleUnknownTypeId (JavaType baseType , String id ,
1083
+ String extraDesc ) throws IOException
1084
+ {
1085
+ LinkedNode <DeserializationProblemHandler > h = _config .getProblemHandlers ();
1086
+ while (h != null ) {
1087
+ // Can bail out if it's handled
1088
+ JavaType type = h .value ().handleUnknownTypeId (this , baseType , id , extraDesc );
1089
+ if (type != null ) {
1090
+ if (type .hasRawClass (Void .class )) {
1091
+ return null ;
1092
+ }
1093
+ // But ensure there's type compatibility
1094
+ if (type .isTypeOrSubTypeOf (baseType .getRawClass ())) {
1095
+ return type ;
1096
+ }
1097
+ throw unknownTypeIdException (baseType , id ,
1098
+ "problem handler tried to resolve into non-subtype: " +type );
1099
+ }
1100
+ h = h .next ();
1101
+ }
1102
+ throw unknownTypeIdException (baseType , id , extraDesc );
1103
+ }
1104
+
1065
1105
/*
1066
1106
/**********************************************************
1067
- /* Methods for problem reporting
1107
+ /* Methods for problem reporting, in cases where recovery
1108
+ /* is not considered possible
1068
1109
/**********************************************************
1069
1110
*/
1070
1111
1112
+ /**
1113
+ * Method for deserializers to call
1114
+ * when the token encountered was of type different than what <b>should</b>
1115
+ * be seen at that position, usually within a sequence of expected tokens.
1116
+ * Note that this method will throw a {@link JsonMappingException} and no
1117
+ * recovery is attempted (via {@link DeserializationProblemHandler}, as
1118
+ * problem is considered to be difficult to recover from, in general.
1119
+ *
1120
+ * @since 2.8
1121
+ */
1122
+ public void reportWrongTokenException (JsonParser p ,
1123
+ JsonToken expToken , String msg , Object ... msgArgs )
1124
+ throws JsonMappingException
1125
+ {
1126
+ if (msgArgs .length > 0 ) {
1127
+ msg = String .format (msg , msgArgs );
1128
+ }
1129
+ throw wrongTokenException (p , expToken , msg );
1130
+ }
1131
+
1071
1132
/**
1072
1133
* Helper method for reporting a problem with unhandled unknown property.
1073
1134
*
@@ -1093,32 +1154,6 @@ public void reportUnknownProperty(Object instanceOrClass, String fieldName,
1093
1154
instanceOrClass , fieldName , propIds );
1094
1155
}
1095
1156
1096
- /**
1097
- * @since 2.8
1098
- */
1099
- public void reportInstantiationException (Class <?> instClass ,
1100
- String msg , Object ... msgArgs )
1101
- throws JsonMappingException
1102
- {
1103
- if (msgArgs .length > 0 ) {
1104
- msg = String .format (msg , msgArgs );
1105
- }
1106
- throw instantiationException (instClass , msg );
1107
- }
1108
-
1109
- /**
1110
- * @since 2.8
1111
- */
1112
- public JsonMappingException reportWrongTokenException (JsonParser p ,
1113
- JsonToken expToken , String msg , Object ... msgArgs )
1114
- throws JsonMappingException
1115
- {
1116
- if (msgArgs .length > 0 ) {
1117
- msg = String .format (msg , msgArgs );
1118
- }
1119
- throw wrongTokenException (p , expToken , msg );
1120
- }
1121
-
1122
1157
/**
1123
1158
* @since 2.8
1124
1159
*/
@@ -1203,7 +1238,7 @@ public JsonMappingException mappingException(String msgTemplate, Object... args)
1203
1238
*/
1204
1239
1205
1240
/**
1206
- * Helper method for constructing {@link JsonMappingException} to indicated
1241
+ * Helper method for constructing {@link JsonMappingException} to indicate
1207
1242
* that the token encountered was of type different than what <b>should</b>
1208
1243
* be seen at that position, usually within a sequence of expected tokens.
1209
1244
* Note that most of the time this method should NOT be directly called;
@@ -1288,6 +1323,21 @@ public JsonMappingException instantiationException(Class<?> instClass, Throwable
1288
1323
instClass .getName (), t .getMessage ()), t );
1289
1324
}
1290
1325
1326
+ /**
1327
+ * Helper method for constructing instantiation exception for specified type,
1328
+ * to indicate that instantiation failed due to missing instantiator
1329
+ * (creator; constructor or factory method).
1330
+ *<p>
1331
+ * Note that most of the time this method should NOT be called; instead,
1332
+ * {@link #handleMissingInstantiator} should be called which will call this method
1333
+ * if necessary.
1334
+ */
1335
+ public JsonMappingException instantiationException (Class <?> instClass , String msg ) {
1336
+ return JsonMappingException .from (_parser ,
1337
+ String .format ("Can not construct instance of %s: %s" ,
1338
+ instClass .getName (), msg ));
1339
+ }
1340
+
1291
1341
/**
1292
1342
* Helper method for constructing exception to indicate that given type id
1293
1343
* could not be resolved to a valid subtype of specified base type, during
@@ -1313,16 +1363,6 @@ public JsonMappingException unknownTypeIdException(JavaType baseType, String typ
1313
1363
/**********************************************************
1314
1364
*/
1315
1365
1316
- /**
1317
- * @deprecated Since 2.8 use {@link #reportInstantiationException} instead
1318
- */
1319
- @ Deprecated
1320
- public JsonMappingException instantiationException (Class <?> instClass , String msg ) {
1321
- return JsonMappingException .from (_parser ,
1322
- String .format ("Can not construct instance of %s: %s" ,
1323
- instClass .getName (), msg ));
1324
- }
1325
-
1326
1366
/**
1327
1367
* @since 2.5
1328
1368
*
0 commit comments