31
31
import com .fasterxml .jackson .databind .jsontype .TypeDeserializer ;
32
32
import com .fasterxml .jackson .databind .jsontype .TypeIdResolver ;
33
33
import com .fasterxml .jackson .databind .node .JsonNodeFactory ;
34
+ import com .fasterxml .jackson .databind .node .TreeTraversingParser ;
34
35
import com .fasterxml .jackson .databind .type .LogicalType ;
35
36
import com .fasterxml .jackson .databind .type .TypeFactory ;
36
37
import com .fasterxml .jackson .databind .util .*;
@@ -912,6 +913,10 @@ public <T> T readValue(JsonParser p, JavaType type) throws IOException {
912
913
* for reading one-off values for the composite type, taking into account
913
914
* annotations that the property (passed to this method -- usually property that
914
915
* has custom serializer that called this method) has.
916
+ *
917
+ * @param p Parser that points to the first token of the value to read
918
+ * @param prop Logical property of a POJO being type
919
+ * @return Value of type {@code type} that was read
915
920
*
916
921
* @since 2.4
917
922
*/
@@ -920,6 +925,10 @@ public <T> T readPropertyValue(JsonParser p, BeanProperty prop, Class<T> type) t
920
925
}
921
926
922
927
/**
928
+ * Same as {@link #readPropertyValue(JsonParser, BeanProperty, Class)} but with
929
+ * fully resolved {@link JavaType} as target: needs to be used for generic types,
930
+ * for example.
931
+ *
923
932
* @since 2.4
924
933
*/
925
934
@ SuppressWarnings ("unchecked" )
@@ -934,6 +943,13 @@ public <T> T readPropertyValue(JsonParser p, BeanProperty prop, JavaType type) t
934
943
}
935
944
936
945
/**
946
+ * Convenience method for reading the value that passed {@link JsonParser}
947
+ * points to as a {@link JsonNode}.
948
+ *
949
+ * @param p Parser that points to the first token of the value to read
950
+ *
951
+ * @return Value read as {@link JsonNode}
952
+ *
937
953
* @since 2.10
938
954
*/
939
955
public JsonNode readTree (JsonParser p ) throws IOException {
@@ -951,6 +967,71 @@ public JsonNode readTree(JsonParser p) throws IOException {
951
967
.deserialize (p , this );
952
968
}
953
969
970
+ /**
971
+ * Helper method similar to {@link ObjectReader#treeToValue(TreeNode, Class)}
972
+ * which will read contents of given tree ({@link JsonNode})
973
+ * and bind them into specified target type. This is often used in two-phase
974
+ * deserialization in which content is first read as a tree, then manipulated
975
+ * (adding and/or removing properties of Object values, for example),
976
+ * and finally converted into actual target type using default deserialization
977
+ * logic for the type.
978
+ *<p>
979
+ * NOTE: deserializer implementations should be careful not to try to recursively
980
+ * deserialize into target type deserializer has registered itself to handle.
981
+ *
982
+ * @param n Tree value to convert, if not {@code null}: if {@code null}, will simply
983
+ * return {@code null}
984
+ * @param targetType Type to deserialize contents of {@code n} into (if {@code n} not {@code null})
985
+ *
986
+ * @return Either {@code null} (if {@code n} was {@code null} or a value of
987
+ * type {@code type} that was read from non-{@code null} {@code n} argument
988
+ *
989
+ * @since 2.13
990
+ */
991
+ public <T > T readTreeAsValue (JsonNode n , Class <T > targetType ) throws IOException
992
+ {
993
+ if (n == null ) {
994
+ return null ;
995
+ }
996
+ try (TreeTraversingParser p = _treeAsTokens (n )) {
997
+ return readValue (p , targetType );
998
+ }
999
+ }
1000
+
1001
+ /**
1002
+ * Same as {@link #readTreeAsValue(JsonNode, Class)} but will fully resolved
1003
+ * {@link JavaType} as {@code targetType}
1004
+ *<p>
1005
+ * NOTE: deserializer implementations should be careful not to try to recursively
1006
+ * deserialize into target type deserializer has registered itself to handle.
1007
+ *
1008
+ * @param n Tree value to convert
1009
+ * @param targetType Type to deserialize contents of {@code n} into
1010
+ *
1011
+ * @return Value of type {@code type} that was read
1012
+ *
1013
+ * @since 2.13
1014
+ */
1015
+ public <T > T readTreeAsValue (JsonNode n , JavaType targetType ) throws IOException
1016
+ {
1017
+ if (n == null ) {
1018
+ return null ;
1019
+ }
1020
+ try (TreeTraversingParser p = _treeAsTokens (n )) {
1021
+ return readValue (p , targetType );
1022
+ }
1023
+ }
1024
+
1025
+ private TreeTraversingParser _treeAsTokens (JsonNode n ) throws IOException
1026
+ {
1027
+ // Not perfect but has to do...
1028
+ ObjectCodec codec = (_parser == null ) ? null : _parser .getCodec ();
1029
+ TreeTraversingParser p = new TreeTraversingParser (n , codec );
1030
+ // important: must initialize...
1031
+ p .nextToken ();
1032
+ return p ;
1033
+ }
1034
+
954
1035
/*
955
1036
/**********************************************************
956
1037
/* Methods for problem handling
0 commit comments