001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.dto.swagger;
014
015import static org.apache.juneau.internal.ArrayUtils.*;
016import static org.apache.juneau.internal.StringUtils.*;
017import static org.apache.juneau.internal.ConverterUtils.*;
018import static org.apache.juneau.internal.CollectionUtils.*;
019
020import java.util.*;
021
022import org.apache.juneau.*;
023import org.apache.juneau.annotation.*;
024import org.apache.juneau.collections.*;
025import org.apache.juneau.internal.*;
026
027/**
028 * Describes a single HTTP header.
029 *
030 * <h5 class='section'>Example:</h5>
031 * <p class='bcode w800'>
032 *    <jc>// Construct using SwaggerBuilder.</jc>
033 *    HeaderInfo x = <jsm>headerInfo</jsm>(<js>"integer"</js>).description(<js>"The number of allowed requests in the current period"</js>);
034 *
035 *    <jc>// Serialize using JsonSerializer.</jc>
036 *    String json = JsonSerializer.<jsf>DEFAULT</jsf>.toString(x);
037 *
038 *    <jc>// Or just use toString() which does the same as above.</jc>
039 *    String json = x.toString();
040 * </p>
041 * <p class='bcode w800'>
042 *    <jc>// Output</jc>
043 *    {
044 *       <js>"description"</js>: <js>"The number of allowed requests in the current period"</js>,
045 *       <js>"type"</js>: <js>"integer"</js>
046 *    }
047 * </p>
048 *
049 * <ul class='seealso'>
050 *    <li class='link'>{@doc DtoSwagger}
051 * </ul>
052 */
053@Bean(bpi="description,type,format,items,collectionFormat,default,maximum,exclusiveMaximum,minimum,exclusiveMinimum,maxLength,minLength,pattern,maxItems,minItems,uniqueItems,enum,multipleOf,$ref,x-example,*")
054@SuppressWarnings({"unchecked"})
055public class HeaderInfo extends SwaggerElement {
056
057   private static final String[] VALID_TYPES = {"string", "number", "integer", "boolean", "array"};
058   private static final String[] VALID_COLLECTION_FORMATS = {"csv","ssv","tsv","pipes","multi"};
059
060   private String
061      description,
062      type,
063      format,
064      collectionFormat,
065      pattern,
066      ref;
067   private Number
068      maximum,
069      minimum,
070      multipleOf;
071   private Integer
072      maxLength,
073      minLength,
074      maxItems,
075      minItems;
076   private Boolean
077      exclusiveMaximum,
078      exclusiveMinimum,
079      uniqueItems;
080   private Items items;
081   private Object _default;
082   private List<Object> _enum;
083   private Object example;
084
085   /**
086    * Default constructor.
087    */
088   public HeaderInfo() {}
089
090   /**
091    * Copy constructor.
092    *
093    * @param copyFrom The object to copy.
094    */
095   public HeaderInfo(HeaderInfo copyFrom) {
096      super(copyFrom);
097
098      this.description = copyFrom.description;
099      this.type = copyFrom.type;
100      this.format = copyFrom.format;
101      this.collectionFormat = copyFrom.collectionFormat;
102      this.pattern = copyFrom.pattern;
103      this.maximum = copyFrom.maximum;
104      this.minimum = copyFrom.minimum;
105      this.multipleOf = copyFrom.multipleOf;
106      this.maxLength = copyFrom.maxLength;
107      this.minLength = copyFrom.minLength;
108      this.maxItems = copyFrom.maxItems;
109      this.minItems = copyFrom.minItems;
110      this.exclusiveMaximum = copyFrom.exclusiveMaximum;
111      this.exclusiveMinimum = copyFrom.exclusiveMinimum;
112      this.uniqueItems = copyFrom.uniqueItems;
113      this._default = copyFrom._default;
114      this.items = copyFrom.items == null ? null : copyFrom.items.copy();
115      this._enum = newList(copyFrom._enum);
116      this.example = copyFrom.example;
117   }
118
119   /**
120    * Make a deep copy of this object.
121    *
122    * @return A deep copy of this object.
123    */
124   public HeaderInfo copy() {
125      return new HeaderInfo(this);
126   }
127
128   @Override /* SwaggerElement */
129   protected HeaderInfo strict() {
130      super.strict();
131      return this;
132   }
133
134   /**
135    * Bean property getter:  <property>description</property>.
136    *
137    * <p>
138    * A short description of the header.
139    *
140    * @return The property value, or <jk>null</jk> if it is not set.
141    */
142   public String getDescription() {
143      return description;
144   }
145
146   /**
147    * Bean property setter:  <property>description</property>.
148    *
149    * <p>
150    * A short description of the header.
151    *
152    * @param value
153    *    The new value for this property.
154    *    <br>Can be <jk>null</jk> to unset the property.
155    * @return This object (for method chaining).
156    */
157   public HeaderInfo setDescription(String value) {
158      description = value;
159      return this;
160   }
161
162   /**
163    * Same as {@link #setDescription(String)}.
164    *
165    * @param value
166    *    The new value for this property.
167    *    <br>Non-String values will be converted to String using <c>toString()</c>.
168    *    <br>Can be <jk>null</jk> to unset the property.
169    * @return This object (for method chaining).
170    */
171   public HeaderInfo description(Object value) {
172      return setDescription(stringify(value));
173   }
174
175   /**
176    * Bean property getter:  <property>type</property>.
177    *
178    * <p>
179    * The type of the object.
180    *
181    * @return The property value, or <jk>null</jk> if it is not set.
182    */
183   public String getType() {
184      return type;
185   }
186
187   /**
188    * Bean property setter:  <property>type</property>.
189    *
190    * <p>
191    * The type of the object.
192    *
193    * <ul class='seealso'>
194    *    <li class='extlink'>{@doc ExtSwaggerDataTypes}
195    * </ul>
196    *
197    * @param value
198    *    The new value for this property.
199    *    <br>Property value is required.
200    *    <br>Valid values:
201    *    <ul>
202    *       <li><js>"string"</js>
203    *       <li><js>"number"</js>
204    *       <li><js>"integer"</js>
205    *       <li><js>"boolean"</js>
206    *       <li><js>"array"</js>
207    *    </ul>
208    * @return This object (for method chaining).
209    */
210   public HeaderInfo setType(String value) {
211      if (isStrict() && ! contains(value, VALID_TYPES))
212         throw new BasicRuntimeException(
213            "Invalid value passed in to setType(String).  Value=''{0}'', valid values={1}",
214            value, VALID_TYPES
215         );
216      type = value;
217      return this;
218   }
219
220   /**
221    * Same as {@link #setType(String)}.
222    *
223    * @param value
224    *    The new value for this property.
225    *    <br>Non-String values will be converted to String using <c>toString()</c>.
226    *    <br>Can be <jk>null</jk> to unset the property.
227    * @return This object (for method chaining).
228    */
229   public HeaderInfo type(Object value) {
230      return setType(stringify(value));
231   }
232
233   /**
234    * Bean property getter:  <property>format</property>.
235    *
236    * <p>
237    * The extending format for the previously mentioned <c>type</c>.
238    *
239    * <ul class='seealso'>
240    *    <li class='extlink'>{@doc ExtSwaggerDataTypeFormats}
241    * </ul>
242    *
243    * @return The property value, or <jk>null</jk> if it is not set.
244    */
245   public String getFormat() {
246      return format;
247   }
248
249   /**
250    * Bean property setter:  <property>format</property>.
251    *
252    * <p>
253    * The extending format for the previously mentioned <c>type</c>.
254    *
255    * <ul class='seealso'>
256    *    <li class='extlink'>{@doc ExtSwaggerDataTypes}
257    * </ul>
258    *
259    * @param value
260    *    The new value for this property.
261    *    <br>Can be <jk>null</jk> to unset the property.
262    * @return This object (for method chaining).
263    */
264   public HeaderInfo setFormat(String value) {
265      format = value;
266      return this;
267   }
268
269   /**
270    * Same as {@link #setFormat(String)}.
271    *
272    * @param value
273    *    The new value for this property.
274    *    <br>Non-String values will be converted to String using <c>toString()</c>.
275    *    <br>Can be <jk>null</jk> to unset the property.
276    * @return This object (for method chaining).
277    */
278   public HeaderInfo format(Object value) {
279      return setFormat(stringify(value));
280   }
281
282   /**
283    * Bean property getter:  <property>items</property>.
284    *
285    * <p>
286    * Describes the type of items in the array.
287    *
288    * @return The property value, or <jk>null</jk> if it is not set.
289    */
290   public Items getItems() {
291      return items;
292   }
293
294   /**
295    * Bean property setter:  <property>items</property>.
296    *
297    * <p>
298    * Describes the type of items in the array.
299    *
300    * @param value
301    *    The new value for this property.
302    *    <br>Property value is required if <c>type</c> is <js>"array"</js>.
303    *    <br>Can be <jk>null</jk> to unset the property.
304    * @return This object (for method chaining).
305    */
306   public HeaderInfo setItems(Items value) {
307      items = value;
308      return this;
309   }
310
311   /**
312    * Same as {@link #setItems(Items)}.
313    *
314    * @param value
315    *    The new value for this property.
316    *    <br>Valid types:
317    *    <ul>
318    *       <li>{@link Items}
319    *       <li><c>String</c> - JSON object representation of {@link Items}
320    *          <p class='bcode w800'>
321    *    <jc>// Example </jc>
322    *    items(<js>"{type:'type',format:'format',...}"</js>);
323    *          </p>
324    *    </ul>
325    *    <br>Can be <jk>null</jk> to unset the property.
326    * @return This object (for method chaining).
327    */
328   public HeaderInfo items(Object value) {
329      return setItems(toType(value, Items.class));
330   }
331
332   /**
333    * Bean property getter:  <property>collectionFormat</property>.
334    *
335    * <p>
336    * Determines the format of the array if type array is used.
337    *
338    * @return The property value, or <jk>null</jk> if it is not set.
339    */
340   public String getCollectionFormat() {
341      return collectionFormat;
342   }
343
344   /**
345    * Bean property setter:  <property>collectionFormat</property>.
346    *
347    * <p>
348    * Determines the format of the array if type array is used.
349    *
350    * @param value
351    *    The new value for this property.
352    *    <br>Valid values:
353    *    <ul>
354    *       <li><js>"csv"</js> (default) - comma separated values <c>foo,bar</c>.
355    *       <li><js>"ssv"</js> - space separated values <c>foo bar</c>.
356    *       <li><js>"tsv"</js> - tab separated values <c>foo\tbar</c>.
357    *       <li><js>"pipes"</js> - pipe separated values <c>foo|bar</c>.
358    *    </ul>
359    * @return This object (for method chaining).
360    */
361   public HeaderInfo setCollectionFormat(String value) {
362      if (isStrict() && ! contains(value, VALID_COLLECTION_FORMATS))
363         throw new BasicRuntimeException(
364            "Invalid value passed in to setCollectionFormat(String).  Value=''{0}'', valid values={1}",
365            value, VALID_COLLECTION_FORMATS
366         );
367      collectionFormat = value;
368      return this;
369   }
370
371   /**
372    * Same as {@link #setCollectionFormat(String)}.
373    *
374    * @param value
375    *    The new value for this property.
376    *    <br>Non-String values will be converted to String using <c>toString()</c>.
377    *    <br>Can be <jk>null</jk> to unset the property.
378    * @return This object (for method chaining).
379    */
380   public HeaderInfo collectionFormat(Object value) {
381      return setCollectionFormat(stringify(value));
382   }
383
384   /**
385    * Bean property getter:  <property>default</property>.
386    *
387    * <p>
388    * Declares the value of the header that the server will use if none is provided.
389    *
390    * <ul class='notes'>
391    *    <li>
392    *       <js>"default"</js> has no meaning for required items.
393    *    <li>
394    *       Unlike JSON Schema this value MUST conform to the defined <c>type</c> for the header.
395    * </ul>
396    *
397    * <ul class='seealso'>
398    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
399    * </ul>
400    *
401    * @return The property value, or <jk>null</jk> if it is not set.
402    */
403   public Object getDefault() {
404      return _default;
405   }
406
407   /**
408    * Bean property setter:  <property>default</property>.
409    *
410    * <p>
411    * Declares the value of the header that the server will use if none is provided.
412    *
413    * <ul class='notes'>
414    *    <li>
415    *       <js>"default"</js> has no meaning for required items.
416    *    <li>
417    *       Unlike JSON Schema this value MUST conform to the defined <c>type</c> for the header.
418    * </ul>
419    *
420    * <ul class='seealso'>
421    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
422    * </ul>
423    *
424    * @param value
425    *    The new value for this property.
426    *    <br>Can be <jk>null</jk> to unset the property.
427    * @return This object (for method chaining).
428    */
429   public HeaderInfo setDefault(Object value) {
430      _default = value;
431      return this;
432   }
433
434   /**
435    * Same as {@link #setDefault(Object)}.
436    *
437    * @param value The new value for this property.
438    * @return This object (for method chaining).
439    */
440   public HeaderInfo _default(Object value) {
441      return setDefault(value);
442   }
443
444   /**
445    * Bean property getter:  <property>maximum</property>.
446    *
447    * <ul class='seealso'>
448    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
449    * </ul>
450    *
451    * @return The property value, or <jk>null</jk> if it is not set.
452    */
453   public Number getMaximum() {
454      return maximum;
455   }
456
457   /**
458    * Bean property setter:  <property>maximum</property>.
459    *
460    * <ul class='seealso'>
461    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
462    * </ul>
463    *
464    * @param value
465    *    The new value for this property.
466    *    <br>Can be <jk>null</jk> to unset the property.
467    * @return This object (for method chaining).
468    */
469   public HeaderInfo setMaximum(Number value) {
470      maximum = value;
471      return this;
472   }
473
474   /**
475    * Same as {@link #setMaximum(Number)}.
476    *
477    * @param value
478    *    The new value for this property.
479    *    <br>Non-Number values will be converted to Number using <c>toString()</c> then best number match.
480    *    <br>Can be <jk>null</jk> to unset the property.
481    * @return This object (for method chaining).
482    */
483   public HeaderInfo maximum(Object value) {
484      return setMaximum(toNumber(value));
485   }
486
487   /**
488    * Bean property getter:  <property>exclusiveMaximum</property>.
489    *
490    * <ul class='seealso'>
491    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
492    * </ul>
493    *
494    * @return The property value, or <jk>null</jk> if it is not set.
495    */
496   public Boolean getExclusiveMaximum() {
497      return exclusiveMaximum;
498   }
499
500   /**
501    * Bean property setter:  <property>exclusiveMaximum</property>.
502    *
503    * <ul class='seealso'>
504    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
505    * </ul>
506    *
507    * @param value
508    *    The new value for this property.
509    *    <br>Can be <jk>null</jk> to unset the property.
510    * @return This object (for method chaining).
511    */
512   public HeaderInfo setExclusiveMaximum(Boolean value) {
513      exclusiveMaximum = value;
514      return this;
515   }
516
517   /**
518    * Same as {@link #setExclusiveMaximum(Boolean)}.
519    *
520    * @param value
521    *    The new value for this property.
522    *    <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>.
523    *    <br>Can be <jk>null</jk> to unset the property.
524    * @return This object (for method chaining).
525    */
526   public HeaderInfo exclusiveMaximum(Object value) {
527      return setExclusiveMaximum(toBoolean(value));
528   }
529
530   /**
531    * Bean property getter:  <property>minimum</property>.
532    *
533    * <ul class='seealso'>
534    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
535    * </ul>
536    *
537    * @return The property value, or <jk>null</jk> if it is not set.
538    */
539   public Number getMinimum() {
540      return minimum;
541   }
542
543   /**
544    * Bean property setter:  <property>minimum</property>.
545    *
546    * <ul class='seealso'>
547    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
548    * </ul>
549    *
550    * @param value
551    *    The new value for this property.
552    *    <br>Can be <jk>null</jk> to unset the property.
553    * @return This object (for method chaining).
554    */
555   public HeaderInfo setMinimum(Number value) {
556      minimum = value;
557      return this;
558   }
559
560   /**
561    * Same as {@link #setMinimum(Number)}.
562    *
563    * @param value
564    *    The new value for this property.
565    *    <br>Non-Number values will be converted to Number using <c>toString()</c> then best number match.
566    *    <br>Can be <jk>null</jk> to unset the property.
567    * @return This object (for method chaining).
568    */
569   public HeaderInfo minimum(Object value) {
570      return setMinimum(toNumber(value));
571   }
572
573   /**
574    * Bean property getter:  <property>exclusiveMinimum</property>.
575    *
576    * <ul class='seealso'>
577    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
578    * </ul>
579    *
580    * @return The property value, or <jk>null</jk> if it is not set.
581    */
582   public Boolean getExclusiveMinimum() {
583      return exclusiveMinimum;
584   }
585
586   /**
587    * Bean property setter:  <property>exclusiveMinimum</property>.
588    *
589    * <ul class='seealso'>
590    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
591    * </ul>
592    *
593    * @param value
594    *    The new value for this property.
595    *    <br>Can be <jk>null</jk> to unset the property.
596    * @return This object (for method chaining).
597    */
598   public HeaderInfo setExclusiveMinimum(Boolean value) {
599      exclusiveMinimum = value;
600      return this;
601   }
602
603   /**
604    * Same as {@link #setExclusiveMinimum(Boolean)}.
605    *
606    * @param value
607    *    The new value for this property.
608    *    <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>.
609    *    <br>Can be <jk>null</jk> to unset the property.
610    * @return This object (for method chaining).
611    */
612   public HeaderInfo exclusiveMinimum(Object value) {
613      return setExclusiveMinimum(toBoolean(value));
614   }
615
616   /**
617    * Bean property getter:  <property>maxLength</property>.
618    *
619    * <ul class='seealso'>
620    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
621    * </ul>
622    *
623    * @return The property value, or <jk>null</jk> if it is not set.
624    */
625   public Integer getMaxLength() {
626      return maxLength;
627   }
628
629   /**
630    * Bean property setter:  <property>maxLength</property>.
631    *
632    * <ul class='seealso'>
633    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
634    * </ul>
635    *
636    * @param value
637    *    The new value for this property.
638    *    <br>Can be <jk>null</jk> to unset the property.
639    * @return This object (for method chaining).
640    */
641   public HeaderInfo setMaxLength(Integer value) {
642      maxLength = value;
643      return this;
644   }
645
646   /**
647    * Same as {@link #setMaxLength(Integer)}.
648    *
649    * @param value
650    *    The new value for this property.
651    *    <br>Non-Integer values will be converted to Integer using <code>Integer.<jsm>valueOf</jsm>(value.toString())</code>.
652    *    <br>Can be <jk>null</jk> to unset the property.
653    * @return This object (for method chaining).
654    */
655   public HeaderInfo maxLength(Object value) {
656      return setMaxLength(toInteger(value));
657   }
658
659   /**
660    * Bean property getter:  <property>minLength</property>.
661    *
662    * <ul class='seealso'>
663    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
664    * </ul>
665    *
666    * @return The property value, or <jk>null</jk> if it is not set.
667    */
668   public Integer getMinLength() {
669      return minLength;
670   }
671
672   /**
673    * Bean property setter:  <property>minLength</property>.
674    *
675    * <ul class='seealso'>
676    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
677    * </ul>
678    *
679    * @param value
680    *    The new value for this property.
681    *    <br>Can be <jk>null</jk> to unset the property.
682    * @return This object (for method chaining).
683    */
684   public HeaderInfo setMinLength(Integer value) {
685      minLength = value;
686      return this;
687   }
688
689   /**
690    * Same as {@link #setMinLength(Integer)}.
691    *
692    * @param value
693    *    The new value for this property.
694    *    <br>Non-Integer values will be converted to Integer using <code>Integer.<jsm>valueOf</jsm>(value.toString())</code>.
695    *    <br>Can be <jk>null</jk> to unset the property.
696    * @return This object (for method chaining).
697    */
698   public HeaderInfo minLength(Object value) {
699      return setMinLength(toInteger(value));
700   }
701
702   /**
703    * Bean property getter:  <property>pattern</property>.
704    *
705    * <ul class='seealso'>
706    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
707    * </ul>
708    *
709    * @return The property value, or <jk>null</jk> if it is not set.
710    */
711   public String getPattern() {
712      return pattern;
713   }
714
715   /**
716    * Bean property setter:  <property>pattern</property>.
717    *
718    * <p>
719    * This string SHOULD be a valid regular expression.
720    *
721    * <ul class='seealso'>
722    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
723    * </ul>
724    *
725    * @param value
726    *    The new value for this property.
727    *    <br>Can be <jk>null</jk> to unset the property.
728    * @return This object (for method chaining).
729    */
730   public HeaderInfo setPattern(String value) {
731      pattern = value;
732      return this;
733   }
734
735   /**
736    * Same as {@link #setPattern(String)}.
737    *
738    * @param value
739    *    The new value for this property.
740    *    <br>Non-String values will be converted to String using <c>toString()</c>.
741    *    <br>Can be <jk>null</jk> to unset the property.
742    * @return This object (for method chaining).
743    */
744   public HeaderInfo pattern(Object value) {
745      return setPattern(stringify(value));
746   }
747
748   /**
749    * Bean property getter:  <property>maxItems</property>.
750    *
751    * <ul class='seealso'>
752    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
753    * </ul>
754    *
755    * @return The property value, or <jk>null</jk> if it is not set.
756    */
757   public Integer getMaxItems() {
758      return maxItems;
759   }
760
761   /**
762    * Bean property setter:  <property>maxItems</property>.
763    *
764    * <ul class='seealso'>
765    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
766    * </ul>
767    *
768    * @param value
769    *    The new value for this property.
770    *    <br>Can be <jk>null</jk> to unset the property.
771    * @return This object (for method chaining).
772    */
773   public HeaderInfo setMaxItems(Integer value) {
774      maxItems = value;
775      return this;
776   }
777
778   /**
779    * Same as {@link #setMaxItems(Integer)}.
780    *
781    * @param value
782    *    The new value for this property.
783    *    <br>Non-Integer values will be converted to Integer using <code>Integer.<jsm>valueOf</jsm>(value.toString())</code>.
784    *    <br>Can be <jk>null</jk> to unset the property.
785    * @return This object (for method chaining).
786    */
787   public HeaderInfo maxItems(Object value) {
788      return setMaxItems(toInteger(value));
789   }
790
791   /**
792    * Bean property getter:  <property>minItems</property>.
793    *
794    * <ul class='seealso'>
795    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
796    * </ul>
797    *
798    * @return The property value, or <jk>null</jk> if it is not set.
799    */
800   public Integer getMinItems() {
801      return minItems;
802   }
803
804   /**
805    * Bean property setter:  <property>minItems</property>.
806    *
807    * <ul class='seealso'>
808    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
809    * </ul>
810    *
811    * @param value
812    *    The new value for this property.
813    *    <br>Can be <jk>null</jk> to unset the property.
814    * @return This object (for method chaining).
815    */
816   public HeaderInfo setMinItems(Integer value) {
817      minItems = value;
818      return this;
819   }
820
821   /**
822    * Same as {@link #setMinItems(Integer)}.
823    *
824    * @param value
825    *    The new value for this property.
826    *    <br>Non-Integer values will be converted to Integer using <code>Integer.<jsm>valueOf</jsm>(value.toString())</code>.
827    *    <br>Can be <jk>null</jk> to unset the property.
828    * @return This object (for method chaining).
829    */
830   public HeaderInfo minItems(Object value) {
831      return setMinItems(toInteger(value));
832   }
833
834   /**
835    * Bean property getter:  <property>uniqueItems</property>.
836    *
837    * <ul class='seealso'>
838    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
839    * </ul>
840    *
841    * @return The property value, or <jk>null</jk> if it is not set.
842    */
843   public Boolean getUniqueItems() {
844      return uniqueItems;
845   }
846
847   /**
848    * Bean property setter:  <property>uniqueItems</property>.
849    *
850    * <ul class='seealso'>
851    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
852    * </ul>
853    *
854    * @param value
855    *    The new value for this property.
856    *    <br>Can be <jk>null</jk> to unset the property.
857    * @return This object (for method chaining).
858    */
859   public HeaderInfo setUniqueItems(Boolean value) {
860      uniqueItems = value;
861      return this;
862   }
863
864   /**
865    * Same as {@link #setUniqueItems(Boolean)}.
866    *
867    * @param value
868    *    The new value for this property.
869    *    <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>.
870    *    <br>Can be <jk>null</jk> to unset the property.
871    * @return This object (for method chaining).
872    */
873   public HeaderInfo uniqueItems(Object value) {
874      return setUniqueItems(toBoolean(value));
875   }
876
877   /**
878    * Bean property getter:  <property>enum</property>.
879    *
880    * <ul class='seealso'>
881    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
882    * </ul>
883    *
884    * @return The property value, or <jk>null</jk> if it is not set.
885    */
886   public List<Object> getEnum() {
887      return _enum;
888   }
889
890   /**
891    * Bean property setter:  <property>enum</property>.
892    *
893    * <ul class='seealso'>
894    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
895    * </ul>
896    *
897    * @param value
898    *    The new value for this property.
899    *    <br>Can be <jk>null</jk> to unset the property.
900    * @return This object (for method chaining).
901    */
902   public HeaderInfo setEnum(Collection<Object> value) {
903      _enum = newList(value);
904      return this;
905   }
906
907   /**
908    * Adds one or more values to the <property>enum</property> property.
909    *
910    * @param values
911    *    The values to add to this property.
912    *    <br>Ignored if <jk>null</jk>.
913    * @return This object (for method chaining).
914    */
915   public HeaderInfo addEnum(Collection<Object> values) {
916      _enum = addToList(_enum, values);
917      return this;
918   }
919
920   /**
921    * Adds one or more values to the <property>enum</property> property.
922    *
923    * @param values
924    *    The values to add to this property.
925    *    <br>Valid types:
926    *    <ul>
927    *       <li><c>Object</c>
928    *       <li><c>Collection&lt;Object&gt;</c>
929    *       <li><c>String</c> - JSON array representation of <c>Collection&lt;Object&gt;</c>.
930    *          <p class='bcode w800'>
931    *    <jc>// Example </jc>
932    *    _enum(<js>"['foo','bar']"</js>);
933    *          </p>
934    *       <li><c>String</c> - Individual values.
935    *          <p class='bcode w800'>
936    *    <jc>// Example </jc>
937    *    _enum(<js>"foo"</js>, <js>"bar"</js>);
938    *          </p>
939    *    </ul>
940    *    <br>Ignored if <jk>null</jk>.
941    * @return This object (for method chaining).
942    */
943   public HeaderInfo _enum(Object...values) {
944      _enum = addToList(_enum, values, Object.class);
945      return this;
946   }
947
948   /**
949    * Bean property getter:  <property>multipleOf</property>.
950    *
951    * <ul class='seealso'>
952    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
953    * </ul>
954    *
955    * @return The property value, or <jk>null</jk> if it is not set.
956    */
957   public Number getMultipleOf() {
958      return multipleOf;
959   }
960
961   /**
962    * Bean property setter:  <property>multipleOf</property>.
963    *
964    * <ul class='seealso'>
965    *    <li class='extlink'>{@doc ExtJsonSchemaValidation}
966    * </ul>
967    *
968    * @param value
969    *    The new value for this property.
970    *    <br>Can be <jk>null</jk> to unset the property.
971    * @return This object (for method chaining).
972    */
973   public HeaderInfo setMultipleOf(Number value) {
974      multipleOf = value;
975      return this;
976   }
977
978   /**
979    * Same as {@link #setMultipleOf(Number)}.
980    *
981    * @param value
982    *    The new value for this property.
983    *    <br>Non-Number values will be converted to Number using <c>toString()</c> then best number match.
984    *    <br>Can be <jk>null</jk> to unset the property.
985    * @return This object (for method chaining).
986    */
987   public HeaderInfo multipleOf(Object value) {
988      return setMultipleOf(toNumber(value));
989   }
990
991   /**
992    * Bean property getter:  <property>$ref</property>.
993    *
994    * @return The property value, or <jk>null</jk> if it is not set.
995    */
996   @Beanp("$ref")
997   public String getRef() {
998      return ref;
999   }
1000
1001   /**
1002    * Returns <jk>true</jk> if this object has a <js>"$ref"</js> attribute.
1003    *
1004    * @return <jk>true</jk> if this object has a <js>"$ref"</js> attribute.
1005    */
1006   public boolean hasRef() {
1007      return ref != null;
1008   }
1009
1010   /**
1011    * Bean property setter:  <property>$ref</property>.
1012    *
1013    * @param value
1014    *    The new value for this property.
1015    *    <br>Can be <jk>null</jk> to unset the property.
1016    * @return This object (for method chaining).
1017    */
1018   @Beanp("$ref")
1019   public HeaderInfo setRef(Object value) {
1020      ref = StringUtils.stringify(value);
1021      return this;
1022   }
1023
1024   /**
1025    * Same as {@link #setRef(Object)}.
1026    *
1027    * @param value
1028    *    The new value for this property.
1029    *    <br>Can be <jk>null</jk> to unset the property.
1030    * @return This object (for method chaining).
1031    */
1032   public HeaderInfo ref(Object value) {
1033      return setRef(value);
1034   }
1035
1036   /**
1037    * Bean property getter:  <property>x-example</property>.
1038    *
1039    * @return The property value, or <jk>null</jk> if it is not set.
1040    */
1041   @Beanp("x-example")
1042   public Object getExample() {
1043      return example;
1044   }
1045
1046   /**
1047    * Bean property setter:  <property>examples</property>.
1048    *
1049    * @param value
1050    *    The new value for this property.
1051    *    <br>Can be <jk>null</jk> to unset the property.
1052    * @return This object (for method chaining).
1053    */
1054   @Beanp("x-example")
1055   public HeaderInfo setExample(Object value) {
1056      example = value;
1057      return this;
1058   }
1059
1060   /**
1061    * Bean property setter:  <property>examples</property>.
1062    *
1063    * @param value
1064    *    The new value for this property.
1065    *    <br>Can be <jk>null</jk> to unset the property.
1066    * @return This object (for method chaining).
1067    */
1068   public HeaderInfo example(Object value) {
1069      example = value;
1070      return this;
1071   }
1072
1073   @Override /* SwaggerElement */
1074   public <T> T get(String property, Class<T> type) {
1075      if (property == null)
1076         return null;
1077      switch (property) {
1078         case "description": return (T)getDescription();
1079         case "type": return toType(getType(), type);
1080         case "format": return toType(getFormat(), type);
1081         case "items": return toType(getItems(), type);
1082         case "collectionFormat": return toType(getCollectionFormat(), type);
1083         case "$ref": return toType(getRef(), type);
1084         case "default": return toType(getDefault(), type);
1085         case "maximum": return toType(getMaximum(), type);
1086         case "exclusiveMaximum": return toType(getExclusiveMaximum(), type);
1087         case "minimum": return toType(getMinimum(), type);
1088         case "exclusiveMinimum": return toType(getExclusiveMinimum(), type);
1089         case "maxLength": return toType(getMaxLength(), type);
1090         case "minLength": return toType(getMinLength(), type);
1091         case "pattern": return toType(getPattern(), type);
1092         case "maxItems": return toType(getMaxItems(), type);
1093         case "minItems": return toType(getMinItems(), type);
1094         case "uniqueItems": return toType(getUniqueItems(), type);
1095         case "enum": return toType(getEnum(), type);
1096         case "multipleOf": return toType(getMultipleOf(), type);
1097         case "x-example": return toType(getExample(), type);
1098         default: return super.get(property, type);
1099      }
1100   }
1101
1102   @Override /* SwaggerElement */
1103   public HeaderInfo set(String property, Object value) {
1104      if (property == null)
1105         return this;
1106      switch (property) {
1107         case "description": return description(value);
1108         case "type": return type(value);
1109         case "format": return format(value);
1110         case "items": return items(value);
1111         case "collectionFormat": return collectionFormat(value);
1112         case "$ref": return ref(value);
1113         case "default": return _default(value);
1114         case "maximum": return maximum(value);
1115         case "exclusiveMaximum": return exclusiveMaximum(value);
1116         case "minimum": return minimum(value);
1117         case "exclusiveMinimum": return exclusiveMinimum(value);
1118         case "maxLength": return maxLength(value);
1119         case "minLength": return minLength(value);
1120         case "pattern": return pattern(value);
1121         case "maxItems": return maxItems(value);
1122         case "minItems": return minItems(value);
1123         case "uniqueItems": return uniqueItems(value);
1124         case "enum": return setEnum(null)._enum(value);
1125         case "multipleOf": return multipleOf(value);
1126         case "x-example": return example(value);
1127         default:
1128            super.set(property, value);
1129            return this;
1130      }
1131   }
1132
1133   @Override /* SwaggerElement */
1134   public Set<String> keySet() {
1135      ASet<String> s = ASet.<String>of()
1136         .aif(description != null, "description")
1137         .aif(type != null, "type")
1138         .aif(format != null, "format")
1139         .aif(items != null, "items")
1140         .aif(collectionFormat != null, "collectionFormat")
1141         .aif(ref != null, "$ref")
1142         .aif(_default != null, "default")
1143         .aif(maximum != null, "maximum")
1144         .aif(exclusiveMaximum != null, "exclusiveMaximum")
1145         .aif(minimum != null, "minimum")
1146         .aif(exclusiveMinimum != null, "exclusiveMinimum")
1147         .aif(maxLength != null, "maxLength")
1148         .aif(minLength != null, "minLength")
1149         .aif(pattern != null, "pattern")
1150         .aif(maxItems != null, "maxItems")
1151         .aif(minItems != null, "minItems")
1152         .aif(uniqueItems != null, "uniqueItems")
1153         .aif(_enum != null, "enum")
1154         .aif(multipleOf != null, "multipleOf")
1155         .aif(example != null, "example");
1156      return new MultiSet<>(s, super.keySet());
1157
1158   }
1159
1160   /**
1161    * Resolves any <js>"$ref"</js> attributes in this element.
1162    *
1163    * @param swagger The swagger document containing the definitions.
1164    * @param refStack Keeps track of previously-visited references so that we don't cause recursive loops.
1165    * @param maxDepth
1166    *    The maximum depth to resolve references.
1167    *    <br>After that level is reached, <c>$ref</c> references will be left alone.
1168    *    <br>Useful if you have very complex models and you don't want your swagger page to be overly-complex.
1169    * @return
1170    *    This object with references resolved.
1171    *    <br>May or may not be the same object.
1172    */
1173   public HeaderInfo resolveRefs(Swagger swagger, Deque<String> refStack, int maxDepth) {
1174
1175      if (ref != null) {
1176         if (refStack.contains(ref) || refStack.size() >= maxDepth)
1177            return this;
1178         refStack.addLast(ref);
1179         HeaderInfo r = swagger.findRef(ref, HeaderInfo.class).resolveRefs(swagger, refStack, maxDepth);
1180         refStack.removeLast();
1181         return r;
1182      }
1183
1184      if (items != null)
1185         items = items.resolveRefs(swagger, refStack, maxDepth);
1186
1187      return this;
1188   }
1189}