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