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