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