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 /********************************************************** 410 /* Public API, straight value access 411 /********************************************************** 412 */ 413 414 /** 415 * Method to use for accessing String values. 416 * Does <b>NOT</b> do any conversions for non-String value nodes; 417 * for non-String values (ones for which {@link #isTextual} returns 418 * false) null will be returned. 419 * For String values, null is never returned (but empty Strings may be) 420 * 421 * @return Textual value this node contains, iff it is a textual 422 * JSON node (comes from JSON String value entry) 423 */ textValue()424 public String textValue() { return null; } 425 426 /** 427 * Method to use for accessing binary content of binary nodes (nodes 428 * for which {@link #isBinary} returns true); or for Text Nodes 429 * (ones for which {@link #textValue} returns non-null value), 430 * to read decoded base64 data. 431 * For other types of nodes, returns null. 432 * 433 * @return Binary data this node contains, iff it is a binary 434 * node; null otherwise 435 */ binaryValue()436 public byte[] binaryValue() throws IOException { 437 return null; 438 } 439 440 /** 441 * Method to use for accessing JSON boolean values (value 442 * literals 'true' and 'false'). 443 * For other types, always returns false. 444 * 445 * @return Textual value this node contains, iff it is a textual 446 * json node (comes from JSON String value entry) 447 */ booleanValue()448 public boolean booleanValue() { return false; } 449 450 /** 451 * Returns numeric value for this node, <b>if and only if</b> 452 * this node is numeric ({@link #isNumber} returns true); otherwise 453 * returns null 454 * 455 * @return Number value this node contains, if any (null for non-number 456 * nodes). 457 */ numberValue()458 public Number numberValue() { return null; } 459 460 /** 461 * Returns 16-bit short value for this node, <b>if and only if</b> 462 * this node is numeric ({@link #isNumber} returns true). For other 463 * types returns 0. 464 * For floating-point numbers, value is truncated using default 465 * Java coercion, similar to how cast from double to short operates. 466 * 467 * @return Short value this node contains, if any; 0 for non-number 468 * nodes. 469 */ shortValue()470 public short shortValue() { return 0; } 471 472 /** 473 * Returns integer value for this node, <b>if and only if</b> 474 * this node is numeric ({@link #isNumber} returns true). For other 475 * types returns 0. 476 * For floating-point numbers, value is truncated using default 477 * Java coercion, similar to how cast from double to int operates. 478 * 479 * @return Integer value this node contains, if any; 0 for non-number 480 * nodes. 481 */ intValue()482 public int intValue() { return 0; } 483 484 /** 485 * Returns 64-bit long value for this node, <b>if and only if</b> 486 * this node is numeric ({@link #isNumber} returns true). For other 487 * types returns 0. 488 * For floating-point numbers, value is truncated using default 489 * Java coercion, similar to how cast from double to long operates. 490 * 491 * @return Long value this node contains, if any; 0 for non-number 492 * nodes. 493 */ longValue()494 public long longValue() { return 0L; } 495 496 /** 497 * Returns 32-bit floating value for this node, <b>if and only if</b> 498 * this node is numeric ({@link #isNumber} returns true). For other 499 * types returns 0.0. 500 * For integer values, conversion is done using coercion; this means 501 * that an overflow is possible for `long` values 502 * 503 * @return 32-bit float value this node contains, if any; 0.0 for non-number nodes. 504 * 505 * @since 2.2 506 */ floatValue()507 public float floatValue() { return 0.0f; } 508 509 /** 510 * Returns 64-bit floating point (double) value for this node, <b>if and only if</b> 511 * this node is numeric ({@link #isNumber} returns true). For other 512 * types returns 0.0. 513 * For integer values, conversion is done using coercion; this may result 514 * in overflows with {@link BigInteger} values. 515 * 516 * @return 64-bit double value this node contains, if any; 0.0 for non-number nodes. 517 * 518 * @since 2.2 519 */ doubleValue()520 public double doubleValue() { return 0.0; } 521 522 /** 523 * Returns floating point value for this node (as {@link BigDecimal}), <b>if and only if</b> 524 * this node is numeric ({@link #isNumber} returns true). For other 525 * types returns <code>BigDecimal.ZERO</code>. 526 * 527 * @return {@link BigDecimal} value this node contains, if numeric node; <code>BigDecimal.ZERO</code> for non-number nodes. 528 */ decimalValue()529 public BigDecimal decimalValue() { return BigDecimal.ZERO; } 530 531 /** 532 * Returns integer value for this node (as {@link BigDecimal}), <b>if and only if</b> 533 * this node is numeric ({@link #isNumber} returns true). For other 534 * types returns <code>BigInteger.ZERO</code>. 535 * 536 * @return {@link BigInteger} value this node contains, if numeric node; <code>BigInteger.ZERO</code> for non-number nodes. 537 */ bigIntegerValue()538 public BigInteger bigIntegerValue() { return BigInteger.ZERO; } 539 540 /* 541 /********************************************************** 542 /* Public API, value access with conversion(s)/coercion(s) 543 /********************************************************** 544 */ 545 546 /** 547 * Method that will return a valid String representation of 548 * the container value, if the node is a value node 549 * (method {@link #isValueNode} returns true), 550 * otherwise empty String. 551 */ asText()552 public abstract String asText(); 553 554 /** 555 * Method similar to {@link #asText()}, except that it will return 556 * <code>defaultValue</code> in cases where null value would be returned; 557 * either for missing nodes (trying to access missing property, or element 558 * at invalid item for array) or explicit nulls. 559 * 560 * @since 2.4 561 */ asText(String defaultValue)562 public String asText(String defaultValue) { 563 String str = asText(); 564 return (str == null) ? defaultValue : str; 565 } 566 567 /** 568 * Method that will try to convert value of this node to a Java <b>int</b>. 569 * Numbers are coerced using default Java rules; booleans convert to 0 (false) 570 * and 1 (true), and Strings are parsed using default Java language integer 571 * parsing rules. 572 *<p> 573 * If representation cannot be converted to an int (including structured types 574 * like Objects and Arrays), 575 * default value of <b>0</b> will be returned; no exceptions are thrown. 576 */ asInt()577 public int asInt() { 578 return asInt(0); 579 } 580 581 /** 582 * Method that will try to convert value of this node to a Java <b>int</b>. 583 * Numbers are coerced using default Java rules; booleans convert to 0 (false) 584 * and 1 (true), and Strings are parsed using default Java language integer 585 * parsing rules. 586 *<p> 587 * If representation cannot be converted to an int (including structured types 588 * like Objects and Arrays), 589 * specified <b>defaultValue</b> will be returned; no exceptions are thrown. 590 */ asInt(int defaultValue)591 public int asInt(int defaultValue) { 592 return defaultValue; 593 } 594 595 /** 596 * Method that will try to convert value of this node to a Java <b>long</b>. 597 * Numbers are coerced using default Java rules; booleans convert to 0 (false) 598 * and 1 (true), and Strings are parsed using default Java language integer 599 * parsing rules. 600 *<p> 601 * If representation cannot be converted to a long (including structured types 602 * like Objects and Arrays), 603 * default value of <b>0</b> will be returned; no exceptions are thrown. 604 */ asLong()605 public long asLong() { 606 return asLong(0L); 607 } 608 609 /** 610 * Method that will try to convert value of this node to a Java <b>long</b>. 611 * Numbers are coerced using default Java rules; booleans convert to 0 (false) 612 * and 1 (true), and Strings are parsed using default Java language integer 613 * parsing rules. 614 *<p> 615 * If representation cannot be converted to a long (including structured types 616 * like Objects and Arrays), 617 * specified <b>defaultValue</b> will be returned; no exceptions are thrown. 618 */ asLong(long defaultValue)619 public long asLong(long defaultValue) { 620 return defaultValue; 621 } 622 623 /** 624 * Method that will try to convert value of this node to a Java <b>double</b>. 625 * Numbers are coerced using default Java rules; booleans convert to 0.0 (false) 626 * and 1.0 (true), and Strings are parsed using default Java language integer 627 * parsing rules. 628 *<p> 629 * If representation cannot be converted to an int (including structured types 630 * like Objects and Arrays), 631 * default value of <b>0.0</b> will be returned; no exceptions are thrown. 632 */ asDouble()633 public double asDouble() { 634 return asDouble(0.0); 635 } 636 637 /** 638 * Method that will try to convert value of this node to a Java <b>double</b>. 639 * Numbers are coerced using default Java rules; booleans convert to 0.0 (false) 640 * and 1.0 (true), and Strings are parsed using default Java language integer 641 * parsing rules. 642 *<p> 643 * If representation cannot be converted to an int (including structured types 644 * like Objects and Arrays), 645 * specified <b>defaultValue</b> will be returned; no exceptions are thrown. 646 */ asDouble(double defaultValue)647 public double asDouble(double defaultValue) { 648 return defaultValue; 649 } 650 651 /** 652 * Method that will try to convert value of this node to a Java <b>boolean</b>. 653 * JSON booleans map naturally; integer numbers other than 0 map to true, and 654 * 0 maps to false 655 * and Strings 'true' and 'false' map to corresponding values. 656 *<p> 657 * If representation cannot be converted to a boolean value (including structured types 658 * like Objects and Arrays), 659 * default value of <b>false</b> will be returned; no exceptions are thrown. 660 */ asBoolean()661 public boolean asBoolean() { 662 return asBoolean(false); 663 } 664 665 /** 666 * Method that will try to convert value of this node to a Java <b>boolean</b>. 667 * JSON booleans map naturally; integer numbers other than 0 map to true, and 668 * 0 maps to false 669 * and Strings 'true' and 'false' map to corresponding values. 670 *<p> 671 * If representation cannot be converted to a boolean value (including structured types 672 * like Objects and Arrays), 673 * specified <b>defaultValue</b> will be returned; no exceptions are thrown. 674 */ asBoolean(boolean defaultValue)675 public boolean asBoolean(boolean defaultValue) { 676 return defaultValue; 677 } 678 679 /* 680 /********************************************************************** 681 /* Public API, extended traversal (2.10) with "required()" 682 /********************************************************************** 683 */ 684 685 /** 686 * Method that may be called to verify that {@code this} node is NOT so-called 687 * "missing node": that is, one for which {@link #isMissingNode()} returns {@code true}. 688 * If not missing node, {@code this} is returned to allow chaining; otherwise 689 * {@link IllegalArgumentException} is thrown. 690 * 691 * @return {@code this} node to allow chaining 692 * 693 * @throws IllegalArgumentException if this node is "missing node" 694 * 695 * @since 2.10 696 */ require()697 public <T extends JsonNode> T require() throws IllegalArgumentException { 698 return _this(); 699 } 700 701 /** 702 * Method that may be called to verify that {@code this} node is neither so-called 703 * "missing node" (that is, one for which {@link #isMissingNode()} returns {@code true}) 704 * nor "null node" (one for which {@link #isNull()} returns {@code true}). 705 * If non-null non-missing node, {@code this} is returned to allow chaining; otherwise 706 * {@link IllegalArgumentException} is thrown. 707 * 708 * @return {@code this} node to allow chaining 709 * 710 * @throws IllegalArgumentException if this node is either "missing node" or "null node" 711 * 712 * @since 2.10 713 */ requireNonNull()714 public <T extends JsonNode> T requireNonNull() throws IllegalArgumentException { 715 return _this(); 716 } 717 718 /** 719 * Method is functionally equivalent to 720 *{@code 721 * path(fieldName).required() 722 *} 723 * and can be used to check that this node is an {@code ObjectNode} (that is, represents 724 * JSON Object value) and has value for specified property with key {@code fieldName} 725 * (but note that value may be explicit JSON null value). 726 * If this node is Object Node and has value for specified property, {@code this} is returned 727 * to allow chaining; otherwise {@link IllegalArgumentException} is thrown. 728 * 729 * @return {@code this} node to allow chaining 730 * 731 * @throws IllegalArgumentException if this node is not an Object node or if it does not 732 * have value for specified property 733 * 734 * @since 2.10 735 */ required(String fieldName)736 public JsonNode required(String fieldName) throws IllegalArgumentException { 737 return _reportRequiredViolation("Node of type `%s` has no fields", getClass().getName()); 738 } 739 740 /** 741 * Method is functionally equivalent to 742 *{@code 743 * path(index).required() 744 *} 745 * and can be used to check that this node is an {@code ArrayNode} (that is, represents 746 * JSON Array value) and has value for specified {@code index} 747 * (but note that value may be explicit JSON null value). 748 * If this node is Array Node and has value for specified index, {@code this} is returned 749 * to allow chaining; otherwise {@link IllegalArgumentException} is thrown. 750 * 751 * @return {@code this} node to allow chaining 752 * 753 * @throws IllegalArgumentException if this node is not an Array node or if it does not 754 * have value for specified index 755 * 756 * @since 2.10 757 */ required(int index)758 public JsonNode required(int index) throws IllegalArgumentException { 759 return _reportRequiredViolation("Node of type `%s` has no indexed values", getClass().getName()); 760 } 761 762 /** 763 * Method is functionally equivalent to 764 *{@code 765 * at(pathExpr).required() 766 *} 767 * and can be used to check that there is an actual value node at specified {@link JsonPointer} 768 * starting from {@code this} node 769 * (but note that value may be explicit JSON null value). 770 * If such value node exists {@code this} is returned 771 * to allow chaining; otherwise {@link IllegalArgumentException} is thrown. 772 * 773 * @return {@code this} node to allow chaining 774 * 775 * @throws IllegalArgumentException if no value node exists at given {@code JSON Pointer} path 776 * 777 * @since 2.10 778 */ requiredAt(String pathExpr)779 public JsonNode requiredAt(String pathExpr) throws IllegalArgumentException { 780 return requiredAt(JsonPointer.compile(pathExpr)); 781 } 782 783 /** 784 * Method is functionally equivalent to 785 *{@code 786 * at(path).required() 787 *} 788 * and can be used to check that there is an actual value node at specified {@link JsonPointer} 789 * starting from {@code this} node 790 * (but note that value may be explicit JSON null value). 791 * If such value node exists {@code this} is returned 792 * to allow chaining; otherwise {@link IllegalArgumentException} is thrown. 793 * 794 * @return {@code this} node to allow chaining 795 * 796 * @throws IllegalArgumentException if no value node exists at given {@code JSON Pointer} path 797 * 798 * @since 2.10 799 */ requiredAt(final JsonPointer path)800 public final JsonNode requiredAt(final JsonPointer path) throws IllegalArgumentException { 801 JsonPointer currentExpr = path; 802 JsonNode curr = this; 803 804 // Note: copied from `at()` 805 while (true) { 806 if (currentExpr.matches()) { 807 return curr; 808 } 809 curr = curr._at(currentExpr); 810 if (curr == null) { 811 _reportRequiredViolation("No node at '%s' (unmatched part: '%s')", 812 path, currentExpr); 813 } 814 currentExpr = currentExpr.tail(); 815 } 816 } 817 818 /* 819 /********************************************************** 820 /* Public API, value find / existence check methods 821 /********************************************************** 822 */ 823 824 /** 825 * Method that allows checking whether this node is JSON Object node 826 * and contains value for specified property. If this is the case 827 * (including properties with explicit null values), returns true; 828 * otherwise returns false. 829 *<p> 830 * This method is equivalent to: 831 *<pre> 832 * node.get(fieldName) != null 833 *</pre> 834 * (since return value of get() is node, not value node contains) 835 *<p> 836 * NOTE: when explicit <code>null</code> values are added, this 837 * method will return <code>true</code> for such properties. 838 * 839 * @param fieldName Name of element to check 840 * 841 * @return True if this node is a JSON Object node, and has a property 842 * entry with specified name (with any value, including null value) 843 */ has(String fieldName)844 public boolean has(String fieldName) { 845 return get(fieldName) != null; 846 } 847 848 /** 849 * Method that allows checking whether this node is JSON Array node 850 * and contains a value for specified index 851 * If this is the case 852 * (including case of specified indexing having null as value), returns true; 853 * otherwise returns false. 854 *<p> 855 * Note: array element indexes are 0-based. 856 *<p> 857 * This method is equivalent to: 858 *<pre> 859 * node.get(index) != null 860 *</pre> 861 *<p> 862 * NOTE: this method will return <code>true</code> for explicitly added 863 * null values. 864 * 865 * @param index Index to check 866 * 867 * @return True if this node is a JSON Object node, and has a property 868 * entry with specified name (with any value, including null value) 869 */ has(int index)870 public boolean has(int index) { 871 return get(index) != null; 872 } 873 874 /** 875 * Method that is similar to {@link #has(String)}, but that will 876 * return <code>false</code> for explicitly added nulls. 877 *<p> 878 * This method is functionally equivalent to: 879 *<pre> 880 * node.get(fieldName) != null && !node.get(fieldName).isNull() 881 *</pre> 882 * 883 * @since 2.1 884 */ hasNonNull(String fieldName)885 public boolean hasNonNull(String fieldName) { 886 JsonNode n = get(fieldName); 887 return (n != null) && !n.isNull(); 888 } 889 890 /** 891 * Method that is similar to {@link #has(int)}, but that will 892 * return <code>false</code> for explicitly added nulls. 893 *<p> 894 * This method is equivalent to: 895 *<pre> 896 * node.get(index) != null && !node.get(index).isNull() 897 *</pre> 898 * 899 * @since 2.1 900 */ hasNonNull(int index)901 public boolean hasNonNull(int index) { 902 JsonNode n = get(index); 903 return (n != null) && !n.isNull(); 904 } 905 906 /* 907 /********************************************************** 908 /* Public API, container access 909 /********************************************************** 910 */ 911 912 /** 913 * Same as calling {@link #elements}; implemented so that 914 * convenience "for-each" loop can be used for looping over elements 915 * of JSON Array constructs. 916 */ 917 @Override iterator()918 public final Iterator<JsonNode> iterator() { return elements(); } 919 920 /** 921 * Method for accessing all value nodes of this Node, iff 922 * this node is a JSON Array or Object node. In case of Object node, 923 * field names (keys) are not included, only values. 924 * For other types of nodes, returns empty iterator. 925 */ elements()926 public Iterator<JsonNode> elements() { 927 return ClassUtil.emptyIterator(); 928 } 929 930 /** 931 * @return Iterator that can be used to traverse all key/value pairs for 932 * object nodes; empty iterator (no contents) for other types 933 */ fields()934 public Iterator<Map.Entry<String, JsonNode>> fields() { 935 return ClassUtil.emptyIterator(); 936 } 937 938 /* 939 /********************************************************** 940 /* Public API, find methods 941 /********************************************************** 942 */ 943 944 /** 945 * Method for finding a JSON Object field with specified name in this 946 * node or its child nodes, and returning value it has. 947 * If no matching field is found in this node or its descendants, returns null. 948 * 949 * @param fieldName Name of field to look for 950 * 951 * @return Value of first matching node found, if any; null if none 952 */ findValue(String fieldName)953 public abstract JsonNode findValue(String fieldName); 954 955 /** 956 * Method for finding JSON Object fields with specified name, and returning 957 * found ones as a List. Note that sub-tree search ends if a field is found, 958 * so possible children of result nodes are <b>not</b> included. 959 * If no matching fields are found in this node or its descendants, returns 960 * an empty List. 961 * 962 * @param fieldName Name of field to look for 963 */ findValues(String fieldName)964 public final List<JsonNode> findValues(String fieldName) 965 { 966 List<JsonNode> result = findValues(fieldName, null); 967 if (result == null) { 968 return Collections.emptyList(); 969 } 970 return result; 971 } 972 973 /** 974 * Similar to {@link #findValues}, but will additionally convert 975 * values into Strings, calling {@link #asText}. 976 */ findValuesAsText(String fieldName)977 public final List<String> findValuesAsText(String fieldName) 978 { 979 List<String> result = findValuesAsText(fieldName, null); 980 if (result == null) { 981 return Collections.emptyList(); 982 } 983 return result; 984 } 985 986 /** 987 * Method similar to {@link #findValue}, but that will return a 988 * "missing node" instead of null if no field is found. Missing node 989 * is a specific kind of node for which {@link #isMissingNode} 990 * returns true; and all value access methods return empty or 991 * missing value. 992 * 993 * @param fieldName Name of field to look for 994 * 995 * @return Value of first matching node found; or if not found, a 996 * "missing node" (non-null instance that has no value) 997 */ findPath(String fieldName)998 public abstract JsonNode findPath(String fieldName); 999 1000 /** 1001 * Method for finding a JSON Object that contains specified field, 1002 * within this node or its descendants. 1003 * If no matching field is found in this node or its descendants, returns null. 1004 * 1005 * @param fieldName Name of field to look for 1006 * 1007 * @return Value of first matching node found, if any; null if none 1008 */ findParent(String fieldName)1009 public abstract JsonNode findParent(String fieldName); 1010 1011 /** 1012 * Method for finding a JSON Object that contains specified field, 1013 * within this node or its descendants. 1014 * If no matching field is found in this node or its descendants, returns null. 1015 * 1016 * @param fieldName Name of field to look for 1017 * 1018 * @return Value of first matching node found, if any; null if none 1019 */ findParents(String fieldName)1020 public final List<JsonNode> findParents(String fieldName) 1021 { 1022 List<JsonNode> result = findParents(fieldName, null); 1023 if (result == null) { 1024 return Collections.emptyList(); 1025 } 1026 return result; 1027 } 1028 findValues(String fieldName, List<JsonNode> foundSoFar)1029 public abstract List<JsonNode> findValues(String fieldName, List<JsonNode> foundSoFar); findValuesAsText(String fieldName, List<String> foundSoFar)1030 public abstract List<String> findValuesAsText(String fieldName, List<String> foundSoFar); findParents(String fieldName, List<JsonNode> foundSoFar)1031 public abstract List<JsonNode> findParents(String fieldName, List<JsonNode> foundSoFar); 1032 1033 /* 1034 /********************************************************** 1035 /* Public API, path handling 1036 /********************************************************** 1037 */ 1038 1039 /** 1040 * Method that can be called on Object nodes, to access a property 1041 * that has Object value; or if no such property exists, to create, 1042 * add and return such Object node. 1043 * If the node method is called on is not Object node, 1044 * or if property exists and has value that is not Object node, 1045 * {@link UnsupportedOperationException} is thrown 1046 *<p> 1047 * NOTE: since 2.10 has had co-variant return type 1048 */ with(String propertyName)1049 public <T extends JsonNode> T with(String propertyName) { 1050 throw new UnsupportedOperationException("JsonNode not of type ObjectNode (but " 1051 +getClass().getName()+"), cannot call with() on it"); 1052 } 1053 1054 /** 1055 * Method that can be called on Object nodes, to access a property 1056 * that has <code>Array</code> value; or if no such property exists, to create, 1057 * add and return such Array node. 1058 * If the node method is called on is not Object node, 1059 * or if property exists and has value that is not Array node, 1060 * {@link UnsupportedOperationException} is thrown 1061 *<p> 1062 * NOTE: since 2.10 has had co-variant return type 1063 */ withArray(String propertyName)1064 public <T extends JsonNode> T withArray(String propertyName) { 1065 throw new UnsupportedOperationException("JsonNode not of type ObjectNode (but " 1066 +getClass().getName()+"), cannot call withArray() on it"); 1067 } 1068 1069 /* 1070 /********************************************************** 1071 /* Public API, comparison 1072 /********************************************************** 1073 */ 1074 1075 /** 1076 * Entry method for invoking customizable comparison, using passed-in 1077 * {@link Comparator} object. Nodes will handle traversal of structured 1078 * types (arrays, objects), but defer to comparator for scalar value 1079 * comparisons. If a "natural" {@link Comparator} is passed -- one that 1080 * simply calls <code>equals()</code> on one of arguments, passing the other 1081 * -- implementation is the same as directly calling <code>equals()</code> 1082 * on node. 1083 *<p> 1084 * Default implementation simply delegates to passed in <code>comparator</code>, 1085 * with <code>this</code> as the first argument, and <code>other</code> as 1086 * the second argument. 1087 * 1088 * @param comparator Object called to compare two scalar {@link JsonNode} 1089 * instances, and return either 0 (are equals) or non-zero (not equal) 1090 * 1091 * @since 2.6 1092 */ equals(Comparator<JsonNode> comparator, JsonNode other)1093 public boolean equals(Comparator<JsonNode> comparator, JsonNode other) { 1094 return comparator.compare(this, other) == 0; 1095 } 1096 1097 /* 1098 /********************************************************** 1099 /* Overridden standard methods 1100 /********************************************************** 1101 */ 1102 1103 /** 1104 * Method that will produce (as of Jackson 2.10) valid JSON using 1105 * default settings of databind, as String. 1106 * If you want other kinds of JSON output (or output formatted using one of 1107 * other Jackson-supported data formats) make sure to use 1108 * {@link ObjectMapper} or {@link ObjectWriter} to serialize an 1109 * instance, for example: 1110 *<pre> 1111 * String json = objectMapper.writeValueAsString(rootNode); 1112 *</pre> 1113 *<p> 1114 * Note: method defined as abstract to ensure all implementation 1115 * classes explicitly implement method, instead of relying 1116 * on {@link Object#toString()} definition. 1117 */ 1118 @Override toString()1119 public abstract String toString(); 1120 1121 /** 1122 * Alternative to {@link #toString} that will serialize this node using 1123 * Jackson default pretty-printer. 1124 * 1125 * @since 2.10 1126 */ toPrettyString()1127 public String toPrettyString() { 1128 return toString(); 1129 } 1130 1131 /** 1132 * Equality for node objects is defined as full (deep) value 1133 * equality. This means that it is possible to compare complete 1134 * JSON trees for equality by comparing equality of root nodes. 1135 *<p> 1136 * Note: marked as abstract to ensure all implementation 1137 * classes define it properly and not rely on definition 1138 * from {@link java.lang.Object}. 1139 */ 1140 @Override equals(Object o)1141 public abstract boolean equals(Object o); 1142 1143 /* 1144 /********************************************************************** 1145 /* Helper methods, for sub-classes 1146 /********************************************************************** 1147 */ 1148 1149 // @since 2.10 1150 @SuppressWarnings("unchecked") _this()1151 protected <T extends JsonNode> T _this() { 1152 return (T) this; 1153 } 1154 1155 /** 1156 * Helper method that throws {@link IllegalArgumentException} as a result of 1157 * violating "required-constraint" for this node (for {@link #required} or related 1158 * methods). 1159 */ _reportRequiredViolation(String msgTemplate, Object...args)1160 protected <T> T _reportRequiredViolation(String msgTemplate, Object...args) { 1161 throw new IllegalArgumentException(String.format(msgTemplate, args)); 1162 } 1163 } 1164