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.StringUtils.*;
016import static org.apache.juneau.internal.ObjectUtils.*;
017import static org.apache.juneau.internal.CollectionUtils.*;
018
019import java.util.*;
020
021import org.apache.juneau.annotation.*;
022import org.apache.juneau.internal.*;
023import org.apache.juneau.utils.*;
024
025/**
026 * The Schema Object allows the definition of input and output data types.
027 *
028 * <p>
029 * These types can be objects, but also primitives and arrays.
030 * This object is based on the JSON Schema Specification Draft 4 and uses a predefined subset of it.
031 * On top of this subset, there are extensions provided by this specification to allow for more complete documentation.
032 *
033 * <p>
034 * Further information about the properties can be found in JSON Schema Core and JSON Schema Validation.
035 * Unless stated otherwise, the property definitions follow the JSON Schema specification as referenced here.
036 *
037 * <h5 class='section'>Example:</h5>
038 * <p class='bcode w800'>
039 *    <jc>// Construct using SwaggerBuilder.</jc>
040 *    SchemaInfo x = <jsm>schemaInfo</jsm>()
041 *       .type("string")
042 *       .title("foo")
043 *
044 *    <jc>// Serialize using JsonSerializer.</jc>
045 *    String json = JsonSerializer.<jsf>DEFAULT</jsf>.toString(x);
046 *
047 *    <jc>// Or just use toString() which does the same as above.</jc>
048 *    String json = x.toString();
049 * </p>
050 * <p class='bcode w800'>
051 *    <jc>// Output</jc>
052 *    {
053 *       <js>"type"</js>: <js>"string"</js>,
054 *       <js>"title"</js>: <js>"foo"</js>
055 *    }
056 * </p>
057 *
058 * <ul class='seealso'>
059 *    <li class='link'>{@doc juneau-dto.Swagger}
060 * </ul>
061 */
062@Bean(bpi="format,title,description,default,multipleOf,maximum,exclusiveMaximum,minimum,exclusiveMinimum,maxLength,minLength,pattern,maxItems,minItems,uniqueItems,maxProperties,minProperties,required,enum,type,items,allOf,properties,additionalProperties,discriminator,readOnly,xml,externalDocs,example,$ref,*")
063public class SchemaInfo extends SwaggerElement {
064
065   private String
066      format,
067      title,
068      description,
069      pattern,
070      type,
071      discriminator,
072      ref;
073   private Number
074      multipleOf,
075      maximum,
076      minimum;
077   private Integer
078      maxLength,
079      minLength,
080      maxItems,
081      minItems,
082      maxProperties,
083      minProperties;
084   private Boolean
085      exclusiveMaximum,
086      exclusiveMinimum,
087      uniqueItems,
088      readOnly;
089   private Object
090      _default,
091      example;
092   private Items items;
093   private Xml xml;
094   private ExternalDocumentation externalDocs;
095   private List<Object>
096      _enum,
097      allOf;
098   private List<String>
099      required;
100   private Map<String,SchemaInfo> properties;
101   private SchemaInfo additionalProperties;
102
103   /**
104    * Default constructor.
105    */
106   public SchemaInfo() {}
107
108   /**
109    * Copy constructor.
110    *
111    * @param copyFrom The object to copy.
112    */
113   public SchemaInfo(SchemaInfo copyFrom) {
114      super(copyFrom);
115
116      this.format = copyFrom.format;
117      this.title = copyFrom.title;
118      this.description = copyFrom.description;
119      this.pattern = copyFrom.pattern;
120      this.type = copyFrom.type;
121      this.discriminator = copyFrom.discriminator;
122      this.ref = copyFrom.ref;
123      this.multipleOf = copyFrom.multipleOf;
124      this.maximum = copyFrom.maximum;
125      this.minimum = copyFrom.minimum;
126      this.maxLength = copyFrom.maxLength;
127      this.minLength = copyFrom.minLength;
128      this.maxItems = copyFrom.maxItems;
129      this.minItems = copyFrom.minItems;
130      this.maxProperties = copyFrom.maxProperties;
131      this.minProperties = copyFrom.minProperties;
132      this.exclusiveMaximum = copyFrom.exclusiveMaximum;
133      this.exclusiveMinimum = copyFrom.exclusiveMinimum;
134      this.uniqueItems = copyFrom.uniqueItems;
135      this.readOnly = copyFrom.readOnly;
136      this._default = copyFrom._default;
137      this.example = copyFrom.example;
138      this.items = copyFrom.items == null ? null : copyFrom.items.copy();
139      this.xml = copyFrom.xml == null ? null : copyFrom.xml.copy();
140      this.externalDocs = copyFrom.externalDocs == null ? null : copyFrom.externalDocs.copy();
141      this._enum = newList(copyFrom._enum);
142      this.allOf = newList(copyFrom.allOf);
143      this.required = newList(copyFrom.required);
144
145      if (copyFrom.properties == null) {
146         this.properties = null;
147      } else {
148         this.properties = new LinkedHashMap<>();
149         for (Map.Entry<String,SchemaInfo> e : copyFrom.properties.entrySet())
150            this.properties.put(e.getKey(), e.getValue().copy());
151      }
152
153      this.additionalProperties = copyFrom.additionalProperties == null ? null : copyFrom.additionalProperties.copy();
154   }
155
156   /**
157    * Make a deep copy of this object.
158    *
159    * @return A deep copy of this object.
160    */
161   public SchemaInfo copy() {
162      return new SchemaInfo(this);
163   }
164
165   /**
166    * Bean property getter:  <property>format</property>.
167    *
168    * <ul class='seealso'>
169    *    <li class='extlink'>{@doc SwaggerDataTypeFormats}
170    * </ul>
171    *
172    * @return The property value, or <jk>null</jk> if it is not set.
173    */
174   public String getFormat() {
175      return format;
176   }
177
178   /**
179    * Bean property setter:  <property>format</property>.
180    *
181    * <ul class='seealso'>
182    *    <li class='extlink'>{@doc SwaggerDataTypes}
183    * </ul>
184    *
185    * @param value
186    *    The new value for this property.
187    *    <br>Can be <jk>null</jk> to unset the property.
188    *    <br>Formats defined by the OAS include:
189    *    <ul>
190    *       <li><js>"int32"</js>
191    *       <li><js>"int64"</js>
192    *       <li><js>"float"</js>
193    *       <li><js>"double"</js>
194    *       <li><js>"byte"</js>
195    *       <li><js>"binary"</js>
196    *       <li><js>"date"</js>
197    *       <li><js>"date-time"</js>
198    *       <li><js>"password"</js>
199    *    </ul>
200    * @return This object (for method chaining).
201    */
202   public SchemaInfo setFormat(String value) {
203      format = value;
204      return this;
205   }
206
207   /**
208    * Same as {@link #setFormat(String)}.
209    *
210    * @param value
211    *    The new value for this property.
212    *    <br>Non-String values will be converted to String using <c>toString()</c>.
213    *    <br>Can be <jk>null</jk> to unset the property.
214    * @return This object (for method chaining).
215    */
216   public SchemaInfo format(Object value) {
217      return setFormat(stringify(value));
218   }
219
220   /**
221    * Bean property getter:  <property>title</property>.
222    *
223    * @return The property value, or <jk>null</jk> if it is not set.
224    */
225   public String getTitle() {
226      return title;
227   }
228
229   /**
230    * Bean property setter:  <property>title</property>.
231    *
232    * @param value
233    *    The new value for this property.
234    *    <br>Can be <jk>null</jk> to unset the property.
235    * @return This object (for method chaining).
236    */
237   public SchemaInfo setTitle(String value) {
238      title = value;
239      return this;
240   }
241
242   /**
243    * Same as {@link #setTitle(String)}.
244    *
245    * @param value
246    *    The new value for this property.
247    *    <br>Non-String values will be converted to String using <c>toString()</c>.
248    *    <br>Can be <jk>null</jk> to unset the property.
249    * @return This object (for method chaining).
250    */
251   public SchemaInfo title(Object value) {
252      return setTitle(stringify(value));
253   }
254
255   /**
256    * Bean property getter:  <property>description</property>.
257    *
258    * @return The property value, or <jk>null</jk> if it is not set.
259    */
260   public String getDescription() {
261      return description;
262   }
263
264   /**
265    * Bean property setter:  <property>description</property>.
266    *
267    * @param value
268    *    The new value for this property.
269    *    <br>{@doc GFM} can be used for rich text representation.
270    *    <br>Can be <jk>null</jk> to unset the property.
271    * @return This object (for method chaining).
272    */
273   public SchemaInfo setDescription(String value) {
274      description = value;
275      return this;
276   }
277
278   /**
279    * Same as {@link #setDescription(String)}.
280    *
281    * @param value
282    *    The new value for this property.
283    *    <br>Non-String values will be converted to String using <c>toString()</c>.
284    *    <br>Can be <jk>null</jk> to unset the property.
285    * @return This object (for method chaining).
286    */
287   public SchemaInfo description(Object value) {
288      return setDescription(stringify(value));
289   }
290
291   /**
292    * Bean property getter:  <property>default</property>.
293    *
294    * <p>
295    * Unlike JSON Schema, the value MUST conform to the defined type for the Schema Object.
296    *
297    * @return The property value, or <jk>null</jk> if it is not set.
298    */
299   public Object getDefault() {
300      return _default;
301   }
302
303   /**
304    * Bean property setter:  <property>default</property>.
305    *
306    * <p>
307    * Unlike JSON Schema, the value MUST conform to the defined type for the Schema Object.
308    *
309    * @param value
310    *    The new value for this property.
311    *    <br>Can be <jk>null</jk> to unset the property.
312    * @return This object (for method chaining).
313    */
314   public SchemaInfo setDefault(Object value) {
315      _default = value;
316      return this;
317   }
318
319   /**
320    * Same as {@link #setDefault(Object)}.
321    *
322    * @param value The new value for this property.
323    * @return This object (for method chaining).
324    */
325   public SchemaInfo _default(Object value) {
326      return setDefault(value);
327   }
328
329   /**
330    * Bean property getter:  <property>multipleOf</property>.
331    *
332    * @return The property value, or <jk>null</jk> if it is not set.
333    */
334   public Number getMultipleOf() {
335      return multipleOf;
336   }
337
338   /**
339    * Bean property setter:  <property>multipleOf</property>.
340    *
341    * @param value
342    *    The new value for this property.
343    *    <br>Can be <jk>null</jk> to unset the property.
344    * @return This object (for method chaining).
345    */
346   public SchemaInfo setMultipleOf(Number value) {
347      multipleOf = value;
348      return this;
349   }
350
351   /**
352    * Same as {@link #setMultipleOf(Number)}.
353    *
354    * @param value
355    *    The new value for this property.
356    *    <br>Non-Number values will be converted to Number using <c>toString()</c> then best number match.
357    *    <br>Can be <jk>null</jk> to unset the property.
358    * @return This object (for method chaining).
359    */
360   public SchemaInfo multipleOf(Object value) {
361      return setMultipleOf(toNumber(value));
362   }
363
364   /**
365    * Bean property getter:  <property>maximum</property>.
366    *
367    * @return The property value, or <jk>null</jk> if it is not set.
368    */
369   public Number getMaximum() {
370      return maximum;
371   }
372
373   /**
374    * Bean property setter:  <property>maximum</property>.
375    *
376    * @param value
377    *    The new value for this property.
378    *    <br>Can be <jk>null</jk> to unset the property.
379    * @return This object (for method chaining).
380    */
381   public SchemaInfo setMaximum(Number value) {
382      maximum = value;
383      return this;
384   }
385
386   /**
387    * Same as {@link #setMaximum(Number)}.
388    *
389    * @param value
390    *    The new value for this property.
391    *    <br>Non-Number values will be converted to Number using <c>toString()</c> then best number match.
392    *    <br>Can be <jk>null</jk> to unset the property.
393    * @return This object (for method chaining).
394    */
395   public SchemaInfo maximum(Object value) {
396      return setMaximum(toNumber(value));
397   }
398
399   /**
400    * Bean property getter:  <property>exclusiveMaximum</property>.
401    *
402    * @return The property value, or <jk>null</jk> if it is not set.
403    */
404   public Boolean getExclusiveMaximum() {
405      return exclusiveMaximum;
406   }
407
408   /**
409    * Bean property setter:  <property>exclusiveMaximum</property>.
410    *
411    * @param value
412    *    The new value for this property.
413    *    <br>Can be <jk>null</jk> to unset the property.
414    * @return This object (for method chaining).
415    */
416   public SchemaInfo setExclusiveMaximum(Boolean value) {
417      exclusiveMaximum = value;
418      return this;
419   }
420
421   /**
422    * Same as {@link #setExclusiveMaximum(Boolean)}.
423    *
424    * @param value
425    *    The new value for this property.
426    *    <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>.
427    *    <br>Can be <jk>null</jk> to unset the property.
428    * @return This object (for method chaining).
429    */
430   public SchemaInfo exclusiveMaximum(Object value) {
431      return setExclusiveMaximum(toBoolean(value));
432   }
433
434   /**
435    * Bean property getter:  <property>minimum</property>.
436    *
437    * @return The property value, or <jk>null</jk> if it is not set.
438    */
439   public Number getMinimum() {
440      return minimum;
441   }
442
443   /**
444    * Bean property setter:  <property>minimum</property>.
445    *
446    * @param value
447    *    The new value for this property.
448    *    <br>Can be <jk>null</jk> to unset the property.
449    * @return This object (for method chaining).
450    */
451   public SchemaInfo setMinimum(Number value) {
452      minimum = value;
453      return this;
454   }
455
456   /**
457    * Same as {@link #setMinimum(Number)}.
458    *
459    * @param value
460    *    The new value for this property.
461    *    <br>Non-Number values will be converted to Number using <c>toString()</c> then best number match.
462    *    <br>Can be <jk>null</jk> to unset the property.
463    * @return This object (for method chaining).
464    */
465   public SchemaInfo minimum(Object value) {
466      return setMinimum(toNumber(value));
467   }
468
469   /**
470    * Bean property getter:  <property>exclusiveMinimum</property>.
471    *
472    * @return The property value, or <jk>null</jk> if it is not set.
473    */
474   public Boolean getExclusiveMinimum() {
475      return exclusiveMinimum;
476   }
477
478   /**
479    * Bean property setter:  <property>exclusiveMinimum</property>.
480    *
481    * @param value
482    *    The new value for this property.
483    *    <br>Can be <jk>null</jk> to unset the property.
484    * @return This object (for method chaining).
485    */
486   public SchemaInfo setExclusiveMinimum(Boolean value) {
487      exclusiveMinimum = value;
488      return this;
489   }
490
491   /**
492    * Same as {@link #setExclusiveMinimum(Boolean)}.
493    *
494    * @param value
495    *    The new value for this property.
496    *    <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>.
497    *    <br>Can be <jk>null</jk> to unset the property.
498    * @return This object (for method chaining).
499    */
500   public SchemaInfo exclusiveMinimum(Object value) {
501      return setExclusiveMinimum(toBoolean(value));
502   }
503
504   /**
505    * Bean property getter:  <property>maxLength</property>.
506    *
507    * @return The property value, or <jk>null</jk> if it is not set.
508    */
509   public Integer getMaxLength() {
510      return maxLength;
511   }
512
513   /**
514    * Bean property setter:  <property>maxLength</property>.
515    *
516    * @param value
517    *    The new value for this property.
518    *    <br>Can be <jk>null</jk> to unset the property.
519    * @return This object (for method chaining).
520    */
521   public SchemaInfo setMaxLength(Integer value) {
522      maxLength = value;
523      return this;
524   }
525
526   /**
527    * Same as {@link #setMaxLength(Integer)}.
528    *
529    * @param value
530    *    The new value for this property.
531    *    <br>Non-Integer values will be converted to Integer using <code>Integer.<jsm>valueOf</jsm>(value.toString())</code>.
532    *    <br>Can be <jk>null</jk> to unset the property.
533    * @return This object (for method chaining).
534    */
535   public SchemaInfo maxLength(Object value) {
536      return setMaxLength(toInteger(value));
537   }
538
539   /**
540    * Bean property getter:  <property>minLength</property>.
541    *
542    * @return The property value, or <jk>null</jk> if it is not set.
543    */
544   public Integer getMinLength() {
545      return minLength;
546   }
547
548   /**
549    * Bean property setter:  <property>minLength</property>.
550    *
551    * @param value
552    *    The new value for this property.
553    *    <br>Can be <jk>null</jk> to unset the property.
554    * @return This object (for method chaining).
555    */
556   public SchemaInfo setMinLength(Integer value) {
557      minLength = value;
558      return this;
559   }
560
561   /**
562    * Same as {@link #setMinLength(Integer)}.
563    *
564    * @param value
565    *    The new value for this property.
566    *    <br>Non-Integer values will be converted to Integer using <code>Integer.<jsm>valueOf</jsm>(value.toString())</code>.
567    *    <br>Can be <jk>null</jk> to unset the property.
568    * @return This object (for method chaining).
569    */
570   public SchemaInfo minLength(Object value) {
571      return setMinLength(toInteger(value));
572   }
573
574   /**
575    * Bean property getter:  <property>pattern</property>.
576    *
577    * @return The property value, or <jk>null</jk> if it is not set.
578    */
579   public String getPattern() {
580      return pattern;
581   }
582
583   /**
584    * Bean property setter:  <property>pattern</property>.
585    *
586    * <p>
587    * This string SHOULD be a valid regular expression.
588    *
589    * @param value
590    *    The new value for this property.
591    *    <br>Can be <jk>null</jk> to unset the property.
592    * @return This object (for method chaining).
593    */
594   public SchemaInfo setPattern(String value) {
595      pattern = value;
596      return this;
597   }
598
599   /**
600    * Same as {@link #setPattern(String)}.
601    *
602    * @param value
603    *    The new value for this property.
604    *    <br>Non-String values will be converted to String using <c>toString()</c>.
605    *    <br>Can be <jk>null</jk> to unset the property.
606    * @return This object (for method chaining).
607    */
608   public SchemaInfo pattern(Object value) {
609      return setPattern(stringify(value));
610   }
611
612   /**
613    * Bean property getter:  <property>maxItems</property>.
614    *
615    * @return The property value, or <jk>null</jk> if it is not set.
616    */
617   public Integer getMaxItems() {
618      return maxItems;
619   }
620
621   /**
622    * Bean property setter:  <property>maxItems</property>.
623    *
624    * @param value
625    *    The new value for this property.
626    *    <br>Can be <jk>null</jk> to unset the property.
627    * @return This object (for method chaining).
628    */
629   public SchemaInfo setMaxItems(Integer value) {
630      maxItems = value;
631      return this;
632   }
633
634   /**
635    * Same as {@link #setMaxItems(Integer)}.
636    *
637    * @param value
638    *    The new value for this property.
639    *    <br>Non-Integer values will be converted to Integer using <code>Integer.<jsm>valueOf</jsm>(value.toString())</code>.
640    *    <br>Can be <jk>null</jk> to unset the property.
641    * @return This object (for method chaining).
642    */
643   public SchemaInfo maxItems(Object value) {
644      return setMaxItems(toInteger(value));
645   }
646
647   /**
648    * Bean property getter:  <property>minItems</property>.
649    *
650    * @return The property value, or <jk>null</jk> if it is not set.
651    */
652   public Integer getMinItems() {
653      return minItems;
654   }
655
656   /**
657    * Bean property setter:  <property>minItems</property>.
658    *
659    * @param value
660    *    The new value for this property.
661    *    <br>Can be <jk>null</jk> to unset the property.
662    * @return This object (for method chaining).
663    */
664   public SchemaInfo setMinItems(Integer value) {
665      minItems = value;
666      return this;
667   }
668
669   /**
670    * Same as {@link #setMinItems(Integer)}.
671    *
672    * @param value
673    *    The new value for this property.
674    *    <br>Non-Integer values will be converted to Integer using <code>Integer.<jsm>valueOf</jsm>(value.toString())</code>.
675    *    <br>Can be <jk>null</jk> to unset the property.
676    * @return This object (for method chaining).
677    */
678   public SchemaInfo minItems(Object value) {
679      return setMinItems(toInteger(value));
680   }
681
682   /**
683    * Bean property getter:  <property>uniqueItems</property>.
684    *
685    * @return The property value, or <jk>null</jk> if it is not set.
686    */
687   public Boolean getUniqueItems() {
688      return uniqueItems;
689   }
690   /**
691    * Bean property setter:  <property>uniqueItems</property>.
692    *
693    * @param value
694    *    The new value for this property.
695    *    <br>Can be <jk>null</jk> to unset the property.
696    * @return This object (for method chaining).
697    */
698   public SchemaInfo setUniqueItems(Boolean value) {
699      uniqueItems = value;
700      return this;
701   }
702
703   /**
704    * Same as {@link #setUniqueItems(Boolean)}.
705    *
706    * @param value
707    *    The new value for this property.
708    *    <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>.
709    *    <br>Can be <jk>null</jk> to unset the property.
710    * @return This object (for method chaining).
711    */
712   public SchemaInfo uniqueItems(Object value) {
713      return setUniqueItems(toBoolean(value));
714   }
715
716   /**
717    * Bean property getter:  <property>maxProperties</property>.
718    *
719    * @return The property value, or <jk>null</jk> if it is not set.
720    */
721   public Integer getMaxProperties() {
722      return maxProperties;
723   }
724
725   /**
726    * Bean property setter:  <property>maxProperties</property>.
727    *
728    * @param value
729    *    The new value for this property.
730    *    <br>Can be <jk>null</jk> to unset the property.
731    * @return This object (for method chaining).
732    */
733   public SchemaInfo setMaxProperties(Integer value) {
734      maxProperties = value;
735      return this;
736   }
737
738   /**
739    * Same as {@link #setMaxProperties(Integer)}.
740    *
741    * @param value
742    *    The new value for this property.
743    *    <br>Non-Integer values will be converted to Integer using <code>Integer.<jsm>valueOf</jsm>(value.toString())</code>.
744    *    <br>Can be <jk>null</jk> to unset the property.
745    * @return This object (for method chaining).
746    */
747   public SchemaInfo maxProperties(Object value) {
748      return setMaxProperties(toInteger(value));
749   }
750
751   /**
752    * Bean property getter:  <property>minProperties</property>.
753    *
754    * @return The property value, or <jk>null</jk> if it is not set.
755    */
756   public Integer getMinProperties() {
757      return minProperties;
758   }
759
760   /**
761    * Bean property setter:  <property>minProperties</property>.
762    *
763    * @param value
764    *    The new value for this property.
765    *    <br>Can be <jk>null</jk> to unset the property.
766    * @return This object (for method chaining).
767    */
768   public SchemaInfo setMinProperties(Integer value) {
769      minProperties = value;
770      return this;
771   }
772
773   /**
774    * Same as {@link #setMinProperties(Integer)}.
775    *
776    * @param value
777    *    The new value for this property.
778    *    <br>Non-Integer values will be converted to Integer using <code>Integer.<jsm>valueOf</jsm>(value.toString())</code>.
779    *    <br>Can be <jk>null</jk> to unset the property.
780    * @return This object (for method chaining).
781    */
782   public SchemaInfo minProperties(Object value) {
783      return setMinProperties(toInteger(value));
784   }
785
786   /**
787    * Bean property getter:  <property>required</property>.
788    *
789    * <p>
790    * The list of required properties.
791    *
792    * @return The property value, or <jk>null</jk> if it is not set.
793    */
794   public List<String> getRequired() {
795      return required;
796   }
797
798   /**
799    * Bean property setter:  <property>required</property>.
800    *
801    * <p>
802    * The list of required properties.
803    *
804    * @param value
805    *    The new value for this property.
806    *    <br>Valid values:
807    *    <ul>
808    *       <li><js>"http"</js>
809    *       <li><js>"https"</js>
810    *       <li><js>"ws"</js>
811    *       <li><js>"wss"</js>
812    *    </ul>
813    *    <br>Can be <jk>null</jk> to unset the property.
814    * @return This object (for method chaining).
815    */
816   public SchemaInfo setRequired(Collection<String> value) {
817      required = newList(value);
818      return this;
819   }
820
821   /**
822    * Adds one or more values to the <property>required</property> property.
823    *
824    * <p>
825    * The list of required properties.
826    *
827    * @param value
828    *    The values to add to this property.
829    *    <br>Ignored if <jk>null</jk>.
830    * @return This object (for method chaining).
831    */
832   public SchemaInfo addRequired(Collection<String> value) {
833      required = addToList(required, value);
834      return this;
835   }
836
837   /**
838    * Same as {@link #addRequired(Collection)}.
839    *
840    * @param values
841    *    The new value for this property.
842    *    <br>Valid types:
843    *    <ul>
844    *       <li><c>Collection&lt;String&gt;</c>
845    *       <li><c>String</c> - JSON array representation of <c>Collection&lt;String&gt;</c>
846    *          <h5 class='figure'>Example:</h5>
847    *          <p class='bcode w800'>
848    *    schemes(<js>"['scheme1','scheme2']"</js>);
849    *          </p>
850    *       <li><c>String</c> - Individual values
851    *          <h5 class='figure'>Example:</h5>
852    *          <p class='bcode w800'>
853    *    schemes(<js>"scheme1</js>, <js>"scheme2"</js>);
854    *          </p>
855    *    </ul>
856    * @return This object (for method chaining).
857    */
858   public SchemaInfo required(Object...values) {
859      required = addToList(required, values, String.class);
860      return this;
861   }
862
863   /**
864    * Bean property getter:  <property>enum</property>.
865    *
866    * @return The property value, or <jk>null</jk> if it is not set.
867    */
868   public List<Object> getEnum() {
869      return _enum;
870   }
871
872   /**
873    * Bean property setter:  <property>enum</property>.
874    *
875    * <ul class='seealso'>
876    *    <li class='extlink'>{@doc JsonSchemaValidation}
877    * </ul>
878    *
879    * @param value
880    *    The new value for this property.
881    *    <br>Can be <jk>null</jk> to unset the property.
882    * @return This object (for method chaining).
883    */
884   public SchemaInfo setEnum(Collection<Object> value) {
885      _enum = newList(value);
886      return this;
887   }
888
889   /**
890    * Adds one or more values to the <property>enum</property> property.
891    *
892    * @param value
893    *    The values to add to this property.
894    *    <br>Ignored if <jk>null</jk>.
895    * @return This object (for method chaining).
896    */
897   public SchemaInfo addEnum(Collection<Object> value) {
898      _enum = addToList(_enum, value);
899      return this;
900   }
901
902   /**
903    * Adds one or more values to the <property>enum</property> property.
904    *
905    * @param values
906    *    The values to add to this property.
907    *    <br>Valid types:
908    *    <ul>
909    *       <li><c>Object</c>
910    *       <li><c>Collection&lt;Object&gt;</c>
911    *       <li><c>String</c> - JSON array representation of <c>Collection&lt;Object&gt;</c>
912    *          <h5 class='figure'>Example:</h5>
913    *          <p class='bcode w800'>
914    *    _enum(<js>"['foo','bar']"</js>);
915    *          </p>
916    *       <li><c>String</c> - Individual values
917    *          <h5 class='figure'>Example:</h5>
918    *          <p class='bcode w800'>
919    *    _enum(<js>"foo"</js>, <js>"bar"</js>);
920    *          </p>
921    *    </ul>
922    *    <br>Ignored if <jk>null</jk>.
923    * @return This object (for method chaining).
924    */
925   public SchemaInfo _enum(Object...values) {
926      _enum = addToList(_enum, values, Object.class);
927      return this;
928   }
929
930   /**
931    * Bean property getter:  <property>type</property>.
932    *
933    * @return The property value, or <jk>null</jk> if it is not set.
934    */
935   public String getType() {
936      return type;
937   }
938
939   /**
940    * Bean property setter:  <property>type</property>.
941    *
942    * <ul class='seealso'>
943    *    <li class='extlink'>{@doc SwaggerDataTypes}
944    * </ul>
945    *
946    * @param value
947    *    The new value for this property.
948    *    <br>Can be <jk>null</jk> to unset the property.
949    *    <br>Possible values include:
950    *    <ul>
951    *       <li><js>"object"</js>
952    *       <li><js>"string"</js>
953    *       <li><js>"number"</js>
954    *       <li><js>"integer"</js>
955    *       <li><js>"boolean"</js>
956    *       <li><js>"array"</js>
957    *       <li><js>"file"</js>
958    *    </ul>
959    * @return This object (for method chaining).
960    */
961   public SchemaInfo setType(String value) {
962      type = value;
963      return this;
964   }
965
966   /**
967    * Same as {@link #setType(String)}.
968    *
969    * @param value
970    *    The new value for this property.
971    *    <br>Non-String values will be converted to String using <c>toString()</c>.
972    *    <br>Can be <jk>null</jk> to unset the property.
973    * @return This object (for method chaining).
974    */
975   public SchemaInfo type(Object value) {
976      return setType(stringify(value));
977   }
978
979   /**
980    * Bean property getter:  <property>items</property>.
981    *
982    * @return The property value, or <jk>null</jk> if it is not set.
983    */
984   public Items getItems() {
985      return items;
986   }
987
988   /**
989    * Bean property setter:  <property>items</property>.
990    *
991    * @param value
992    *    The new value for this property.
993    *    <br>Can be <jk>null</jk> to unset the property.
994    * @return This object (for method chaining).
995    */
996   public SchemaInfo setItems(Items value) {
997      items = value;
998      return this;
999   }
1000
1001   /**
1002    * Same as {@link #setItems(Items)}.
1003    *
1004    * @param value
1005    *    The new value for this property.
1006    *    <br>Valid types:
1007    *    <ul>
1008    *       <li>{@link Items}
1009    *       <li><c>String</c> - JSON object representation of {@link Items}
1010    *          <h5 class='figure'>Example:</h5>
1011    *          <p class='bcode w800'>
1012    *    items(<js>"{type:'type',format:'format',...}"</js>);
1013    *          </p>
1014    *    </ul>
1015    *    <br>Can be <jk>null</jk> to unset the property.
1016    * @return This object (for method chaining).
1017    */
1018   public SchemaInfo items(Object value) {
1019      return setItems(toType(value, Items.class));
1020   }
1021
1022   /**
1023    * Bean property getter:  <property>allOf</property>.
1024    *
1025    * @return The property value, or <jk>null</jk> if it is not set.
1026    */
1027   public List<Object> getAllOf() {
1028      return allOf;
1029   }
1030
1031   /**
1032    * Bean property setter:  <property>allOf</property>.
1033    *
1034    * @param value
1035    *    The new value for this property.
1036    *    <br>Can be <jk>null</jk> to unset the property.
1037    * @return This object (for method chaining).
1038    */
1039   public SchemaInfo setAllOf(Collection<Object> value) {
1040      allOf = newList(value);
1041      return this;
1042   }
1043
1044   /**
1045    * Adds one or more values to the <property>allOf</property> property.
1046    *
1047    * @param values
1048    *    The values to add to this property.
1049    *    <br>Ignored if <jk>null</jk>.
1050    * @return This object (for method chaining).
1051    */
1052   public SchemaInfo addAllOf(Collection<Object> values) {
1053      allOf = addToList(allOf, values);
1054      return this;
1055   }
1056
1057   /**
1058    * Adds one or more values to the <property>allOf</property> property.
1059    *
1060    * @param values
1061    *    The values to add to this property.
1062    *    <br>Valid types:
1063    *    <ul>
1064    *       <li><c>Object</c>
1065    *       <li><c>Collection&lt;Object&gt;</c>
1066    *       <li><c>String</c> - JSON array representation of <c>Collection&lt;Object&gt;</c>
1067    *          <h5 class='figure'>Example:</h5>
1068    *          <p class='bcode w800'>
1069    *    allOf(<js>"['foo','bar']"</js>);
1070    *          </p>
1071    *       <li><c>String</c> - Individual values
1072    *          <h5 class='figure'>Example:</h5>
1073    *          <p class='bcode w800'>
1074    *    allOf(<js>"foo"</js>, <js>"bar"</js>);
1075    *          </p>
1076    *    </ul>
1077    *    <br>Ignored if <jk>null</jk>.
1078    * @return This object (for method chaining).
1079    */
1080   public SchemaInfo allOf(Object...values) {
1081      allOf = addToList(allOf, values, Object.class);
1082      return this;
1083   }
1084
1085   /**
1086    * Bean property getter:  <property>properties</property>.
1087    *
1088    * @return The property value, or <jk>null</jk> if it is not set.
1089    */
1090   public Map<String,SchemaInfo> getProperties() {
1091      return properties;
1092   }
1093
1094   /**
1095    * Bean property setter:  <property>properties</property>.
1096    *
1097    * @param value
1098    *    The new value for this property.
1099    *    <br>Can be <jk>null</jk> to unset the property.
1100    * @return This object (for method chaining).
1101    */
1102   public SchemaInfo setProperties(Map<String,SchemaInfo> value) {
1103      properties = newMap(value);
1104      return this;
1105   }
1106
1107   /**
1108    * Adds one or more values to the <property>properties</property> property.
1109    *
1110    * @param values
1111    *    The values to add to this property.
1112    *    <br>Ignored if <jk>null</jk>.
1113    * @return This object (for method chaining).
1114    */
1115   public SchemaInfo addProperties(Map<String,SchemaInfo> values) {
1116      properties = addToMap(properties, values);
1117      return this;
1118   }
1119
1120   /**
1121    * Adds one or more values to the <property>properties</property> property.
1122    *
1123    * @param values
1124    *    The values to add to this property.
1125    *    <br>Valid types:
1126    *    <ul>
1127    *       <li><c>Map&lt;String,Map&lt;String,Object&gt;&gt;</c>
1128    *       <li><c>String</c> - JSON object representation of <c>Map&lt;String,Map&lt;String,Object&gt;&gt;</c>
1129    *          <h5 class='figure'>Example:</h5>
1130    *          <p class='bcode w800'>
1131    *    properties(<js>"{name:{foo:'bar'}}"</js>);
1132    *          </p>
1133    *    </ul>
1134    *    <br>Ignored if <jk>null</jk>.
1135    * @return This object (for method chaining).
1136    */
1137   public SchemaInfo properties(Object...values) {
1138      properties = addToMap(properties, values, String.class, SchemaInfo.class);
1139      return this;
1140   }
1141
1142   /**
1143    * Bean property getter:  <property>additionalProperties</property>.
1144    *
1145    * @return The property value, or <jk>null</jk> if it is not set.
1146    */
1147   public SchemaInfo getAdditionalProperties() {
1148      return additionalProperties;
1149   }
1150
1151   /**
1152    * Bean property setter:  <property>additionalProperties</property>.
1153    *
1154    * @param value
1155    *    The new value for this property.
1156    *    <br>Can be <jk>null</jk> to unset the property.
1157    * @return This object (for method chaining).
1158    */
1159   public SchemaInfo setAdditionalProperties(SchemaInfo value) {
1160      additionalProperties = value;
1161      return this;
1162   }
1163
1164   /**
1165    * Bean property setter:  <property>additionalProperties</property>.
1166    *
1167    * @param value
1168    *    The new value for this property.
1169    *    <br>Can be <jk>null</jk> to unset the property.
1170    * @return This object (for method chaining).
1171    */
1172   public SchemaInfo additionalProperties(Object value) {
1173      additionalProperties = toType(value, SchemaInfo.class);
1174      return this;
1175   }
1176
1177   /**
1178    * Bean property getter:  <property>discriminator</property>.
1179    *
1180    * @return The property value, or <jk>null</jk> if it is not set.
1181    */
1182   public String getDiscriminator() {
1183      return discriminator;
1184   }
1185
1186   /**
1187    * Bean property setter:  <property>discriminator</property>.
1188    *
1189    * @param value
1190    *    The new value for this property.
1191    *    <br>Can be <jk>null</jk> to unset the property.
1192    * @return This object (for method chaining).
1193    */
1194   public SchemaInfo setDiscriminator(String value) {
1195      discriminator = value;
1196      return this;
1197   }
1198
1199   /**
1200    * Same as {@link #setDiscriminator(String)}.
1201    *
1202    * @param value
1203    *    The new value for this property.
1204    *    <br>Non-String values will be converted to String using <c>toString()</c>.
1205    *    <br>Can be <jk>null</jk> to unset the property.
1206    * @return This object (for method chaining).
1207    */
1208   public SchemaInfo discriminator(Object value) {
1209      return setDiscriminator(stringify(value));
1210   }
1211
1212   /**
1213    * Bean property getter:  <property>readOnly</property>.
1214    *
1215    * @return The property value, or <jk>null</jk> if it is not set.
1216    */
1217   public Boolean getReadOnly() {
1218      return readOnly;
1219   }
1220
1221   /**
1222    * Bean property setter:  <property>readOnly</property>.
1223    *
1224    * @param value
1225    *    The new value for this property.
1226    *    <br>Can be <jk>null</jk> to unset the property.
1227    * @return This object (for method chaining).
1228    */
1229   public SchemaInfo setReadOnly(Boolean value) {
1230      readOnly = value;
1231      return this;
1232   }
1233
1234   /**
1235    * Same as {@link #setReadOnly(Boolean)}.
1236    *
1237    * @param value
1238    *    The new value for this property.
1239    *    <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>.
1240    *    <br>Can be <jk>null</jk> to unset the property.
1241    * @return This object (for method chaining).
1242    */
1243   public SchemaInfo readOnly(Object value) {
1244      return setReadOnly(toBoolean(value));
1245   }
1246
1247   /**
1248    * Bean property getter:  <property>xml</property>.
1249    *
1250    * @return The property value, or <jk>null</jk> if it is not set.
1251    */
1252   public Xml getXml() {
1253      return xml;
1254   }
1255
1256   /**
1257    * Bean property setter:  <property>xml</property>.
1258    *
1259    * @param value
1260    *    The new value for this property.
1261    *    <br>Can be <jk>null</jk> to unset the property.
1262    * @return This object (for method chaining).
1263    */
1264   public SchemaInfo setXml(Xml value) {
1265      xml = value;
1266      return this;
1267   }
1268
1269   /**
1270    * Same as {@link #setXml(Xml)}.
1271    *
1272    * @param value
1273    *    The new value for this property.
1274    *    <br>Valid types:
1275    *    <ul>
1276    *       <li>{@link Xml}
1277    *       <li><c>String</c> - JSON object representation of {@link Xml}
1278    *          <h5 class='figure'>Example:</h5>
1279    *          <p class='bcode w800'>
1280    *    xml(<js>"{name:'name',namespace:'namespace',...}"</js>);
1281    *          </p>
1282    *    </ul>
1283    *    <br>Can be <jk>null</jk> to unset the property.
1284    * @return This object (for method chaining).
1285    */
1286   public SchemaInfo xml(Object value) {
1287      return setXml(toType(value, Xml.class));
1288   }
1289
1290   /**
1291    * Bean property getter:  <property>externalDocs</property>.
1292    *
1293    * @return The property value, or <jk>null</jk> if it is not set.
1294    */
1295   public ExternalDocumentation getExternalDocs() {
1296      return externalDocs;
1297   }
1298
1299   /**
1300    * Bean property setter:  <property>externalDocs</property>.
1301    *
1302    * @param value
1303    *    The new value for this property.
1304    *    <br>Can be <jk>null</jk> to unset the property.
1305    * @return This object (for method chaining).
1306    */
1307   public SchemaInfo setExternalDocs(ExternalDocumentation value) {
1308      externalDocs = value;
1309      return this;
1310   }
1311
1312   /**
1313    * Same as {@link #setExternalDocs(ExternalDocumentation)}.
1314    *
1315    * @param value
1316    *    The new value for this property.
1317    *    <br>Valid types:
1318    *    <ul>
1319    *       <li>{@link ExternalDocumentation}
1320    *       <li><c>String</c> - JSON object representation of {@link ExternalDocumentation}
1321    *          <h5 class='figure'>Example:</h5>
1322    *          <p class='bcode w800'>
1323    *    externalDocs(<js>"{description:'description',url:'url'}"</js>);
1324    *          </p>
1325    *    </ul>
1326    *    <br>Can be <jk>null</jk> to unset the property.
1327    * @return This object (for method chaining).
1328    */
1329   public SchemaInfo externalDocs(Object value) {
1330      return setExternalDocs(toType(value, ExternalDocumentation.class));
1331   }
1332
1333   /**
1334    * Bean property getter:  <property>example</property>.
1335    *
1336    * @return The property value, or <jk>null</jk> if it is not set.
1337    */
1338   public Object getExample() {
1339      return example;
1340   }
1341
1342   /**
1343    * Bean property setter:  <property>example</property>.
1344    *
1345    * @param value
1346    *    The new value for this property.
1347    *    <br>Can be <jk>null</jk> to unset the property.
1348    * @return This object (for method chaining).
1349    */
1350   public SchemaInfo setExample(Object value) {
1351      example = value;
1352      return this;
1353   }
1354
1355   /**
1356    * Same as {@link #setExample(Object)}.
1357    *
1358    * @param value
1359    *    The new value for this property.
1360    *    <br>Can be <jk>null</jk> to unset the property.
1361    * @return This object (for method chaining).
1362    */
1363   public SchemaInfo example(Object value) {
1364      return setExample(value);
1365   }
1366
1367   /**
1368    * Bean property getter:  <property>$ref</property>.
1369    *
1370    * @return The property value, or <jk>null</jk> if it is not set.
1371    */
1372   @Beanp("$ref")
1373   public String getRef() {
1374      return ref;
1375   }
1376
1377   /**
1378    * Returns <jk>true</jk> if this object has a <js>"$ref"</js> attribute.
1379    *
1380    * @return <jk>true</jk> if this object has a <js>"$ref"</js> attribute.
1381    */
1382   public boolean hasRef() {
1383      return ref != null;
1384   }
1385
1386   /**
1387    * Bean property setter:  <property>$ref</property>.
1388    *
1389    * @param value
1390    *    The new value for this property.
1391    *    <br>Can be <jk>null</jk> to unset the property.
1392    * @return This object (for method chaining).
1393    */
1394   @Beanp("$ref")
1395   public SchemaInfo setRef(Object value) {
1396      ref = StringUtils.stringify(value);
1397      return this;
1398   }
1399
1400   /**
1401    * Same as {@link #setRef(Object)}.
1402    *
1403    * @param value
1404    *    The new value for this property.
1405    *    <br>Can be <jk>null</jk> to unset the property.
1406    * @return This object (for method chaining).
1407    */
1408   public SchemaInfo ref(Object value) {
1409      return setRef(value);
1410   }
1411
1412   @Override /* SwaggerElement */
1413   public <T> T get(String property, Class<T> type) {
1414      if (property == null)
1415         return null;
1416      switch (property) {
1417         case "format": return toType(getFormat(), type);
1418         case "title": return toType(getTitle(), type);
1419         case "description": return toType(getDescription(), type);
1420         case "default": return toType(getDefault(), type);
1421         case "multipleOf": return toType(getMultipleOf(), type);
1422         case "maximum": return toType(getMaximum(), type);
1423         case "exclusiveMaximum": return toType(getExclusiveMaximum(), type);
1424         case "minimum": return toType(getMinimum(), type);
1425         case "exclusiveMinimum": return toType(getExclusiveMinimum(), type);
1426         case "maxLength": return toType(getMaxLength(), type);
1427         case "minLength": return toType(getMinLength(), type);
1428         case "pattern": return toType(getPattern(), type);
1429         case "maxItems": return toType(getMaxItems(), type);
1430         case "minItems": return toType(getMinItems(), type);
1431         case "uniqueItems": return toType(getUniqueItems(), type);
1432         case "maxProperties": return toType(getMaxProperties(), type);
1433         case "minProperties": return toType(getMinProperties(), type);
1434         case "required": return toType(getRequired(), type);
1435         case "enum": return toType(getEnum(), type);
1436         case "type": return toType(getType(), type);
1437         case "items": return toType(getItems(), type);
1438         case "allOf": return toType(getAllOf(), type);
1439         case "properties": return toType(getProperties(), type);
1440         case "additionalProperties": return toType(getAdditionalProperties(), type);
1441         case "discriminator": return toType(getDiscriminator(), type);
1442         case "readOnly": return toType(getReadOnly(), type);
1443         case "xml": return toType(getXml(), type);
1444         case "externalDocs": return toType(getExternalDocs(), type);
1445         case "example": return toType(getExample(), type);
1446         case "$ref": return toType(getRef(), type);
1447         default: return super.get(property, type);
1448      }
1449   }
1450
1451   @Override /* SwaggerElement */
1452   public SchemaInfo set(String property, Object value) {
1453      if (property == null)
1454         return this;
1455      switch (property) {
1456         case "format": return format(value);
1457         case "title": return title(value);
1458         case "description": return description(value);
1459         case "default": return _default(value);
1460         case "multipleOf": return multipleOf(value);
1461         case "maximum": return maximum(value);
1462         case "exclusiveMaximum": return exclusiveMaximum(value);
1463         case "minimum": return minimum(value);
1464         case "exclusiveMinimum": return exclusiveMinimum(value);
1465         case "maxLength": return maxLength(value);
1466         case "minLength": return minLength(value);
1467         case "pattern": return pattern(value);
1468         case "maxItems": return maxItems(value);
1469         case "minItems": return minItems(value);
1470         case "uniqueItems": return uniqueItems(value);
1471         case "maxProperties": return maxProperties(value);
1472         case "minProperties": return minProperties(value);
1473         case "required": return setRequired(null).required(value);
1474         case "enum": return setEnum(null)._enum(value);
1475         case "type": return type(value);
1476         case "items": return items(value);
1477         case "allOf": return setAllOf(null).allOf(value);
1478         case "properties": return setProperties(null).properties(value);
1479         case "additionalProperties": return additionalProperties(value);
1480         case "discriminator": return discriminator(value);
1481         case "readOnly": return readOnly(value);
1482         case "xml": return xml(value);
1483         case "externalDocs": return externalDocs(value);
1484         case "example": return example(value);
1485         case "$ref": return ref(value);
1486         default:
1487            super.set(property, value);
1488            return this;
1489      }
1490   }
1491
1492   @Override /* SwaggerElement */
1493   public Set<String> keySet() {
1494      ASet<String> s = new ASet<String>()
1495         .appendIf(format != null, "format")
1496         .appendIf(title != null, "title")
1497         .appendIf(description != null, "description")
1498         .appendIf(_default != null, "default")
1499         .appendIf(multipleOf != null, "multipleOf")
1500         .appendIf(maximum != null, "maximum")
1501         .appendIf(exclusiveMaximum != null, "exclusiveMaximum")
1502         .appendIf(minimum != null, "minimum")
1503         .appendIf(exclusiveMinimum != null, "exclusiveMinimum")
1504         .appendIf(maxLength != null, "maxLength")
1505         .appendIf(minLength != null, "minLength")
1506         .appendIf(pattern != null, "pattern")
1507         .appendIf(maxItems != null, "maxItems")
1508         .appendIf(minItems != null, "minItems")
1509         .appendIf(uniqueItems != null, "uniqueItems")
1510         .appendIf(maxProperties != null, "maxProperties")
1511         .appendIf(minProperties != null, "minProperties")
1512         .appendIf(required != null, "required")
1513         .appendIf(_enum != null, "enum")
1514         .appendIf(type != null, "type")
1515         .appendIf(items != null, "items")
1516         .appendIf(allOf != null, "allOf")
1517         .appendIf(properties != null, "properties")
1518         .appendIf(additionalProperties != null, "additionalProperties")
1519         .appendIf(discriminator != null, "discriminator")
1520         .appendIf(readOnly != null, "readOnly")
1521         .appendIf(xml != null, "xml")
1522         .appendIf(externalDocs != null, "externalDocs")
1523         .appendIf(example != null, "example")
1524         .appendIf(ref != null, "$ref");
1525      return new MultiSet<>(s, super.keySet());
1526   }
1527
1528
1529
1530   /**
1531    * Returns <jk>true</jk> if this schema info has one or more properties defined on it.
1532    *
1533    * @return <jk>true</jk> if this schema info has one or more properties defined on it.
1534    */
1535   public boolean hasProperties() {
1536      return properties != null && ! properties.isEmpty();
1537   }
1538
1539   /**
1540    * Resolves any <js>"$ref"</js> attributes in this element.
1541    *
1542    * @param swagger The swagger document containing the definitions.
1543    * @param refStack Keeps track of previously-visited references so that we don't cause recursive loops.
1544    * @param maxDepth
1545    *    The maximum depth to resolve references.
1546    *    <br>After that level is reached, <c>$ref</c> references will be left alone.
1547    *    <br>Useful if you have very complex models and you don't want your swagger page to be overly-complex.
1548    * @return
1549    *    This object with references resolved.
1550    *    <br>May or may not be the same object.
1551    */
1552   public SchemaInfo resolveRefs(Swagger swagger, Deque<String> refStack, int maxDepth) {
1553
1554      if (ref != null) {
1555         if (refStack.contains(ref) || refStack.size() >= maxDepth)
1556            return this;
1557         refStack.addLast(ref);
1558         SchemaInfo r = swagger.findRef(ref, SchemaInfo.class).resolveRefs(swagger, refStack, maxDepth);
1559         refStack.removeLast();
1560         return r;
1561      }
1562
1563      if (items != null)
1564         items = items.resolveRefs(swagger, refStack, maxDepth);
1565
1566      if (properties != null)
1567         for (Map.Entry<String,SchemaInfo> e : properties.entrySet())
1568            e.setValue(e.getValue().resolveRefs(swagger, refStack, maxDepth));
1569
1570      if (additionalProperties != null)
1571         additionalProperties = additionalProperties.resolveRefs(swagger, refStack, maxDepth);
1572
1573      this.example = null;
1574
1575      return this;
1576   }
1577}