27
27
*/
28
28
package org .hisp .dhis .jsontree ;
29
29
30
+ import org .hisp .dhis .jsontree .internal .Maybe ;
30
31
import org .hisp .dhis .jsontree .internal .Surly ;
31
32
32
33
import java .io .IOException ;
@@ -250,42 +251,56 @@ default JsonNode getParent() {
250
251
* @throws JsonPathException when no such node exists in the subtree of this node
251
252
*/
252
253
@ Surly
253
- default JsonNode get (@ Surly String path )
254
- throws JsonPathException {
254
+ default JsonNode get (@ Surly String path ) throws JsonPathException {
255
255
if ( path .isEmpty () ) return this ;
256
256
if ( "$" .equals ( path ) ) return getRoot ();
257
- if ( path . startsWith ( "$" ) ) return getRoot (). get ( path .substring ( 1 ) );
258
- if (! path . startsWith ( "{" ) && ! path . startsWith ( "[" ) && ! path . startsWith ( "." ))
259
- path = "." +path ;
257
+ char c0 = path .charAt ( 0 );
258
+ if ( c0 == '$' ) return getRoot (). get ( path . substring ( 1 ) );
259
+ if ( c0 != '{' && c0 != '[' && c0 != '.' ) path = "." +path ;
260
260
return get ( JsonPath .of ( path ) );
261
261
}
262
262
263
263
/**
264
+ * Access the node at the given path in the subtree of this node.
264
265
*
266
+ * @param path a simple or nested path relative to this node. A path starting with {@code $} is relative to the root
267
+ * node of this node, in other words it is an absolute path
268
+ * @return the node at the given path or {@code null} if no such node exists
269
+ * @throws JsonPathException when the provided path is malformed
270
+ * @since 1.5
271
+ */
272
+ @ Maybe
273
+ default JsonNode getOrNull (@ Surly String path ) throws JsonPathException {
274
+ if ( path .isEmpty () ) return this ;
275
+ if ( "$" .equals ( path ) ) return getRoot ();
276
+ char c0 = path .charAt ( 0 );
277
+ if ( c0 == '$' ) return getRoot ().getOrNull ( path .substring ( 1 ) );
278
+ if ( c0 != '{' && c0 != '[' && c0 != '.' ) path = "." +path ;
279
+ return getOrNull ( JsonPath .of ( path ) );
280
+ }
281
+
282
+ /**
265
283
* @param path a path understood relative to this node's {@link #getPath()}
266
284
* @return the node at the given path
285
+ * @throws JsonPathException when no such node exists in the subtree of this node
267
286
* @since 1.1
268
287
*/
269
288
@ Surly
270
- default JsonNode get (@ Surly JsonPath path ) {
289
+ default JsonNode get (@ Surly JsonPath path ) throws JsonPathException {
271
290
throw new JsonPathException ( path ,
272
291
format ( "This is a leaf node of type %s that does not have any children at path: %s" , getType (), path ) );
273
292
}
274
293
275
294
/**
276
- * Access node by path with default.
277
- *
278
- * @param path a simple or nested path relative to this node
279
- * @param orDefault value to return in no node at the given path exist in this subtree
280
- * @return the node at path or the provided default if no such node exists
281
- * @since 1.1
295
+ * @param path a path understood relative to this node's {@link #getPath()}
296
+ * @return the node at the given path or {@code null} if no such node exists
297
+ * @throws JsonPathException when the provided path is malformed
298
+ * @since 1.5
282
299
*/
283
- default JsonNode getOrDefault ( String path , JsonNode orDefault ) {
284
- try {
285
- return get ( path );
286
- } catch ( JsonPathException ex ) {
287
- return orDefault ;
288
- }
300
+ @ Maybe
301
+ default JsonNode getOrNull (@ Surly JsonPath path ) throws JsonPathException {
302
+ throw new JsonPathException ( path ,
303
+ format ( "This is a leaf node of type %s that does not have any children at path: %s" , getType (), path ) );
289
304
}
290
305
291
306
/**
@@ -332,7 +347,7 @@ default boolean isRoot() {
332
347
*/
333
348
default boolean isMember ( String name ) {
334
349
try {
335
- return member ( name ) != null ;
350
+ return memberOrNull ( name ) != null ;
336
351
} catch ( JsonPathException ex ) {
337
352
return false ;
338
353
}
@@ -347,7 +362,7 @@ default boolean isMember( String name ) {
347
362
*/
348
363
default boolean isElement ( int index ) {
349
364
try {
350
- return element ( index ) != null ;
365
+ return elementOrNull ( index ) != null ;
351
366
} catch ( JsonPathException ex ) {
352
367
return false ;
353
368
}
@@ -379,11 +394,27 @@ default boolean isElement( int index ) {
379
394
* @throws JsonPathException when no such member exists
380
395
* @throws JsonTreeException if this node is not an object node that could have members
381
396
*/
397
+ @ Surly
382
398
default JsonNode member ( String name )
383
399
throws JsonPathException {
384
400
throw new JsonTreeException ( getType () + " node has no member property: " + name );
385
401
}
386
402
403
+ /**
404
+ * OBS! Only defined when this node is of type {@link JsonNodeType#OBJECT}).
405
+ *
406
+ * @param name name of the member to access
407
+ * @return the member with the given name or {@code null} if no such member exists
408
+ * @throws JsonPathException when the path is malformed
409
+ * @throws JsonTreeException if this node is not an object node that could have members
410
+ * @since 1.5
411
+ */
412
+ @ Maybe
413
+ default JsonNode memberOrNull ( String name )
414
+ throws JsonPathException {
415
+ throw new JsonTreeException ( getType () + " node has no member property: " + name );
416
+ }
417
+
387
418
/**
388
419
* OBS! Only defined when this node is of type {@link JsonNodeType#OBJECT}).
389
420
* <p>
@@ -463,11 +494,27 @@ default Iterator<Entry<String, JsonNode>> members( boolean cacheNodes ) {
463
494
* @throws JsonPathException when no such element exists
464
495
* @throws JsonTreeException if this node is not an array node that could have elements
465
496
*/
497
+ @ Surly
466
498
default JsonNode element ( int index )
467
499
throws JsonPathException {
468
500
throw new JsonTreeException ( getType () + " node has no element property for index: " + index );
469
501
}
470
502
503
+ /**
504
+ * OBS! Only defined when this node is of type {@link JsonNodeType#ARRAY}).
505
+ *
506
+ * @param index index of the element to access
507
+ * @return the node at the given array index or {@code null} if no such element exists
508
+ * @throws JsonPathException when the index is negative (invalid)
509
+ * @throws JsonTreeException if this node is not an array node that could have elements
510
+ * @since 1.5
511
+ */
512
+ @ Maybe
513
+ default JsonNode elementOrNull ( int index )
514
+ throws JsonPathException {
515
+ throw new JsonTreeException ( getType () + " node has no element property for index: " + index );
516
+ }
517
+
471
518
/**
472
519
* OBS! Only defined when this node is of type {@link JsonNodeType#ARRAY}).
473
520
* <p>
0 commit comments