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