1 package com.fasterxml.jackson.databind; 2 3 import java.io.IOException; 4 import java.math.BigDecimal; 5 import java.math.BigInteger; 6 import java.util.*; 7 8 import com.fasterxml.jackson.core.*; 9 import com.fasterxml.jackson.databind.node.JsonNodeType; 10 import com.fasterxml.jackson.databind.node.MissingNode; 11 import com.fasterxml.jackson.databind.util.ClassUtil; 12 13 /** 14 * Base class for all JSON nodes, which form the basis of JSON 15 * Tree Model that Jackson implements. 16 * One way to think of these nodes is to consider them 17 * similar to DOM nodes in XML DOM trees. 18 *<p> 19 * As a general design rule, most accessors ("getters") are included 20 * in this base class, to allow for traversing structure without 21 * type casts. Most mutators, however, need to be accessed through 22 * specific sub-classes (such as <code>ObjectNode</code> 23 * and <code>ArrayNode</code>). 24 * This seems sensible because proper type 25 * information is generally available when building or modifying 26 * trees, but less often when reading a tree (newly built from 27 * parsed JSON content). 28 *<p> 29 * Actual concrete sub-classes can be found from package 30 * {@link com.fasterxml.jackson.databind.node}. 31 *<p> 32 * Note that it is possible to "read" from nodes, using 33 * method {@link TreeNode#traverse(ObjectCodec)}, which will result in 34 * a {@link JsonParser} being constructed. This can be used for (relatively) 35 * efficient conversations between different representations; and it is what 36 * core databind uses for methods like {@link ObjectMapper#treeToValue(TreeNode, Class)} 37 * and {@link ObjectMapper#treeAsTokens(TreeNode)} 38 */ 39 public abstract class JsonNode 40 extends JsonSerializable.Base // i.e. implements JsonSerializable 41 implements TreeNode, Iterable<JsonNode> 42 { 43 /* 44 /********************************************************** 45 /* Construction, related 46 /********************************************************** 47 */ 48 JsonNode()49 protected JsonNode() { } 50 51 /** 52 * Method that can be called to get a node that is guaranteed 53 * not to allow changing of this node through mutators on 54 * this node or any of its children. 55 * This means it can either make a copy of this node (and all 56 * mutable children and grand children nodes), or node itself 57 * if it is immutable. 58 *<p> 59 * Note: return type is guaranteed to have same type as the 60 * node method is called on; which is why method is declared 61 * with local generic type. 62 * 63 * @since 2.0 64 * 65 * @return Node that is either a copy of this node (and all non-leaf 66 * children); or, for immutable leaf nodes, node itself. 67 */ deepCopy()68 public abstract <T extends JsonNode> T deepCopy(); 69 70 /* 71 /********************************************************** 72 /* TreeNode implementation 73 /********************************************************** 74 */ 75 76 // public abstract JsonToken asToken(); 77 // public abstract JsonToken traverse(); 78 // public abstract JsonToken traverse(ObjectCodec codec); 79 // public abstract JsonParser.NumberType numberType(); 80 81 @Override size()82 public int size() { return 0; } 83 84 /** 85 * Convenience method that is functionally same as: 86 *<pre> 87 * size() == 0 88 *</pre> 89 * for all node types. 90 * 91 * @since 2.10 92 */ isEmpty()93 public boolean isEmpty() { return size() == 0; } 94 95 @Override isValueNode()96 public final boolean isValueNode() 97 { 98 switch (getNodeType()) { 99 case ARRAY: case OBJECT: case MISSING: 100 return false; 101 default: 102 return true; 103 } 104 } 105 106 @Override isContainerNode()107 public final boolean isContainerNode() { 108 final JsonNodeType type = getNodeType(); 109 return type == JsonNodeType.OBJECT || type == JsonNodeType.ARRAY; 110 } 111 112 @Override isMissingNode()113 public boolean isMissingNode() { 114 return false; 115 } 116 117 @Override isArray()118 public boolean isArray() { 119 return false; 120 } 121 122 @Override isObject()123 public boolean isObject() { 124 return false; 125 } 126 127 /** 128 * Method for accessing value of the specified element of 129 * an array node. For other nodes, null is always returned. 130 *<p> 131 * For array nodes, index specifies 132 * exact location within array and allows for efficient iteration 133 * over child elements (underlying storage is guaranteed to 134 * be efficiently indexable, i.e. has random-access to elements). 135 * If index is less than 0, or equal-or-greater than 136 * <code>node.size()</code>, null is returned; no exception is 137 * thrown for any index. 138 *<p> 139 * NOTE: if the element value has been explicitly set as <code>null</code> 140 * (which is different from removal!), 141 * a {@link com.fasterxml.jackson.databind.node.NullNode} will be returned, 142 * not null. 143 * 144 * @return Node that represent value of the specified element, 145 * if this node is an array and has specified element. 146 * Null otherwise. 147 */ 148 @Override get(int index)149 public abstract JsonNode get(int index); 150 151 /** 152 * Method for accessing value of the specified field of 153 * an object node. If this node is not an object (or it 154 * does not have a value for specified field name), or 155 * if there is no field with such name, null is returned. 156 *<p> 157 * NOTE: if the property value has been explicitly set as <code>null</code> 158 * (which is different from removal!), 159 * a {@link com.fasterxml.jackson.databind.node.NullNode} will be returned, 160 * not null. 161 * 162 * @return Node that represent value of the specified field, 163 * if this node is an object and has value for the specified 164 * field. Null otherwise. 165 */ 166 @Override get(String fieldName)167 public JsonNode get(String fieldName) { return null; } 168 /** 169 * This method is similar to {@link #get(String)}, except 170 * that instead of returning null if no such value exists (due 171 * to this node not being an object, or object not having value 172 * for the specified field), 173 * a "missing node" (node that returns true for 174 * {@link #isMissingNode}) will be returned. This allows for 175 * convenient and safe chained access via path calls. 176 */ 177 178 @Override path(String fieldName)179 public abstract JsonNode path(String fieldName); 180 181 /** 182 * This method is similar to {@link #get(int)}, except 183 * that instead of returning null if no such element exists (due 184 * to index being out of range, or this node not being an array), 185 * a "missing node" (node that returns true for 186 * {@link #isMissingNode}) will be returned. This allows for 187 * convenient and safe chained access via path calls. 188 */ 189 @Override path(int index)190 public abstract JsonNode path(int index); 191 192 @Override fieldNames()193 public Iterator<String> fieldNames() { 194 return ClassUtil.emptyIterator(); 195 } 196 197 /** 198 * Method for locating node specified by given JSON pointer instances. 199 * Method will never return null; if no matching node exists, 200 * will return a node for which {@link #isMissingNode()} returns true. 201 * 202 * @return Node that matches given JSON Pointer: if no match exists, 203 * will return a node for which {@link #isMissingNode()} returns true. 204 * 205 * @since 2.3 206 */ 207 @Override at(JsonPointer ptr)208 public final JsonNode at(JsonPointer ptr) 209 { 210 // Basically: value nodes only match if we have "empty" path left 211 if (ptr.matches()) { 212 return this; 213 } 214 JsonNode n = _at(ptr); 215 if (n == null) { 216 return MissingNode.getInstance(); 217 } 218 return n.at(ptr.tail()); 219 } 220 221 /** 222 * Convenience method that is functionally equivalent to: 223 *<pre> 224 * return at(JsonPointer.valueOf(jsonPointerExpression)); 225 *</pre> 226 *<p> 227 * Note that if the same expression is used often, it is preferable to construct 228 * {@link JsonPointer} instance once and reuse it: this method will not perform 229 * any caching of compiled expressions. 230 * 231 * @param jsonPtrExpr Expression to compile as a {@link JsonPointer} 232 * instance 233 * 234 * @return Node that matches given JSON Pointer: if no match exists, 235 * will return a node for which {@link TreeNode#isMissingNode()} returns true. 236 * 237 * @since 2.3 238 */ 239 @Override at(String jsonPtrExpr)240 public final JsonNode at(String jsonPtrExpr) { 241 return at(JsonPointer.compile(jsonPtrExpr)); 242 } 243 _at(JsonPointer ptr)244 protected abstract JsonNode _at(JsonPointer ptr); 245 246 /* 247 /********************************************************** 248 /* Public API, type introspection 249 /********************************************************** 250 */ 251 252 // // First high-level division between values, containers and "missing" 253 254 /** 255 * Return the type of this node 256 * 257 * @return the node type as a {@link JsonNodeType} enum value 258 * 259 * @since 2.2 260 */ getNodeType()261 public abstract JsonNodeType getNodeType(); 262 263 /** 264 * Method that can be used to check if the node is a wrapper 265 * for a POJO ("Plain Old Java Object" aka "bean". 266 * Returns true only for 267 * instances of <code>POJONode</code>. 268 * 269 * @return True if this node wraps a POJO 270 */ isPojo()271 public final boolean isPojo() { 272 return getNodeType() == JsonNodeType.POJO; 273 } 274 275 /** 276 * @return True if this node represents a numeric JSON value 277 */ isNumber()278 public final boolean isNumber() { 279 return getNodeType() == JsonNodeType.NUMBER; 280 } 281 282 /** 283 * 284 * @return True if this node represents an integral (integer) 285 * numeric JSON value 286 */ isIntegralNumber()287 public boolean isIntegralNumber() { return false; } 288 289 /** 290 * @return True if this node represents a non-integral 291 * numeric JSON value 292 */ isFloatingPointNumber()293 public boolean isFloatingPointNumber() { return false; } 294 295 /** 296 * Method that can be used to check whether contained value 297 * is a number represented as Java <code>short</code>. 298 * Note, however, that even if this method returns false, it 299 * is possible that conversion would be possible from other numeric 300 * types -- to check if this is possible, use 301 * {@link #canConvertToInt()} instead. 302 * 303 * @return True if the value contained by this node is stored as Java short 304 */ isShort()305 public boolean isShort() { return false; } 306 307 /** 308 * Method that can be used to check whether contained value 309 * is a number represented as Java <code>int</code>. 310 * Note, however, that even if this method returns false, it 311 * is possible that conversion would be possible from other numeric 312 * types -- to check if this is possible, use 313 * {@link #canConvertToInt()} instead. 314 * 315 * @return True if the value contained by this node is stored as Java int 316 */ isInt()317 public boolean isInt() { return false; } 318 319 /** 320 * Method that can be used to check whether contained value 321 * is a number represented as Java <code>long</code>. 322 * Note, however, that even if this method returns false, it 323 * is possible that conversion would be possible from other numeric 324 * types -- to check if this is possible, use 325 * {@link #canConvertToLong()} instead. 326 * 327 * @return True if the value contained by this node is stored as Java <code>long</code> 328 */ isLong()329 public boolean isLong() { return false; } 330 331 /** 332 * @since 2.2 333 */ isFloat()334 public boolean isFloat() { return false; } 335 isDouble()336 public boolean isDouble() { return false; } isBigDecimal()337 public boolean isBigDecimal() { return false; } isBigInteger()338 public boolean isBigInteger() { return false; } 339 340 /** 341 * Method that checks whether this node represents basic JSON String 342 * value. 343 */ isTextual()344 public final boolean isTextual() { 345 return getNodeType() == JsonNodeType.STRING; 346 } 347 348 /** 349 * Method that can be used to check if this node was created from 350 * JSON boolean value (literals "true" and "false"). 351 */ isBoolean()352 public final boolean isBoolean() { 353 return getNodeType() == JsonNodeType.BOOLEAN; 354 } 355 356 /** 357 * Method that can be used to check if this node was created from 358 * JSON literal null value. 359 */ isNull()360 public final boolean isNull() { 361 return getNodeType() == JsonNodeType.NULL; 362 } 363 364 /** 365 * Method that can be used to check if this node represents 366 * binary data (Base64 encoded). Although this will be externally 367 * written as JSON String value, {@link #isTextual} will 368 * return false if this method returns true. 369 * 370 * @return True if this node represents base64 encoded binary data 371 */ isBinary()372 public final boolean isBinary() { 373 return getNodeType() == JsonNodeType.BINARY; 374 } 375 376 /** 377 * Method that can be used to check whether this node is a numeric 378 * node ({@link #isNumber} would return true) AND its value fits 379 * within Java's 32-bit signed integer type, <code>int</code>. 380 * Note that floating-point numbers are convertible if the integral 381 * part fits without overflow (as per standard Java coercion rules) 382 *<p> 383 * NOTE: this method does not consider possible value type conversion 384 * from JSON String into Number; so even if this method returns false, 385 * it is possible that {@link #asInt} could still succeed 386 * if node is a JSON String representing integral number, or boolean. 387 * 388 * @since 2.0 389 */ canConvertToInt()390 public boolean canConvertToInt() { return false; } 391 392 /** 393 * Method that can be used to check whether this node is a numeric 394 * node ({@link #isNumber} would return true) AND its value fits 395 * within Java's 64-bit signed integer type, <code>long</code>. 396 * Note that floating-point numbers are convertible if the integral 397 * part fits without overflow (as per standard Java coercion rules) 398 *<p> 399 * NOTE: this method does not consider possible value type conversion 400 * from JSON String into Number; so even if this method returns false, 401 * it is possible that {@link #asLong} could still succeed 402 * if node is a JSON String representing integral number, or boolean. 403 * 404 * @since 2.0 405 */ canConvertToLong()406 public boolean canConvertToLong() { return false; } 407 408 /** 409 * Method that can be used to check whether contained value 410 * is numeric (returns true for {@link #isNumber()}) and 411 * can be losslessly converted to integral number (specifically, 412 * {@link BigInteger} but potentially others, see 413 * {@link #canConvertToInt} and {@link #canConvertToInt}). 414 * Latter part allows floating-point numbers 415 * (for which {@link #isFloatingPointNumber()} returns {@code true}) 416 * that do not have fractional part. 417 * Note that "not-a-number" values of {@code double} and {@code float} 418 * will return {@code false} as they can not be converted to matching 419 * integral representations. 420 * 421 * @return True if the value is an actual number with no fractional 422 * part; false for non-numeric types, NaN representations of floating-point 423 * numbers, and floating-point numbers with fractional part. 424 * 425 * @since 2.12 426 */ canConvertToExactIntegral()427 public boolean canConvertToExactIntegral() { 428 return isIntegralNumber(); 429 } 430 431 /* 432 /********************************************************** 433 /* Public API, straight value access 434 /********************************************************** 435 */ 436 437 /** 438 * Method to use for accessing String values. 439 * Does <b>NOT</b> do any conversions for non-String value nodes; 440 * for non-String values (ones for which {@link #isTextual} returns 441 * false) null will be returned. 442 * For String values, null is never returned (but empty Strings may be) 443 * 444 * @return Textual value this node contains, iff it is a textual 445 * JSON node (comes from JSON String value entry) 446 */ textValue()447 public String textValue() { return null; } 448 449 /** 450 * Method to use for accessing binary content of binary nodes (nodes 451 * for which {@link #isBinary} returns true); or for Text Nodes 452 * (ones for which {@link #textValue} returns non-null value), 453 * to read decoded base64 data. 454 * For other types of nodes, returns null. 455 * 456 * @return Binary data this node contains, iff it is a binary 457 * node; null otherwise 458 */ binaryValue()459 public byte[] binaryValue() throws IOException { 460 return null; 461 } 462 463 /** 464 * Method to use for accessing JSON boolean values (value 465 * literals 'true' and 'false'). 466 * For other types, always returns false. 467 * 468 * @return Textual value this node contains, iff it is a textual 469 * json node (comes from JSON String value entry) 470 */ booleanValue()471 public boolean booleanValue() { return false; } 472 473 /** 474 * Returns numeric value for this node, <b>if and only if</b> 475 * this node is numeric ({@link #isNumber} returns true); otherwise 476 * returns null 477 * 478 * @return Number value this node contains, if any (null for non-number 479 * nodes). 480 */ numberValue()481 public Number numberValue() { return null; } 482 483 /** 484 * Returns 16-bit short value for this node, <b>if and only if</b> 485 * this node is numeric ({@link #isNumber} returns true). For other 486 * types returns 0. 487 * For floating-point numbers, value is truncated using default 488 * Java coercion, similar to how cast from double to short operates. 489 * 490 * @return Short value this node contains, if any; 0 for non-number 491 * nodes. 492 */ shortValue()493 public short shortValue() { return 0; } 494 495 /** 496 * Returns integer value for this node, <b>if and only if</b> 497 * this node is numeric ({@link #isNumber} returns true). For other 498 * types returns 0. 499 * For floating-point numbers, value is truncated using default 500 * Java coercion, similar to how cast from double to int operates. 501 * 502 * @return Integer value this node contains, if any; 0 for non-number 503 * nodes. 504 */ intValue()505 public int intValue() { return 0; } 506 507 /** 508 * Returns 64-bit long value for this node, <b>if and only if</b> 509 * this node is numeric ({@link #isNumber} returns true). For other 510 * types returns 0. 511 * For floating-point numbers, value is truncated using default 512 * Java coercion, similar to how cast from double to long operates. 513 * 514 * @return Long value this node contains, if any; 0 for non-number 515 * nodes. 516 */ longValue()517 public long longValue() { return 0L; } 518 519 /** 520 * Returns 32-bit floating value for this node, <b>if and only if</b> 521 * this node is numeric ({@link #isNumber} returns true). For other 522 * types returns 0.0. 523 * For integer values, conversion is done using coercion; this means 524 * that an overflow is possible for `long` values 525 * 526 * @return 32-bit float value this node contains, if any; 0.0 for non-number nodes. 527 * 528 * @since 2.2 529 */ floatValue()530 public float floatValue() { return 0.0f; } 531 532 /** 533 * Returns 64-bit floating point (double) value for this node, <b>if and only if</b> 534 * this node is numeric ({@link #isNumber} returns true). For other 535 * types returns 0.0. 536 * For integer values, conversion is done using coercion; this may result 537 * in overflows with {@link BigInteger} values. 538 * 539 * @return 64-bit double value this node contains, if any; 0.0 for non-number nodes. 540 * 541 * @since 2.2 542 */ doubleValue()543 public double doubleValue() { return 0.0; } 544 545 /** 546 * Returns floating point value for this node (as {@link BigDecimal}), <b>if and only if</b> 547 * this node is numeric ({@link #isNumber} returns true). For other 548 * types returns <code>BigDecimal.ZERO</code>. 549 * 550 * @return {@link BigDecimal} value this node contains, if numeric node; <code>BigDecimal.ZERO</code> for non-number nodes. 551 */ decimalValue()552 public BigDecimal decimalValue() { return BigDecimal.ZERO; } 553 554 /** 555 * Returns integer value for this node (as {@link BigDecimal}), <b>if and only if</b> 556 * this node is numeric ({@link #isNumber} returns true). For other 557 * types returns <code>BigInteger.ZERO</code>. 558 * 559 * @return {@link BigInteger} value this node contains, if numeric node; <code>BigInteger.ZERO</code> for non-number nodes. 560 */ bigIntegerValue()561 public BigInteger bigIntegerValue() { return BigInteger.ZERO; } 562 563 /* 564 /********************************************************** 565 /* Public API, value access with conversion(s)/coercion(s) 566 /********************************************************** 567 */ 568 569 /** 570 * Method that will return a valid String representation of 571 * the container value, if the node is a value node 572 * (method {@link #isValueNode} returns true), 573 * otherwise empty String. 574 */ asText()575 public abstract String asText(); 576 577 /** 578 * Method similar to {@link #asText()}, except that it will return 579 * <code>defaultValue</code> in cases where null value would be returned; 580 * either for missing nodes (trying to access missing property, or element 581 * at invalid item for array) or explicit nulls. 582 * 583 * @since 2.4 584 */ asText(String defaultValue)585 public String asText(String defaultValue) { 586 String str = asText(); 587 return (str == null) ? defaultValue : str; 588 } 589 590 /** 591 * Method that will try to convert value of this node to a Java <b>int</b>. 592 * Numbers are coerced using default Java rules; booleans convert to 0 (false) 593 * and 1 (true), and Strings are parsed using default Java language integer 594 * parsing rules. 595 *<p> 596 * If representation cannot be converted to an int (including structured types 597 * like Objects and Arrays), 598 * default value of <b>0</b> will be returned; no exceptions are thrown. 599 */ asInt()600 public int asInt() { 601 return asInt(0); 602 } 603 604 /** 605 * Method that will try to convert value of this node to a Java <b>int</b>. 606 * Numbers are coerced using default Java rules; booleans convert to 0 (false) 607 * and 1 (true), and Strings are parsed using default Java language integer 608 * parsing rules. 609 *<p> 610 * If representation cannot be converted to an int (including structured types 611 * like Objects and Arrays), 612 * specified <b>defaultValue</b> will be returned; no exceptions are thrown. 613 */ asInt(int defaultValue)614 public int asInt(int defaultValue) { 615 return defaultValue; 616 } 617 618 /** 619 * Method that will try to convert value of this node to a Java <b>long</b>. 620 * Numbers are coerced using default Java rules; booleans convert to 0 (false) 621 * and 1 (true), and Strings are parsed using default Java language integer 622 * parsing rules. 623 *<p> 624 * If representation cannot be converted to a long (including structured types 625 * like Objects and Arrays), 626 * default value of <b>0</b> will be returned; no exceptions are thrown. 627 */ asLong()628 public long asLong() { 629 return asLong(0L); 630 } 631 632 /** 633 * Method that will try to convert value of this node to a Java <b>long</b>. 634 * Numbers are coerced using default Java rules; booleans convert to 0 (false) 635 * and 1 (true), and Strings are parsed using default Java language integer 636 * parsing rules. 637 *<p> 638 * If representation cannot be converted to a long (including structured types 639 * like Objects and Arrays), 640 * specified <b>defaultValue</b> will be returned; no exceptions are thrown. 641 */ asLong(long defaultValue)642 public long asLong(long defaultValue) { 643 return defaultValue; 644 } 645 646 /** 647 * Method that will try to convert value of this node to a Java <b>double</b>. 648 * Numbers are coerced using default Java rules; booleans convert to 0.0 (false) 649 * and 1.0 (true), and Strings are parsed using default Java language integer 650 * parsing rules. 651 *<p> 652 * If representation cannot be converted to an int (including structured types 653 * like Objects and Arrays), 654 * default value of <b>0.0</b> will be returned; no exceptions are thrown. 655 */ asDouble()656 public double asDouble() { 657 return asDouble(0.0); 658 } 659 660 /** 661 * Method that will try to convert value of this node to a Java <b>double</b>. 662 * Numbers are coerced using default Java rules; booleans convert to 0.0 (false) 663 * and 1.0 (true), and Strings are parsed using default Java language integer 664 * parsing rules. 665 *<p> 666 * If representation cannot be converted to an int (including structured types 667 * like Objects and Arrays), 668 * specified <b>defaultValue</b> will be returned; no exceptions are thrown. 669 */ asDouble(double defaultValue)670 public double asDouble(double defaultValue) { 671 return defaultValue; 672 } 673 674 /** 675 * Method that will try to convert value of this node to a Java <b>boolean</b>. 676 * JSON booleans map naturally; integer numbers other than 0 map to true, and 677 * 0 maps to false 678 * and Strings 'true' and 'false' map to corresponding values. 679 *<p> 680 * If representation cannot be converted to a boolean value (including structured types 681 * like Objects and Arrays), 682 * default value of <b>false</b> will be returned; no exceptions are thrown. 683 */ asBoolean()684 public boolean asBoolean() { 685 return asBoolean(false); 686 } 687 688 /** 689 * Method that will try to convert value of this node to a Java <b>boolean</b>. 690 * JSON booleans map naturally; integer numbers other than 0 map to true, and 691 * 0 maps to false 692 * and Strings 'true' and 'false' map to corresponding values. 693 *<p> 694 * If representation cannot be converted to a boolean value (including structured types 695 * like Objects and Arrays), 696 * specified <b>defaultValue</b> will be returned; no exceptions are thrown. 697 */ asBoolean(boolean defaultValue)698 public boolean asBoolean(boolean defaultValue) { 699 return defaultValue; 700 } 701 702 /* 703 /********************************************************************** 704 /* Public API, extended traversal (2.10) with "required()" 705 /********************************************************************** 706 */ 707 708 /** 709 * Method that may be called to verify that {@code this} node is NOT so-called 710 * "missing node": that is, one for which {@link #isMissingNode()} returns {@code true}. 711 * If not missing node, {@code this} is returned to allow chaining; otherwise 712 * {@link IllegalArgumentException} is thrown. 713 * 714 * @return {@code this} node to allow chaining 715 * 716 * @throws IllegalArgumentException if this node is "missing node" 717 * 718 * @since 2.10 719 */ require()720 public <T extends JsonNode> T require() throws IllegalArgumentException { 721 return _this(); 722 } 723 724 /** 725 * Method that may be called to verify that {@code this} node is neither so-called 726 * "missing node" (that is, one for which {@link #isMissingNode()} returns {@code true}) 727 * nor "null node" (one for which {@link #isNull()} returns {@code true}). 728 * If non-null non-missing node, {@code this} is returned to allow chaining; otherwise 729 * {@link IllegalArgumentException} is thrown. 730 * 731 * @return {@code this} node to allow chaining 732 * 733 * @throws IllegalArgumentException if this node is either "missing node" or "null node" 734 * 735 * @since 2.10 736 */ requireNonNull()737 public <T extends JsonNode> T requireNonNull() throws IllegalArgumentException { 738 return _this(); 739 } 740 741 /** 742 * Method is functionally equivalent to 743 *{@code 744 * path(fieldName).required() 745 *} 746 * and can be used to check that this node is an {@code ObjectNode} (that is, represents 747 * JSON Object value) and has value for specified property with key {@code fieldName} 748 * (but note that value may be explicit JSON null value). 749 * If this node is Object Node and has value for specified property, {@code this} is returned 750 * to allow chaining; otherwise {@link IllegalArgumentException} is thrown. 751 * 752 * @return {@code this} node to allow chaining 753 * 754 * @throws IllegalArgumentException if this node is not an Object node or if it does not 755 * have value for specified property 756 * 757 * @since 2.10 758 */ required(String fieldName)759 public JsonNode required(String fieldName) throws IllegalArgumentException { 760 return _reportRequiredViolation("Node of type `%s` has no fields", getClass().getName()); 761 } 762 763 /** 764 * Method is functionally equivalent to 765 *{@code 766 * path(index).required() 767 *} 768 * and can be used to check that this node is an {@code ArrayNode} (that is, represents 769 * JSON Array value) and has value for specified {@code index} 770 * (but note that value may be explicit JSON null value). 771 * If this node is Array Node and has value for specified index, {@code this} is returned 772 * to allow chaining; otherwise {@link IllegalArgumentException} is thrown. 773 * 774 * @return {@code this} node to allow chaining 775 * 776 * @throws IllegalArgumentException if this node is not an Array node or if it does not 777 * have value for specified index 778 * 779 * @since 2.10 780 */ required(int index)781 public JsonNode required(int index) throws IllegalArgumentException { 782 return _reportRequiredViolation("Node of type `%s` has no indexed values", getClass().getName()); 783 } 784 785 /** 786 * Method is functionally equivalent to 787 *{@code 788 * at(pathExpr).required() 789 *} 790 * and can be used to check that there is an actual value node at specified {@link JsonPointer} 791 * starting from {@code this} node 792 * (but note that value may be explicit JSON null value). 793 * If such value node exists {@code this} is returned 794 * to allow chaining; otherwise {@link IllegalArgumentException} is thrown. 795 * 796 * @return {@code this} node to allow chaining 797 * 798 * @throws IllegalArgumentException if no value node exists at given {@code JSON Pointer} path 799 * 800 * @since 2.10 801 */ requiredAt(String pathExpr)802 public JsonNode requiredAt(String pathExpr) throws IllegalArgumentException { 803 return requiredAt(JsonPointer.compile(pathExpr)); 804 } 805 806 /** 807 * Method is functionally equivalent to 808 *{@code 809 * at(path).required() 810 *} 811 * and can be used to check that there is an actual value node at specified {@link JsonPointer} 812 * starting from {@code this} node 813 * (but note that value may be explicit JSON null value). 814 * If such value node exists {@code this} is returned 815 * to allow chaining; otherwise {@link IllegalArgumentException} is thrown. 816 * 817 * @return {@code this} node to allow chaining 818 * 819 * @throws IllegalArgumentException if no value node exists at given {@code JSON Pointer} path 820 * 821 * @since 2.10 822 */ requiredAt(final JsonPointer path)823 public final JsonNode requiredAt(final JsonPointer path) throws IllegalArgumentException { 824 JsonPointer currentExpr = path; 825 JsonNode curr = this; 826 827 // Note: copied from `at()` 828 while (true) { 829 if (currentExpr.matches()) { 830 return curr; 831 } 832 curr = curr._at(currentExpr); 833 if (curr == null) { 834 _reportRequiredViolation("No node at '%s' (unmatched part: '%s')", 835 path, currentExpr); 836 } 837 currentExpr = currentExpr.tail(); 838 } 839 } 840 841 /* 842 /********************************************************** 843 /* Public API, value find / existence check methods 844 /********************************************************** 845 */ 846 847 /** 848 * Method that allows checking whether this node is JSON Object node 849 * and contains value for specified property. If this is the case 850 * (including properties with explicit null values), returns true; 851 * otherwise returns false. 852 *<p> 853 * This method is equivalent to: 854 *<pre> 855 * node.get(fieldName) != null 856 *</pre> 857 * (since return value of get() is node, not value node contains) 858 *<p> 859 * NOTE: when explicit <code>null</code> values are added, this 860 * method will return <code>true</code> for such properties. 861 * 862 * @param fieldName Name of element to check 863 * 864 * @return True if this node is a JSON Object node, and has a property 865 * entry with specified name (with any value, including null value) 866 */ has(String fieldName)867 public boolean has(String fieldName) { 868 return get(fieldName) != null; 869 } 870 871 /** 872 * Method that allows checking whether this node is JSON Array node 873 * and contains a value for specified index 874 * If this is the case 875 * (including case of specified indexing having null as value), returns true; 876 * otherwise returns false. 877 *<p> 878 * Note: array element indexes are 0-based. 879 *<p> 880 * This method is equivalent to: 881 *<pre> 882 * node.get(index) != null 883 *</pre> 884 *<p> 885 * NOTE: this method will return <code>true</code> for explicitly added 886 * null values. 887 * 888 * @param index Index to check 889 * 890 * @return True if this node is a JSON Object node, and has a property 891 * entry with specified name (with any value, including null value) 892 */ has(int index)893 public boolean has(int index) { 894 return get(index) != null; 895 } 896 897 /** 898 * Method that is similar to {@link #has(String)}, but that will 899 * return <code>false</code> for explicitly added nulls. 900 *<p> 901 * This method is functionally equivalent to: 902 *<pre> 903 * node.get(fieldName) != null && !node.get(fieldName).isNull() 904 *</pre> 905 * 906 * @since 2.1 907 */ hasNonNull(String fieldName)908 public boolean hasNonNull(String fieldName) { 909 JsonNode n = get(fieldName); 910 return (n != null) && !n.isNull(); 911 } 912 913 /** 914 * Method that is similar to {@link #has(int)}, but that will 915 * return <code>false</code> for explicitly added nulls. 916 *<p> 917 * This method is equivalent to: 918 *<pre> 919 * node.get(index) != null && !node.get(index).isNull() 920 *</pre> 921 * 922 * @since 2.1 923 */ hasNonNull(int index)924 public boolean hasNonNull(int index) { 925 JsonNode n = get(index); 926 return (n != null) && !n.isNull(); 927 } 928 929 /* 930 /********************************************************** 931 /* Public API, container access 932 /********************************************************** 933 */ 934 935 /** 936 * Same as calling {@link #elements}; implemented so that 937 * convenience "for-each" loop can be used for looping over elements 938 * of JSON Array constructs. 939 */ 940 @Override iterator()941 public final Iterator<JsonNode> iterator() { return elements(); } 942 943 /** 944 * Method for accessing all value nodes of this Node, iff 945 * this node is a JSON Array or Object node. In case of Object node, 946 * field names (keys) are not included, only values. 947 * For other types of nodes, returns empty iterator. 948 */ elements()949 public Iterator<JsonNode> elements() { 950 return ClassUtil.emptyIterator(); 951 } 952 953 /** 954 * @return Iterator that can be used to traverse all key/value pairs for 955 * object nodes; empty iterator (no contents) for other types 956 */ fields()957 public Iterator<Map.Entry<String, JsonNode>> fields() { 958 return ClassUtil.emptyIterator(); 959 } 960 961 /** 962 * Accessor that will return properties of {@code ObjectNode} 963 * similar to how {@link Map#entrySet()} works; 964 * for other node types will return empty {@link java.util.Set}. 965 * 966 * @return Set of properties, if this node is an {@code ObjectNode} 967 * ({@link JsonNode#isObject()} returns {@code true}); empty 968 * {@link java.util.Set} otherwise. 969 * 970 * @since 2.15 971 */ properties()972 public Set<Map.Entry<String, JsonNode>> properties() { 973 return Collections.emptySet(); 974 } 975 976 /* 977 /********************************************************** 978 /* Public API, find methods 979 /********************************************************** 980 */ 981 982 /** 983 * Method for finding a JSON Object field with specified name in this 984 * node or its child nodes, and returning value it has. 985 * If no matching field is found in this node or its descendants, returns null. 986 * 987 * @param fieldName Name of field to look for 988 * 989 * @return Value of first matching node found, if any; null if none 990 */ findValue(String fieldName)991 public abstract JsonNode findValue(String fieldName); 992 993 /** 994 * Method for finding JSON Object fields with specified name, and returning 995 * found ones as a List. Note that sub-tree search ends if a field is found, 996 * so possible children of result nodes are <b>not</b> included. 997 * If no matching fields are found in this node or its descendants, returns 998 * an empty List. 999 * 1000 * @param fieldName Name of field to look for 1001 */ findValues(String fieldName)1002 public final List<JsonNode> findValues(String fieldName) 1003 { 1004 List<JsonNode> result = findValues(fieldName, null); 1005 if (result == null) { 1006 return Collections.emptyList(); 1007 } 1008 return result; 1009 } 1010 1011 /** 1012 * Similar to {@link #findValues}, but will additionally convert 1013 * values into Strings, calling {@link #asText}. 1014 */ findValuesAsText(String fieldName)1015 public final List<String> findValuesAsText(String fieldName) 1016 { 1017 List<String> result = findValuesAsText(fieldName, null); 1018 if (result == null) { 1019 return Collections.emptyList(); 1020 } 1021 return result; 1022 } 1023 1024 /** 1025 * Method similar to {@link #findValue}, but that will return a 1026 * "missing node" instead of null if no field is found. Missing node 1027 * is a specific kind of node for which {@link #isMissingNode} 1028 * returns true; and all value access methods return empty or 1029 * missing value. 1030 * 1031 * @param fieldName Name of field to look for 1032 * 1033 * @return Value of first matching node found; or if not found, a 1034 * "missing node" (non-null instance that has no value) 1035 */ findPath(String fieldName)1036 public abstract JsonNode findPath(String fieldName); 1037 1038 /** 1039 * Method for finding a JSON Object that contains specified field, 1040 * within this node or its descendants. 1041 * If no matching field is found in this node or its descendants, returns null. 1042 * 1043 * @param fieldName Name of field to look for 1044 * 1045 * @return Value of first matching node found, if any; null if none 1046 */ findParent(String fieldName)1047 public abstract JsonNode findParent(String fieldName); 1048 1049 /** 1050 * Method for finding a JSON Object that contains specified field, 1051 * within this node or its descendants. 1052 * If no matching field is found in this node or its descendants, returns null. 1053 * 1054 * @param fieldName Name of field to look for 1055 * 1056 * @return Value of first matching node found, if any; null if none 1057 */ findParents(String fieldName)1058 public final List<JsonNode> findParents(String fieldName) 1059 { 1060 List<JsonNode> result = findParents(fieldName, null); 1061 if (result == null) { 1062 return Collections.emptyList(); 1063 } 1064 return result; 1065 } 1066 findValues(String fieldName, List<JsonNode> foundSoFar)1067 public abstract List<JsonNode> findValues(String fieldName, List<JsonNode> foundSoFar); findValuesAsText(String fieldName, List<String> foundSoFar)1068 public abstract List<String> findValuesAsText(String fieldName, List<String> foundSoFar); findParents(String fieldName, List<JsonNode> foundSoFar)1069 public abstract List<JsonNode> findParents(String fieldName, List<JsonNode> foundSoFar); 1070 1071 /* 1072 /********************************************************** 1073 /* Public API, path handling 1074 /********************************************************** 1075 */ 1076 1077 /** 1078 * Method that can be called on Object nodes, to access a property 1079 * that has Object value; or if no such property exists, to create, 1080 * add and return such Object node. 1081 * If the node method is called on is not Object node, 1082 * or if property exists and has value that is not Object node, 1083 * {@link UnsupportedOperationException} is thrown 1084 *<p> 1085 * NOTE: since 2.10 has had co-variant return type 1086 */ with(String propertyName)1087 public <T extends JsonNode> T with(String propertyName) { 1088 throw new UnsupportedOperationException("JsonNode not of type ObjectNode (but " 1089 +getClass().getName()+"), cannot call with() on it"); 1090 } 1091 1092 /** 1093 * Method that can be called on Object nodes, to access a property 1094 * that has <code>Array</code> value; or if no such property exists, to create, 1095 * add and return such Array node. 1096 * If the node method is called on is not Object node, 1097 * or if property exists and has value that is not Array node, 1098 * {@link UnsupportedOperationException} is thrown 1099 *<p> 1100 * NOTE: since 2.10 has had co-variant return type 1101 */ withArray(String propertyName)1102 public <T extends JsonNode> T withArray(String propertyName) { 1103 throw new UnsupportedOperationException("JsonNode not of type ObjectNode (but " 1104 +getClass().getName()+"), cannot call withArray() on it"); 1105 } 1106 1107 /* 1108 /********************************************************** 1109 /* Public API, comparison 1110 /********************************************************** 1111 */ 1112 1113 /** 1114 * Entry method for invoking customizable comparison, using passed-in 1115 * {@link Comparator} object. Nodes will handle traversal of structured 1116 * types (arrays, objects), but defer to comparator for scalar value 1117 * comparisons. If a "natural" {@link Comparator} is passed -- one that 1118 * simply calls <code>equals()</code> on one of arguments, passing the other 1119 * -- implementation is the same as directly calling <code>equals()</code> 1120 * on node. 1121 *<p> 1122 * Default implementation simply delegates to passed in <code>comparator</code>, 1123 * with <code>this</code> as the first argument, and <code>other</code> as 1124 * the second argument. 1125 * 1126 * @param comparator Object called to compare two scalar {@link JsonNode} 1127 * instances, and return either 0 (are equals) or non-zero (not equal) 1128 * 1129 * @since 2.6 1130 */ equals(Comparator<JsonNode> comparator, JsonNode other)1131 public boolean equals(Comparator<JsonNode> comparator, JsonNode other) { 1132 return comparator.compare(this, other) == 0; 1133 } 1134 1135 /* 1136 /********************************************************** 1137 /* Overridden standard methods 1138 /********************************************************** 1139 */ 1140 1141 /** 1142 * Method that will produce (as of Jackson 2.10) valid JSON using 1143 * default settings of databind, as String. 1144 * If you want other kinds of JSON output (or output formatted using one of 1145 * other Jackson-supported data formats) make sure to use 1146 * {@link ObjectMapper} or {@link ObjectWriter} to serialize an 1147 * instance, for example: 1148 *<pre> 1149 * String json = objectMapper.writeValueAsString(rootNode); 1150 *</pre> 1151 *<p> 1152 * Note: method defined as abstract to ensure all implementation 1153 * classes explicitly implement method, instead of relying 1154 * on {@link Object#toString()} definition. 1155 */ 1156 @Override toString()1157 public abstract String toString(); 1158 1159 /** 1160 * Alternative to {@link #toString} that will serialize this node using 1161 * Jackson default pretty-printer. 1162 * 1163 * @since 2.10 1164 */ toPrettyString()1165 public String toPrettyString() { 1166 return toString(); 1167 } 1168 1169 /** 1170 * Equality for node objects is defined as full (deep) value 1171 * equality. This means that it is possible to compare complete 1172 * JSON trees for equality by comparing equality of root nodes. 1173 *<p> 1174 * Note: marked as abstract to ensure all implementation 1175 * classes define it properly and not rely on definition 1176 * from {@link java.lang.Object}. 1177 */ 1178 @Override equals(Object o)1179 public abstract boolean equals(Object o); 1180 1181 /* 1182 /********************************************************************** 1183 /* Helper methods, for sub-classes 1184 /********************************************************************** 1185 */ 1186 1187 // @since 2.10 1188 @SuppressWarnings("unchecked") _this()1189 protected <T extends JsonNode> T _this() { 1190 return (T) this; 1191 } 1192 1193 /** 1194 * Helper method that throws {@link IllegalArgumentException} as a result of 1195 * violating "required-constraint" for this node (for {@link #required} or related 1196 * methods). 1197 */ _reportRequiredViolation(String msgTemplate, Object...args)1198 protected <T> T _reportRequiredViolation(String msgTemplate, Object...args) { 1199 throw new IllegalArgumentException(String.format(msgTemplate, args)); 1200 } 1201 } 1202