66import java .util .*;
77
88import com .fasterxml .jackson .core .*;
9+ import com .fasterxml .jackson .databind .node .ArrayNode ;
910import com .fasterxml .jackson .databind .node .JsonNodeType ;
1011import com .fasterxml .jackson .databind .node .MissingNode ;
1112import com .fasterxml .jackson .databind .node .ObjectNode ;
@@ -1124,10 +1125,16 @@ public final List<JsonNode> findParents(String fieldName)
11241125 * If the node method is called on is not Object node,
11251126 * or if property exists and has value that is not Object node,
11261127 * {@link UnsupportedOperationException} is thrown
1128+ *
1129+ * @param propertyName Name of property for the {@link ObjectNode}
1130+ *
1131+ * @return {@link ObjectNode} found or created
1132+ *
1133+ * @since 2.14
11271134 */
1128- public < T extends JsonNode > T withObject (String propertyName ) {
1129- throw new UnsupportedOperationException ("JsonNode not of type ObjectNode (but "
1130- +getClass ().getName ()+"), cannot call withObject() on it" );
1135+ public ObjectNode withObject (String propertyName ) {
1136+ throw new UnsupportedOperationException ("` JsonNode` not of type ` ObjectNode` (but "
1137+ +getClass ().getName ()+"), cannot call ` withObject()` on it" );
11311138 }
11321139
11331140 /**
@@ -1137,10 +1144,10 @@ public <T extends JsonNode> T withObject(String propertyName) {
11371144 * consider {@link JsonPointer} segments index if at all possible
11381145 * and only secondarily as property name
11391146 *
1140- * @param ptr Pointer that indicates path to use for Object value to return
1147+ * @param ptr {@link JsonPointer} that indicates path to use for Object value to return
11411148 * (potentially creating as necessary)
11421149 *
1143- * @return ObjectNode found or created
1150+ * @return {@link ObjectNode} found or created
11441151 *
11451152 * @since 2.14
11461153 */
@@ -1149,18 +1156,70 @@ public final ObjectNode withObject(JsonPointer ptr) {
11491156 }
11501157
11511158 /**
1152- * Method that can be called on Object nodes, to access a Object-valued
1159+ * Method that can be called on Object or Array nodes, to access a Object-valued
11531160 * node pointed to by given {@link JsonPointer}, if such a node exists:
1154- * if not, an attempt is made to create it.
1155- * If the node method is called on is not Object node,
1156- * or if property exists and has value that is not Object node,
1157- * {@link UnsupportedOperationException} is thrown
1161+ * or if not, an attempt is made to create one and return it.
1162+ * For example, on document
1163+ *<pre>
1164+ * { "a" : {
1165+ * "b" : {
1166+ * "c" : 13
1167+ * }
1168+ * }
1169+ * }
1170+ *</pre>
1171+ * calling method with {@link JsonPointer} of {@code /a/b} would return
1172+ * {@link ObjectNode}
1173+ *<pre>
1174+ * { "c" : 13 }
1175+ *</pre>
1176+ *<p>
1177+ * In cases where path leads to "missing" nodes, a path is created.
1178+ * So, for example, on above document, and
1179+ * {@link JsonPointer} of {@code /a/x} an empty {@link ObjectNode} would
1180+ * be returned and the document would look like:
1181+ *<pre>
1182+ * { "a" : {
1183+ * "b" : {
1184+ * "c" : 13
1185+ * },
1186+ * "x" : { }
1187+ * }
1188+ * }
1189+ *</pre>
1190+ * Finally, if the path is incompatible with the document -- there is an existing
1191+ * {@code JsonNode} through which expression cannot go -- a replacement is
1192+ * attempted if (and only if) conversion is allowed as per {@code overwriteMode}
1193+ * passed in. For example, with above document and expression of {@code /a/b/c},
1194+ * conversion is allowed if passing {@code OverwriteMode.SCALARS} or
1195+ * {@code OvewriteMode.ALL}, and resulting document would look like:
1196+ *<pre>
1197+ * { "a" : {
1198+ * "b" : {
1199+ * "c" : { }
1200+ * },
1201+ * "x" : { }
1202+ * }
1203+ * }
1204+ *</pre>
1205+ * but if different modes ({@code NONE} or {@code NULLS}) is passed, an exception
1206+ * is thrown instead.
11581207 *
1159- * @param ptr Pointer that indicates path to use for Object value to return
1160- * (potentially creating as necessary)
1161- * @param overwriteMode Defines w
1208+ * @param ptr Pointer that indicates path to use for {@link ObjectNode} value to return
1209+ * (potentially creating one as necessary)
1210+ * @param overwriteMode Defines which node types may be converted in case of
1211+ * incompatible {@code JsonPointer} expression: if conversion not allowed,
1212+ * {@link UnsupportedOperationException} is thrown.
1213+ * @param preferIndex When creating a path (for empty or replacement), and path
1214+ * contains segment that may be an array index (simple integer number like
1215+ * {@code 3}), whether to construct an {@link ArrayNode} ({@code true}) or
1216+ * {@link ObjectNode} ({@code false}). In latter case matching property with
1217+ * quoted number (like {@code "3"}) is used within Object.
11621218 *
1163- * @return ObjectNode found or created
1219+ * @return {@link ObjectNode} found or created
1220+ *
1221+ * @throws UnsupportedOperationException if a conversion would be needed for given
1222+ * {@code JsonPointer}, document, but was not allowed for the type encountered
11641223 *
11651224 * @since 2.14
11661225 */
@@ -1172,26 +1231,116 @@ public ObjectNode withObject(JsonPointer ptr,
11721231 }
11731232
11741233 /**
1175- * @deprecated Since 2.14 use {@code withObject} instead
1234+ * @deprecated Since 2.14 use {@code withObject(String) } instead
11761235 */
1236+ @ SuppressWarnings ("unchecked" )
11771237 @ Deprecated // since 2.14
11781238 public final <T extends JsonNode > T with (String propertyName ) {
1179- return withObject (propertyName );
1239+ return ( T ) withObject (propertyName );
11801240 }
11811241
11821242 /**
1183- * Method that can be called on Object nodes, to access a property
1243+ * Method that can be called on {@link ObjectNode} nodes, to access a property
11841244 * that has <code>Array</code> value; or if no such property exists, to create,
11851245 * add and return such Array node.
11861246 * If the node method is called on is not Object node,
11871247 * or if property exists and has value that is not Array node,
11881248 * {@link UnsupportedOperationException} is thrown
1249+ *
1250+ * @param propertyName Name of property for the {@link ArrayNode}
1251+ *
1252+ * @return {@link ArrayNode} found or created
11891253 */
11901254 public <T extends JsonNode > T withArray (String propertyName ) {
11911255 throw new UnsupportedOperationException ("JsonNode not of type ObjectNode (but "
11921256 +getClass ().getName ()+"), cannot call withArray() on it" );
11931257 }
11941258
1259+ /**
1260+ * Same as {@link #withArray(JsonPointer, OverwriteMode, boolean)} but
1261+ * with defaults of {@code OvewriteMode#NULLS} (overwrite mode)
1262+ * and {@code true} for {@code preferIndex}.
1263+ *
1264+ * @param ptr Pointer that indicates path to use for {@link ArrayNode} to return
1265+ * (potentially creating as necessary)
1266+ *
1267+ * @return {@link ArrayNode} found or created
1268+ *
1269+ * @since 2.14
1270+ */
1271+ public final ArrayNode withArray (JsonPointer ptr ) {
1272+ return withArray (ptr , OverwriteMode .NULLS , true );
1273+ }
1274+
1275+ /**
1276+ * Method that can be called on Object or Array nodes, to access a Array-valued
1277+ * node pointed to by given {@link JsonPointer}, if such a node exists:
1278+ * or if not, an attempt is made to create one and return it.
1279+ * For example, on document
1280+ *<pre>
1281+ * { "a" : {
1282+ * "b" : [ 1, 2 ]
1283+ * }
1284+ * }
1285+ *</pre>
1286+ * calling method with {@link JsonPointer} of {@code /a/b} would return
1287+ * {@code Array}
1288+ *<pre>
1289+ * [ 1, 2 ]
1290+ *</pre>
1291+ *<p>
1292+ * In cases where path leads to "missing" nodes, a path is created.
1293+ * So, for example, on above document, and
1294+ * {@link JsonPointer} of {@code /a/x} an empty {@code ArrayNode} would
1295+ * be returned and the document would look like:
1296+ *<pre>
1297+ * { "a" : {
1298+ * "b" : [ 1, 2 ],
1299+ * "x" : [ ]
1300+ * }
1301+ * }
1302+ *</pre>
1303+ * Finally, if the path is incompatible with the document -- there is an existing
1304+ * {@code JsonNode} through which expression cannot go -- a replacement is
1305+ * attempted if (and only if) conversion is allowed as per {@code overwriteMode}
1306+ * passed in. For example, with above document and expression of {@code /a/b/0},
1307+ * conversion is allowed if passing {@code OverwriteMode.SCALARS} or
1308+ * {@code OvewriteMode.ALL}, and resulting document would look like:
1309+ *<pre>
1310+ * { "a" : {
1311+ * "b" : [ [ ], 2 ],
1312+ * "x" : [ ]
1313+ * }
1314+ * }
1315+ *</pre>
1316+ * but if different modes ({@code NONE} or {@code NULLS}) is passed, an exception
1317+ * is thrown instead.
1318+ *
1319+ * @param ptr Pointer that indicates path to use for {@link ArrayNode} value to return
1320+ * (potentially creating it as necessary)
1321+ * @param overwriteMode Defines which node types may be converted in case of
1322+ * incompatible {@code JsonPointer} expression: if conversion not allowed,
1323+ * an exception is thrown.
1324+ * @param preferIndex When creating a path (for empty or replacement), and path
1325+ * contains segment that may be an array index (simple integer number like
1326+ * {@code 3}), whether to construct an {@link ArrayNode} ({@code true}) or
1327+ * {@link ObjectNode} ({@code false}). In latter case matching property with
1328+ * quoted number (like {@code "3"}) is used within Object.
1329+ *
1330+ * @return {@link ArrayNode} found or created
1331+ *
1332+ * @throws UnsupportedOperationException if a conversion would be needed for given
1333+ * {@code JsonPointer}, document, but was not allowed for the type encountered
1334+ *
1335+ * @since 2.14
1336+ */
1337+ public ArrayNode withArray (JsonPointer ptr ,
1338+ OverwriteMode overwriteMode , boolean preferIndex ) {
1339+ // To avoid abstract method, base implementation just fails
1340+ throw new UnsupportedOperationException ("`withArray(JsonPointer)` not implemented by "
1341+ +getClass ().getName ());
1342+ }
1343+
11951344 /*
11961345 /**********************************************************
11971346 /* Public API, comparison
0 commit comments