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