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