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