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