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