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.AssertionUtils.*;
020import static org.apache.juneau.commons.utils.IoUtils.*;
021import static org.apache.juneau.commons.utils.Utils.*;
022
023import java.lang.annotation.*;
024import java.nio.charset.*;
025import java.util.*;
026
027import org.apache.juneau.*;
028import org.apache.juneau.commons.collections.*;
029import org.apache.juneau.commons.function.*;
030import org.apache.juneau.commons.reflect.*;
031
032/**
033 * Subclass of {@link Parser} for characters-based parsers.
034 *
035 * <h5 class='topic'>Description</h5>
036 * <p>
037 * This class is typically the parent class of all character-based parsers.
038 * It has 1 abstract method to implement on the session object...
039 * <ul>
040 *    <li><c>parse(ParserSession, ClassMeta)</c>
041 * </ul>
042 *
043 * <h5 class='section'>Notes:</h5><ul>
044 *    <li class='note'>This class is thread safe and reusable.
045 * </ul>
046 *
047 * <h5 class='section'>See Also:</h5><ul>
048 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/SerializersAndParsers">Serializers and Parsers</a>
049 * </ul>
050 */
051public class ReaderParser extends Parser {
052
053   /**
054    * Builder class.
055    */
056   public static class Builder extends Parser.Builder {
057
058      private Charset fileCharset;
059      private Charset streamCharset;
060
061      /**
062       * Constructor, default settings.
063       */
064      protected Builder() {
065         fileCharset = env("ReaderParser.fileCharset").map(x -> Charset.forName(x)).orElse(Charset.defaultCharset());
066         streamCharset = env("ReaderParser.streamCharset", UTF8);
067      }
068
069      /**
070       * Copy constructor.
071       *
072       * @param copyFrom The builder to copy from.
073       *    <br>Cannot be <jk>null</jk>.
074       */
075      protected Builder(Builder copyFrom) {
076         super(assertArgNotNull("copyFrom", copyFrom));
077         fileCharset = copyFrom.fileCharset;
078         streamCharset = copyFrom.streamCharset;
079      }
080
081      /**
082       * Copy constructor.
083       *
084       * @param copyFrom The bean to copy from.
085       *    <br>Cannot be <jk>null</jk>.
086       */
087      protected Builder(ReaderParser copyFrom) {
088         super(assertArgNotNull("copyFrom", copyFrom));
089         fileCharset = copyFrom.fileCharset;
090         streamCharset = copyFrom.streamCharset;
091      }
092
093      @Override /* Overridden from Builder */
094      public Builder annotations(Annotation...values) {
095         super.annotations(values);
096         return this;
097      }
098
099      @Override /* Overridden from Builder */
100      public Builder apply(AnnotationWorkList work) {
101         super.apply(work);
102         return this;
103      }
104
105      @Override /* Overridden from Builder */
106      public Builder applyAnnotations(Class<?>...from) {
107         super.applyAnnotations(from);
108         return this;
109      }
110
111      @Override /* Overridden from Builder */
112      public Builder applyAnnotations(Object...from) {
113         super.applyAnnotations(from);
114         return this;
115      }
116
117      @Override /* Overridden from Builder */
118      public Builder autoCloseStreams() {
119         super.autoCloseStreams();
120         return this;
121      }
122
123      @Override /* Overridden from Builder */
124      public Builder autoCloseStreams(boolean value) {
125         super.autoCloseStreams(value);
126         return this;
127      }
128
129      @Override /* Overridden from Builder */
130      public Builder beanClassVisibility(Visibility value) {
131         super.beanClassVisibility(value);
132         return this;
133      }
134
135      @Override /* Overridden from Builder */
136      public Builder beanConstructorVisibility(Visibility value) {
137         super.beanConstructorVisibility(value);
138         return this;
139      }
140
141      @Override /* Overridden from Builder */
142      public Builder beanContext(BeanContext value) {
143         super.beanContext(value);
144         return this;
145      }
146
147      @Override /* Overridden from Builder */
148      public Builder beanContext(BeanContext.Builder value) {
149         super.beanContext(value);
150         return this;
151      }
152
153      @Override /* Overridden from Builder */
154      public Builder beanDictionary(java.lang.Class<?>...values) {
155         super.beanDictionary(values);
156         return this;
157      }
158
159      @Override /* Overridden from Builder */
160      public Builder beanFieldVisibility(Visibility value) {
161         super.beanFieldVisibility(value);
162         return this;
163      }
164
165      @Override /* Overridden from Builder */
166      public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) {
167         super.beanInterceptor(on, value);
168         return this;
169      }
170
171      @Override /* Overridden from Builder */
172      public Builder beanMapPutReturnsOldValue() {
173         super.beanMapPutReturnsOldValue();
174         return this;
175      }
176
177      @Override /* Overridden from Builder */
178      public Builder beanMethodVisibility(Visibility value) {
179         super.beanMethodVisibility(value);
180         return this;
181      }
182
183      @Override /* Overridden from Builder */
184      public Builder beanProperties(Class<?> beanClass, String properties) {
185         super.beanProperties(beanClass, properties);
186         return this;
187      }
188
189      @Override /* Overridden from Builder */
190      public Builder beanProperties(Map<String,Object> values) {
191         super.beanProperties(values);
192         return this;
193      }
194
195      @Override /* Overridden from Builder */
196      public Builder beanProperties(String beanClassName, String properties) {
197         super.beanProperties(beanClassName, properties);
198         return this;
199      }
200
201      @Override /* Overridden from Builder */
202      public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) {
203         super.beanPropertiesExcludes(beanClass, properties);
204         return this;
205      }
206
207      @Override /* Overridden from Builder */
208      public Builder beanPropertiesExcludes(Map<String,Object> values) {
209         super.beanPropertiesExcludes(values);
210         return this;
211      }
212
213      @Override /* Overridden from Builder */
214      public Builder beanPropertiesExcludes(String beanClassName, String properties) {
215         super.beanPropertiesExcludes(beanClassName, properties);
216         return this;
217      }
218
219      @Override /* Overridden from Builder */
220      public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) {
221         super.beanPropertiesReadOnly(beanClass, properties);
222         return this;
223      }
224
225      @Override /* Overridden from Builder */
226      public Builder beanPropertiesReadOnly(Map<String,Object> values) {
227         super.beanPropertiesReadOnly(values);
228         return this;
229      }
230
231      @Override /* Overridden from Builder */
232      public Builder beanPropertiesReadOnly(String beanClassName, String properties) {
233         super.beanPropertiesReadOnly(beanClassName, properties);
234         return this;
235      }
236
237      @Override /* Overridden from Builder */
238      public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) {
239         super.beanPropertiesWriteOnly(beanClass, properties);
240         return this;
241      }
242
243      @Override /* Overridden from Builder */
244      public Builder beanPropertiesWriteOnly(Map<String,Object> values) {
245         super.beanPropertiesWriteOnly(values);
246         return this;
247      }
248
249      @Override /* Overridden from Builder */
250      public Builder beanPropertiesWriteOnly(String beanClassName, String properties) {
251         super.beanPropertiesWriteOnly(beanClassName, properties);
252         return this;
253      }
254
255      @Override /* Overridden from Builder */
256      public Builder beansRequireDefaultConstructor() {
257         super.beansRequireDefaultConstructor();
258         return this;
259      }
260
261      @Override /* Overridden from Builder */
262      public Builder beansRequireSerializable() {
263         super.beansRequireSerializable();
264         return this;
265      }
266
267      @Override /* Overridden from Builder */
268      public Builder beansRequireSettersForGetters() {
269         super.beansRequireSettersForGetters();
270         return this;
271      }
272
273      @Override /* Overridden from Context.Builder */
274      public ReaderParser build() {
275         return build(ReaderParser.class);
276      }
277
278      @Override /* Overridden from Builder */
279      public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) {
280         super.cache(value);
281         return this;
282      }
283
284      @Override /* Overridden from Builder */
285      public Builder consumes(String value) {
286         super.consumes(value);
287         return this;
288      }
289
290      @Override /* Overridden from Context.Builder */
291      public Builder copy() {
292         return new Builder(this);
293      }
294
295      @Override /* Overridden from Builder */
296      public Builder debug() {
297         super.debug();
298         return this;
299      }
300
301      @Override /* Overridden from Builder */
302      public Builder debug(boolean value) {
303         super.debug(value);
304         return this;
305      }
306
307      @Override /* Overridden from Builder */
308      public Builder debugOutputLines(int value) {
309         super.debugOutputLines(value);
310         return this;
311      }
312
313      @Override /* Overridden from Builder */
314      public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) {
315         super.dictionaryOn(on, values);
316         return this;
317      }
318
319      @Override /* Overridden from Builder */
320      public Builder disableBeansRequireSomeProperties() {
321         super.disableBeansRequireSomeProperties();
322         return this;
323      }
324
325      @Override /* Overridden from Builder */
326      public Builder disableIgnoreMissingSetters() {
327         super.disableIgnoreMissingSetters();
328         return this;
329      }
330
331      @Override /* Overridden from Builder */
332      public Builder disableIgnoreTransientFields() {
333         super.disableIgnoreTransientFields();
334         return this;
335      }
336
337      @Override /* Overridden from Builder */
338      public Builder disableIgnoreUnknownNullBeanProperties() {
339         super.disableIgnoreUnknownNullBeanProperties();
340         return this;
341      }
342
343      @Override /* Overridden from Builder */
344      public Builder disableInterfaceProxies() {
345         super.disableInterfaceProxies();
346         return this;
347      }
348
349      @Override /* Overridden from Builder */
350      public <T> Builder example(Class<T> pojoClass, String json) {
351         super.example(pojoClass, json);
352         return this;
353      }
354
355      @Override /* Overridden from Builder */
356      public <T> Builder example(Class<T> pojoClass, T o) {
357         super.example(pojoClass, o);
358         return this;
359      }
360
361      /**
362       * File charset.
363       *
364       * <p>
365       * The character set to use for reading <c>Files</c> from the file system.
366       *
367       * <p>
368       * Used when passing in files to {@link Parser#parse(Object, Class)}.
369       *
370       * <h5 class='section'>Example:</h5>
371       * <p class='bjava'>
372       *    <jc>// Create a parser that reads UTF-8 files.</jc>
373       *    ReaderParser <jv>parser</jv> = JsonParser
374       *       .<jsm>create</jsm>()
375       *       .fileCharset(<js>"UTF-8"</js>)
376       *       .build();
377       *
378       *    <jc>// Use it to read a UTF-8 encoded file.</jc>
379       *    MyBean <jv>myBean</jv> = <jv>parser</jv>.parse(<jk>new</jk> File(<js>"MyBean.txt"</js>), MyBean.<jk>class</jk>);
380       * </p>
381       *
382       * @param value
383       *    The new value for this property.
384       *    <br>The default value is <js>"DEFAULT"</js> which causes the system default to be used.
385       *    <br>Can be <jk>null</jk> (defaults to system default).
386       * @return This object.
387       */
388      public Builder fileCharset(Charset value) {
389         fileCharset = value;
390         return this;
391      }
392
393      @Override /* Overridden from Builder */
394      public Builder findFluentSetters() {
395         super.findFluentSetters();
396         return this;
397      }
398
399      @Override /* Overridden from Builder */
400      public Builder findFluentSetters(Class<?> on) {
401         super.findFluentSetters(on);
402         return this;
403      }
404
405      @Override /* Overridden from Context.Builder */
406      public HashKey hashKey() {
407         // @formatter:off
408         return HashKey.of(
409            super.hashKey(),
410            fileCharset,
411            streamCharset
412         );
413         // @formatter:on
414      }
415
416      @Override /* Overridden from Builder */
417      public Builder ignoreInvocationExceptionsOnGetters() {
418         super.ignoreInvocationExceptionsOnGetters();
419         return this;
420      }
421
422      @Override /* Overridden from Builder */
423      public Builder ignoreInvocationExceptionsOnSetters() {
424         super.ignoreInvocationExceptionsOnSetters();
425         return this;
426      }
427
428      @Override /* Overridden from Builder */
429      public Builder ignoreUnknownBeanProperties() {
430         super.ignoreUnknownBeanProperties();
431         return this;
432      }
433
434      @Override /* Overridden from Builder */
435      public Builder ignoreUnknownEnumValues() {
436         super.ignoreUnknownEnumValues();
437         return this;
438      }
439
440      @Override /* Overridden from Builder */
441      public Builder impl(Context value) {
442         super.impl(value);
443         return this;
444      }
445
446      @Override /* Overridden from Builder */
447      public Builder implClass(Class<?> interfaceClass, Class<?> implClass) {
448         super.implClass(interfaceClass, implClass);
449         return this;
450      }
451
452      @Override /* Overridden from Builder */
453      public Builder implClasses(Map<Class<?>,Class<?>> values) {
454         super.implClasses(values);
455         return this;
456      }
457
458      @Override /* Overridden from Builder */
459      public Builder interfaceClass(Class<?> on, Class<?> value) {
460         super.interfaceClass(on, value);
461         return this;
462      }
463
464      @Override /* Overridden from Builder */
465      public Builder interfaces(java.lang.Class<?>...value) {
466         super.interfaces(value);
467         return this;
468      }
469
470      @Override /* Overridden from Builder */
471      public Builder listener(Class<? extends org.apache.juneau.parser.ParserListener> value) {
472         super.listener(value);
473         return this;
474      }
475
476      @Override /* Overridden from Builder */
477      public Builder locale(Locale value) {
478         super.locale(value);
479         return this;
480      }
481
482      @Override /* Overridden from Builder */
483      public Builder mediaType(MediaType value) {
484         super.mediaType(value);
485         return this;
486      }
487
488      @Override /* Overridden from Builder */
489      public Builder notBeanClasses(java.lang.Class<?>...values) {
490         super.notBeanClasses(values);
491         return this;
492      }
493
494      @Override /* Overridden from Builder */
495      public Builder notBeanPackages(String...values) {
496         super.notBeanPackages(values);
497         return this;
498      }
499
500      @Override /* Overridden from Builder */
501      public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) {
502         super.propertyNamer(on, value);
503         return this;
504      }
505
506      @Override /* Overridden from Builder */
507      public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) {
508         super.propertyNamer(value);
509         return this;
510      }
511
512      @Override /* Overridden from Builder */
513      public Builder sortProperties() {
514         super.sortProperties();
515         return this;
516      }
517
518      @Override /* Overridden from Builder */
519      public Builder sortProperties(java.lang.Class<?>...on) {
520         super.sortProperties(on);
521         return this;
522      }
523
524      @Override /* Overridden from Builder */
525      public Builder stopClass(Class<?> on, Class<?> value) {
526         super.stopClass(on, value);
527         return this;
528      }
529
530      /**
531       * Input stream charset.
532       *
533       * <p>
534       * The character set to use for converting <c>InputStreams</c> and byte arrays to readers.
535       *
536       * <p>
537       * Used when passing in input streams and byte arrays to {@link Parser#parse(Object, Class)}.
538       *
539       * <h5 class='section'>Example:</h5>
540       * <p class='bjava'>
541       *    <jc>// Create a parser that reads UTF-8 files.</jc>
542       *    ReaderParser <jv>parser</jv> = JsonParser
543       *       .<jsm>create</jsm>()
544       *       .streamCharset(Charset.<jsm>forName</jsm>(<js>"UTF-8"</js>))
545       *       .build();
546       *
547       *    <jc>// Use it to read a UTF-8 encoded input stream.</jc>
548       *    MyBean <jv>myBean</jv> = <jv>parser</jv>.parse(<jk>new</jk> FileInputStream(<js>"MyBean.txt"</js>), MyBean.<jk>class</jk>);
549       * </p>
550       *
551       * @param value
552       *    The new value for this property.
553       *    <br>The default value is <js>"UTF-8"</js>.
554       *    <br>Can be <jk>null</jk> (defaults to UTF-8).
555       * @return This object.
556       */
557      public Builder streamCharset(Charset value) {
558         streamCharset = value;
559         return this;
560      }
561
562      @Override /* Overridden from Builder */
563      public Builder strict() {
564         super.strict();
565         return this;
566      }
567
568      @Override /* Overridden from Builder */
569      public Builder strict(boolean value) {
570         super.strict(value);
571         return this;
572      }
573
574      @Override /* Overridden from Builder */
575      public <T,S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) {
576         super.swap(normalClass, swappedClass, swapFunction);
577         return this;
578      }
579
580      @Override /* Overridden from Builder */
581      public <T,S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) {
582         super.swap(normalClass, swappedClass, swapFunction, unswapFunction);
583         return this;
584      }
585
586      @Override /* Overridden from Builder */
587      public Builder swaps(Class<?>...values) {
588         super.swaps(values);
589         return this;
590      }
591
592      @Override /* Overridden from Builder */
593      public Builder swaps(Object...values) {
594         super.swaps(values);
595         return this;
596      }
597
598      @Override /* Overridden from Builder */
599      public Builder timeZone(TimeZone value) {
600         super.timeZone(value);
601         return this;
602      }
603
604      @Override /* Overridden from Builder */
605      public Builder trimStrings() {
606         super.trimStrings();
607         return this;
608      }
609
610      @Override /* Overridden from Builder */
611      public Builder trimStrings(boolean value) {
612         super.trimStrings(value);
613         return this;
614      }
615
616      @Override /* Overridden from Builder */
617      public Builder type(Class<? extends org.apache.juneau.Context> value) {
618         super.type(value);
619         return this;
620      }
621
622      @Override /* Overridden from Builder */
623      public Builder typeName(Class<?> on, String value) {
624         super.typeName(on, value);
625         return this;
626      }
627
628      @Override /* Overridden from Builder */
629      public Builder typePropertyName(Class<?> on, String value) {
630         super.typePropertyName(on, value);
631         return this;
632      }
633
634      @Override /* Overridden from Builder */
635      public Builder typePropertyName(String value) {
636         super.typePropertyName(value);
637         return this;
638      }
639
640      @Override /* Overridden from Builder */
641      public Builder unbuffered() {
642         super.unbuffered();
643         return this;
644      }
645
646      @Override /* Overridden from Builder */
647      public Builder unbuffered(boolean value) {
648         super.unbuffered(value);
649         return this;
650      }
651
652      @Override /* Overridden from Builder */
653      public Builder useEnumNames() {
654         super.useEnumNames();
655         return this;
656      }
657
658      @Override /* Overridden from Builder */
659      public Builder useJavaBeanIntrospector() {
660         super.useJavaBeanIntrospector();
661         return this;
662      }
663   }
664
665   /**
666    * Creates a new builder for this object.
667    *
668    * @return A new builder.
669    */
670   public static Builder create() {
671      return new Builder();
672   }
673
674   private final Charset fileCharset;
675   private final Charset streamCharset;
676
677   /**
678    * Constructor.
679    *
680    * @param builder The builder for this object.
681    */
682   protected ReaderParser(Builder builder) {
683      super(builder);
684      fileCharset = builder.fileCharset;
685      streamCharset = builder.streamCharset;
686   }
687
688   @Override /* Overridden from Context */
689   public ReaderParserSession.Builder createSession() {
690      return ReaderParserSession.create(this);
691   }
692
693   @Override /* Overridden from Context */
694   public ReaderParserSession getSession() { return createSession().build(); }
695
696   @Override /* Overridden from Parser */
697   public final boolean isReaderParser() { return true; }
698
699   /**
700    * File charset.
701    *
702    * @see Builder#fileCharset(Charset)
703    * @return
704    *    The character set to use for reading <c>Files</c> from the file system.
705    */
706   protected final Charset getFileCharset() { return fileCharset; }
707
708   /**
709    * Input stream charset.
710    *
711    * @see Builder#streamCharset(Charset)
712    * @return
713    *    The character set to use for converting <c>InputStreams</c> and byte arrays to readers.
714    */
715   protected final Charset getStreamCharset() { return streamCharset; }
716
717   @Override /* Overridden from Parser */
718   protected FluentMap<String,Object> properties() {
719      return super.properties()
720         .a("fileCharset", fileCharset)
721         .a("streamCharset", streamCharset);
722   }
723}