001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.xml;
014
015import static org.apache.juneau.collections.JsonMap.*;
016import static org.apache.juneau.common.internal.ThrowableUtils.*;
017
018import java.lang.annotation.*;
019import java.lang.reflect.*;
020import java.nio.charset.*;
021import java.util.*;
022import java.util.concurrent.*;
023
024import javax.xml.stream.*;
025import javax.xml.stream.util.*;
026
027import org.apache.juneau.*;
028import org.apache.juneau.collections.*;
029import org.apache.juneau.internal.*;
030import org.apache.juneau.parser.*;
031import org.apache.juneau.utils.*;
032
033/**
034 * Parses text generated by the {@link XmlSerializer} class back into a POJO model.
035 *
036 * <h5 class='topic'>Media types</h5>
037 * <p>
038 * Handles <c>Content-Type</c> types:  <bc>text/xml</bc>
039 *
040 * <h5 class='topic'>Description</h5>
041 * <p>
042 * See the {@link XmlSerializer} class for a description of Juneau-generated XML.
043 *
044 * <h5 class='section'>Notes:</h5><ul>
045 *    <li class='note'>This class is thread safe and reusable.
046 * </ul>
047 *
048 * <h5 class='section'>See Also:</h5><ul>
049 *    <li class='link'><a class="doclink" href="../../../../index.html#jm.XmlDetails">XML Details</a>
050
051 * </ul>
052 */
053public class XmlParser extends ReaderParser implements XmlMetaProvider {
054
055   //-------------------------------------------------------------------------------------------------------------------
056   // Static
057   //-------------------------------------------------------------------------------------------------------------------
058
059   /** Default parser, all default settings.*/
060   public static final XmlParser DEFAULT = new XmlParser(create());
061
062   /**
063    * Creates a new builder for this object.
064    *
065    * @return A new builder.
066    */
067   public static Builder create() {
068      return new Builder();
069   }
070
071   //-------------------------------------------------------------------------------------------------------------------
072   // Builder
073   //-------------------------------------------------------------------------------------------------------------------
074
075   /**
076    * Builder class.
077    */
078   @FluentSetters
079   public static class Builder extends ReaderParser.Builder {
080
081      private static final Cache<HashKey,XmlParser> CACHE = Cache.of(HashKey.class, XmlParser.class).build();
082
083      boolean preserveRootElement, validating;
084      Class<? extends XMLEventAllocator> eventAllocator;
085      Class<? extends XMLReporter> reporter;
086      Class<? extends XMLResolver> resolver;
087
088      /**
089       * Constructor, default settings.
090       */
091      protected Builder() {
092         super();
093         consumes("text/xml,application/xml");
094         preserveRootElement = env("XmlParser.preserveRootElement", false);
095         validating = env("XmlParser.validating", false);
096         eventAllocator = null;
097         reporter = null;
098         resolver = null;
099      }
100
101      /**
102       * Copy constructor.
103       *
104       * @param copyFrom The bean to copy from.
105       */
106      protected Builder(XmlParser copyFrom) {
107         super(copyFrom);
108         preserveRootElement = copyFrom.preserveRootElement;
109         validating = copyFrom.validating;
110         eventAllocator = copyFrom.eventAllocator;
111         reporter = copyFrom.reporter;
112         resolver = copyFrom.resolver;
113      }
114
115      /**
116       * Copy constructor.
117       *
118       * @param copyFrom The builder to copy from.
119       */
120      protected Builder(Builder copyFrom) {
121         super(copyFrom);
122         preserveRootElement = copyFrom.preserveRootElement;
123         validating = copyFrom.validating;
124         eventAllocator = copyFrom.eventAllocator;
125         reporter = copyFrom.reporter;
126         resolver = copyFrom.resolver;
127      }
128
129      @Override /* Context.Builder */
130      public Builder copy() {
131         return new Builder(this);
132      }
133
134      @Override /* Context.Builder */
135      public XmlParser build() {
136         return cache(CACHE).build(XmlParser.class);
137      }
138
139      @Override /* Context.Builder */
140      public HashKey hashKey() {
141         return HashKey.of(
142            super.hashKey(),
143            preserveRootElement,
144            validating,
145            eventAllocator,
146            reporter,
147            resolver
148         );
149      }
150
151      //-----------------------------------------------------------------------------------------------------------------
152      // Properties
153      //-----------------------------------------------------------------------------------------------------------------
154
155      /**
156       * XML event allocator.
157       *
158       * <p>
159       * Associates an {@link XMLEventAllocator} with this parser.
160       *
161       * @param value The new value for this property.
162       * @return This object.
163       */
164      @FluentSetter
165      public Builder eventAllocator(Class<? extends XMLEventAllocator> value) {
166         eventAllocator = value;
167         return this;
168      }
169
170      /**
171       * Preserve root element during generalized parsing.
172       *
173       * <p>
174       * When enabled, when parsing into a generic {@link JsonMap}, the map will contain a single entry whose key
175       * is the root element name.
176       *
177       * <h5 class='section'>Example:</h5>
178       * <p class='bjava'>
179       *    <jc>// Parser with preserve-root-element.</jc>
180       *    ReaderParser <jv>parser1</jv> = XmlParser
181       *       .<jsm>create</jsm>()
182       *       .preserveRootElement()
183       *       .build();
184       *
185       *    <jc>// Parser without preserve-root-element (the default behavior).</jc>
186       *    ReaderParser <jv>parser2</jv> = XmlParser
187       *       .<jsm>create</jsm>()
188       *       .build();
189       *
190       *    String <jv>xml</jv> = <js>"&lt;root&gt;&lt;a&gt;foobar&lt;/a&gt;&lt;/root&gt;"</js>;
191       *
192       *    <jc>// Produces:  "{ root: { a:'foobar' }}"</jc>
193       *    JsonMap <jv>map1</jv> = <jv>parser1</jv>.parse(<jv>xml</jv>, JsonMap.<jk>class</jk>);
194       *
195       *    <jc>// Produces:  "{ a:'foobar' }"</jc>
196       *    JsonMap <jv>map2</jv> = <jv>parser2</jv>.parse(<jv>xml</jv>, JsonMap.<jk>class</jk>);
197       * </p>
198       *
199       * @return This object.
200       */
201      @FluentSetter
202      public Builder preserveRootElement() {
203         return preserveRootElement(true);
204      }
205
206      /**
207       * Same as {@link #preserveRootElement()} but allows you to explicitly specify the value.
208       *
209       * @param value The value for this setting.
210       * @return This object.
211       */
212      @FluentSetter
213      public Builder preserveRootElement(boolean value) {
214         preserveRootElement = value;
215         return this;
216      }
217
218      /**
219       * XML reporter.
220       *
221       * <p>
222       * Associates an {@link XMLReporter} with this parser.
223       *
224       * @param value The new value for this property.
225       * @return This object.
226       */
227      @FluentSetter
228      public Builder reporter(Class<? extends XMLReporter> value) {
229         reporter = value;
230         return this;
231      }
232
233      /**
234       * XML resolver.
235       *
236       * <p>
237       * Associates an {@link XMLResolver} with this parser.
238       *
239       * @param value The new value for this property.
240       * @return This object.
241       */
242      @FluentSetter
243      public Builder resolver(Class<? extends XMLResolver> value) {
244         resolver = value;
245         return this;
246      }
247
248      /**
249       * Enable validation.
250       *
251       * <p>
252       * If <jk>true</jk>, XML document will be validated.
253       *
254       * <p>
255       * See {@link XMLInputFactory#IS_VALIDATING} for more info.
256       *
257       * @return This object.
258       */
259      @FluentSetter
260      public Builder validating() {
261         return validating(true);
262      }
263
264      /**
265       * Same as {@link #validating()} but allows you to explicitly specify the value.
266       *
267       * @param value The value for this setting.
268       * @return This object.
269       */
270      @FluentSetter
271      public Builder validating(boolean value) {
272         validating = value;
273         return this;
274      }
275
276      // <FluentSetters>
277
278      @Override /* GENERATED - org.apache.juneau.Context.Builder */
279      public Builder annotations(Annotation...values) {
280         super.annotations(values);
281         return this;
282      }
283
284      @Override /* GENERATED - org.apache.juneau.Context.Builder */
285      public Builder apply(AnnotationWorkList work) {
286         super.apply(work);
287         return this;
288      }
289
290      @Override /* GENERATED - org.apache.juneau.Context.Builder */
291      public Builder applyAnnotations(java.lang.Class<?>...fromClasses) {
292         super.applyAnnotations(fromClasses);
293         return this;
294      }
295
296      @Override /* GENERATED - org.apache.juneau.Context.Builder */
297      public Builder applyAnnotations(Method...fromMethods) {
298         super.applyAnnotations(fromMethods);
299         return this;
300      }
301
302      @Override /* GENERATED - org.apache.juneau.Context.Builder */
303      public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) {
304         super.cache(value);
305         return this;
306      }
307
308      @Override /* GENERATED - org.apache.juneau.Context.Builder */
309      public Builder debug() {
310         super.debug();
311         return this;
312      }
313
314      @Override /* GENERATED - org.apache.juneau.Context.Builder */
315      public Builder debug(boolean value) {
316         super.debug(value);
317         return this;
318      }
319
320      @Override /* GENERATED - org.apache.juneau.Context.Builder */
321      public Builder impl(Context value) {
322         super.impl(value);
323         return this;
324      }
325
326      @Override /* GENERATED - org.apache.juneau.Context.Builder */
327      public Builder type(Class<? extends org.apache.juneau.Context> value) {
328         super.type(value);
329         return this;
330      }
331
332      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
333      public Builder beanClassVisibility(Visibility value) {
334         super.beanClassVisibility(value);
335         return this;
336      }
337
338      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
339      public Builder beanConstructorVisibility(Visibility value) {
340         super.beanConstructorVisibility(value);
341         return this;
342      }
343
344      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
345      public Builder beanContext(BeanContext value) {
346         super.beanContext(value);
347         return this;
348      }
349
350      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
351      public Builder beanContext(BeanContext.Builder value) {
352         super.beanContext(value);
353         return this;
354      }
355
356      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
357      public Builder beanDictionary(java.lang.Class<?>...values) {
358         super.beanDictionary(values);
359         return this;
360      }
361
362      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
363      public Builder beanFieldVisibility(Visibility value) {
364         super.beanFieldVisibility(value);
365         return this;
366      }
367
368      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
369      public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) {
370         super.beanInterceptor(on, value);
371         return this;
372      }
373
374      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
375      public Builder beanMapPutReturnsOldValue() {
376         super.beanMapPutReturnsOldValue();
377         return this;
378      }
379
380      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
381      public Builder beanMethodVisibility(Visibility value) {
382         super.beanMethodVisibility(value);
383         return this;
384      }
385
386      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
387      public Builder beanProperties(Map<String,Object> values) {
388         super.beanProperties(values);
389         return this;
390      }
391
392      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
393      public Builder beanProperties(Class<?> beanClass, String properties) {
394         super.beanProperties(beanClass, properties);
395         return this;
396      }
397
398      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
399      public Builder beanProperties(String beanClassName, String properties) {
400         super.beanProperties(beanClassName, properties);
401         return this;
402      }
403
404      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
405      public Builder beanPropertiesExcludes(Map<String,Object> values) {
406         super.beanPropertiesExcludes(values);
407         return this;
408      }
409
410      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
411      public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) {
412         super.beanPropertiesExcludes(beanClass, properties);
413         return this;
414      }
415
416      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
417      public Builder beanPropertiesExcludes(String beanClassName, String properties) {
418         super.beanPropertiesExcludes(beanClassName, properties);
419         return this;
420      }
421
422      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
423      public Builder beanPropertiesReadOnly(Map<String,Object> values) {
424         super.beanPropertiesReadOnly(values);
425         return this;
426      }
427
428      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
429      public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) {
430         super.beanPropertiesReadOnly(beanClass, properties);
431         return this;
432      }
433
434      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
435      public Builder beanPropertiesReadOnly(String beanClassName, String properties) {
436         super.beanPropertiesReadOnly(beanClassName, properties);
437         return this;
438      }
439
440      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
441      public Builder beanPropertiesWriteOnly(Map<String,Object> values) {
442         super.beanPropertiesWriteOnly(values);
443         return this;
444      }
445
446      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
447      public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) {
448         super.beanPropertiesWriteOnly(beanClass, properties);
449         return this;
450      }
451
452      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
453      public Builder beanPropertiesWriteOnly(String beanClassName, String properties) {
454         super.beanPropertiesWriteOnly(beanClassName, properties);
455         return this;
456      }
457
458      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
459      public Builder beansRequireDefaultConstructor() {
460         super.beansRequireDefaultConstructor();
461         return this;
462      }
463
464      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
465      public Builder beansRequireSerializable() {
466         super.beansRequireSerializable();
467         return this;
468      }
469
470      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
471      public Builder beansRequireSettersForGetters() {
472         super.beansRequireSettersForGetters();
473         return this;
474      }
475
476      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
477      public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) {
478         super.dictionaryOn(on, values);
479         return this;
480      }
481
482      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
483      public Builder disableBeansRequireSomeProperties() {
484         super.disableBeansRequireSomeProperties();
485         return this;
486      }
487
488      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
489      public Builder disableIgnoreMissingSetters() {
490         super.disableIgnoreMissingSetters();
491         return this;
492      }
493
494      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
495      public Builder disableIgnoreTransientFields() {
496         super.disableIgnoreTransientFields();
497         return this;
498      }
499
500      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
501      public Builder disableIgnoreUnknownNullBeanProperties() {
502         super.disableIgnoreUnknownNullBeanProperties();
503         return this;
504      }
505
506      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
507      public Builder disableInterfaceProxies() {
508         super.disableInterfaceProxies();
509         return this;
510      }
511
512      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
513      public <T> Builder example(Class<T> pojoClass, T o) {
514         super.example(pojoClass, o);
515         return this;
516      }
517
518      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
519      public <T> Builder example(Class<T> pojoClass, String json) {
520         super.example(pojoClass, json);
521         return this;
522      }
523
524      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
525      public Builder findFluentSetters() {
526         super.findFluentSetters();
527         return this;
528      }
529
530      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
531      public Builder findFluentSetters(Class<?> on) {
532         super.findFluentSetters(on);
533         return this;
534      }
535
536      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
537      public Builder ignoreInvocationExceptionsOnGetters() {
538         super.ignoreInvocationExceptionsOnGetters();
539         return this;
540      }
541
542      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
543      public Builder ignoreInvocationExceptionsOnSetters() {
544         super.ignoreInvocationExceptionsOnSetters();
545         return this;
546      }
547
548      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
549      public Builder ignoreUnknownBeanProperties() {
550         super.ignoreUnknownBeanProperties();
551         return this;
552      }
553
554      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
555      public Builder ignoreUnknownEnumValues() {
556         super.ignoreUnknownEnumValues();
557         return this;
558      }
559
560      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
561      public Builder implClass(Class<?> interfaceClass, Class<?> implClass) {
562         super.implClass(interfaceClass, implClass);
563         return this;
564      }
565
566      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
567      public Builder implClasses(Map<Class<?>,Class<?>> values) {
568         super.implClasses(values);
569         return this;
570      }
571
572      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
573      public Builder interfaceClass(Class<?> on, Class<?> value) {
574         super.interfaceClass(on, value);
575         return this;
576      }
577
578      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
579      public Builder interfaces(java.lang.Class<?>...value) {
580         super.interfaces(value);
581         return this;
582      }
583
584      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
585      public Builder locale(Locale value) {
586         super.locale(value);
587         return this;
588      }
589
590      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
591      public Builder mediaType(MediaType value) {
592         super.mediaType(value);
593         return this;
594      }
595
596      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
597      public Builder notBeanClasses(java.lang.Class<?>...values) {
598         super.notBeanClasses(values);
599         return this;
600      }
601
602      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
603      public Builder notBeanPackages(String...values) {
604         super.notBeanPackages(values);
605         return this;
606      }
607
608      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
609      public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) {
610         super.propertyNamer(value);
611         return this;
612      }
613
614      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
615      public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) {
616         super.propertyNamer(on, value);
617         return this;
618      }
619
620      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
621      public Builder sortProperties() {
622         super.sortProperties();
623         return this;
624      }
625
626      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
627      public Builder sortProperties(java.lang.Class<?>...on) {
628         super.sortProperties(on);
629         return this;
630      }
631
632      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
633      public Builder stopClass(Class<?> on, Class<?> value) {
634         super.stopClass(on, value);
635         return this;
636      }
637
638      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
639      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) {
640         super.swap(normalClass, swappedClass, swapFunction);
641         return this;
642      }
643
644      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
645      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) {
646         super.swap(normalClass, swappedClass, swapFunction, unswapFunction);
647         return this;
648      }
649
650      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
651      public Builder swaps(java.lang.Class<?>...values) {
652         super.swaps(values);
653         return this;
654      }
655
656      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
657      public Builder timeZone(TimeZone value) {
658         super.timeZone(value);
659         return this;
660      }
661
662      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
663      public Builder typeName(Class<?> on, String value) {
664         super.typeName(on, value);
665         return this;
666      }
667
668      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
669      public Builder typePropertyName(String value) {
670         super.typePropertyName(value);
671         return this;
672      }
673
674      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
675      public Builder typePropertyName(Class<?> on, String value) {
676         super.typePropertyName(on, value);
677         return this;
678      }
679
680      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
681      public Builder useEnumNames() {
682         super.useEnumNames();
683         return this;
684      }
685
686      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
687      public Builder useJavaBeanIntrospector() {
688         super.useJavaBeanIntrospector();
689         return this;
690      }
691
692      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
693      public Builder autoCloseStreams() {
694         super.autoCloseStreams();
695         return this;
696      }
697
698      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
699      public Builder autoCloseStreams(boolean value) {
700         super.autoCloseStreams(value);
701         return this;
702      }
703
704      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
705      public Builder consumes(String value) {
706         super.consumes(value);
707         return this;
708      }
709
710      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
711      public Builder debugOutputLines(int value) {
712         super.debugOutputLines(value);
713         return this;
714      }
715
716      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
717      public Builder listener(Class<? extends org.apache.juneau.parser.ParserListener> value) {
718         super.listener(value);
719         return this;
720      }
721
722      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
723      public Builder strict() {
724         super.strict();
725         return this;
726      }
727
728      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
729      public Builder strict(boolean value) {
730         super.strict(value);
731         return this;
732      }
733
734      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
735      public Builder trimStrings() {
736         super.trimStrings();
737         return this;
738      }
739
740      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
741      public Builder trimStrings(boolean value) {
742         super.trimStrings(value);
743         return this;
744      }
745
746      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
747      public Builder unbuffered() {
748         super.unbuffered();
749         return this;
750      }
751
752      @Override /* GENERATED - org.apache.juneau.parser.Parser.Builder */
753      public Builder unbuffered(boolean value) {
754         super.unbuffered(value);
755         return this;
756      }
757
758      @Override /* GENERATED - org.apache.juneau.parser.ReaderParser.Builder */
759      public Builder fileCharset(Charset value) {
760         super.fileCharset(value);
761         return this;
762      }
763
764      @Override /* GENERATED - org.apache.juneau.parser.ReaderParser.Builder */
765      public Builder streamCharset(Charset value) {
766         super.streamCharset(value);
767         return this;
768      }
769
770      // </FluentSetters>
771   }
772
773   //-------------------------------------------------------------------------------------------------------------------
774   // Instance
775   //-------------------------------------------------------------------------------------------------------------------
776
777   final boolean
778      validating,
779      preserveRootElement;
780   final Class<? extends XMLEventAllocator> eventAllocator;
781   final Class<? extends XMLReporter> reporter;
782   final Class<? extends XMLResolver> resolver;
783
784   private final XMLReporter reporterImpl;
785   private final XMLResolver resolverImpl;
786   private final XMLEventAllocator eventAllocatorImpl;
787   private final Map<ClassMeta<?>,XmlClassMeta> xmlClassMetas = new ConcurrentHashMap<>();
788   private final Map<BeanMeta<?>,XmlBeanMeta> xmlBeanMetas = new ConcurrentHashMap<>();
789   private final Map<BeanPropertyMeta,XmlBeanPropertyMeta> xmlBeanPropertyMetas = new ConcurrentHashMap<>();
790
791   /**
792    * Constructor.
793    *
794    * @param builder
795    *    The property store containing all the settings for this object.
796    */
797   public XmlParser(Builder builder) {
798      super(builder);
799      validating = builder.validating;
800      preserveRootElement = builder.preserveRootElement;
801      reporter = builder.reporter;
802      resolver = builder.resolver;
803      eventAllocator = builder.eventAllocator;
804
805      reporterImpl = reporter != null ? newInstance(reporter) : null;
806      resolverImpl = resolver != null ? newInstance(resolver) : null;
807      eventAllocatorImpl = eventAllocator != null ? newInstance(eventAllocator) : null;
808   }
809
810   @Override /* Context */
811   public Builder copy() {
812      return new Builder(this);
813   }
814
815   @Override /* Context */
816   public XmlParserSession.Builder createSession() {
817      return XmlParserSession.create(this);
818   }
819
820   @Override /* Context */
821   public XmlParserSession getSession() {
822      return createSession().build();
823   }
824
825   //-----------------------------------------------------------------------------------------------------------------
826   // Extended metadata
827   //-----------------------------------------------------------------------------------------------------------------
828
829   @Override /* XmlMetaProvider */
830   public XmlClassMeta getXmlClassMeta(ClassMeta<?> cm) {
831      XmlClassMeta m = xmlClassMetas.get(cm);
832      if (m == null) {
833         m = new XmlClassMeta(cm, this);
834         xmlClassMetas.put(cm, m);
835      }
836      return m;
837   }
838
839   @Override /* XmlMetaProvider */
840   public XmlBeanMeta getXmlBeanMeta(BeanMeta<?> bm) {
841      XmlBeanMeta m = xmlBeanMetas.get(bm);
842      if (m == null) {
843         m = new XmlBeanMeta(bm, this);
844         xmlBeanMetas.put(bm, m);
845      }
846      return m;
847   }
848
849   @Override /* XmlMetaProvider */
850   public XmlBeanPropertyMeta getXmlBeanPropertyMeta(BeanPropertyMeta bpm) {
851      XmlBeanPropertyMeta m = xmlBeanPropertyMetas.get(bpm);
852      if (m == null) {
853         BeanPropertyMeta dbpm = bpm.getDelegateFor();
854         m = new XmlBeanPropertyMeta(dbpm, this);
855         xmlBeanPropertyMetas.put(bpm, m);
856      }
857      return m;
858   }
859
860   //-----------------------------------------------------------------------------------------------------------------
861   // Properties
862   //-----------------------------------------------------------------------------------------------------------------
863
864   /**
865    * XML event allocator.
866    *
867    * @see Builder#eventAllocator(Class)
868    * @return
869    *    The {@link XMLEventAllocator} associated with this parser, or <jk>null</jk> if there isn't one.
870    */
871   protected final XMLEventAllocator getEventAllocator() {
872      return eventAllocatorImpl;
873   }
874
875   /**
876    * Preserve root element during generalized parsing.
877    *
878    * @see Builder#preserveRootElement()
879    * @return
880    *    <jk>true</jk> if when parsing into a generic {@link JsonMap}, the map will contain a single entry whose key
881    *    is the root element name.
882    */
883   protected final boolean isPreserveRootElement() {
884      return preserveRootElement;
885   }
886
887   /**
888    * XML reporter.
889    *
890    * @see Builder#reporter(Class)
891    * @return
892    *    The {@link XMLReporter} associated with this parser, or <jk>null</jk> if there isn't one.
893    */
894   protected final XMLReporter getReporter() {
895      return reporterImpl;
896   }
897
898   /**
899    * XML resolver.
900    *
901    * @see Builder#resolver(Class)
902    * @return
903    *    The {@link XMLResolver} associated with this parser, or <jk>null</jk> if there isn't one.
904    */
905   protected final XMLResolver getResolver() {
906      return resolverImpl;
907   }
908
909   /**
910    * Enable validation.
911    *
912    * @see Builder#validating()
913    * @return
914    *    <jk>true</jk> if XML document will be validated.
915    */
916   protected final boolean isValidating() {
917      return validating;
918   }
919
920   //-----------------------------------------------------------------------------------------------------------------
921   // Other methods
922   //-----------------------------------------------------------------------------------------------------------------
923
924   private <T> T newInstance(Class<T> c) {
925      try {
926         return c.getDeclaredConstructor().newInstance();
927      } catch (Exception e) {
928         throw asRuntimeException(e);
929      }
930   }
931
932   @Override /* Context */
933   protected JsonMap properties() {
934      return filteredMap()
935         .append("validating", validating)
936         .append("preserveRootElement", preserveRootElement)
937         .append("reporter", reporter)
938         .append("resolver", resolver)
939         .append("eventAllocator", eventAllocator);
940   }
941}