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