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.parser;
014
015import static org.apache.juneau.internal.CollectionUtils.*;
016import static org.apache.juneau.parser.Parser.*;
017
018import java.util.*;
019
020import org.apache.juneau.*;
021import org.apache.juneau.http.*;
022import org.apache.juneau.internal.*;
023
024/**
025 * Builder class for creating instances of {@link ParserGroup}.
026 */
027public class ParserGroupBuilder extends BeanContextBuilder {
028
029   private final List<Object> parsers;
030
031   /**
032    * Create an empty parser group builder.
033    */
034   public ParserGroupBuilder() {
035      this.parsers = new ArrayList<>();
036   }
037
038   /**
039    * Clone an existing parser group builder.
040    * 
041    * @param copyFrom The parser group that we're copying settings and parsers from.
042    */
043   public ParserGroupBuilder(ParserGroup copyFrom) {
044      super(copyFrom.getPropertyStore());
045      this.parsers = new ArrayList<>();
046      addReverse(parsers, copyFrom.getParsers());
047   }
048
049   /**
050    * Registers the specified parsers with this group.
051    * 
052    * @param p The parsers to append to this group.
053    * @return This object (for method chaining).
054    */
055   public ParserGroupBuilder append(Class<?>...p) {
056      addReverse(parsers, p);
057      return this;
058   }
059
060   /**
061    * Registers the specified parsers with this group.
062    * 
063    * <p>
064    * When passing in pre-instantiated parsers to this group, applying properties and transforms to the group
065    * do not affect them.
066    * 
067    * @param p The parsers to append to this group.
068    * @return This object (for method chaining).
069    */
070   public ParserGroupBuilder append(Parser...p) {
071      addReverse(parsers, p);
072      return this;
073   }
074
075   /**
076    * Registers the specified parsers with this group.
077    * 
078    * <p>
079    * Objects can either be instances of parsers or parser classes.
080    * 
081    * @param p The parsers to append to this group.
082    * @return This object (for method chaining).
083    */
084   public ParserGroupBuilder append(List<Object> p) {
085      addReverse(parsers, p);
086      return this;
087   }
088
089   /**
090    * Registers the specified parsers with this group.
091    * 
092    * <p>
093    * Objects can either be instances of parsers or parser classes.
094    * 
095    * @param p The parsers to append to this group.
096    * @return This object (for method chaining).
097    */
098   public ParserGroupBuilder append(Object...p) {
099      addReverse(parsers, p);
100      return this;
101   }
102
103   /**
104    * Creates a new {@link ParserGroup} object using a snapshot of the settings defined in this builder.
105    * 
106    * <p>
107    * This method can be called multiple times to produce multiple parser groups.
108    * 
109    * @return A new {@link ParserGroup} object.
110    */
111   @Override /* Context */
112   @SuppressWarnings("unchecked")
113   public ParserGroup build() {
114      List<Parser> l = new ArrayList<>();
115      for (Object p : parsers) {
116         Class<? extends Parser> c = null;
117         PropertyStore ps = getPropertyStore();
118         if (p instanceof Class) {
119            c = (Class<? extends Parser>)p;
120            l.add(ContextCache.INSTANCE.create(c, ps));
121         } else {
122            l.add((Parser)p);
123         }
124      }
125      return new ParserGroup(getPropertyStore(), ArrayUtils.toReverseArray(Parser.class, l));
126   }
127
128
129   //--------------------------------------------------------------------------------
130   // Properties
131   //--------------------------------------------------------------------------------
132
133   /**
134    * Configuration property:  Auto-close streams.
135    * 
136    * <p>
137    * If <jk>true</jk>, <l>InputStreams</l> and <l>Readers</l> passed into parsers will be closed
138    * after parsing is complete.
139    * 
140    * <h5 class='section'>See Also:</h5>
141    * <ul>
142    *    <li class='jf'>{@link Parser#PARSER_autoCloseStreams}
143    * </ul>
144    * 
145    * @param value 
146    *    The new value for this property.
147    *    <br>The default value is <jk>false</jk>.
148    * @return This object (for method chaining).
149    */
150   public ParserGroupBuilder autoCloseStreams(boolean value) {
151      return set(PARSER_autoCloseStreams, value);
152   }
153
154   /**
155    * Configuration property:  Auto-close streams.
156    * <p>
157    * Shortcut for calling <code>autoCloseStreams(<jk>true</jk>)</code>.
158    * 
159    * <h5 class='section'>See Also:</h5>
160    * <ul>
161    *    <li class='jf'>{@link Parser#PARSER_autoCloseStreams}
162    * </ul>
163    * 
164    * @return This object (for method chaining).
165    */
166   public ParserGroupBuilder autoCloseStreams() {
167      return set(PARSER_autoCloseStreams, true);
168   }
169
170   /**
171    * Configuration property:  File charset.
172    * 
173    * <p>
174    * The character set to use for reading <code>Files</code> from the file system.
175    * 
176    * <h5 class='section'>See Also:</h5>
177    * <ul>
178    *    <li class='jf'>{@link Parser#PARSER_fileCharset}
179    * </ul>
180    * 
181    * @param value 
182    *    The new value for this property.
183    *    <br>The default value is <js>"DEFAULT"</js> which causes the system default to be used.
184    * @return This object (for method chaining).
185    */
186   public ParserGroupBuilder fileCharset(String value) {
187      return set(PARSER_fileCharset, value);
188   }
189
190   /**
191    * Configuration property:  Input stream charset.
192    * 
193    * <p>
194    * The character set to use for converting <code>InputStreams</code> and byte arrays to readers.
195    * 
196    * <h5 class='section'>See Also:</h5>
197    * <ul>
198    *    <li class='jf'>{@link Parser#PARSER_inputStreamCharset}
199    * </ul>
200    * 
201    * @param value 
202    *    The new value for this property.
203    *    <br>The default value is <js>"UTF-8"</js>.
204    * @return This object (for method chaining).
205    */
206   public ParserGroupBuilder inputStreamCharset(String value) {
207      return set(PARSER_inputStreamCharset, value);
208   }
209
210   /**
211    * Configuration property:  Parser listener.
212    * 
213    * <p>
214    * Class used to listen for errors and warnings that occur during parsing.
215    * 
216    * <h5 class='section'>See Also:</h5>
217    * <ul>
218    *    <li class='jf'>{@link Parser#PARSER_listener}
219    * </ul>
220    * 
221    * @param value The new value for this property.
222    * @return This object (for method chaining).
223    */
224   public ParserGroupBuilder listener(Class<? extends ParserListener> value) {
225      return set(PARSER_listener, value);
226   }
227
228   /**
229    * Configuration property:  Strict mode.
230    * 
231    * <p>
232    * If <jk>true</jk>, strict mode for the parsers are enabled.
233    * 
234    * <h5 class='section'>See Also:</h5>
235    * <ul>
236    *    <li class='jf'>{@link Parser#PARSER_strict}
237    * </ul>
238    * 
239    * @param value 
240    *    The new value for this property.
241    *    <br>The default value is <jk>false</jk>.
242    * @return This object (for method chaining).
243    */
244   public ParserGroupBuilder strict(boolean value) {
245      return set(PARSER_strict, value);
246   }
247
248   /**
249    * Configuration property:  Strict mode.
250    * 
251    * <p>
252    * Shortcut for calling <code>strict(<jk>true</jk>)</code>.
253    * 
254    * <h5 class='section'>See Also:</h5>
255    * <ul>
256    *    <li class='jf'>{@link Parser#PARSER_strict}
257    * </ul>
258    * 
259    * @return This object (for method chaining).
260    */
261   public ParserGroupBuilder strict() {
262      return set(PARSER_strict, true);
263   }
264
265   /**
266    * Configuration property:  Trim parsed strings.
267    * 
268    * <p>
269    * If <jk>true</jk>, string values will be trimmed of whitespace using {@link String#trim()} before being added to
270    * the POJO.
271    * 
272    * <h5 class='section'>See Also:</h5>
273    * <ul>
274    *    <li class='jf'>{@link Parser#PARSER_trimStrings}
275    * </ul>
276    * 
277    * @param value 
278    *    The new value for this property.
279    *    <br>The default value is <jk>false</jk>.
280    * @return This object (for method chaining).
281    */
282   public ParserGroupBuilder trimStrings(boolean value) {
283      return set(PARSER_trimStrings, value);
284   }
285   
286   /**
287    * Configuration property:  Trim parsed strings.
288    * 
289    * <p>
290    * Shortcut for calling <code>trimStrings(<jk>true</jk>)</code>.
291    * 
292    * <h5 class='section'>See Also:</h5>
293    * <ul>
294    *    <li class='jf'>{@link Parser#PARSER_trimStrings}
295    * </ul>
296    * 
297    * @return This object (for method chaining).
298    */
299   public ParserGroupBuilder trimStrings() {
300      return set(PARSER_trimStrings, true);
301   }
302
303   /**
304    * Configuration property:  Unbuffered.
305    * 
306    * <p>
307    * If <jk>true</jk>, don't use internal buffering during parsing.
308    * 
309    * <h5 class='section'>See Also:</h5>
310    * <ul>
311    *    <li class='jf'>{@link Parser#PARSER_unbuffered}
312    * </ul>
313    * 
314    * @param value 
315    *    The new value for this property.
316    *    <br>The default value is <jk>false</jk>.
317    * @return This object (for method chaining).
318    */
319   public ParserGroupBuilder unbuffered(boolean value) {
320      return set(PARSER_unbuffered, value);
321   }
322
323   /**
324    * Configuration property:  Unbuffered.
325    * 
326    * <p>
327    * Shortcut for calling <code>unbuffered(<jk>true</jk>)</code>.
328    * 
329    * <h5 class='section'>See Also:</h5>
330    * <ul>
331    *    <li class='jf'>{@link Parser#PARSER_unbuffered}
332    * </ul>
333    * 
334    * @return This object (for method chaining).
335    */
336   public ParserGroupBuilder unbuffered() {
337      return set(PARSER_unbuffered, true);
338   }
339
340   @Override /* BeanContextBuilder */
341   public ParserGroupBuilder beansRequireDefaultConstructor(boolean value) {
342      super.beansRequireDefaultConstructor(value);
343      return this;
344   }
345
346   @Override /* BeanContextBuilder */
347   public ParserGroupBuilder beansRequireDefaultConstructor() {
348      super.beansRequireDefaultConstructor();
349      return this;
350   }
351
352   @Override /* BeanContextBuilder */
353   public ParserGroupBuilder beansRequireSerializable(boolean value) {
354      super.beansRequireSerializable(value);
355      return this;
356   }
357
358   @Override /* BeanContextBuilder */
359   public ParserGroupBuilder beansRequireSerializable() {
360      super.beansRequireSerializable();
361      return this;
362   }
363
364   @Override /* BeanContextBuilder */
365   public ParserGroupBuilder beansRequireSettersForGetters(boolean value) {
366      super.beansRequireSettersForGetters(value);
367      return this;
368   }
369
370   @Override /* BeanContextBuilder */
371   public ParserGroupBuilder beansRequireSettersForGetters() {
372      super.beansRequireSettersForGetters();
373      return this;
374   }
375
376   @Override /* BeanContextBuilder */
377   public ParserGroupBuilder beansRequireSomeProperties(boolean value) {
378      super.beansRequireSomeProperties(value);
379      return this;
380   }
381
382   @Override /* BeanContextBuilder */
383   public ParserGroupBuilder beanMapPutReturnsOldValue(boolean value) {
384      super.beanMapPutReturnsOldValue(value);
385      return this;
386   }
387
388   @Override /* BeanContextBuilder */
389   public ParserGroupBuilder beanMapPutReturnsOldValue() {
390      super.beanMapPutReturnsOldValue();
391      return this;
392   }
393
394   @Override /* BeanContextBuilder */
395   public ParserGroupBuilder beanConstructorVisibility(Visibility value) {
396      super.beanConstructorVisibility(value);
397      return this;
398   }
399
400   @Override /* BeanContextBuilder */
401   public ParserGroupBuilder beanClassVisibility(Visibility value) {
402      super.beanClassVisibility(value);
403      return this;
404   }
405
406   @Override /* BeanContextBuilder */
407   public ParserGroupBuilder beanFieldVisibility(Visibility value) {
408      super.beanFieldVisibility(value);
409      return this;
410   }
411
412   @Override /* BeanContextBuilder */
413   public ParserGroupBuilder beanMethodVisibility(Visibility value) {
414      super.beanMethodVisibility(value);
415      return this;
416   }
417
418   @Override /* BeanContextBuilder */
419   public ParserGroupBuilder useJavaBeanIntrospector(boolean value) {
420      super.useJavaBeanIntrospector(value);
421      return this;
422   }
423
424   @Override /* BeanContextBuilder */
425   public ParserGroupBuilder useJavaBeanIntrospector() {
426      super.useJavaBeanIntrospector();
427      return this;
428   }
429
430   @Override /* BeanContextBuilder */
431   public ParserGroupBuilder useInterfaceProxies(boolean value) {
432      super.useInterfaceProxies(value);
433      return this;
434   }
435
436   @Override /* BeanContextBuilder */
437   public ParserGroupBuilder ignoreUnknownBeanProperties(boolean value) {
438      super.ignoreUnknownBeanProperties(value);
439      return this;
440   }
441
442   @Override /* BeanContextBuilder */
443   public ParserGroupBuilder ignoreUnknownBeanProperties() {
444      super.ignoreUnknownBeanProperties();
445      return this;
446   }
447
448   @Override /* BeanContextBuilder */
449   public ParserGroupBuilder ignoreUnknownNullBeanProperties(boolean value) {
450      super.ignoreUnknownNullBeanProperties(value);
451      return this;
452   }
453
454   @Override /* BeanContextBuilder */
455   public ParserGroupBuilder ignorePropertiesWithoutSetters(boolean value) {
456      super.ignorePropertiesWithoutSetters(value);
457      return this;
458   }
459
460   @Override /* BeanContextBuilder */
461   public ParserGroupBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
462      super.ignoreInvocationExceptionsOnGetters(value);
463      return this;
464   }
465
466   @Override /* BeanContextBuilder */
467   public ParserGroupBuilder ignoreInvocationExceptionsOnGetters() {
468      super.ignoreInvocationExceptionsOnGetters();
469      return this;
470   }
471
472   @Override /* BeanContextBuilder */
473   public ParserGroupBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
474      super.ignoreInvocationExceptionsOnSetters(value);
475      return this;
476   }
477
478   @Override /* BeanContextBuilder */
479   public ParserGroupBuilder ignoreInvocationExceptionsOnSetters() {
480      super.ignoreInvocationExceptionsOnSetters();
481      return this;
482   }
483
484   @Override /* BeanContextBuilder */
485   public ParserGroupBuilder sortProperties(boolean value) {
486      super.sortProperties(value);
487      return this;
488   }
489
490   @Override /* BeanContextBuilder */
491   public ParserGroupBuilder sortProperties() {
492      super.sortProperties();
493      return this;
494   }
495
496   @Override /* BeanContextBuilder */
497   public ParserGroupBuilder notBeanPackages(Object...values) {
498      super.notBeanPackages(values);
499      return this;
500   }
501
502   @Override /* BeanContextBuilder */
503   public ParserGroupBuilder notBeanPackages(String...values) {
504      super.notBeanPackages(values);
505      return this;
506   }
507
508   @Override /* BeanContextBuilder */
509   public ParserGroupBuilder notBeanPackages(boolean append, Object...values) {
510      super.notBeanPackages(append, values);
511      return this;
512   }
513
514   @Override /* BeanContextBuilder */
515   public ParserGroupBuilder notBeanPackagesRemove(Object...values) {
516      super.notBeanPackagesRemove(values);
517      return this;
518   }
519
520   @Override /* BeanContextBuilder */
521   public ParserGroupBuilder notBeanClasses(Object...values) {
522      super.notBeanClasses(values);
523      return this;
524   }
525
526   @Override /* BeanContextBuilder */
527   public ParserGroupBuilder notBeanClasses(Class<?>...values) {
528      super.notBeanClasses(values);
529      return this;
530   }
531
532   @Override /* BeanContextBuilder */
533   public ParserGroupBuilder notBeanClasses(boolean append, Object...values) {
534      super.notBeanClasses(append, values);
535      return this;
536   }
537
538   @Override /* BeanContextBuilder */
539   public ParserGroupBuilder notBeanClassesRemove(Object...values) {
540      super.notBeanClassesRemove(values);
541      return this;
542   }
543
544   @Override /* BeanContextBuilder */
545   public ParserGroupBuilder beanFilters(Object...values) {
546      super.beanFilters(values);
547      return this;
548   }
549
550   @Override /* BeanContextBuilder */
551   public ParserGroupBuilder beanFilters(Class<?>...values) {
552      super.beanFilters(values);
553      return this;
554   }
555
556   @Override /* BeanContextBuilder */
557   public ParserGroupBuilder beanFilters(boolean append, Object...values) {
558      super.beanFilters(append, values);
559      return this;
560   }
561
562   @Override /* BeanContextBuilder */
563   public ParserGroupBuilder beanFiltersRemove(Object...values) {
564      super.beanFiltersRemove(values);
565      return this;
566   }
567
568   @Override /* BeanContextBuilder */
569   public ParserGroupBuilder pojoSwaps(Object...values) {
570      super.pojoSwaps(values);
571      return this;
572   }
573
574   @Override /* BeanContextBuilder */
575   public ParserGroupBuilder pojoSwaps(Class<?>...values) {
576      super.pojoSwaps(values);
577      return this;
578   }
579
580   @Override /* BeanContextBuilder */
581   public ParserGroupBuilder pojoSwaps(boolean append, Object...values) {
582      super.pojoSwaps(append, values);
583      return this;
584   }
585
586   @Override /* BeanContextBuilder */
587   public ParserGroupBuilder pojoSwapsRemove(Object...values) {
588      super.pojoSwapsRemove(values);
589      return this;
590   }
591
592   @Override /* BeanContextBuilder */
593   public ParserGroupBuilder implClasses(Map<String,Class<?>> values) {
594      super.implClasses(values);
595      return this;
596   }
597
598   @Override /* BeanContextBuilder */
599   public <T> ParserGroupBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
600      super.implClass(interfaceClass, implClass);
601      return this;
602   }
603
604   @Override /* BeanContextBuilder */
605   public ParserGroupBuilder beanDictionary(Object...values) {
606      super.beanDictionary(values);
607      return this;
608   }
609
610   @Override /* BeanContextBuilder */
611   public ParserGroupBuilder beanDictionary(Class<?>...values) {
612      super.beanDictionary(values);
613      return this;
614   }
615
616   @Override /* BeanContextBuilder */
617   public ParserGroupBuilder beanDictionary(boolean append, Object...values) {
618      super.beanDictionary(append, values);
619      return this;
620   }
621
622   @Override /* BeanContextBuilder */
623   public ParserGroupBuilder beanDictionaryRemove(Object...values) {
624      super.beanDictionaryRemove(values);
625      return this;
626   }
627
628   @Override /* BeanContextBuilder */
629   public ParserGroupBuilder beanTypePropertyName(String value) {
630      super.beanTypePropertyName(value);
631      return this;
632   }
633
634   @Override /* BeanContextBuilder */
635   public ParserGroupBuilder locale(Locale value) {
636      super.locale(value);
637      return this;
638   }
639
640   @Override /* BeanContextBuilder */
641   public ParserGroupBuilder timeZone(TimeZone value) {
642      super.timeZone(value);
643      return this;
644   }
645
646   @Override /* BeanContextBuilder */
647   public ParserGroupBuilder mediaType(MediaType value) {
648      super.mediaType(value);
649      return this;
650   }
651
652   @Override /* BeanContextBuilder */
653   public ParserGroupBuilder debug() {
654      super.debug();
655      return this;
656   }
657
658   @Override /* ContextBuilder */
659   public ParserGroupBuilder set(String name, Object value) {
660      super.set(name, value);
661      return this;
662   }
663
664   @Override /* ContextBuilder */
665   public ParserGroupBuilder set(boolean append, String name, Object value) {
666      super.set(append, name, value);
667      return this;
668   }
669
670   @Override /* ContextBuilder */
671   public ParserGroupBuilder set(Map<String,Object> properties) {
672      super.set(properties);
673      return this;
674   }
675
676   @Override /* ContextBuilder */
677   public ParserGroupBuilder add(Map<String,Object> properties) {
678      super.add(properties);
679      return this;
680   }
681
682   @Override /* ContextBuilder */
683   public ParserGroupBuilder addTo(String name, Object value) {
684      super.addTo(name, value);
685      return this;
686   }
687
688   @Override /* ContextBuilder */
689   public ParserGroupBuilder addTo(String name, String key, Object value) {
690      super.addTo(name, key, value);
691      return this;
692   }
693
694   @Override /* ContextBuilder */
695   public ParserGroupBuilder removeFrom(String name, Object value) {
696      super.removeFrom(name, value);
697      return this;
698   }
699
700   @Override /* ContextBuilder */
701   public ParserGroupBuilder apply(PropertyStore copyFrom) {
702      super.apply(copyFrom);
703      return this;
704   }
705}