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 * Serializes POJOs to values suitable for transmission as HTTP headers, query/form-data parameters, and path variables.
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 OpenApiSerializer extends UonSerializer implements OpenApiMetaProvider {
044
045   //-------------------------------------------------------------------------------------------------------------------
046   // Static
047   //-------------------------------------------------------------------------------------------------------------------
048
049   /** Reusable instance of {@link OpenApiSerializer}, all default settings. */
050   public static final OpenApiSerializer DEFAULT = new OpenApiSerializer(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 UonSerializer.Builder {
069
070      private static final Cache<HashKey,OpenApiSerializer> CACHE = Cache.of(HashKey.class, OpenApiSerializer.class).build();
071
072      HttpPartFormat format;
073      HttpPartCollectionFormat collectionFormat;
074
075      /**
076       * Constructor, default settings.
077       */
078      protected Builder() {
079         produces("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(OpenApiSerializer 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 OpenApiSerializer build() {
113         return cache(CACHE).build(OpenApiSerializer.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 serializer.</jc>
138       *    OpenApiSerializer <jv>serializer1</jv> = OpenApiSerializer
139       *       .<jsm>create</jsm>()
140       *       .build();
141       *
142       *    <jc>// Create a UON serializer.</jc>
143       *    OpenApiSerializer <jv>serializer2</jv> = OpenApiSerializer
144       *       .<jsm>create</jsm>()
145       *       .format(<jsf>UON</jsf>)
146       *       .build();
147       *
148       *    String <jv>string</jv> = <js>"foo bar"</js>;
149       *
150       *    <jc>// Produces: "foo bar"</jc>
151       *    String <jv>value1</jv> = <jv>serializer1</jv>.serialize(<jv>string</jv>);
152       *
153       *    <jc>// Produces: "'foo bar'"</jc>
154       *    String <jv>value2</jv> = <jv>serializer2</jv>.serialize(<jv>string</jv>);
155       * </p>
156       *
157       * <ul class='values javatree'>
158       *    <li class='jc'>{@link org.apache.juneau.httppart.HttpPartFormat}
159       *    <ul>
160       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#UON UON} - UON notation (e.g. <js>"'foo bar'"</js>).
161       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#INT32 INT32} - Signed 32 bits.
162       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#INT64 INT64} - Signed 64 bits.
163       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#FLOAT FLOAT} - 32-bit floating point number.
164       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#DOUBLE DOUBLE} - 64-bit floating point number.
165       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#BYTE BYTE} - BASE-64 encoded characters.
166       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#BINARY BINARY} - Hexadecimal encoded octets (e.g. <js>"00FF"</js>).
167       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#BINARY_SPACED BINARY_SPACED} - Spaced-separated hexadecimal encoded octets (e.g. <js>"00 FF"</js>).
168       *       <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>.
169       *       <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>.
170       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#PASSWORD PASSWORD} - Used to hint UIs the input needs to be obscured.
171       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#NO_FORMAT NO_FORMAT} - (default) Not specified.
172       *    </ul>
173       * </ul>
174       *
175       * @param value The new value for this property.
176       * @return This object.
177       */
178      public Builder format(HttpPartFormat value) {
179         format = value;
180         return this;
181      }
182
183      /**
184       * <i><l>OpenApiCommon</l> configuration property:&emsp;</i>  Default collection format for HTTP parts.
185       *
186       * <p>
187       * Specifies the collection format to use for HTTP parts when not otherwise specified via {@link org.apache.juneau.annotation.Schema#collectionFormat()}.
188       *
189       * <h5 class='section'>Example:</h5>
190       * <p class='bjava'>
191       *    <jc>// Create a serializer using CSV for collections.</jc>
192       *    OpenApiSerializer <jv>serializer1</jv> = OpenApiSerializer
193       *       .<jsm>create</jsm>()
194       *       .collectionFormat(<jsf>CSV</jsf>)
195       *       .build();
196       *
197       *    <jc>// Create a serializer using UON for collections.</jc>
198       *    OpenApiSerializer <jv>serializer2</jv> = OpenApiSerializer
199       *       .<jsm>create</jsm>()
200       *       .collectionFormat(<jsf>UON</jsf>)
201       *       .build();
202       *
203       *    <jc>// An arbitrary data structure.</jc>
204       *    JsonList <jv>list</jv> = JsonList.<jsm>of</jsm>(
205       *       <js>"foo"</js>,
206       *       <js>"bar"</js>,
207       *       JsonMap.<jsm>of</jsm>(
208       *          <js>"baz"</js>, JsonList.<jsm>of</jsm>(<js>"qux"</js>,<js>"true"</js>,<js>"123"</js>)
209       *    )
210       * );
211       *
212       *    <jc>// Produces: "foo=bar,baz=qux\,true\,123"</jc>
213       *    String <jv>value1</jv> = <jv>serializer1</jv>.serialize(<jv>list</jv>)
214       *
215       *    <jc>// Produces: "(foo=bar,baz=@(qux,'true','123'))"</jc>
216       *    String <jv>value2</jv> = <jv>serializer2</jv>.serialize(<jv>list</jv>)
217       * </p>
218       *
219       * <ul class='values javatree'>
220       *    <li class='jc'>{@link org.apache.juneau.httppart.HttpPartFormat}
221       *    <ul>
222       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartCollectionFormat#CSV CSV} - (default) Comma-separated values (e.g. <js>"foo,bar"</js>).
223       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartCollectionFormat#SSV SSV} - Space-separated values (e.g. <js>"foo bar"</js>).
224       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartCollectionFormat#TSV TSV} - Tab-separated values (e.g. <js>"foo\tbar"</js>).
225       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartCollectionFormat#PIPES PIPES} - Pipe-separated values (e.g. <js>"foo|bar"</js>).
226       *       <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>).
227       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartCollectionFormat#UONC UONC} - UON collection notation (e.g. <js>"@(foo,bar)"</js>).
228       *    </ul>
229       * </ul>
230       *
231       * @param value The new value for this property.
232       * @return This object.
233       */
234      public Builder collectionFormat(HttpPartCollectionFormat value) {
235         collectionFormat = value;
236         return this;
237      }
238      @Override /* Overridden from Builder */
239      public Builder annotations(Annotation...values) {
240         super.annotations(values);
241         return this;
242      }
243
244      @Override /* Overridden from Builder */
245      public Builder apply(AnnotationWorkList work) {
246         super.apply(work);
247         return this;
248      }
249
250      @Override /* Overridden from Builder */
251      public Builder applyAnnotations(Object...from) {
252         super.applyAnnotations(from);
253         return this;
254      }
255
256      @Override /* Overridden from Builder */
257      public Builder applyAnnotations(Class<?>...from) {
258         super.applyAnnotations(from);
259         return this;
260      }
261
262      @Override /* Overridden from Builder */
263      public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) {
264         super.cache(value);
265         return this;
266      }
267
268      @Override /* Overridden from Builder */
269      public Builder debug() {
270         super.debug();
271         return this;
272      }
273
274      @Override /* Overridden from Builder */
275      public Builder debug(boolean value) {
276         super.debug(value);
277         return this;
278      }
279
280      @Override /* Overridden from Builder */
281      public Builder impl(Context value) {
282         super.impl(value);
283         return this;
284      }
285
286      @Override /* Overridden from Builder */
287      public Builder type(Class<? extends org.apache.juneau.Context> value) {
288         super.type(value);
289         return this;
290      }
291
292      @Override /* Overridden from Builder */
293      public Builder beanClassVisibility(Visibility value) {
294         super.beanClassVisibility(value);
295         return this;
296      }
297
298      @Override /* Overridden from Builder */
299      public Builder beanConstructorVisibility(Visibility value) {
300         super.beanConstructorVisibility(value);
301         return this;
302      }
303
304      @Override /* Overridden from Builder */
305      public Builder beanContext(BeanContext value) {
306         super.beanContext(value);
307         return this;
308      }
309
310      @Override /* Overridden from Builder */
311      public Builder beanContext(BeanContext.Builder value) {
312         super.beanContext(value);
313         return this;
314      }
315
316      @Override /* Overridden from Builder */
317      public Builder beanDictionary(java.lang.Class<?>...values) {
318         super.beanDictionary(values);
319         return this;
320      }
321
322      @Override /* Overridden from Builder */
323      public Builder beanFieldVisibility(Visibility value) {
324         super.beanFieldVisibility(value);
325         return this;
326      }
327
328      @Override /* Overridden from Builder */
329      public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) {
330         super.beanInterceptor(on, value);
331         return this;
332      }
333
334      @Override /* Overridden from Builder */
335      public Builder beanMapPutReturnsOldValue() {
336         super.beanMapPutReturnsOldValue();
337         return this;
338      }
339
340      @Override /* Overridden from Builder */
341      public Builder beanMethodVisibility(Visibility value) {
342         super.beanMethodVisibility(value);
343         return this;
344      }
345
346      @Override /* Overridden from Builder */
347      public Builder beanProperties(Map<String,Object> values) {
348         super.beanProperties(values);
349         return this;
350      }
351
352      @Override /* Overridden from Builder */
353      public Builder beanProperties(Class<?> beanClass, String properties) {
354         super.beanProperties(beanClass, properties);
355         return this;
356      }
357
358      @Override /* Overridden from Builder */
359      public Builder beanProperties(String beanClassName, String properties) {
360         super.beanProperties(beanClassName, properties);
361         return this;
362      }
363
364      @Override /* Overridden from Builder */
365      public Builder beanPropertiesExcludes(Map<String,Object> values) {
366         super.beanPropertiesExcludes(values);
367         return this;
368      }
369
370      @Override /* Overridden from Builder */
371      public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) {
372         super.beanPropertiesExcludes(beanClass, properties);
373         return this;
374      }
375
376      @Override /* Overridden from Builder */
377      public Builder beanPropertiesExcludes(String beanClassName, String properties) {
378         super.beanPropertiesExcludes(beanClassName, properties);
379         return this;
380      }
381
382      @Override /* Overridden from Builder */
383      public Builder beanPropertiesReadOnly(Map<String,Object> values) {
384         super.beanPropertiesReadOnly(values);
385         return this;
386      }
387
388      @Override /* Overridden from Builder */
389      public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) {
390         super.beanPropertiesReadOnly(beanClass, properties);
391         return this;
392      }
393
394      @Override /* Overridden from Builder */
395      public Builder beanPropertiesReadOnly(String beanClassName, String properties) {
396         super.beanPropertiesReadOnly(beanClassName, properties);
397         return this;
398      }
399
400      @Override /* Overridden from Builder */
401      public Builder beanPropertiesWriteOnly(Map<String,Object> values) {
402         super.beanPropertiesWriteOnly(values);
403         return this;
404      }
405
406      @Override /* Overridden from Builder */
407      public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) {
408         super.beanPropertiesWriteOnly(beanClass, properties);
409         return this;
410      }
411
412      @Override /* Overridden from Builder */
413      public Builder beanPropertiesWriteOnly(String beanClassName, String properties) {
414         super.beanPropertiesWriteOnly(beanClassName, properties);
415         return this;
416      }
417
418      @Override /* Overridden from Builder */
419      public Builder beansRequireDefaultConstructor() {
420         super.beansRequireDefaultConstructor();
421         return this;
422      }
423
424      @Override /* Overridden from Builder */
425      public Builder beansRequireSerializable() {
426         super.beansRequireSerializable();
427         return this;
428      }
429
430      @Override /* Overridden from Builder */
431      public Builder beansRequireSettersForGetters() {
432         super.beansRequireSettersForGetters();
433         return this;
434      }
435
436      @Override /* Overridden from Builder */
437      public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) {
438         super.dictionaryOn(on, values);
439         return this;
440      }
441
442      @Override /* Overridden from Builder */
443      public Builder disableBeansRequireSomeProperties() {
444         super.disableBeansRequireSomeProperties();
445         return this;
446      }
447
448      @Override /* Overridden from Builder */
449      public Builder disableIgnoreMissingSetters() {
450         super.disableIgnoreMissingSetters();
451         return this;
452      }
453
454      @Override /* Overridden from Builder */
455      public Builder disableIgnoreTransientFields() {
456         super.disableIgnoreTransientFields();
457         return this;
458      }
459
460      @Override /* Overridden from Builder */
461      public Builder disableIgnoreUnknownNullBeanProperties() {
462         super.disableIgnoreUnknownNullBeanProperties();
463         return this;
464      }
465
466      @Override /* Overridden from Builder */
467      public Builder disableInterfaceProxies() {
468         super.disableInterfaceProxies();
469         return this;
470      }
471
472      @Override /* Overridden from Builder */
473      public <T> Builder example(Class<T> pojoClass, T o) {
474         super.example(pojoClass, o);
475         return this;
476      }
477
478      @Override /* Overridden from Builder */
479      public <T> Builder example(Class<T> pojoClass, String json) {
480         super.example(pojoClass, json);
481         return this;
482      }
483
484      @Override /* Overridden from Builder */
485      public Builder findFluentSetters() {
486         super.findFluentSetters();
487         return this;
488      }
489
490      @Override /* Overridden from Builder */
491      public Builder findFluentSetters(Class<?> on) {
492         super.findFluentSetters(on);
493         return this;
494      }
495
496      @Override /* Overridden from Builder */
497      public Builder ignoreInvocationExceptionsOnGetters() {
498         super.ignoreInvocationExceptionsOnGetters();
499         return this;
500      }
501
502      @Override /* Overridden from Builder */
503      public Builder ignoreInvocationExceptionsOnSetters() {
504         super.ignoreInvocationExceptionsOnSetters();
505         return this;
506      }
507
508      @Override /* Overridden from Builder */
509      public Builder ignoreUnknownBeanProperties() {
510         super.ignoreUnknownBeanProperties();
511         return this;
512      }
513
514      @Override /* Overridden from Builder */
515      public Builder ignoreUnknownEnumValues() {
516         super.ignoreUnknownEnumValues();
517         return this;
518      }
519
520      @Override /* Overridden from Builder */
521      public Builder implClass(Class<?> interfaceClass, Class<?> implClass) {
522         super.implClass(interfaceClass, implClass);
523         return this;
524      }
525
526      @Override /* Overridden from Builder */
527      public Builder implClasses(Map<Class<?>,Class<?>> values) {
528         super.implClasses(values);
529         return this;
530      }
531
532      @Override /* Overridden from Builder */
533      public Builder interfaceClass(Class<?> on, Class<?> value) {
534         super.interfaceClass(on, value);
535         return this;
536      }
537
538      @Override /* Overridden from Builder */
539      public Builder interfaces(java.lang.Class<?>...value) {
540         super.interfaces(value);
541         return this;
542      }
543
544      @Override /* Overridden from Builder */
545      public Builder locale(Locale value) {
546         super.locale(value);
547         return this;
548      }
549
550      @Override /* Overridden from Builder */
551      public Builder mediaType(MediaType value) {
552         super.mediaType(value);
553         return this;
554      }
555
556      @Override /* Overridden from Builder */
557      public Builder notBeanClasses(java.lang.Class<?>...values) {
558         super.notBeanClasses(values);
559         return this;
560      }
561
562      @Override /* Overridden from Builder */
563      public Builder notBeanPackages(String...values) {
564         super.notBeanPackages(values);
565         return this;
566      }
567
568      @Override /* Overridden from Builder */
569      public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) {
570         super.propertyNamer(value);
571         return this;
572      }
573
574      @Override /* Overridden from Builder */
575      public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) {
576         super.propertyNamer(on, value);
577         return this;
578      }
579
580      @Override /* Overridden from Builder */
581      public Builder sortProperties() {
582         super.sortProperties();
583         return this;
584      }
585
586      @Override /* Overridden from Builder */
587      public Builder sortProperties(java.lang.Class<?>...on) {
588         super.sortProperties(on);
589         return this;
590      }
591
592      @Override /* Overridden from Builder */
593      public Builder stopClass(Class<?> on, Class<?> value) {
594         super.stopClass(on, value);
595         return this;
596      }
597
598      @Override /* Overridden from Builder */
599      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) {
600         super.swap(normalClass, swappedClass, swapFunction);
601         return this;
602      }
603
604      @Override /* Overridden from Builder */
605      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) {
606         super.swap(normalClass, swappedClass, swapFunction, unswapFunction);
607         return this;
608      }
609
610      @Override /* Overridden from Builder */
611      public Builder swaps(Object...values) {
612         super.swaps(values);
613         return this;
614      }
615
616      @Override /* Overridden from Builder */
617      public Builder swaps(Class<?>...values) {
618         super.swaps(values);
619         return this;
620      }
621
622      @Override /* Overridden from Builder */
623      public Builder timeZone(TimeZone value) {
624         super.timeZone(value);
625         return this;
626      }
627
628      @Override /* Overridden from Builder */
629      public Builder typeName(Class<?> on, String value) {
630         super.typeName(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 typePropertyName(Class<?> on, String value) {
642         super.typePropertyName(on, value);
643         return this;
644      }
645
646      @Override /* Overridden from Builder */
647      public Builder useEnumNames() {
648         super.useEnumNames();
649         return this;
650      }
651
652      @Override /* Overridden from Builder */
653      public Builder useJavaBeanIntrospector() {
654         super.useJavaBeanIntrospector();
655         return this;
656      }
657
658      @Override /* Overridden from Builder */
659      public Builder detectRecursions() {
660         super.detectRecursions();
661         return this;
662      }
663
664      @Override /* Overridden from Builder */
665      public Builder detectRecursions(boolean value) {
666         super.detectRecursions(value);
667         return this;
668      }
669
670      @Override /* Overridden from Builder */
671      public Builder ignoreRecursions() {
672         super.ignoreRecursions();
673         return this;
674      }
675
676      @Override /* Overridden from Builder */
677      public Builder ignoreRecursions(boolean value) {
678         super.ignoreRecursions(value);
679         return this;
680      }
681
682      @Override /* Overridden from Builder */
683      public Builder initialDepth(int value) {
684         super.initialDepth(value);
685         return this;
686      }
687
688      @Override /* Overridden from Builder */
689      public Builder maxDepth(int value) {
690         super.maxDepth(value);
691         return this;
692      }
693
694      @Override /* Overridden from Builder */
695      public Builder accept(String value) {
696         super.accept(value);
697         return this;
698      }
699
700      @Override /* Overridden from Builder */
701      public Builder addBeanTypes() {
702         super.addBeanTypes();
703         return this;
704      }
705
706      @Override /* Overridden from Builder */
707      public Builder addBeanTypes(boolean value) {
708         super.addBeanTypes(value);
709         return this;
710      }
711
712      @Override /* Overridden from Builder */
713      public Builder addRootType() {
714         super.addRootType();
715         return this;
716      }
717
718      @Override /* Overridden from Builder */
719      public Builder addRootType(boolean value) {
720         super.addRootType(value);
721         return this;
722      }
723
724      @Override /* Overridden from Builder */
725      public Builder keepNullProperties() {
726         super.keepNullProperties();
727         return this;
728      }
729
730      @Override /* Overridden from Builder */
731      public Builder keepNullProperties(boolean value) {
732         super.keepNullProperties(value);
733         return this;
734      }
735
736      @Override /* Overridden from Builder */
737      public Builder listener(Class<? extends org.apache.juneau.serializer.SerializerListener> value) {
738         super.listener(value);
739         return this;
740      }
741
742      @Override /* Overridden from Builder */
743      public Builder produces(String value) {
744         super.produces(value);
745         return this;
746      }
747
748      @Override /* Overridden from Builder */
749      public Builder sortCollections() {
750         super.sortCollections();
751         return this;
752      }
753
754      @Override /* Overridden from Builder */
755      public Builder sortCollections(boolean value) {
756         super.sortCollections(value);
757         return this;
758      }
759
760      @Override /* Overridden from Builder */
761      public Builder sortMaps() {
762         super.sortMaps();
763         return this;
764      }
765
766      @Override /* Overridden from Builder */
767      public Builder sortMaps(boolean value) {
768         super.sortMaps(value);
769         return this;
770      }
771
772      @Override /* Overridden from Builder */
773      public Builder trimEmptyCollections() {
774         super.trimEmptyCollections();
775         return this;
776      }
777
778      @Override /* Overridden from Builder */
779      public Builder trimEmptyCollections(boolean value) {
780         super.trimEmptyCollections(value);
781         return this;
782      }
783
784      @Override /* Overridden from Builder */
785      public Builder trimEmptyMaps() {
786         super.trimEmptyMaps();
787         return this;
788      }
789
790      @Override /* Overridden from Builder */
791      public Builder trimEmptyMaps(boolean value) {
792         super.trimEmptyMaps(value);
793         return this;
794      }
795
796      @Override /* Overridden from Builder */
797      public Builder trimStrings() {
798         super.trimStrings();
799         return this;
800      }
801
802      @Override /* Overridden from Builder */
803      public Builder trimStrings(boolean value) {
804         super.trimStrings(value);
805         return this;
806      }
807
808      @Override /* Overridden from Builder */
809      public Builder uriContext(UriContext value) {
810         super.uriContext(value);
811         return this;
812      }
813
814      @Override /* Overridden from Builder */
815      public Builder uriRelativity(UriRelativity value) {
816         super.uriRelativity(value);
817         return this;
818      }
819
820      @Override /* Overridden from Builder */
821      public Builder uriResolution(UriResolution value) {
822         super.uriResolution(value);
823         return this;
824      }
825
826      @Override /* Overridden from Builder */
827      public Builder fileCharset(Charset value) {
828         super.fileCharset(value);
829         return this;
830      }
831
832      @Override /* Overridden from Builder */
833      public Builder maxIndent(int value) {
834         super.maxIndent(value);
835         return this;
836      }
837
838      @Override /* Overridden from Builder */
839      public Builder quoteChar(char value) {
840         super.quoteChar(value);
841         return this;
842      }
843
844      @Override /* Overridden from Builder */
845      public Builder quoteCharOverride(char value) {
846         super.quoteCharOverride(value);
847         return this;
848      }
849
850      @Override /* Overridden from Builder */
851      public Builder sq() {
852         super.sq();
853         return this;
854      }
855
856      @Override /* Overridden from Builder */
857      public Builder streamCharset(Charset value) {
858         super.streamCharset(value);
859         return this;
860      }
861
862      @Override /* Overridden from Builder */
863      public Builder useWhitespace() {
864         super.useWhitespace();
865         return this;
866      }
867
868      @Override /* Overridden from Builder */
869      public Builder useWhitespace(boolean value) {
870         super.useWhitespace(value);
871         return this;
872      }
873
874      @Override /* Overridden from Builder */
875      public Builder ws() {
876         super.ws();
877         return this;
878      }
879
880      @Override /* Overridden from Builder */
881      public Builder addBeanTypesUon() {
882         super.addBeanTypesUon();
883         return this;
884      }
885
886      @Override /* Overridden from Builder */
887      public Builder addBeanTypesUon(boolean value) {
888         super.addBeanTypesUon(value);
889         return this;
890      }
891
892      @Override /* Overridden from Builder */
893      public Builder encoding() {
894         super.encoding();
895         return this;
896      }
897
898      @Override /* Overridden from Builder */
899      public Builder paramFormat(ParamFormat value) {
900         super.paramFormat(value);
901         return this;
902      }
903
904      @Override /* Overridden from Builder */
905      public Builder paramFormatPlain() {
906         super.paramFormatPlain();
907         return this;
908      }
909
910      @Override /* Overridden from Builder */
911      public Builder quoteCharUon(char value) {
912         super.quoteCharUon(value);
913         return this;
914      }
915   }
916
917   //-------------------------------------------------------------------------------------------------------------------
918   // Instance
919   //-------------------------------------------------------------------------------------------------------------------
920
921   final HttpPartFormat format;
922   final HttpPartCollectionFormat collectionFormat;
923
924   private final Map<ClassMeta<?>,OpenApiClassMeta> openApiClassMetas = new ConcurrentHashMap<>();
925   private final Map<BeanPropertyMeta,OpenApiBeanPropertyMeta> openApiBeanPropertyMetas = new ConcurrentHashMap<>();
926
927   /**
928    * Constructor.
929    *
930    * @param builder
931    *    The builder for this object.
932    */
933   public OpenApiSerializer(Builder builder) {
934      super(builder.encoding(false));
935      format = builder.format;
936      collectionFormat = builder.collectionFormat;
937   }
938
939   @Override /* Context */
940   public Builder copy() {
941      return new Builder(this);
942   }
943
944   @Override /* Context */
945   public OpenApiSerializerSession.Builder createSession() {
946      return OpenApiSerializerSession.create(this);
947   }
948
949   @Override /* Context */
950   public OpenApiSerializerSession getSession() {
951      return createSession().build();
952   }
953
954   @Override /* HttpPartSerializer */
955   public OpenApiSerializerSession getPartSession() {
956      return OpenApiSerializerSession.create(this).build();
957   }
958
959   //-----------------------------------------------------------------------------------------------------------------
960   // Extended metadata
961   //-----------------------------------------------------------------------------------------------------------------
962
963   @Override /* OpenApiMetaProvider */
964   public OpenApiClassMeta getOpenApiClassMeta(ClassMeta<?> cm) {
965      OpenApiClassMeta m = openApiClassMetas.get(cm);
966      if (m == null) {
967         m = new OpenApiClassMeta(cm, this);
968         openApiClassMetas.put(cm, m);
969      }
970      return m;
971   }
972
973   @Override /* OpenApiMetaProvider */
974   public OpenApiBeanPropertyMeta getOpenApiBeanPropertyMeta(BeanPropertyMeta bpm) {
975      if (bpm == null)
976         return OpenApiBeanPropertyMeta.DEFAULT;
977      OpenApiBeanPropertyMeta m = openApiBeanPropertyMetas.get(bpm);
978      if (m == null) {
979         m = new OpenApiBeanPropertyMeta(bpm.getDelegateFor(), this);
980         openApiBeanPropertyMetas.put(bpm, m);
981      }
982      return m;
983   }
984
985   //-----------------------------------------------------------------------------------------------------------------
986   // Properties
987   //-----------------------------------------------------------------------------------------------------------------
988
989   /**
990    * Returns the default format to use when not otherwise specified via {@link Schema#format()}
991    *
992    * @return The default format to use when not otherwise specified via {@link Schema#format()}
993    */
994   protected final HttpPartFormat getFormat() {
995      return format;
996   }
997
998   /**
999    * Returns the default collection format to use when not otherwise specified via {@link Schema#collectionFormat()}
1000    *
1001    * @return The default collection format to use when not otherwise specified via {@link Schema#collectionFormat()}
1002    */
1003   protected final HttpPartCollectionFormat getCollectionFormat() {
1004      return collectionFormat;
1005   }
1006}