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.oapi;
018
019import java.lang.annotation.*;
020import java.nio.charset.*;
021import java.util.*;
022import java.util.concurrent.*;
023
024import org.apache.juneau.*;
025import org.apache.juneau.annotation.*;
026import org.apache.juneau.httppart.*;
027import org.apache.juneau.internal.*;
028import org.apache.juneau.uon.*;
029import org.apache.juneau.utils.*;
030
031/**
032 * OpenAPI part parser.
033 *
034 * <h5 class='section'>Notes:</h5><ul>
035 *    <li class='note'>This class is thread safe and reusable.
036 * </ul>
037 *
038 * <h5 class='section'>See Also:</h5><ul>
039 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/OpenApiBasics">OpenApi Basics</a>
040
041 * </ul>
042 */
043public class OpenApiParser extends UonParser implements OpenApiMetaProvider {
044
045   //-------------------------------------------------------------------------------------------------------------------
046   // Static
047   //-------------------------------------------------------------------------------------------------------------------
048
049   /** Reusable instance of {@link OpenApiParser}. */
050   public static final OpenApiParser DEFAULT = new OpenApiParser(create());
051
052   /**
053    * Creates a new builder for this object.
054    *
055    * @return A new builder.
056    */
057   public static Builder create() {
058      return new Builder();
059   }
060
061   //-------------------------------------------------------------------------------------------------------------------
062   // Builder
063   //-------------------------------------------------------------------------------------------------------------------
064
065   /**
066    * Builder class.
067    */
068   public static class Builder extends UonParser.Builder {
069
070      private static final Cache<HashKey,OpenApiParser> CACHE = Cache.of(HashKey.class, OpenApiParser.class).build();
071
072      HttpPartFormat format;
073      HttpPartCollectionFormat collectionFormat;
074
075      /**
076       * Constructor, default settings.
077       */
078      protected Builder() {
079         consumes("text/openapi");
080         format = HttpPartFormat.NO_FORMAT;
081         collectionFormat = HttpPartCollectionFormat.NO_COLLECTION_FORMAT;
082      }
083
084      /**
085       * Copy constructor.
086       *
087       * @param copyFrom The bean to copy from.
088       */
089      protected Builder(OpenApiParser copyFrom) {
090         super(copyFrom);
091         format = copyFrom.format;
092         collectionFormat = copyFrom.collectionFormat;
093      }
094
095      /**
096       * Copy constructor.
097       *
098       * @param copyFrom The builder to copy from.
099       */
100      protected Builder(Builder copyFrom) {
101         super(copyFrom);
102         format = copyFrom.format;
103         collectionFormat = copyFrom.collectionFormat;
104      }
105
106      @Override /* Context.Builder */
107      public Builder copy() {
108         return new Builder(this);
109      }
110
111      @Override /* Context.Builder */
112      public OpenApiParser build() {
113         return cache(CACHE).build(OpenApiParser.class);
114      }
115
116      @Override /* Context.Builder */
117      public HashKey hashKey() {
118         return HashKey.of(
119            super.hashKey(),
120            format,
121            collectionFormat
122         );
123      }
124
125      //-----------------------------------------------------------------------------------------------------------------
126      // Properties
127      //-----------------------------------------------------------------------------------------------------------------
128
129      /**
130       * <i><l>OpenApiCommon</l> configuration property:&emsp;</i>  Default format for HTTP parts.
131       *
132       * <p>
133       * Specifies the format to use for HTTP parts when not otherwise specified via {@link org.apache.juneau.annotation.Schema#format()}.
134       *
135       * <h5 class='section'>Example:</h5>
136       * <p class='bjava'>
137       *    <jc>// Create a plain-text parser.</jc>
138       *    OpenApiParser <jv>parser1</jv> = OpenApiParser
139       *       .<jsm>create</jsm>()
140       *       .build();
141       *
142       *    <jc>// Create a UON parser.</jc>
143       *    OpenApiParser <jv>parser2</jv> = OpenApiParser
144       *       .<jsm>create</jsm>()
145       *       .format(<jsf>UON</jsf>)
146       *       .build();
147       *
148       *    <jc>// Parse a plain-text string.</jc>
149       *    String <jv>value1</jv> = <jv>parser1</jv>.parse(<js>"foo bar"</js>);
150       *
151       *    <jc>// Parse a UON string.</jc>
152       *    String <jv>value2</jv> = <jv>parser1</jv>.parse(<js>"'foo bar'"</js>);
153       * </p>
154       *
155       * <ul class='values javatree'>
156       *    <li class='jc'>{@link org.apache.juneau.httppart.HttpPartFormat}
157       *    <ul>
158       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#UON UON} - UON notation (e.g. <js>"'foo bar'"</js>).
159       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#INT32 INT32} - Signed 32 bits.
160       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#INT64 INT64} - Signed 64 bits.
161       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#FLOAT FLOAT} - 32-bit floating point number.
162       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#DOUBLE DOUBLE} - 64-bit floating point number.
163       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#BYTE BYTE} - BASE-64 encoded characters.
164       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#BINARY BINARY} - Hexadecimal encoded octets (e.g. <js>"00FF"</js>).
165       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#BINARY_SPACED BINARY_SPACED} - Spaced-separated hexadecimal encoded octets (e.g. <js>"00 FF"</js>).
166       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#DATE DATE} - An <a href='http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14'>RFC3339 full-date</a>.
167       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#DATE_TIME DATE_TIME} - An <a href='http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14'>RFC3339 date-time</a>.
168       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#PASSWORD PASSWORD} - Used to hint UIs the input needs to be obscured.
169       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#NO_FORMAT NO_FORMAT} - (default) Not specified.
170       *    </ul>
171       * </ul>
172       *
173       * @param value The new value for this property.
174       * @return This object.
175       */
176      public Builder format(HttpPartFormat value) {
177         format = value;
178         return this;
179      }
180
181      /**
182       * <i><l>OpenApiCommon</l> configuration property:&emsp;</i>  Default collection format for HTTP parts.
183       *
184       * <p>
185       * Specifies the collection format to use for HTTP parts when not otherwise specified via {@link org.apache.juneau.annotation.Schema#collectionFormat()}.
186       *
187       * <h5 class='section'>Example:</h5>
188       * <p class='bjava'>
189       *    <jc>// Create a parser using CSV for collections.</jc>
190       *    OpenApiParser <jv>parser1</jv> = OpenApiParser
191       *       .<jsm>create</jsm>()
192       *       .collectionFormat(<jsf>CSV</jsf>)
193       *       .build();
194       *
195       *    <jc>// Create a serializer using UON for collections.</jc>
196       *    OpenApiParser <jv>parser2</jv> = OpenApiParser
197       *       .<jsm>create</jsm>()
198       *       .collectionFormat(<jsf>UON</jsf>)
199       *       .build();
200       *
201       *    <jc>// Parse CSV.</jc>
202       *    JsonList <jv>list1</jv> = <jv>parser1</jv>.parse(<js>"foo=bar,baz=qux\,true\,123"</js>, JsonList.<jk>class</jk>)
203       *
204       *    <jc>// Parse UON.</jc>
205       *    JsonList <jv>list2</jv> = <jv>parser2</jv>.parse(<js>"(foo=bar,baz=@(qux,true,123))"</js>, JsonList.<jk>class</jk>)
206       * </p>
207       *
208       * <ul class='values javatree'>
209       *    <li class='jc'>{@link org.apache.juneau.httppart.HttpPartFormat}
210       *    <ul>
211       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartCollectionFormat#CSV CSV} - (default) Comma-separated values (e.g. <js>"foo,bar"</js>).
212       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartCollectionFormat#SSV SSV} - Space-separated values (e.g. <js>"foo bar"</js>).
213       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartCollectionFormat#TSV TSV} - Tab-separated values (e.g. <js>"foo\tbar"</js>).
214       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartCollectionFormat#PIPES PIPES} - Pipe-separated values (e.g. <js>"foo|bar"</js>).
215       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartCollectionFormat#MULTI MULTI} - Corresponds to multiple parameter instances instead of multiple values for a single instance (e.g. <js>"foo=bar&amp;foo=baz"</js>).
216       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartCollectionFormat#UONC UONC} - UON collection notation (e.g. <js>"@(foo,bar)"</js>).
217       *    </ul>
218       * </ul>
219       *
220       * @param value The new value for this property.
221       * @return This object.
222       */
223      public Builder collectionFormat(HttpPartCollectionFormat value) {
224         collectionFormat = value;
225         return this;
226      }
227      @Override /* Overridden from Builder */
228      public Builder annotations(Annotation...values) {
229         super.annotations(values);
230         return this;
231      }
232
233      @Override /* Overridden from Builder */
234      public Builder apply(AnnotationWorkList work) {
235         super.apply(work);
236         return this;
237      }
238
239      @Override /* Overridden from Builder */
240      public Builder applyAnnotations(Object...from) {
241         super.applyAnnotations(from);
242         return this;
243      }
244
245      @Override /* Overridden from Builder */
246      public Builder applyAnnotations(Class<?>...from) {
247         super.applyAnnotations(from);
248         return this;
249      }
250
251      @Override /* Overridden from Builder */
252      public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) {
253         super.cache(value);
254         return this;
255      }
256
257      @Override /* Overridden from Builder */
258      public Builder debug() {
259         super.debug();
260         return this;
261      }
262
263      @Override /* Overridden from Builder */
264      public Builder debug(boolean value) {
265         super.debug(value);
266         return this;
267      }
268
269      @Override /* Overridden from Builder */
270      public Builder impl(Context value) {
271         super.impl(value);
272         return this;
273      }
274
275      @Override /* Overridden from Builder */
276      public Builder type(Class<? extends org.apache.juneau.Context> value) {
277         super.type(value);
278         return this;
279      }
280
281      @Override /* Overridden from Builder */
282      public Builder beanClassVisibility(Visibility value) {
283         super.beanClassVisibility(value);
284         return this;
285      }
286
287      @Override /* Overridden from Builder */
288      public Builder beanConstructorVisibility(Visibility value) {
289         super.beanConstructorVisibility(value);
290         return this;
291      }
292
293      @Override /* Overridden from Builder */
294      public Builder beanContext(BeanContext value) {
295         super.beanContext(value);
296         return this;
297      }
298
299      @Override /* Overridden from Builder */
300      public Builder beanContext(BeanContext.Builder value) {
301         super.beanContext(value);
302         return this;
303      }
304
305      @Override /* Overridden from Builder */
306      public Builder beanDictionary(java.lang.Class<?>...values) {
307         super.beanDictionary(values);
308         return this;
309      }
310
311      @Override /* Overridden from Builder */
312      public Builder beanFieldVisibility(Visibility value) {
313         super.beanFieldVisibility(value);
314         return this;
315      }
316
317      @Override /* Overridden from Builder */
318      public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) {
319         super.beanInterceptor(on, value);
320         return this;
321      }
322
323      @Override /* Overridden from Builder */
324      public Builder beanMapPutReturnsOldValue() {
325         super.beanMapPutReturnsOldValue();
326         return this;
327      }
328
329      @Override /* Overridden from Builder */
330      public Builder beanMethodVisibility(Visibility value) {
331         super.beanMethodVisibility(value);
332         return this;
333      }
334
335      @Override /* Overridden from Builder */
336      public Builder beanProperties(Map<String,Object> values) {
337         super.beanProperties(values);
338         return this;
339      }
340
341      @Override /* Overridden from Builder */
342      public Builder beanProperties(Class<?> beanClass, String properties) {
343         super.beanProperties(beanClass, properties);
344         return this;
345      }
346
347      @Override /* Overridden from Builder */
348      public Builder beanProperties(String beanClassName, String properties) {
349         super.beanProperties(beanClassName, properties);
350         return this;
351      }
352
353      @Override /* Overridden from Builder */
354      public Builder beanPropertiesExcludes(Map<String,Object> values) {
355         super.beanPropertiesExcludes(values);
356         return this;
357      }
358
359      @Override /* Overridden from Builder */
360      public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) {
361         super.beanPropertiesExcludes(beanClass, properties);
362         return this;
363      }
364
365      @Override /* Overridden from Builder */
366      public Builder beanPropertiesExcludes(String beanClassName, String properties) {
367         super.beanPropertiesExcludes(beanClassName, properties);
368         return this;
369      }
370
371      @Override /* Overridden from Builder */
372      public Builder beanPropertiesReadOnly(Map<String,Object> values) {
373         super.beanPropertiesReadOnly(values);
374         return this;
375      }
376
377      @Override /* Overridden from Builder */
378      public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) {
379         super.beanPropertiesReadOnly(beanClass, properties);
380         return this;
381      }
382
383      @Override /* Overridden from Builder */
384      public Builder beanPropertiesReadOnly(String beanClassName, String properties) {
385         super.beanPropertiesReadOnly(beanClassName, properties);
386         return this;
387      }
388
389      @Override /* Overridden from Builder */
390      public Builder beanPropertiesWriteOnly(Map<String,Object> values) {
391         super.beanPropertiesWriteOnly(values);
392         return this;
393      }
394
395      @Override /* Overridden from Builder */
396      public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) {
397         super.beanPropertiesWriteOnly(beanClass, properties);
398         return this;
399      }
400
401      @Override /* Overridden from Builder */
402      public Builder beanPropertiesWriteOnly(String beanClassName, String properties) {
403         super.beanPropertiesWriteOnly(beanClassName, properties);
404         return this;
405      }
406
407      @Override /* Overridden from Builder */
408      public Builder beansRequireDefaultConstructor() {
409         super.beansRequireDefaultConstructor();
410         return this;
411      }
412
413      @Override /* Overridden from Builder */
414      public Builder beansRequireSerializable() {
415         super.beansRequireSerializable();
416         return this;
417      }
418
419      @Override /* Overridden from Builder */
420      public Builder beansRequireSettersForGetters() {
421         super.beansRequireSettersForGetters();
422         return this;
423      }
424
425      @Override /* Overridden from Builder */
426      public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) {
427         super.dictionaryOn(on, values);
428         return this;
429      }
430
431      @Override /* Overridden from Builder */
432      public Builder disableBeansRequireSomeProperties() {
433         super.disableBeansRequireSomeProperties();
434         return this;
435      }
436
437      @Override /* Overridden from Builder */
438      public Builder disableIgnoreMissingSetters() {
439         super.disableIgnoreMissingSetters();
440         return this;
441      }
442
443      @Override /* Overridden from Builder */
444      public Builder disableIgnoreTransientFields() {
445         super.disableIgnoreTransientFields();
446         return this;
447      }
448
449      @Override /* Overridden from Builder */
450      public Builder disableIgnoreUnknownNullBeanProperties() {
451         super.disableIgnoreUnknownNullBeanProperties();
452         return this;
453      }
454
455      @Override /* Overridden from Builder */
456      public Builder disableInterfaceProxies() {
457         super.disableInterfaceProxies();
458         return this;
459      }
460
461      @Override /* Overridden from Builder */
462      public <T> Builder example(Class<T> pojoClass, T o) {
463         super.example(pojoClass, o);
464         return this;
465      }
466
467      @Override /* Overridden from Builder */
468      public <T> Builder example(Class<T> pojoClass, String json) {
469         super.example(pojoClass, json);
470         return this;
471      }
472
473      @Override /* Overridden from Builder */
474      public Builder findFluentSetters() {
475         super.findFluentSetters();
476         return this;
477      }
478
479      @Override /* Overridden from Builder */
480      public Builder findFluentSetters(Class<?> on) {
481         super.findFluentSetters(on);
482         return this;
483      }
484
485      @Override /* Overridden from Builder */
486      public Builder ignoreInvocationExceptionsOnGetters() {
487         super.ignoreInvocationExceptionsOnGetters();
488         return this;
489      }
490
491      @Override /* Overridden from Builder */
492      public Builder ignoreInvocationExceptionsOnSetters() {
493         super.ignoreInvocationExceptionsOnSetters();
494         return this;
495      }
496
497      @Override /* Overridden from Builder */
498      public Builder ignoreUnknownBeanProperties() {
499         super.ignoreUnknownBeanProperties();
500         return this;
501      }
502
503      @Override /* Overridden from Builder */
504      public Builder ignoreUnknownEnumValues() {
505         super.ignoreUnknownEnumValues();
506         return this;
507      }
508
509      @Override /* Overridden from Builder */
510      public Builder implClass(Class<?> interfaceClass, Class<?> implClass) {
511         super.implClass(interfaceClass, implClass);
512         return this;
513      }
514
515      @Override /* Overridden from Builder */
516      public Builder implClasses(Map<Class<?>,Class<?>> values) {
517         super.implClasses(values);
518         return this;
519      }
520
521      @Override /* Overridden from Builder */
522      public Builder interfaceClass(Class<?> on, Class<?> value) {
523         super.interfaceClass(on, value);
524         return this;
525      }
526
527      @Override /* Overridden from Builder */
528      public Builder interfaces(java.lang.Class<?>...value) {
529         super.interfaces(value);
530         return this;
531      }
532
533      @Override /* Overridden from Builder */
534      public Builder locale(Locale value) {
535         super.locale(value);
536         return this;
537      }
538
539      @Override /* Overridden from Builder */
540      public Builder mediaType(MediaType value) {
541         super.mediaType(value);
542         return this;
543      }
544
545      @Override /* Overridden from Builder */
546      public Builder notBeanClasses(java.lang.Class<?>...values) {
547         super.notBeanClasses(values);
548         return this;
549      }
550
551      @Override /* Overridden from Builder */
552      public Builder notBeanPackages(String...values) {
553         super.notBeanPackages(values);
554         return this;
555      }
556
557      @Override /* Overridden from Builder */
558      public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) {
559         super.propertyNamer(value);
560         return this;
561      }
562
563      @Override /* Overridden from Builder */
564      public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) {
565         super.propertyNamer(on, value);
566         return this;
567      }
568
569      @Override /* Overridden from Builder */
570      public Builder sortProperties() {
571         super.sortProperties();
572         return this;
573      }
574
575      @Override /* Overridden from Builder */
576      public Builder sortProperties(java.lang.Class<?>...on) {
577         super.sortProperties(on);
578         return this;
579      }
580
581      @Override /* Overridden from Builder */
582      public Builder stopClass(Class<?> on, Class<?> value) {
583         super.stopClass(on, value);
584         return this;
585      }
586
587      @Override /* Overridden from Builder */
588      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) {
589         super.swap(normalClass, swappedClass, swapFunction);
590         return this;
591      }
592
593      @Override /* Overridden from Builder */
594      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) {
595         super.swap(normalClass, swappedClass, swapFunction, unswapFunction);
596         return this;
597      }
598
599      @Override /* Overridden from Builder */
600      public Builder swaps(Object...values) {
601         super.swaps(values);
602         return this;
603      }
604
605      @Override /* Overridden from Builder */
606      public Builder swaps(Class<?>...values) {
607         super.swaps(values);
608         return this;
609      }
610
611      @Override /* Overridden from Builder */
612      public Builder timeZone(TimeZone value) {
613         super.timeZone(value);
614         return this;
615      }
616
617      @Override /* Overridden from Builder */
618      public Builder typeName(Class<?> on, String value) {
619         super.typeName(on, value);
620         return this;
621      }
622
623      @Override /* Overridden from Builder */
624      public Builder typePropertyName(String value) {
625         super.typePropertyName(value);
626         return this;
627      }
628
629      @Override /* Overridden from Builder */
630      public Builder typePropertyName(Class<?> on, String value) {
631         super.typePropertyName(on, value);
632         return this;
633      }
634
635      @Override /* Overridden from Builder */
636      public Builder useEnumNames() {
637         super.useEnumNames();
638         return this;
639      }
640
641      @Override /* Overridden from Builder */
642      public Builder useJavaBeanIntrospector() {
643         super.useJavaBeanIntrospector();
644         return this;
645      }
646
647      @Override /* Overridden from Builder */
648      public Builder autoCloseStreams() {
649         super.autoCloseStreams();
650         return this;
651      }
652
653      @Override /* Overridden from Builder */
654      public Builder autoCloseStreams(boolean value) {
655         super.autoCloseStreams(value);
656         return this;
657      }
658
659      @Override /* Overridden from Builder */
660      public Builder consumes(String value) {
661         super.consumes(value);
662         return this;
663      }
664
665      @Override /* Overridden from Builder */
666      public Builder debugOutputLines(int value) {
667         super.debugOutputLines(value);
668         return this;
669      }
670
671      @Override /* Overridden from Builder */
672      public Builder listener(Class<? extends org.apache.juneau.parser.ParserListener> value) {
673         super.listener(value);
674         return this;
675      }
676
677      @Override /* Overridden from Builder */
678      public Builder strict() {
679         super.strict();
680         return this;
681      }
682
683      @Override /* Overridden from Builder */
684      public Builder strict(boolean value) {
685         super.strict(value);
686         return this;
687      }
688
689      @Override /* Overridden from Builder */
690      public Builder trimStrings() {
691         super.trimStrings();
692         return this;
693      }
694
695      @Override /* Overridden from Builder */
696      public Builder trimStrings(boolean value) {
697         super.trimStrings(value);
698         return this;
699      }
700
701      @Override /* Overridden from Builder */
702      public Builder unbuffered() {
703         super.unbuffered();
704         return this;
705      }
706
707      @Override /* Overridden from Builder */
708      public Builder unbuffered(boolean value) {
709         super.unbuffered(value);
710         return this;
711      }
712
713      @Override /* Overridden from Builder */
714      public Builder fileCharset(Charset value) {
715         super.fileCharset(value);
716         return this;
717      }
718
719      @Override /* Overridden from Builder */
720      public Builder streamCharset(Charset value) {
721         super.streamCharset(value);
722         return this;
723      }
724
725      @Override /* Overridden from Builder */
726      public Builder decoding() {
727         super.decoding();
728         return this;
729      }
730
731      @Override /* Overridden from Builder */
732      public Builder decoding(boolean value) {
733         super.decoding(value);
734         return this;
735      }
736
737      @Override /* Overridden from Builder */
738      public Builder validateEnd() {
739         super.validateEnd();
740         return this;
741      }
742
743      @Override /* Overridden from Builder */
744      public Builder validateEnd(boolean value) {
745         super.validateEnd(value);
746         return this;
747      }
748   }
749
750   //-------------------------------------------------------------------------------------------------------------------
751   // Instance
752   //-------------------------------------------------------------------------------------------------------------------
753
754   final HttpPartFormat format;
755   final HttpPartCollectionFormat collectionFormat;
756
757   private final Map<ClassMeta<?>,OpenApiClassMeta> openApiClassMetas = new ConcurrentHashMap<>();
758   private final Map<BeanPropertyMeta,OpenApiBeanPropertyMeta> openApiBeanPropertyMetas = new ConcurrentHashMap<>();
759
760   /**
761    * Constructor.
762    *
763    * @param builder The builder for this object.
764    */
765   public OpenApiParser(Builder builder) {
766      super(builder);
767      format = builder.format;
768      collectionFormat = builder.collectionFormat;
769   }
770
771   @Override /* Context */
772   public Builder copy() {
773      return new Builder(this);
774   }
775
776   @Override /* Context */
777   public OpenApiParserSession.Builder createSession() {
778      return OpenApiParserSession.create(this);
779   }
780
781   @Override /* Context */
782   public OpenApiParserSession getSession() {
783      return createSession().build();
784   }
785
786   @Override /* HttpPartParser */
787   public OpenApiParserSession getPartSession() {
788      return OpenApiParserSession.create(this).build();
789   }
790
791   //-----------------------------------------------------------------------------------------------------------------
792   // Extended metadata
793   //-----------------------------------------------------------------------------------------------------------------
794
795   @Override /* OpenApiMetaProvider */
796   public OpenApiClassMeta getOpenApiClassMeta(ClassMeta<?> cm) {
797      OpenApiClassMeta m = openApiClassMetas.get(cm);
798      if (m == null) {
799         m = new OpenApiClassMeta(cm, this);
800         openApiClassMetas.put(cm, m);
801      }
802      return m;
803   }
804
805   @Override /* OpenApiMetaProvider */
806   public OpenApiBeanPropertyMeta getOpenApiBeanPropertyMeta(BeanPropertyMeta bpm) {
807      if (bpm == null)
808         return OpenApiBeanPropertyMeta.DEFAULT;
809      OpenApiBeanPropertyMeta m = openApiBeanPropertyMetas.get(bpm);
810      if (m == null) {
811         m = new OpenApiBeanPropertyMeta(bpm.getDelegateFor(), this);
812         openApiBeanPropertyMetas.put(bpm, m);
813      }
814      return m;
815   }
816
817   //-----------------------------------------------------------------------------------------------------------------
818   // Properties
819   //-----------------------------------------------------------------------------------------------------------------
820
821   /**
822    * Returns the default format to use when not otherwise specified via {@link Schema#format()}
823    *
824    * @return The default format to use when not otherwise specified via {@link Schema#format()}
825    */
826   protected final HttpPartFormat getFormat() {
827      return format;
828   }
829
830   /**
831    * Returns the default collection format to use when not otherwise specified via {@link Schema#collectionFormat()}
832    *
833    * @return The default collection format to use when not otherwise specified via {@link Schema#collectionFormat()}
834    */
835   protected final HttpPartCollectionFormat getCollectionFormat() {
836      return collectionFormat;
837   }
838}