001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.parser;
014
015import static org.apache.juneau.collections.JsonMap.*;
016import static org.apache.juneau.common.internal.StringUtils.*;
017import static org.apache.juneau.internal.CollectionUtils.*;
018
019import java.io.*;
020import java.lang.annotation.*;
021import java.lang.reflect.*;
022import java.nio.charset.*;
023import java.util.*;
024
025import org.apache.juneau.*;
026import org.apache.juneau.collections.*;
027import org.apache.juneau.html.*;
028import org.apache.juneau.internal.*;
029import org.apache.juneau.json.*;
030import org.apache.juneau.msgpack.*;
031import org.apache.juneau.objecttools.*;
032import org.apache.juneau.swap.*;
033import org.apache.juneau.swaps.*;
034import org.apache.juneau.uon.*;
035import org.apache.juneau.utils.*;
036import org.apache.juneau.xml.*;
037
038/**
039 * Parent class for all Juneau parsers.
040 *
041 * <h5 class='topic'>Valid data conversions</h5>
042 * <p>
043 * Parsers can parse any parsable POJO types, as specified in the <a class="doclink" href="../../../../index.html#jm.PojoCategories">POJO Categories</a>.
044 *
045 * <p>
046 * Some examples of conversions are shown below...
047 * </p>
048 * <table class='styled'>
049 *    <tr>
050 *       <th>Data type</th>
051 *       <th>Class type</th>
052 *       <th>JSON example</th>
053 *       <th>XML example</th>
054 *       <th>Class examples</th>
055 *    </tr>
056 *    <tr>
057 *       <td>object</td>
058 *       <td>Maps, Java beans</td>
059 *       <td class='code'>{name:<js>'John Smith'</js>,age:21}</td>
060 *       <td class='code'><xt>&lt;object&gt;
061 *    &lt;name</xt> <xa>type</xa>=<xs>'string'</xs><xt>&gt;</xt>John Smith<xt>&lt;/name&gt;
062 *    &lt;age</xt> <xa>type</xa>=<xs>'number'</xs><xt>&gt;</xt>21<xt>&lt;/age&gt;
063 * &lt;/object&gt;</xt></td>
064 *       <td class='code'>HashMap, TreeMap&lt;String,Integer&gt;</td>
065 *    </tr>
066 *    <tr>
067 *       <td>array</td>
068 *       <td>Collections, Java arrays</td>
069 *       <td class='code'>[1,2,3]</td>
070 *       <td class='code'><xt>&lt;array&gt;
071 *    &lt;number&gt;</xt>1<xt>&lt;/number&gt;
072 *    &lt;number&gt;</xt>2<xt>&lt;/number&gt;
073 *    &lt;number&gt;</xt>3<xt>&lt;/number&gt;
074 * &lt;/array&gt;</xt></td>
075 *       <td class='code'>List&lt;Integer&gt;, <jk>int</jk>[], Float[], Set&lt;Person&gt;</td>
076 *    </tr>
077 *    <tr>
078 *       <td>number</td>
079 *       <td>Numbers</td>
080 *       <td class='code'>123</td>
081 *       <td class='code'><xt>&lt;number&gt;</xt>123<xt>&lt;/number&gt;</xt></td>
082 *       <td class='code'>Integer, Long, Float, <jk>int</jk></td>
083 *    </tr>
084 *    <tr>
085 *       <td>boolean</td>
086 *       <td>Booleans</td>
087 *       <td class='code'><jk>true</jk></td>
088 *       <td class='code'><xt>&lt;boolean&gt;</xt>true<xt>&lt;/boolean&gt;</xt></td>
089 *       <td class='code'>Boolean</td>
090 *    </tr>
091 *    <tr>
092 *       <td>string</td>
093 *       <td>CharSequences</td>
094 *       <td class='code'><js>'foobar'</js></td>
095 *       <td class='code'><xt>&lt;string&gt;</xt>foobar<xt>&lt;/string&gt;</xt></td>
096 *       <td class='code'>String, StringBuilder</td>
097 *    </tr>
098 * </table>
099 *
100 * <p>
101 * In addition, any class types with {@link ObjectSwap ObjectSwaps} associated with them on the registered
102 * bean context can also be passed in.
103 *
104 * <p>
105 * For example, if the {@link TemporalCalendarSwap} transform is used to generalize {@code Calendar} objects to {@code String}
106 * objects.
107 * When registered with this parser, you can construct {@code Calendar} objects from {@code Strings} using the
108 * following syntax...
109 * <p class='bjava'>
110 *    Calendar <jv>calendar</jv> = <jv>parser</jv>.parse(<js>"'Sun Mar 03 04:05:06 EST 2001'"</js>, GregorianCalendar.<jk>class</jk>);
111 * </p>
112 *
113 * <p>
114 * If <code>Object.<jk>class</jk></code> is specified as the target type, then the parser automatically determines the
115 * data types and generates the following object types...
116 * <table class='styled'>
117 *    <tr><th>JSON type</th><th>Class type</th></tr>
118 *    <tr><td>object</td><td>{@link JsonMap}</td></tr>
119 *    <tr><td>array</td><td>{@link JsonList}</td></tr>
120 *    <tr><td>number</td><td>{@link Number}<br>(depending on length and format, could be {@link Integer},
121 *       {@link Double}, {@link Float}, etc...)</td></tr>
122 *    <tr><td>boolean</td><td>{@link Boolean}</td></tr>
123 *    <tr><td>string</td><td>{@link String}</td></tr>
124 * </table>
125 *
126 * <h5 class='section'>Notes:</h5><ul>
127 *    <li class='note'>This class is thread safe and reusable.
128 * </ul>
129 *
130 * <h5 class='section'>See Also:</h5><ul>
131 *    <li class='link'><a class="doclink" href="../../../../index.html#jm.SerializersAndParsers">Serializers and Parsers</a>
132
133 * </ul>
134 */
135public class Parser extends BeanContextable {
136
137   //-------------------------------------------------------------------------------------------------------------------
138   // Static
139   //-------------------------------------------------------------------------------------------------------------------
140
141   /**
142    * Creates a new builder for this object.
143    *
144    * @return A new builder.
145    */
146   public static Builder create() {
147      return new Builder();
148   }
149
150   //-------------------------------------------------------------------------------------------------------------------
151   // Static
152   //-------------------------------------------------------------------------------------------------------------------
153
154   /**
155    * Represents no Parser.
156    */
157   public static abstract class Null extends Parser {
158      private Null(Builder builder) {
159         super(builder);
160      }
161   }
162
163   /**
164    * Instantiates a builder of the specified parser class.
165    *
166    * <p>
167    * Looks for a public static method called <c>create</c> that returns an object that can be passed into a public
168    * or protected constructor of the class.
169    *
170    * @param c The builder to create.
171    * @return A new builder.
172    */
173   public static Builder createParserBuilder(Class<? extends Parser> c) {
174      return (Builder)Context.createBuilder(c);
175   }
176
177   //-------------------------------------------------------------------------------------------------------------------
178   // Builder
179   //-------------------------------------------------------------------------------------------------------------------
180
181   /**
182    * Builder class.
183    */
184   @FluentSetters
185   public static class Builder extends BeanContextable.Builder {
186
187      boolean autoCloseStreams, strict, trimStrings, unbuffered;
188      String consumes;
189      int debugOutputLines;
190      Class<? extends ParserListener> listener;
191
192      /**
193       * Constructor, default settings.
194       */
195      protected Builder() {
196         autoCloseStreams = env("Parser.autoCloseStreams", false);
197         strict = env("Parser.strict", false);
198         trimStrings = env("Parser.trimStrings", false);
199         unbuffered = env("Parser.unbuffered", false);
200         debugOutputLines = env("Parser.debugOutputLines", 5);
201         listener = null;
202         consumes = null;
203      }
204
205      /**
206       * Copy constructor.
207       *
208       * @param copyFrom The bean to copy from.
209       */
210      protected Builder(Parser copyFrom) {
211         super(copyFrom);
212         autoCloseStreams = copyFrom.autoCloseStreams;
213         strict = copyFrom.strict;
214         trimStrings = copyFrom.trimStrings;
215         unbuffered = copyFrom.unbuffered;
216         debugOutputLines = copyFrom.debugOutputLines;
217         listener = copyFrom.listener;
218         consumes = copyFrom.consumes;
219      }
220
221      /**
222       * Copy constructor.
223       *
224       * @param copyFrom The builder to copy from.
225       */
226      protected Builder(Builder copyFrom) {
227         super(copyFrom);
228         autoCloseStreams = copyFrom.autoCloseStreams;
229         strict = copyFrom.strict;
230         trimStrings = copyFrom.trimStrings;
231         unbuffered = copyFrom.unbuffered;
232         debugOutputLines = copyFrom.debugOutputLines;
233         listener = copyFrom.listener;
234         consumes = copyFrom.consumes;
235      }
236
237      @Override /* Context.Builder */
238      public Builder copy() {
239         return new Builder(this);
240      }
241
242      @Override /* Context.Builder */
243      public Parser build() {
244         return build(Parser.class);
245      }
246
247      @Override /* Context.Builder */
248      public HashKey hashKey() {
249         return HashKey.of(
250            super.hashKey(),
251            autoCloseStreams,
252            strict,
253            trimStrings,
254            unbuffered,
255            debugOutputLines,
256            listener,
257            consumes
258         );
259      }
260
261      //-----------------------------------------------------------------------------------------------------------------
262      // Properties
263      //-----------------------------------------------------------------------------------------------------------------
264
265      /**
266       * Specifies the media type that this parser consumes.
267       *
268       * @param value The value for this setting.
269       * @return This object.
270       */
271      @FluentSetter
272      public Builder consumes(String value) {
273         this.consumes = value;
274         return this;
275      }
276
277      /**
278       * Returns the current value for the 'consumes' property.
279       *
280       * @return The current value for the 'consumes' property.
281       */
282      public String getConsumes() {
283         return consumes;
284      }
285
286      /**
287       * Auto-close streams.
288       *
289       * <p>
290       * When enabled, <l>InputStreams</l> and <l>Readers</l> passed into parsers will be closed
291       * after parsing is complete.
292       *
293       * <h5 class='section'>Example:</h5>
294       * <p class='bjava'>
295       *    <jc>// Create a parser using strict mode.</jc>
296       *    ReaderParser <jv>parser</jv> = JsonParser
297       *       .<jsm>create</jsm>()
298       *       .autoCloseStreams()
299       *       .build();
300       *
301       *    Reader <jv>myReader</jv> = <jk>new</jk> FileReader(<js>"/tmp/myfile.json"</js>);
302       *    MyBean <jv>myBean</jv> = <jv>parser</jv>.parse(<jv>myReader</jv>, MyBean.<jk>class</jk>);
303       *
304       *    <jsm>assertTrue</jsm>(<jv>myReader</jv>.isClosed());
305       * </p>
306       *
307       * @return This object.
308       */
309      @FluentSetter
310      public Builder autoCloseStreams() {
311         return autoCloseStreams(true);
312      }
313
314      /**
315       * Same as {@link #autoCloseStreams()} but allows you to explicitly specify the value.
316       *
317       * @param value The value for this setting.
318       * @return This object.
319       */
320      @FluentSetter
321      public Builder autoCloseStreams(boolean value) {
322         autoCloseStreams = value;
323         return this;
324      }
325
326      /**
327       * Debug output lines.
328       *
329       * <p>
330       * When parse errors occur, this specifies the number of lines of input before and after the
331       * error location to be printed as part of the exception message.
332       *
333       * <h5 class='section'>Example:</h5>
334       * <p class='bjava'>
335       *    <jc>// Create a parser whose exceptions print out 100 lines before and after the parse error location.</jc>
336       *    ReaderParser <jv>parser</jv> = JsonParser
337       *       .<jsm>create</jsm>()
338       *       .debug()  <jc>// Enable debug mode to capture Reader contents as strings.</jc>
339       *       .debugOuputLines(100)
340       *       .build();
341       *
342       *    Reader <jv>myReader</jv> = <jk>new</jk> FileReader(<js>"/tmp/mybadfile.json"</js>);
343       *    <jk>try</jk> {
344       *       <jv>parser</jv>.parse(<jv>myReader</jv>, Object.<jk>class</jk>);
345       *    } <jk>catch</jk> (ParseException <jv>e</jv>) {
346       *       System.<jsf>err</jsf>.println(<jv>e</jv>.getMessage());  <jc>// Will display 200 lines of the output.</jc>
347       *    }
348       * </p>
349       *
350       * @param value
351       *    The new value for this property.
352       *    <br>The default value is <c>5</c>.
353       * @return This object.
354       */
355      @FluentSetter
356      public Builder debugOutputLines(int value) {
357         debugOutputLines = value;
358         return this;
359      }
360
361      /**
362       * Parser listener.
363       *
364       * <p>
365       * Class used to listen for errors and warnings that occur during parsing.
366       *
367       * <h5 class='section'>Example:</h5>
368       * <p class='bjava'>
369       *    <jc>// Define our parser listener.</jc>
370       *    <jc>// Simply captures all unknown bean property events.</jc>
371       *    <jk>public class</jk> MyParserListener <jk>extends</jk> ParserListener {
372       *
373       *       <jc>// A simple property to store our events.</jc>
374       *       <jk>public</jk> List&lt;String&gt; <jf>events</jf> = <jk>new</jk> LinkedList&lt;&gt;();
375       *
376       *       <ja>@Override</ja>
377       *       <jk>public</jk> &lt;T&gt; <jk>void</jk> onUnknownBeanProperty(ParserSession <jv>session</jv>, String <jv>propertyName</jv>, Class&lt;T&gt; <jv>beanClass</jv>, T <jv>bean</jv>) {
378       *          Position <jv>position</jv> = <jv>parser</jv>.getPosition();
379       *          <jf>events</jf>.add(<jv>propertyName</jv> + <js>","</js> + <jv>position</jv>.getLine() + <js>","</js> + <jv>position</jv>.getColumn());
380       *       }
381       *    }
382       *
383       *    <jc>// Create a parser using our listener.</jc>
384       *    ReaderParser <jv>parser</jv> = JsonParser
385       *       .<jsm>create</jsm>()
386       *       .listener(MyParserListener.<jk>class</jk>)
387       *       .build();
388       *
389       *    <jc>// Create a session object.</jc>
390       *    <jc>// Needed because listeners are created per-session.</jc>
391       *    <jk>try</jk> (ReaderParserSession <jv>session</jv> = <jv>parser</jv>.createSession()) {
392       *
393       *       <jc>// Parse some JSON object.</jc>
394       *       MyBean <jv>myBean</jv> = <jv>session</jv>.parse(<js>"{...}"</js>, MyBean.<jk>class</jk>);
395       *
396       *       <jc>// Get the listener.</jc>
397       *       MyParserListener <jv>listener</jv> = <jv>session</jv>.getListener(MyParserListener.<jk>class</jk>);
398       *
399       *       <jc>// Dump the results to the console.</jc>
400       *       Json5.<jsf>DEFAULT</jsf>.println(<jv>listener</jv>.<jf>events</jf>);
401       *    }
402       * </p>
403       *
404       * @param value The new value for this property.
405       * @return This object.
406       */
407      @FluentSetter
408      public Builder listener(Class<? extends ParserListener> value) {
409         listener = value;
410         return this;
411      }
412
413      /**
414       * Strict mode.
415       *
416       * <p>
417       * When enabled, strict mode for the parser is enabled.
418       *
419       * <p>
420       * Strict mode can mean different things for different parsers.
421       *
422       * <table class='styled'>
423       *    <tr><th>Parser class</th><th>Strict behavior</th></tr>
424       *    <tr>
425       *       <td>All reader-based parsers</td>
426       *       <td>
427       *          When enabled, throws {@link ParseException ParseExceptions} on malformed charset input.
428       *          Otherwise, malformed input is ignored.
429       *       </td>
430       *    </tr>
431       *    <tr>
432       *       <td>{@link JsonParser}</td>
433       *       <td>
434       *          When enabled, throws exceptions on the following invalid JSON syntax:
435       *          <ul>
436       *             <li>Unquoted attributes.
437       *             <li>Missing attribute values.
438       *             <li>Concatenated strings.
439       *             <li>Javascript comments.
440       *             <li>Numbers and booleans when Strings are expected.
441       *             <li>Numbers valid in Java but not JSON (e.g. octal notation, etc...)
442       *          </ul>
443       *       </td>
444       *    </tr>
445       * </table>
446       *
447       * <h5 class='section'>Example:</h5>
448       * <p class='bjava'>
449       *    <jc>// Create a parser using strict mode.</jc>
450       *    ReaderParser <jv>parser</jv> = JsonParser
451       *       .<jsm>create</jsm>()
452       *       .strict()
453       *       .build();
454       *
455       *    <jc>// Use it.</jc>
456       *    <jk>try</jk> {
457       *       String <jv>json</jv> = <js>"{unquotedAttr:'value'}"</js>;
458       *       <jv>parser</jv>.parse(<jv>json</jv>, MyBean.<jk>class</jk>);
459       *    } <jk>catch</jk> (ParseException <jv>e</jv>) {
460       *       <jsm>assertTrue</jsm>(<jv>e</jv>.getMessage().contains(<js>"Unquoted attribute detected."</js>);
461       *    }
462       * </p>
463       *
464       * @return This object.
465       */
466      @FluentSetter
467      public Builder strict() {
468         return strict(true);
469      }
470
471      /**
472       * Same as {@link #strict()} but allows you to explicitly specify the value.
473       *
474       * @param value The value for this setting.
475       * @return This object.
476       */
477      @FluentSetter
478      public Builder strict(boolean value) {
479         strict = value;
480         return this;
481      }
482
483      /**
484       * Trim parsed strings.
485       *
486       * <p>
487       * When enabled, string values will be trimmed of whitespace using {@link String#trim()} before being added to
488       * the POJO.
489       *
490       * <h5 class='section'>Example:</h5>
491       * <p class='bjava'>
492       *    <jc>// Create a parser with trim-strings enabled.</jc>
493       *    ReaderParser <jv>parser</jv> = JsonParser
494       *       .<jsm>create</jsm>()
495       *       .trimStrings()
496       *       .build();
497       *
498       *    <jc>// Use it.</jc>
499       *    String <jv>json</jv> = <js>"{' foo ':' bar '}"</js>;
500       *    Map&lt;String,String&gt; <jv>myMap</jv> = <jv>parser</jv>.parse(<jv>json</jv>, HashMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>);
501       *
502       *    <jc>// Make sure strings are parsed.</jc>
503       *    <jsm>assertEquals</jsm>(<js>"bar"</js>, <jv>myMap</jv>.get(<js>"foo"</js>));
504       * </p>
505       *
506       * @return This object.
507       */
508      @FluentSetter
509      public Builder trimStrings() {
510         return trimStrings(true);
511      }
512
513      /**
514       * Same as {@link #trimStrings()} but allows you to explicitly specify the value.
515       *
516       * @param value The value for this setting.
517       * @return This object.
518       */
519      @FluentSetter
520      public Builder trimStrings(boolean value) {
521         trimStrings = value;
522         return this;
523      }
524
525      /**
526       * Unbuffered.
527       *
528       * <p>
529       * When enabled, don't use internal buffering during parsing.
530       *
531       * <p>
532       * This is useful in cases when you want to parse the same input stream or reader multiple times
533       * because it may contain multiple independent POJOs to parse.
534       * <br>Buffering would cause the parser to read past the current POJO in the stream.
535       *
536       * <h5 class='section'>Example:</h5>
537       * <p class='bjava'>
538       *    <jc>// Create a parser using strict mode.</jc>
539       *    ReaderParser <jv>parser</jv> = JsonParser.
540       *       .<jsm>create</jsm>()
541       *       .unbuffered(<jk>true</jk>)
542       *       .build();
543       *
544       *    <jc>// If you're calling parse on the same input multiple times, use a session instead of the parser directly.</jc>
545       *    <jc>// It's more efficient because we don't need to recalc the session settings again. </jc>
546       *    ReaderParserSession <jv>session</jv> = <jv>parser</jv>.createSession();
547       *
548       *    <jc>// Read input with multiple POJOs</jc>
549       *    Reader <jv>json</jv> = <jk>new</jk> StringReader(<js>"{foo:'bar'}{foo:'baz'}"</js>);
550       *    MyBean <jv>myBean1</jv> = <jv>session</jv>.parse(<jv>json</jv>, MyBean.<jk>class</jk>);
551       *    MyBean <jv>myBean2</jv> = <jv>session</jv>.parse(<jv>json</jv>, MyBean.<jk>class</jk>);
552       * </p>
553       *
554       * <h5 class='section'>Notes:</h5><ul>
555       *    <li class='note'>
556       *       This only allows for multi-input streams for the following parsers:
557       *       <ul>
558       *          <li class='jc'>{@link JsonParser}
559       *          <li class='jc'>{@link UonParser}
560       *       </ul>
561       *       It has no effect on the following parsers:
562       *       <ul>
563       *          <li class='jc'>{@link MsgPackParser} - It already doesn't use buffering.
564       *          <li class='jc'>{@link XmlParser}, {@link HtmlParser} - These use StAX which doesn't allow for more than one root element anyway.
565       *          <li>RDF parsers - These read everything into an internal model before any parsing begins.
566       *       </ul>
567       * </ul>
568       *
569       * @return This object.
570       */
571      @FluentSetter
572      public Builder unbuffered() {
573         return unbuffered(true);
574      }
575
576      /**
577       * Same as {@link #unbuffered()} but allows you to explicitly specify the value.
578       *
579       * @param value The value for this setting.
580       * @return This object.
581       */
582      @FluentSetter
583      public Builder unbuffered(boolean value) {
584         unbuffered = value;
585         return this;
586      }
587
588      // <FluentSetters>
589
590      @Override /* GENERATED - org.apache.juneau.Context.Builder */
591      public Builder annotations(Annotation...values) {
592         super.annotations(values);
593         return this;
594      }
595
596      @Override /* GENERATED - org.apache.juneau.Context.Builder */
597      public Builder apply(AnnotationWorkList work) {
598         super.apply(work);
599         return this;
600      }
601
602      @Override /* GENERATED - org.apache.juneau.Context.Builder */
603      public Builder applyAnnotations(java.lang.Class<?>...fromClasses) {
604         super.applyAnnotations(fromClasses);
605         return this;
606      }
607
608      @Override /* GENERATED - org.apache.juneau.Context.Builder */
609      public Builder applyAnnotations(Method...fromMethods) {
610         super.applyAnnotations(fromMethods);
611         return this;
612      }
613
614      @Override /* GENERATED - org.apache.juneau.Context.Builder */
615      public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) {
616         super.cache(value);
617         return this;
618      }
619
620      @Override /* GENERATED - org.apache.juneau.Context.Builder */
621      public Builder debug() {
622         super.debug();
623         return this;
624      }
625
626      @Override /* GENERATED - org.apache.juneau.Context.Builder */
627      public Builder debug(boolean value) {
628         super.debug(value);
629         return this;
630      }
631
632      @Override /* GENERATED - org.apache.juneau.Context.Builder */
633      public Builder impl(Context value) {
634         super.impl(value);
635         return this;
636      }
637
638      @Override /* GENERATED - org.apache.juneau.Context.Builder */
639      public Builder type(Class<? extends org.apache.juneau.Context> value) {
640         super.type(value);
641         return this;
642      }
643
644      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
645      public Builder beanClassVisibility(Visibility value) {
646         super.beanClassVisibility(value);
647         return this;
648      }
649
650      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
651      public Builder beanConstructorVisibility(Visibility value) {
652         super.beanConstructorVisibility(value);
653         return this;
654      }
655
656      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
657      public Builder beanContext(BeanContext value) {
658         super.beanContext(value);
659         return this;
660      }
661
662      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
663      public Builder beanContext(BeanContext.Builder value) {
664         super.beanContext(value);
665         return this;
666      }
667
668      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
669      public Builder beanDictionary(java.lang.Class<?>...values) {
670         super.beanDictionary(values);
671         return this;
672      }
673
674      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
675      public Builder beanFieldVisibility(Visibility value) {
676         super.beanFieldVisibility(value);
677         return this;
678      }
679
680      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
681      public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) {
682         super.beanInterceptor(on, value);
683         return this;
684      }
685
686      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
687      public Builder beanMapPutReturnsOldValue() {
688         super.beanMapPutReturnsOldValue();
689         return this;
690      }
691
692      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
693      public Builder beanMethodVisibility(Visibility value) {
694         super.beanMethodVisibility(value);
695         return this;
696      }
697
698      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
699      public Builder beanProperties(Map<String,Object> values) {
700         super.beanProperties(values);
701         return this;
702      }
703
704      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
705      public Builder beanProperties(Class<?> beanClass, String properties) {
706         super.beanProperties(beanClass, properties);
707         return this;
708      }
709
710      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
711      public Builder beanProperties(String beanClassName, String properties) {
712         super.beanProperties(beanClassName, properties);
713         return this;
714      }
715
716      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
717      public Builder beanPropertiesExcludes(Map<String,Object> values) {
718         super.beanPropertiesExcludes(values);
719         return this;
720      }
721
722      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
723      public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) {
724         super.beanPropertiesExcludes(beanClass, properties);
725         return this;
726      }
727
728      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
729      public Builder beanPropertiesExcludes(String beanClassName, String properties) {
730         super.beanPropertiesExcludes(beanClassName, properties);
731         return this;
732      }
733
734      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
735      public Builder beanPropertiesReadOnly(Map<String,Object> values) {
736         super.beanPropertiesReadOnly(values);
737         return this;
738      }
739
740      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
741      public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) {
742         super.beanPropertiesReadOnly(beanClass, properties);
743         return this;
744      }
745
746      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
747      public Builder beanPropertiesReadOnly(String beanClassName, String properties) {
748         super.beanPropertiesReadOnly(beanClassName, properties);
749         return this;
750      }
751
752      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
753      public Builder beanPropertiesWriteOnly(Map<String,Object> values) {
754         super.beanPropertiesWriteOnly(values);
755         return this;
756      }
757
758      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
759      public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) {
760         super.beanPropertiesWriteOnly(beanClass, properties);
761         return this;
762      }
763
764      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
765      public Builder beanPropertiesWriteOnly(String beanClassName, String properties) {
766         super.beanPropertiesWriteOnly(beanClassName, properties);
767         return this;
768      }
769
770      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
771      public Builder beansRequireDefaultConstructor() {
772         super.beansRequireDefaultConstructor();
773         return this;
774      }
775
776      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
777      public Builder beansRequireSerializable() {
778         super.beansRequireSerializable();
779         return this;
780      }
781
782      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
783      public Builder beansRequireSettersForGetters() {
784         super.beansRequireSettersForGetters();
785         return this;
786      }
787
788      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
789      public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) {
790         super.dictionaryOn(on, values);
791         return this;
792      }
793
794      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
795      public Builder disableBeansRequireSomeProperties() {
796         super.disableBeansRequireSomeProperties();
797         return this;
798      }
799
800      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
801      public Builder disableIgnoreMissingSetters() {
802         super.disableIgnoreMissingSetters();
803         return this;
804      }
805
806      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
807      public Builder disableIgnoreTransientFields() {
808         super.disableIgnoreTransientFields();
809         return this;
810      }
811
812      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
813      public Builder disableIgnoreUnknownNullBeanProperties() {
814         super.disableIgnoreUnknownNullBeanProperties();
815         return this;
816      }
817
818      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
819      public Builder disableInterfaceProxies() {
820         super.disableInterfaceProxies();
821         return this;
822      }
823
824      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
825      public <T> Builder example(Class<T> pojoClass, T o) {
826         super.example(pojoClass, o);
827         return this;
828      }
829
830      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
831      public <T> Builder example(Class<T> pojoClass, String json) {
832         super.example(pojoClass, json);
833         return this;
834      }
835
836      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
837      public Builder findFluentSetters() {
838         super.findFluentSetters();
839         return this;
840      }
841
842      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
843      public Builder findFluentSetters(Class<?> on) {
844         super.findFluentSetters(on);
845         return this;
846      }
847
848      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
849      public Builder ignoreInvocationExceptionsOnGetters() {
850         super.ignoreInvocationExceptionsOnGetters();
851         return this;
852      }
853
854      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
855      public Builder ignoreInvocationExceptionsOnSetters() {
856         super.ignoreInvocationExceptionsOnSetters();
857         return this;
858      }
859
860      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
861      public Builder ignoreUnknownBeanProperties() {
862         super.ignoreUnknownBeanProperties();
863         return this;
864      }
865
866      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
867      public Builder ignoreUnknownEnumValues() {
868         super.ignoreUnknownEnumValues();
869         return this;
870      }
871
872      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
873      public Builder implClass(Class<?> interfaceClass, Class<?> implClass) {
874         super.implClass(interfaceClass, implClass);
875         return this;
876      }
877
878      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
879      public Builder implClasses(Map<Class<?>,Class<?>> values) {
880         super.implClasses(values);
881         return this;
882      }
883
884      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
885      public Builder interfaceClass(Class<?> on, Class<?> value) {
886         super.interfaceClass(on, value);
887         return this;
888      }
889
890      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
891      public Builder interfaces(java.lang.Class<?>...value) {
892         super.interfaces(value);
893         return this;
894      }
895
896      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
897      public Builder locale(Locale value) {
898         super.locale(value);
899         return this;
900      }
901
902      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
903      public Builder mediaType(MediaType value) {
904         super.mediaType(value);
905         return this;
906      }
907
908      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
909      public Builder notBeanClasses(java.lang.Class<?>...values) {
910         super.notBeanClasses(values);
911         return this;
912      }
913
914      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
915      public Builder notBeanPackages(String...values) {
916         super.notBeanPackages(values);
917         return this;
918      }
919
920      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
921      public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) {
922         super.propertyNamer(value);
923         return this;
924      }
925
926      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
927      public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) {
928         super.propertyNamer(on, value);
929         return this;
930      }
931
932      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
933      public Builder sortProperties() {
934         super.sortProperties();
935         return this;
936      }
937
938      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
939      public Builder sortProperties(java.lang.Class<?>...on) {
940         super.sortProperties(on);
941         return this;
942      }
943
944      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
945      public Builder stopClass(Class<?> on, Class<?> value) {
946         super.stopClass(on, value);
947         return this;
948      }
949
950      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
951      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) {
952         super.swap(normalClass, swappedClass, swapFunction);
953         return this;
954      }
955
956      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
957      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) {
958         super.swap(normalClass, swappedClass, swapFunction, unswapFunction);
959         return this;
960      }
961
962      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
963      public Builder swaps(java.lang.Class<?>...values) {
964         super.swaps(values);
965         return this;
966      }
967
968      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
969      public Builder timeZone(TimeZone value) {
970         super.timeZone(value);
971         return this;
972      }
973
974      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
975      public Builder typeName(Class<?> on, String value) {
976         super.typeName(on, value);
977         return this;
978      }
979
980      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
981      public Builder typePropertyName(String value) {
982         super.typePropertyName(value);
983         return this;
984      }
985
986      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
987      public Builder typePropertyName(Class<?> on, String value) {
988         super.typePropertyName(on, value);
989         return this;
990      }
991
992      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
993      public Builder useEnumNames() {
994         super.useEnumNames();
995         return this;
996      }
997
998      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
999      public Builder useJavaBeanIntrospector() {
1000         super.useJavaBeanIntrospector();
1001         return this;
1002      }
1003
1004      // </FluentSetters>
1005   }
1006   //-------------------------------------------------------------------------------------------------------------------
1007   // Instance
1008   //-------------------------------------------------------------------------------------------------------------------
1009
1010   final boolean trimStrings, strict, autoCloseStreams, unbuffered;
1011   final int debugOutputLines;
1012   final String consumes;
1013   final Class<? extends ParserListener> listener;
1014
1015   /** General parser properties currently set on this parser. */
1016   private final MediaType[] consumesArray;
1017
1018   /**
1019    * Constructor.
1020    *
1021    * @param builder The builder this object.
1022    */
1023   protected Parser(Builder builder) {
1024      super(builder);
1025
1026      consumes = builder.consumes;
1027      trimStrings = builder.trimStrings;
1028      strict = builder.strict;
1029      autoCloseStreams = builder.autoCloseStreams;
1030      debugOutputLines = builder.debugOutputLines;
1031      unbuffered = builder.unbuffered;
1032      listener = builder.listener;
1033
1034      String[] _consumes = split(consumes != null ? consumes : "");
1035      this.consumesArray = new MediaType[_consumes.length];
1036      for (int i = 0; i < _consumes.length; i++) {
1037         this.consumesArray[i] = MediaType.of(_consumes[i]);
1038      }
1039   }
1040
1041   @Override /* Context */
1042   public Builder copy() {
1043      return new Builder(this);
1044   }
1045
1046   //-----------------------------------------------------------------------------------------------------------------
1047   // Abstract methods
1048   //-----------------------------------------------------------------------------------------------------------------
1049
1050   /**
1051    * Returns <jk>true</jk> if this parser subclasses from {@link ReaderParser}.
1052    *
1053    * @return <jk>true</jk> if this parser subclasses from {@link ReaderParser}.
1054    */
1055   public boolean isReaderParser() {
1056      return true;
1057   }
1058
1059   //-----------------------------------------------------------------------------------------------------------------
1060   // Other methods
1061   //-----------------------------------------------------------------------------------------------------------------
1062
1063   /**
1064    * Parses input into the specified object type.
1065    *
1066    * <p>
1067    * The type can be a simple type (e.g. beans, strings, numbers) or parameterized type (collections/maps).
1068    *
1069    * <h5 class='section'>Examples:</h5>
1070    * <p class='bjava'>
1071    *    ReaderParser <jv>parser</jv> = JsonParser.<jsf>DEFAULT</jsf>;
1072    *
1073    *    <jc>// Parse into a linked-list of strings.</jc>
1074    *    List <jv>list1</jv> = <jv>parser</jv>.parse(<jv>json</jv>, LinkedList.<jk>class</jk>, String.<jk>class</jk>);
1075    *
1076    *    <jc>// Parse into a linked-list of beans.</jc>
1077    *    List <jv>list2</jv> = <jv>parser</jv>.parse(<jv>json</jv>, LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>);
1078    *
1079    *    <jc>// Parse into a linked-list of linked-lists of strings.</jc>
1080    *    List <jv>list3</jv> = <jv>parser</jv>.parse(<jv>json</jv>, LinkedList.<jk>class</jk>, LinkedList.<jk>class</jk>, String.<jk>class</jk>);
1081    *
1082    *    <jc>// Parse into a map of string keys/values.</jc>
1083    *    Map <jv>map1</jv> = <jv>parser</jv>.parse(<jv>json</jv>, TreeMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>);
1084    *
1085    *    <jc>// Parse into a map containing string keys and values of lists containing beans.</jc>
1086    *    Map <jv>map2</jv> = <jv>parser</jv>.parse(<jv>json</jv>, TreeMap.<jk>class</jk>, String.<jk>class</jk>, List.<jk>class</jk>, MyBean.<jk>class</jk>);
1087    * </p>
1088    *
1089    * <p>
1090    * <c>Collection</c> classes are assumed to be followed by zero or one objects indicating the element type.
1091    *
1092    * <p>
1093    * <c>Map</c> classes are assumed to be followed by zero or two meta objects indicating the key and value types.
1094    *
1095    * <p>
1096    * The array can be arbitrarily long to indicate arbitrarily complex data structures.
1097    *
1098    * <h5 class='section'>Notes:</h5><ul>
1099    *    <li class='note'>
1100    *       Use the {@link #parse(Object, Class)} method instead if you don't need a parameterized map/collection.
1101    * </ul>
1102    *
1103    * @param <T> The class type of the object to create.
1104    * @param input
1105    *    The input.
1106    *    <br>Character-based parsers can handle the following input class types:
1107    *    <ul>
1108    *       <li><jk>null</jk>
1109    *       <li>{@link Reader}
1110    *       <li>{@link CharSequence}
1111    *       <li>{@link InputStream} containing UTF-8 encoded text (or charset defined by
1112    *          {@link ReaderParser.Builder#streamCharset(Charset)} property value).
1113    *       <li><code><jk>byte</jk>[]</code> containing UTF-8 encoded text (or charset defined by
1114    *          {@link ReaderParser.Builder#streamCharset(Charset)} property value).
1115    *       <li>{@link File} containing system encoded text (or charset defined by
1116    *          {@link ReaderParser.Builder#fileCharset(Charset)} property value).
1117    *    </ul>
1118    *    <br>Stream-based parsers can handle the following input class types:
1119    *    <ul>
1120    *       <li><jk>null</jk>
1121    *       <li>{@link InputStream}
1122    *       <li><code><jk>byte</jk>[]</code>
1123    *       <li>{@link File}
1124    *       <li>{@link CharSequence} containing encoded bytes according to the {@link InputStreamParser.Builder#binaryFormat(BinaryFormat)} setting.
1125    *    </ul>
1126    * @param type
1127    *    The object type to create.
1128    *    <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
1129    * @param args
1130    *    The type arguments of the class if it's a collection or map.
1131    *    <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
1132    *    <br>Ignored if the main type is not a map or collection.
1133    * @return The parsed object.
1134    * @throws ParseException Malformed input encountered.
1135    * @throws IOException Thrown by underlying stream.
1136    * @see BeanSession#getClassMeta(Type,Type...) for argument syntax for maps and collections.
1137    */
1138   public final <T> T parse(Object input, Type type, Type...args) throws ParseException, IOException {
1139      return getSession().parse(input, type, args);
1140   }
1141
1142   /**
1143    * Same as {@link #parse(Object, Type, Type...)} but since it's a {@link String} input doesn't throw an {@link IOException}.
1144    *
1145    * @param <T> The class type of the object being created.
1146    * @param input
1147    *    The input.
1148    *    See {@link #parse(Object, Type, Type...)} for details.
1149    * @param type
1150    *    The object type to create.
1151    *    <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
1152    * @param args
1153    *    The type arguments of the class if it's a collection or map.
1154    *    <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
1155    *    <br>Ignored if the main type is not a map or collection.
1156    * @return The parsed object.
1157    * @throws ParseException Malformed input encountered.
1158    */
1159   public final <T> T parse(String input, Type type, Type...args) throws ParseException {
1160      return getSession().parse(input, type, args);
1161   }
1162
1163   /**
1164    * Same as {@link #parse(Object, Type, Type...)} except optimized for a non-parameterized class.
1165    *
1166    * <p>
1167    * This is the preferred parse method for simple types since you don't need to cast the results.
1168    *
1169    * <h5 class='section'>Examples:</h5>
1170    * <p class='bjava'>
1171    *    ReaderParser <jv>parser</jv> = JsonParser.<jsf>DEFAULT</jsf>;
1172    *
1173    *    <jc>// Parse into a string.</jc>
1174    *    String <jv>string</jv> = <jv>parser</jv>.parse(<jv>json</jv>, String.<jk>class</jk>);
1175    *
1176    *    <jc>// Parse into a bean.</jc>
1177    *    MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<jv>json</jv>, MyBean.<jk>class</jk>);
1178    *
1179    *    <jc>// Parse into a bean array.</jc>
1180    *    MyBean[] <jv>beanArray</jv> = <jv>parser</jv>.parse(<jv>json</jv>, MyBean[].<jk>class</jk>);
1181    *
1182    *    <jc>// Parse into a linked-list of objects.</jc>
1183    *    List <jv>list</jv> = <jv>parser</jv>.parse(<jv>json</jv>, LinkedList.<jk>class</jk>);
1184    *
1185    *    <jc>// Parse into a map of object keys/values.</jc>
1186    *    Map <jv>map</jv> = <jv>parser</jv>.parse(<jv>json</jv>, TreeMap.<jk>class</jk>);
1187    * </p>
1188    *
1189    * @param <T> The class type of the object being created.
1190    * @param input
1191    *    The input.
1192    *    See {@link #parse(Object, Type, Type...)} for details.
1193    * @param type The object type to create.
1194    * @return The parsed object.
1195    * @throws ParseException Malformed input encountered.
1196    * @throws IOException Thrown by the underlying stream.
1197    */
1198   public final <T> T parse(Object input, Class<T> type) throws ParseException, IOException {
1199      return getSession().parse(input, type);
1200   }
1201
1202   /**
1203    * Same as {@link #parse(Object, Class)} but since it's a {@link String} input doesn't throw an {@link IOException}.
1204    *
1205    * @param <T> The class type of the object being created.
1206    * @param input
1207    *    The input.
1208    *    See {@link #parse(Object, Type, Type...)} for details.
1209    * @param type The object type to create.
1210    * @return The parsed object.
1211    * @throws ParseException Malformed input encountered.
1212    */
1213   public final <T> T parse(String input, Class<T> type) throws ParseException {
1214      return getSession().parse(input, type);
1215   }
1216
1217   /**
1218    * Same as {@link #parse(Object, Type, Type...)} except the type has already been converted into a {@link ClassMeta}
1219    * object.
1220    *
1221    * <p>
1222    * This is mostly an internal method used by the framework.
1223    *
1224    * @param <T> The class type of the object being created.
1225    * @param input
1226    *    The input.
1227    *    See {@link #parse(Object, Type, Type...)} for details.
1228    * @param type The object type to create.
1229    * @return The parsed object.
1230    * @throws ParseException Malformed input encountered.
1231    * @throws IOException Thrown by the underlying stream.
1232    */
1233   public final <T> T parse(Object input, ClassMeta<T> type) throws ParseException, IOException {
1234      return getSession().parse(input, type);
1235   }
1236
1237   /**
1238    * Same as {@link #parse(Object, ClassMeta)} but since it's a {@link String} input doesn't throw an {@link IOException}.
1239    *
1240    * @param <T> The class type of the object being created.
1241    * @param input
1242    *    The input.
1243    *    See {@link #parse(Object, Type, Type...)} for details.
1244    * @param type The object type to create.
1245    * @return The parsed object.
1246    * @throws ParseException Malformed input encountered.
1247    */
1248   public final <T> T parse(String input, ClassMeta<T> type) throws ParseException {
1249      return getSession().parse(input, type);
1250   }
1251
1252   @Override /* Context */
1253   public ParserSession.Builder createSession() {
1254      return ParserSession.create(this);
1255   }
1256
1257   @Override /* Context */
1258   public ParserSession getSession() {
1259      return createSession().build();
1260   }
1261
1262   /**
1263    * Workhorse method.
1264    *
1265    * <p>
1266    * Subclasses are expected to either implement this method or {@link ParserSession#doParse(ParserPipe, ClassMeta)}.
1267    *
1268    * @param session The current session.
1269    * @param pipe Where to get the input from.
1270    * @param type
1271    *    The class type of the object to create.
1272    *    If <jk>null</jk> or <code>Object.<jk>class</jk></code>, object type is based on what's being parsed.
1273    *    For example, when parsing JSON text, it may return a <c>String</c>, <c>Number</c>,
1274    *    <c>JsonMap</c>, etc...
1275    * @param <T> The class type of the object to create.
1276    * @return The parsed object.
1277    * @throws IOException Thrown by underlying stream.
1278    * @throws ParseException Malformed input encountered.
1279    * @throws ExecutableException Exception occurred on invoked constructor/method/field.
1280    */
1281   public <T> T doParse(ParserSession session, ParserPipe pipe, ClassMeta<T> type) throws IOException, ParseException {
1282      throw new UnsupportedOperationException();
1283   }
1284
1285   //-----------------------------------------------------------------------------------------------------------------
1286   // Optional methods
1287   //-----------------------------------------------------------------------------------------------------------------
1288
1289   /**
1290    * Parses the contents of the specified reader and loads the results into the specified map.
1291    *
1292    * <p>
1293    * Reader must contain something that serializes to a map (such as text containing a JSON object).
1294    *
1295    * <p>
1296    * Used in the following locations:
1297    * <ul class='spaced-list'>
1298    *    <li>
1299    *       The various character-based constructors in {@link JsonMap} (e.g.
1300    *       {@link JsonMap#JsonMap(CharSequence,Parser)}).
1301    * </ul>
1302    *
1303    * @param <K> The key class type.
1304    * @param <V> The value class type.
1305    * @param input The input.  See {@link #parse(Object, ClassMeta)} for supported input types.
1306    * @param m The map being loaded.
1307    * @param keyType The class type of the keys, or <jk>null</jk> to default to <code>String.<jk>class</jk></code>.
1308    * @param valueType The class type of the values, or <jk>null</jk> to default to whatever is being parsed.
1309    * @return The same map that was passed in to allow this method to be chained.
1310    * @throws ParseException Malformed input encountered.
1311    * @throws UnsupportedOperationException If not implemented.
1312    */
1313   public final <K,V> Map<K,V> parseIntoMap(Object input, Map<K,V> m, Type keyType, Type valueType) throws ParseException {
1314      return getSession().parseIntoMap(input, m, keyType, valueType);
1315   }
1316
1317   /**
1318    * Parses the contents of the specified reader and loads the results into the specified collection.
1319    *
1320    * <p>
1321    * Used in the following locations:
1322    * <ul class='spaced-list'>
1323    *    <li>
1324    *       The various character-based constructors in {@link JsonList} (e.g.
1325    *       {@link JsonList#JsonList(CharSequence,Parser)}.
1326    * </ul>
1327    *
1328    * @param <E> The element class type.
1329    * @param input The input.  See {@link #parse(Object, ClassMeta)} for supported input types.
1330    * @param c The collection being loaded.
1331    * @param elementType The class type of the elements, or <jk>null</jk> to default to whatever is being parsed.
1332    * @return The same collection that was passed in to allow this method to be chained.
1333    * @throws ParseException Malformed input encountered.
1334    * @throws UnsupportedOperationException If not implemented.
1335    */
1336   public final <E> Collection<E> parseIntoCollection(Object input, Collection<E> c, Type elementType) throws ParseException {
1337      return getSession().parseIntoCollection(input, c, elementType);
1338   }
1339
1340   /**
1341    * Parses the specified array input with each entry in the object defined by the {@code argTypes}
1342    * argument.
1343    *
1344    * <p>
1345    * Used for converting arrays (e.g. <js>"[arg1,arg2,...]"</js>) into an {@code Object[]} that can be passed
1346    * to the {@code Method.invoke(target, args)} method.
1347    *
1348    * <p>
1349    * Used in the following locations:
1350    * <ul class='spaced-list'>
1351    *    <li>
1352    *       Used to parse argument strings in the {@link ObjectIntrospector#invokeMethod(Method, Reader)} method.
1353    * </ul>
1354    *
1355    * @param input The input.  Subclasses can support different input types.
1356    * @param argTypes Specifies the type of objects to create for each entry in the array.
1357    * @return An array of parsed objects.
1358    * @throws ParseException Malformed input encountered.
1359    */
1360   public final Object[] parseArgs(Object input, Type[] argTypes) throws ParseException {
1361      if (argTypes == null || argTypes.length == 0)
1362         return new Object[0];
1363      return getSession().parseArgs(input, argTypes);
1364   }
1365
1366
1367   //-----------------------------------------------------------------------------------------------------------------
1368   // Other methods
1369   //-----------------------------------------------------------------------------------------------------------------
1370
1371   /**
1372    * Returns the media types handled based on the values passed to the <c>consumes</c> constructor parameter.
1373    *
1374    * @return The list of media types.  Never <jk>null</jk>.
1375    */
1376   public final List<MediaType> getMediaTypes() {
1377      return ulist(consumesArray);
1378   }
1379
1380   /**
1381    * Returns the first media type handled based on the values passed to the <c>consumes</c> constructor parameter.
1382    *
1383    * @return The media type.
1384    */
1385   public final MediaType getPrimaryMediaType() {
1386      return consumesArray == null || consumesArray.length == 0 ? null : consumesArray[0];
1387   }
1388
1389   /**
1390    * Returns <jk>true</jk> if this parser can handle the specified content type.
1391    *
1392    * @param contentType The content type to test.
1393    * @return <jk>true</jk> if this parser can handle the specified content type.
1394    */
1395   public boolean canHandle(String contentType) {
1396      if (contentType != null)
1397         for (MediaType mt : getMediaTypes())
1398            if (contentType.equals(mt.toString()))
1399               return true;
1400      return false;
1401   }
1402
1403   //-----------------------------------------------------------------------------------------------------------------
1404   // Properties
1405   //-----------------------------------------------------------------------------------------------------------------
1406
1407   /**
1408    * Auto-close streams.
1409    *
1410    * @see Parser.Builder#autoCloseStreams()
1411    * @return
1412    *    <jk>true</jk> if <l>InputStreams</l> and <l>Readers</l> passed into parsers will be closed
1413    *    after parsing is complete.
1414    */
1415   protected final boolean isAutoCloseStreams() {
1416      return autoCloseStreams;
1417   }
1418
1419   /**
1420    * Debug output lines.
1421    *
1422    * @see Parser.Builder#debugOutputLines(int)
1423    * @return
1424    *    The number of lines of input before and after the error location to be printed as part of the exception message.
1425    */
1426   protected final int getDebugOutputLines() {
1427      return debugOutputLines;
1428   }
1429
1430   /**
1431    * Parser listener.
1432    *
1433    * @see Parser.Builder#listener(Class)
1434    * @return
1435    *    Class used to listen for errors and warnings that occur during parsing.
1436    */
1437   protected final Class<? extends ParserListener> getListener() {
1438      return listener;
1439   }
1440
1441   /**
1442    * Strict mode.
1443    *
1444    * @see Parser.Builder#strict()
1445    * @return
1446    *    <jk>true</jk> if strict mode for the parser is enabled.
1447    */
1448   protected final boolean isStrict() {
1449      return strict;
1450   }
1451
1452   /**
1453    * Trim parsed strings.
1454    *
1455    * @see Parser.Builder#trimStrings()
1456    * @return
1457    *    <jk>true</jk> if string values will be trimmed of whitespace using {@link String#trim()} before being added to
1458    *    the POJO.
1459    */
1460   protected final boolean isTrimStrings() {
1461      return trimStrings;
1462   }
1463
1464   /**
1465    * Unbuffered.
1466    *
1467    * @see Parser.Builder#unbuffered()
1468    * @return
1469    *    <jk>true</jk> if parsers don't use internal buffering during parsing.
1470    */
1471   protected final boolean isUnbuffered() {
1472      return unbuffered;
1473   }
1474
1475   //-----------------------------------------------------------------------------------------------------------------
1476   // Other methods
1477   //-----------------------------------------------------------------------------------------------------------------
1478
1479   @Override /* Context */
1480   protected JsonMap properties() {
1481      return filteredMap()
1482         .append("autoCloseStreams", autoCloseStreams)
1483         .append("debugOutputLines", debugOutputLines)
1484         .append("listener", listener)
1485         .append("strict", strict)
1486         .append("trimStrings", trimStrings)
1487         .append("unbuffered", unbuffered);
1488   }
1489}