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 java.util.*;
017
018import org.apache.juneau.annotation.*;
019import org.apache.juneau.http.*;
020import org.apache.juneau.json.*;
021
022/**
023 * This is the root document object for the API specification.
024 * 
025 * <h5 class='section'>See Also:</h5>
026 * <ul class='doctree'>
027 *    <li class='link'><a class='doclink' href='../../../../../overview-summary.html#juneau-dto.Swagger'>Overview &gt; juneau-dto &gt; Swagger</a>
028 * </ul>
029 */
030@Bean(properties="swagger,info,tags,externalDocs,basePath,schemes,consumes,produces,paths,definitions,parameters,responses,securityDefinitions,security,*")
031public class Swagger extends SwaggerElement {
032
033   /** Represents a null swagger */
034   public static final Swagger NULL = new Swagger();
035
036   private String 
037      swagger = "2.0",
038      host, 
039      basePath;
040   private Info info;
041   private ExternalDocumentation externalDocs;
042   private List<String> schemes;
043   private List<MediaType> 
044      consumes,
045      produces;
046   private List<Tag> tags;
047   private List<Map<String,List<String>>> security;
048   private Map<String,SchemaInfo> definitions;
049   private Map<String,ParameterInfo> parameters;
050   private Map<String,ResponseInfo> responses;
051   private Map<String,SecurityScheme> securityDefinitions;
052   private Map<String,Map<String,Operation>> paths;
053
054   /**
055    * Bean property getter:  <property>swagger</property>.
056    * 
057    * <p>
058    * Specifies the Swagger Specification version being used.
059    * 
060    * <p>
061    * It can be used by the Swagger UI and other clients to interpret the API listing.
062    * 
063    * @return The property value, or <jk>null</jk> if it is not set.
064    */
065   public String getSwagger() {
066      return swagger;
067   }
068
069   /**
070    * Bean property setter:  <property>swagger</property>.
071    * 
072    * <p>
073    * Specifies the Swagger Specification version being used.
074    * 
075    * <p>
076    * It can be used by the Swagger UI and other clients to interpret the API listing.
077    * 
078    * @param value 
079    *    The new value for this property.
080    *    <br>Property value is required.
081    * @return This object (for method chaining).
082    */
083   public Swagger setSwagger(String value) {
084      swagger = value;
085      return this;
086   }
087
088   /**
089    * Same as {@link #setSwagger(String)}.
090    * 
091    * @param value
092    *    The new value for this property.
093    *    <br>Non-String values will be converted to String using <code>toString()</code>.
094    *    <br>Can be <jk>null</jk> to unset the property.
095    * @return This object (for method chaining).
096    */
097   public Swagger swagger(Object value) {
098      return setSwagger(toStringVal(value));
099   }
100
101   /**
102    * Bean property getter:  <property>info</property>.
103    * 
104    * <p>
105    * Provides metadata about the API.
106    * 
107    * <p>
108    * The metadata can be used by the clients if needed.
109    * 
110    * @return The property value, or <jk>null</jk> if it is not set.
111    */
112   public Info getInfo() {
113      return info;
114   }
115
116   /**
117    * Bean property setter:  <property>info</property>.
118    * 
119    * <p>
120    * Provides metadata about the API.
121    * 
122    * <p>
123    * The metadata can be used by the clients if needed.
124    * 
125    * @param value 
126    *    The new value for this property.
127    *    <br>Property value is required.
128    * @return This object (for method chaining).
129    */
130   public Swagger setInfo(Info value) {
131      info = value;
132      return this;
133   }
134
135   /**
136    * Same as {@link #setInfo(Info)}.
137    * 
138    * @param value 
139    *    The new value for this property.
140    *    <br>Valid types:
141    *    <ul>
142    *       <li>{@link Info}
143    *       <li><code>String</code> - JSON object representation of {@link Info}
144    *          <h5 class='figure'>Example:</h5>
145    *          <p class='bcode'>
146    *    info(<js>"{title:'title',description:'description',...}"</js>);
147    *          </p>
148    *    </ul>
149    *    <br>Property value is required.
150    * @return This object (for method chaining).
151    */
152   public Swagger info(Object value) {
153      return setInfo(toType(value, Info.class));
154   }
155
156   /**
157    * Bean property getter:  <property>host</property>.
158    * 
159    * <p>
160    * The host (name or IP) serving the API.
161    * 
162    * @return The property value, or <jk>null</jk> if it is not set.
163    */
164   public String getHost() {
165      return host;
166   }
167
168   /**
169    * Bean property setter:  <property>host</property>.
170    * 
171    * <p>
172    * The host (name or IP) serving the API.
173    * 
174    * @param value 
175    *    The new value for this property.
176    *    <br>This MUST be the host only and does not include the scheme nor sub-paths.
177    *    <br>It MAY include a port.
178    *    <br>If the host is not included, the host serving the documentation is to be used (including the port).
179    *    <br>The host does not support <a class="doclink" href="http://swagger.io/specification/#pathTemplating">
180    *       path templating</a>
181    *    <br>Can be <jk>null</jk> to unset the property.
182    * @return This object (for method chaining).
183    */
184   public Swagger setHost(String value) {
185      host = value;
186      return this;
187   }
188
189   /**
190    * Same as {@link #setHost(String)}.
191    * 
192    * @param value
193    *    The new value for this property.
194    *    <br>Non-String values will be converted to String using <code>toString()</code>.
195    *    <br>This MUST be the host only and does not include the scheme nor sub-paths.
196    *    <br>It MAY include a port.
197    *    <br>If the host is not included, the host serving the documentation is to be used (including the port).
198    *    <br>The host does not support <a class="doclink" href="http://swagger.io/specification/#pathTemplating">path templating</a>
199    *    <br>Can be <jk>null</jk> to unset the property.
200    * @return This object (for method chaining).
201    */
202   public Swagger host(Object value) {
203      return setHost(toStringVal(value));
204   }
205
206   /**
207    * Bean property getter:  <property>basePath</property>.
208    * 
209    * <p>
210    * The base path on which the API is served, which is relative to the <code>host</code>.
211    * 
212    * @return The property value, or <jk>null</jk> if it is not set.
213    */
214   public String getBasePath() {
215      return basePath;
216   }
217
218   /**
219    * Bean property setter:  <property>basePath</property>.
220    * 
221    * <p>
222    * The base path on which the API is served, which is relative to the <code>host</code>.
223    * 
224    * @param value 
225    *    The new value for this property.
226    *    <br>If it is not included, the API is served directly under the <code>host</code>.
227    *    <br>The value MUST start with a leading slash (/).
228    *    <br>The <code>basePath</code> does not support <a class="doclink" href="http://swagger.io/specification/#pathTemplating">path templating</a>.
229    *    <br>Can be <jk>null</jk> to unset the property.
230    * @return This object (for method chaining).
231    */
232   public Swagger setBasePath(String value) {
233      basePath = value;
234      return this;
235   }
236
237   /**
238    * Same as {@link #setBasePath(String)}.
239    * 
240    * @param value
241    *    The new value for this property.
242    *    <br>Non-String values will be converted to String using <code>toString()</code>.
243    *    <br>If it is not included, the API is served directly under the <code>host</code>.
244    *    <br>The value MUST start with a leading slash (/).
245    *    <br>The <code>basePath</code> does not support <a class="doclink" href="http://swagger.io/specification/#pathTemplating">path templating</a>.
246    *    <br>Can be <jk>null</jk> to unset the property.
247    * @return This object (for method chaining).
248    */
249   public Swagger basePath(Object value) {
250      return setBasePath(toStringVal(value));
251   }
252
253   /**
254    * Bean property getter:  <property>schemes</property>.
255    * 
256    * <p>
257    * The transfer protocol of the API.
258    * 
259    * <p>
260    * If the <code>schemes</code> is not included, the default scheme to be used is the one used to access the Swagger
261    * definition itself.
262    * 
263    * @return The property value, or <jk>null</jk> if it is not set.
264    */
265   public List<String> getSchemes() {
266      return schemes;
267   }
268
269   /**
270    * Bean property setter:  <property>schemes</property>.
271    * 
272    * <p>
273    * The transfer protocol of the API.
274    * 
275    * <p>
276    * If the <code>schemes</code> is not included, the default scheme to be used is the one used to access the Swagger
277    * definition itself.
278    * 
279    * @param value 
280    *    The new value for this property.
281    *    <br>Valid values:
282    *    <ul>
283    *       <li><js>"http"</js>
284    *       <li><js>"https"</js>
285    *       <li><js>"ws"</js>
286    *       <li><js>"wss"</js>
287    *    </ul>
288    *    <br>Can be <jk>null</jk> to unset the property.
289    * @return This object (for method chaining).
290    */
291   public Swagger setSchemes(Collection<String> value) {
292      schemes = newList(value);
293      return this;
294   }
295
296   /**
297    * Adds one or more values to the <property>schemes</property> property.
298    * 
299    * <p>
300    * The transfer protocol of the API.
301    * 
302    * <p>
303    * Values MUST be from the list:  <js>"http"</js>, <js>"https"</js>, <js>"ws"</js>, <js>"wss"</js>.
304    * If the <code>schemes</code> is not included, the default scheme to be used is the one used to access the Swagger
305    * definition itself.
306    * 
307    * @param values 
308    *    The values to add to this property.
309    *    <br>Valid values:
310    *    <ul>
311    *       <li><js>"http"</js>
312    *       <li><js>"https"</js>
313    *       <li><js>"ws"</js>
314    *       <li><js>"wss"</js>
315    *    </ul>
316    *    <br>Ignored if <jk>null</jk>.
317    * @return This object (for method chaining).
318    */
319   public Swagger addSchemes(Collection<String> values) {
320      schemes = addToList(schemes, values);
321      return this;
322   }
323
324   /**
325    * Same as {@link #addSchemes(Collection)}.
326    * 
327    * @param values
328    *    The values to add to this property.
329    *    <br>Valid types:
330    *    <ul>
331    *       <li><code>Collection&lt;String&gt;</code>
332    *       <li><code>String</code> - JSON array representation of <code>Collection&lt;String&gt;</code>
333    *       <h5 class='figure'>Example:</h5>
334    *       <p class='bcode'>
335    *    schemes(<js>"['scheme1','scheme2']"</js>);
336    *       </p>
337    *       <li><code>String</code> - Individual values
338    *       <h5 class='figure'>Example:</h5>
339    *       <p class='bcode'>
340    *    schemes(<js>"scheme1"</js>, <js>"scheme2"</js>);
341    *       </p>
342    *    </ul>
343    * @return This object (for method chaining).
344    */
345   public Swagger schemes(Object...values) {
346      schemes = addToList(schemes, values, String.class);
347      return this;
348   }
349
350   /**
351    * Bean property getter:  <property>consumes</property>.
352    * 
353    * <p>
354    * A list of MIME types the APIs can consume.
355    * 
356    * <p>
357    * This is global to all APIs but can be overridden on specific API calls.
358    * 
359    * @return The property value, or <jk>null</jk> if it is not set.
360    */
361   public List<MediaType> getConsumes() {
362      return consumes;
363   }
364
365   /**
366    * Bean property setter:  <property>consumes</property>.
367    * 
368    * <p>
369    * A list of MIME types the APIs can consume.
370    * 
371    * <p>
372    * This is global to all APIs but can be overridden on specific API calls.
373    * 
374    * @param value 
375    *    The new value for this property.
376    *    <br>Value MUST be as described under <a class="doclink" href="http://swagger.io/specification/#mimeTypes">Mime Types</a>.
377    *    <br>Can be <jk>null</jk> to unset the property.
378    * @return This object (for method chaining).
379    */
380   public Swagger setConsumes(Collection<MediaType> value) {
381      consumes = newList(value);
382      return this;
383   }
384
385   /**
386    * Adds one or more values to the <property>consumes</property> property.
387    * 
388    * <p>
389    * A list of MIME types the operation can consume.
390    * This overrides the <code>consumes</code> definition at the Swagger Object.
391    * An empty value MAY be used to clear the global definition.
392    * Value MUST be as described under <a class="doclink" href="http://swagger.io/specification/#mimeTypes">Mime Types</a>.
393    * 
394    * @param values 
395    *    The values to add to this property.
396    *    <br>Values MUST be as described under <a class="doclink" href="http://swagger.io/specification/#mimeTypes">Mime Types</a>.
397    *    <br>Ignored if <jk>null</jk>.
398    * @return This object (for method chaining).
399    */
400   public Swagger addConsumes(Collection<MediaType> values) {
401      consumes = addToList(consumes, values);
402      return this;
403   }
404
405   /**
406    * Adds one or more values to the <property>consumes</property> property.
407    * 
408    * @param values
409    *    The values to add to this property.
410    *    <br>Valid types:
411    *    <ul>
412    *       <li>{@link MediaType}
413    *       <li><code>Collection&lt;{@link MediaType}|String&gt;</code>
414    *       <li><code>String</code> - JSON array representation of <code>Collection&lt;{@link MediaType}&gt;</code>
415    *          <h5 class='figure'>Example:</h5>
416    *          <p class='bcode'>
417    *    consumes(<js>"['text/json']"</js>);
418    *          </p>
419    *       <li><code>String</code> - Individual values
420    *          <h5 class='figure'>Example:</h5>
421    *          <p class='bcode'>
422    *    consumes(<js>"text/json"</js>);
423    *          </p>
424    *    </ul>
425    *    <br>Ignored if <jk>null</jk>.
426    * @return This object (for method chaining).
427    */
428   public Swagger consumes(Object...values) {
429      consumes = addToList(consumes, values, MediaType.class);
430      return this;
431   }
432   
433   /**
434    * Bean property getter:  <property>produces</property>.
435    * 
436    * <p>
437    * A list of MIME types the APIs can produce.
438    * 
439    * <p>
440    * This is global to all APIs but can be overridden on specific API calls.
441    * 
442    * @return The property value, or <jk>null</jk> if it is not set.
443    */
444   public List<MediaType> getProduces() {
445      return produces;
446   }
447
448   /**
449    * Bean property setter:  <property>produces</property>.
450    * 
451    * <p>
452    * A list of MIME types the APIs can produce.
453    * 
454    * <p>
455    * This is global to all APIs but can be overridden on specific API calls.
456    * 
457    * @param value 
458    *    The new value for this property.
459    *    <br>Value MUST be as described under <a class="doclink" href="http://swagger.io/specification/#mimeTypes">Mime Types</a>.
460    *    <br>Can be <jk>null</jk> to unset the property.
461    * @return This object (for method chaining).
462    */
463   public Swagger setProduces(Collection<MediaType> value) {
464      produces = newList(value);
465      return this;
466   }
467
468   /**
469    * Adds one or more values to the <property>produces</property> property.
470    * 
471    * <p>
472    * A list of MIME types the APIs can produce.
473    * 
474    * <p>
475    * This is global to all APIs but can be overridden on specific API calls.
476    * 
477    * @param values 
478    *    The values to add to this property.
479    *    <br>Value MUST be as described under <a class="doclink" href="http://swagger.io/specification/#mimeTypes">Mime Types</a>.
480    *    <br>Can be <jk>null</jk> to unset the property.
481    * @return This object (for method chaining).
482    */
483   public Swagger addProduces(Collection<MediaType> values) {
484      produces = addToList(produces, values);
485      return this;
486   }
487
488   /**
489    * Adds one or more values to the <property>produces</property> property.
490    * 
491    * @param values
492    *    The values to add to this property.
493    *    <br>Valid types:
494    *    <ul>
495    *       <li>{@link MediaType}
496    *       <li><code>Collection&lt;{@link MediaType}|String&gt;</code>
497    *       <li><code>String</code> - JSON array representation of <code>Collection&lt;{@link MediaType}&gt;</code>
498    *          <h5 class='figure'>Example:</h5>
499    *          <p class='bcode'>
500    *    consumes(<js>"['text/json']"</js>);
501    *          </p>
502    *       <li><code>String</code> - Individual values
503    *          <h5 class='figure'>Example:</h5>
504    *          <p class='bcode'>
505    *    consumes(<js>"text/json"</js>);
506    *          </p>
507    *    </ul>
508    *    <br>Ignored if <jk>null</jk>.
509    * @return This object (for method chaining).
510    */
511   public Swagger produces(Object...values) {
512      produces = addToList(produces, values, MediaType.class);
513      return this;
514   }
515
516   /**
517    * Bean property getter:  <property>paths</property>.
518    * 
519    * <p>
520    * The available paths and operations for the API.
521    * 
522    * @return The property value, or <jk>null</jk> if it is not set.
523    */
524   public Map<String,Map<String,Operation>> getPaths() {
525      return paths;
526   }
527
528   /**
529    * Bean property setter:  <property>paths</property>.
530    * 
531    * <p>
532    * The available paths and operations for the API.
533    * 
534    * @param value 
535    *    The new value for this property.
536    *    <br>Property value is required.
537    * @return This object (for method chaining).
538    */
539   public Swagger setPaths(Map<String,Map<String,Operation>> value) {
540      paths = newMap(value);
541      return this;
542   }
543
544   /**
545    * Adds one or more values to the <property>produces</property> property.
546    * 
547    * <p>
548    * A list of MIME types the APIs can produce.
549    * 
550    * <p>
551    * This is global to all APIs but can be overridden on specific API calls.
552    * 
553    * @param values 
554    *    The values to add to this property.
555    *    <br>Ignored if <jk>null</jk>.
556    * @return This object (for method chaining).
557    */
558   public Swagger addPaths(Map<String,Map<String,Operation>> values) {
559      paths = addToMap(paths, values);
560      return this;
561   }
562   
563   /**
564    * Adds a single value to the <property>paths</property> property.
565    * 
566    * @param path The path template.
567    * @param methodName The HTTP method name.
568    * @param operation The operation that describes the path.
569    * @return This object (for method chaining).
570    */
571   public Swagger path(String path, String methodName, Operation operation) {
572      if (paths == null)
573         paths = new LinkedHashMap<>();
574      Map<String,Operation> p = paths.get(path);
575      if (p == null) {
576         p = new LinkedHashMap<>();
577         paths.put(path, p);
578      }
579      p.put(methodName, operation);
580      return this;
581   }
582
583   /**
584    * Adds one or more values to the <property>paths</property> property.
585    * 
586    * @param values
587    *    The values to add to this property.
588    *    <br>Valid types:
589    *    <ul>
590    *       <li><code>Map&lt;String,Map&lt;String,{@link Operation}&gt;|String&gt;</code>
591    *       <li><code>String</code> - JSON object representation of <code>Map&lt;String,Map&lt;String,{@link Operation}&gt;&gt;</code>
592    *          <h5 class='figure'>Example:</h5>
593    *          <p class='bcode'>
594    *    paths(<js>"{'foo':{'get':{operationId:'operationId',...}}}"</js>);
595    *          </p>
596    *    </ul>
597    *    <br>Ignored if <jk>null</jk>.
598    * @return This object (for method chaining).
599    */
600   @SuppressWarnings({ "unchecked", "rawtypes" })
601   public Swagger paths(Object...values) {
602      paths = addToMap((Map)paths, values, String.class, Map.class, String.class, Operation.class);
603      return this;
604   }
605   
606   /**
607    * Bean property getter:  <property>definitions</property>.
608    * 
609    * <p>
610    * An object to hold data types produced and consumed by operations.
611    * 
612    * @return The property value, or <jk>null</jk> if it is not set.
613    */
614   public Map<String,SchemaInfo> getDefinitions() {
615      return definitions;
616   }
617
618   /**
619    * Bean property setter:  <property>definitions</property>.
620    * 
621    * <p>
622    * An object to hold data types produced and consumed by operations.
623    * 
624    * @param value 
625    *    The new value for this property.
626    *    <br>Can be <jk>null</jk> to unset the property.
627    * @return This object (for method chaining).
628    */
629   public Swagger setDefinitions(Map<String,SchemaInfo> value) {
630      definitions = newMap(value);
631      return this;
632   }
633
634   /**
635    * Adds one or more values to the <property>definitions</property> property.
636    * 
637    * <p>
638    * An object to hold data types produced and consumed by operations.
639    * 
640    * @param values 
641    *    The values to add to this property.
642    *    <br>Ignored if <jk>null</jk>.
643    * @return This object (for method chaining).
644    */
645   public Swagger addDefinitions(Map<String,SchemaInfo> values) {
646      definitions = addToMap(definitions, values);
647      return this;
648   }
649
650   /**
651    * Adds a single value to the <property>definitions</property> property.
652    * 
653    * @param name A definition name.
654    * @param schema The schema that the name defines.
655    * @return This object (for method chaining).
656    */
657   public Swagger definition(String name, SchemaInfo schema) {
658      definitions = addToMap(definitions, name, schema);
659      return this;
660   }
661
662   /**
663    * Adds one or more values to the <property>definitions</property> property.
664    * 
665    * @param values
666    *    The values to add to this property.
667    *    <br>Valid types:
668    *    <ul>
669    *       <li><code>Map&lt;String,Map&lt;String,{@link SchemaInfo}&gt;|String&gt;</code>
670    *       <li><code>String</code> - JSON object representation of <code>Map&lt;String,Map&lt;String,{@link SchemaInfo}&gt;&gt;</code>
671    *          <h5 class='figure'>Example:</h5>
672    *          <p class='bcode'>
673    *    definitions(<js>"{'foo':{'bar':{format:'format',...}}}"</js>);
674    *          </p>
675    *    </ul>
676    *    <br>Ignored if <jk>null</jk>.
677    * @return This object (for method chaining).
678    */
679   public Swagger definitions(Object...values) {
680      definitions = addToMap(definitions, values, String.class, SchemaInfo.class);
681      return this;
682   }
683
684   /**
685    * Bean property getter:  <property>parameters</property>.
686    * 
687    * <p>
688    * An object to hold parameters that can be used across operations.
689    * 
690    * <p>
691    * This property does not define global parameters for all operations.
692    * 
693    * @return The property value, or <jk>null</jk> if it is not set.
694    */
695   public Map<String,ParameterInfo> getParameters() {
696      return parameters;
697   }
698
699   /**
700    * Bean property setter:  <property>parameters</property>.
701    * 
702    * <p>
703    * An object to hold parameters that can be used across operations.
704    * 
705    * <p>
706    * This property does not define global parameters for all operations.
707    * 
708    * @param value
709    *    The new value for this property.
710    *    <br>Can be <jk>null</jk> to unset the property.
711    * @return This object (for method chaining).
712    */
713   public Swagger setParameters(Map<String,ParameterInfo> value) {
714      parameters = newMap(value);
715      return this;
716   }
717
718   /**
719    * Adds one or more values to the <property>parameters</property> property.
720    * 
721    * <p>
722    * An object to hold parameters that can be used across operations.
723    * 
724    * <p>
725    * This property does not define global parameters for all operations.
726    * 
727    * @param values 
728    *    The values to add to this property.
729    *    <br>Ignored if <jk>null</jk>.
730    * @return This object (for method chaining).
731    */
732   public Swagger addParameters(Map<String,ParameterInfo> values) {
733      parameters = addToMap(parameters, values);
734      return this;
735   }
736
737   /**
738    * Adds a single value to the <property>parameter</property> property.
739    * 
740    * @param name The parameter name.
741    * @param parameter The parameter definition.
742    * @return This object (for method chaining).
743    */
744   public Swagger parameter(String name, ParameterInfo parameter) {
745      parameters = addToMap(parameters, name, parameter);
746      return this;
747   }
748
749   /**
750    * Adds one or more values to the <property>properties</property> property.
751    * 
752    * @param values
753    *    The values to add to this property.
754    *    <br>Valid types:
755    *    <ul>
756    *       <li><code>Map&lt;String,{@link ParameterInfo}|String&gt;</code>
757    *       <li><code>String</code> - JSON object representation of <code>Map&lt;String,{@link ParameterInfo}&gt;</code>
758    *          <h5 class='figure'>Example:</h5>
759    *          <p class='bcode'>
760    *    parameters(<js>"{'foo':{name:'name',...}}"</js>);
761    *          </p>
762    *    </ul>
763    *    <br>Ignored if <jk>null</jk>.
764    * @return This object (for method chaining).
765    */
766   public Swagger parameters(Object...values) {
767      parameters = addToMap(parameters, values, String.class, ParameterInfo.class);
768      return this;
769   }
770
771   /**
772    * Bean property getter:  <property>responses</property>.
773    * 
774    * <p>
775    * An object to hold responses that can be used across operations.
776    * 
777    * <p>
778    * This property does not define global responses for all operations.
779    * 
780    * @return The property value, or <jk>null</jk> if it is not set.
781    */
782   public Map<String,ResponseInfo> getResponses() {
783      return responses;
784   }
785
786   /**
787    * Bean property setter:  <property>responses</property>.
788    * 
789    * <p>
790    * An object to hold responses that can be used across operations.
791    * 
792    * <p>
793    * This property does not define global responses for all operations.
794    * 
795    * @param value 
796    *    The new value for this property.
797    *    <br>Can be <jk>null</jk> to unset the property.
798    * @return This object (for method chaining).
799    */
800   public Swagger setResponses(Map<String,ResponseInfo> value) {
801      responses = newMap(value);
802      return this;
803   }
804
805   /**
806    * Adds one or more values to the <property>responses</property> property.
807    * 
808    * <p>
809    * An object to hold responses that can be used across operations.
810    * 
811    * <p>
812    * This property does not define global responses for all operations.
813    * 
814    * @param values 
815    *    The values to add to this property.
816    *    <br>Ignored if <jk>null</jk>.
817    * @return This object (for method chaining).
818    */
819   public Swagger addResponses(Map<String,ResponseInfo> values) {
820      responses = addToMap(responses, values);
821      return this;
822   }
823
824   /**
825    * Adds a single value to the <property>responses</property> property.
826    * 
827    * @param name The response name.
828    * @param response The response definition.
829    * @return This object (for method chaining).
830    */
831   public Swagger response(String name, ResponseInfo response) {
832      responses = addToMap(responses, name, response);
833      return this;
834   }
835
836   /**
837    * Adds one or more values to the <property>properties</property> property.
838    * 
839    * @param values
840    *    The values to add to this property.
841    *    <br>Valid types:
842    *    <ul>
843    *       <li><code>Map&lt;String,{@link ResponseInfo}|String&gt;</code>
844    *       <li><code>String</code> - JSON object representation of <code>Map&lt;String,{@link ResponseInfo}&gt;</code>
845    *          <h5 class='figure'>Example:</h5>
846    *          <p class='bcode'>
847    *    responses(<js>"{'foo':{description:'description',...}}"</js>);
848    *          </p>
849    *    </ul>
850    *    <br>Ignored if <jk>null</jk>.
851    * @return This object (for method chaining).
852    */
853   public Swagger responses(Object...values) {
854      responses = addToMap(responses, values, String.class, ResponseInfo.class);
855      return this;
856   }
857
858   /**
859    * Bean property getter:  <property>securityDefinitions</property>.
860    * 
861    * <p>
862    * Security scheme definitions that can be used across the specification.
863    * 
864    * @return The property value, or <jk>null</jk> if it is not set.
865    */
866   public Map<String,SecurityScheme> getSecurityDefinitions() {
867      return securityDefinitions;
868   }
869
870   /**
871    * Bean property setter:  <property>securityDefinitions</property>.
872    * 
873    * <p>
874    * Security scheme definitions that can be used across the specification.
875    * 
876    * @param value 
877    *    The new value for this property.
878    *    <br>Can be <jk>null</jk> to unset the property.
879    * @return This object (for method chaining).
880    */
881   public Swagger setSecurityDefinitions(Map<String,SecurityScheme> value) {
882      securityDefinitions = newMap(value);
883      return this;
884   }
885
886   /**
887    * Adds one or more values to the <property>securityDefinitions</property> property.
888    * 
889    * <p>
890    * Security scheme definitions that can be used across the specification.
891    * 
892    * @param values 
893    *    The values to add to this property.
894    *    <br>Ignored if <jk>null</jk>.
895    * @return This object (for method chaining).
896    */
897   public Swagger addSecurityDefinitions(Map<String,SecurityScheme> values) {
898      securityDefinitions = addToMap(securityDefinitions, values);
899      return this;
900   }
901
902   /**
903    * Adds a single value to the <property>securityDefinitions</property> property.
904    * 
905    * @param name A security name.
906    * @param securityScheme A security schema.
907    * @return This object (for method chaining).
908    */
909   public Swagger securityDefinition(String name, SecurityScheme securityScheme) {
910      securityDefinitions = addToMap(securityDefinitions, name, securityScheme);
911      return this;
912   }
913
914   /**
915    * Adds one or more values to the <property>securityDefinitions</property> property.
916    * 
917    * @param values
918    *    The values to add to this property.
919    *    <br>Valid types:
920    *    <ul>
921    *       <li><code>Map&lt;String,{@link SecurityScheme}|String&gt;</code>
922    *       <li><code>String</code> - JSON object representation of <code>Map&lt;String,{@link SecurityScheme}&gt;</code>
923    *          <h5 class='figure'>Example:</h5>
924    *          <p class='bcode'>
925    *    securityDefinitions(<js>"{'foo':{name:'name',...}}"</js>);
926    *          </p>
927    *    </ul>
928    *    <br>Ignored if <jk>null</jk>.
929    * @return This object (for method chaining).
930    */
931   public Swagger securityDefinitions(Object...values) {
932      securityDefinitions = addToMap(securityDefinitions, values, String.class, SecurityScheme.class);
933      return this;
934   }
935
936   /**
937    * Bean property getter:  <property>security</property>.
938    * 
939    * <p>
940    * A declaration of which security schemes are applied for the API as a whole.
941    * 
942    * <p>
943    * The list of values describes alternative security schemes that can be used (that is, there is a logical OR
944    * between the security requirements).
945    * <br>Individual operations can override this definition.
946    * 
947    * @return The property value, or <jk>null</jk> if it is not set.
948    */
949   public List<Map<String,List<String>>> getSecurity() {
950      return security;
951   }
952
953   /**
954    * Bean property setter:  <property>security</property>.
955    * 
956    * <p>
957    * A declaration of which security schemes are applied for the API as a whole.
958    * 
959    * <p>
960    * The list of values describes alternative security schemes that can be used (that is, there is a logical OR
961    * between the security requirements).
962    * <br>Individual operations can override this definition.
963    * 
964    * @param value
965    *    The new value for this property.
966    *    <br>Can be <jk>null</jk> to unset the property.
967    * @return This object (for method chaining).
968    */
969   public Swagger setSecurity(Collection<Map<String,List<String>>> value) {
970      security = newList(value);
971      return this;
972   }
973
974   /**
975    * Adds one or more values to the <property>security</property> property.
976    * 
977    * <p>
978    * A declaration of which security schemes are applied for the API as a whole.
979    * 
980    * <p>
981    * The list of values describes alternative security schemes that can be used (that is, there is a logical OR
982    * between the security requirements).
983    * <br>Individual operations can override this definition.
984    * 
985    * @param values 
986    *    The values to add to this property.
987    *    <br>Ignored if <jk>null</jk>.
988    * @return This object (for method chaining).
989    */
990   public Swagger addSecurity(Collection<Map<String,List<String>>> values) {
991      security = addToList(security, values);
992      return this;
993   }
994
995
996   /**
997    * Adds a single value to the <property>securityDefinitions</property> property.
998    * 
999    * @param scheme The security scheme that applies to this operation
1000    * @param alternatives 
1001    *    The list of values describes alternative security schemes that can be used (that is, there is a logical OR between the security requirements).
1002    * @return This object (for method chaining).
1003    */
1004   public Swagger security(String scheme, String...alternatives) {
1005      Map<String,List<String>> m = new LinkedHashMap<>();
1006      m.put(scheme, Arrays.asList(alternatives));
1007      return addSecurity(Collections.singleton(m));
1008   }
1009
1010   /**
1011    * Adds one or more values to the <property>securityDefinitions</property> property.
1012    * 
1013    * @param values
1014    *    The values to add to this property.
1015    *    <br>Valid types:
1016    *    <ul>
1017    *       <li><code>Collection&lt;Map&lt;String,List&lt;String&gt;&gt;&gt;</code>
1018    *       <li><code>String</code> - JSON array representation of <code>Collection&lt;Map&lt;String,List&lt;String&gt;&gt;&gt;</code>
1019    *          <h5 class='figure'>Example:</h5>
1020    *          <p class='bcode'>
1021    *    securities(<js>"[{...}]"</js>);
1022    *          </p>
1023    *       <li><code>String</code> - JSON object representation of <code>Map&lt;String,List&lt;String&gt;&gt;</code>
1024    *          <h5 class='figure'>Example:</h5>
1025    *          <p class='bcode'>
1026    *    securities(<js>"{...}"</js>);
1027    *          </p>
1028    *    </ul>
1029    *    <br>Ignored if <jk>null</jk>.
1030    * @return This object (for method chaining).
1031    */
1032   @SuppressWarnings({ "unchecked", "rawtypes" })
1033   public Swagger securities(Object...values) {
1034      security = addToList((List)security, values, Map.class, String.class, List.class, String.class);
1035      return this;
1036   }
1037
1038   /**
1039    * Bean property getter:  <property>tags</property>.
1040    * 
1041    * <p>
1042    * A list of tags used by the specification with additional metadata.
1043    * 
1044    * @return The property value, or <jk>null</jk> if it is not set.
1045    */
1046   public List<Tag> getTags() {
1047      return tags;
1048   }
1049
1050   /**
1051    * Bean property setter:  <property>tags</property>.
1052    * 
1053    * <p>
1054    * A list of tags used by the specification with additional metadata.
1055    * 
1056    * @param value 
1057    *    The new value for this property.
1058    *    <br>The order of the tags can be used to reflect on their order by the parsing tools.
1059    *    <br>Not all tags that are used by the <a class="doclink" href="http://swagger.io/specification/#operationObject">Operation Object</a> must be declared.
1060    *    <br>The tags that are not declared may be organized randomly or based on the tools' logic.
1061    *    <br>Each tag name in the list MUST be unique.
1062    *    <br>Can be <jk>null</jk> to unset the property.
1063    * @return This object (for method chaining).
1064    */
1065   public Swagger setTags(Collection<Tag> value) {
1066      tags = newList(value);
1067      return this;
1068   }
1069
1070   /**
1071    * Adds one or more values to the <property>security</property> property.
1072    * 
1073    * <p>
1074    * A list of tags used by the specification with additional metadata.
1075    * 
1076    * @param values 
1077    *    The values to add to this property.
1078    *    <br>The order of the tags can be used to reflect on their order by the parsing tools.
1079    *    <br>Not all tags that are used by the <a class="doclink" href="http://swagger.io/specification/#operationObject">Operation Object</a> must be declared.
1080    *    <br>The tags that are not declared may be organized randomly or based on the tools' logic.
1081    *    <br>Each tag name in the list MUST be unique.
1082    *    <br>Ignored if <jk>null</jk>.
1083    * @return This object (for method chaining).
1084    */
1085   public Swagger addTags(Collection<Tag> values) {
1086      tags = addToList(tags, values);
1087      return this;
1088   }
1089
1090
1091   /**
1092    * Adds one or more values to the <property>tags</property> property.
1093    * 
1094    * @param values
1095    *    The values to add to this property.
1096    *    <br>Valid types:
1097    *    <ul>
1098    *       <li>{@link Tag}
1099    *       <li><code>Collection&lt;{@link Tag}|String&gt;</code>
1100    *       <li><code>{@link Tag}[]</code>
1101    *       <li><code>String</code> - JSON array representation of <code>Collection&lt;{@link Tag}&gt;</code>
1102    *          <h5 class='figure'>Example:</h5>
1103    *          <p class='bcode'>
1104    *    tags(<js>"[{name:'name',description:'description',...}]"</js>);
1105    *          </p>
1106    *       <li><code>String</code> - JSON object representation of <code>{@link Tag}</code>
1107    *          <h5 class='figure'>Example:</h5>
1108    *          <p class='bcode'>
1109    *    tags(<js>"{name:'name',description:'description',...}"</js>);
1110    *          </p>
1111    *    </ul>
1112    *    <br>Ignored if <jk>null</jk>.
1113    * @return This object (for method chaining).
1114    */
1115   public Swagger tags(Object...values) {
1116      tags = addToList(tags, values, Tag.class);
1117      return this;
1118   }
1119
1120   /**
1121    * Bean property getter:  <property>externalDocs</property>.
1122    * 
1123    * <p>
1124    * Additional external documentation.
1125    * 
1126    * @return The property value, or <jk>null</jk> if it is not set.
1127    */
1128   public ExternalDocumentation getExternalDocs() {
1129      return externalDocs;
1130   }
1131
1132   /**
1133    * Bean property setter:  <property>externalDocs</property>.
1134    * 
1135    * <p>
1136    * Additional external documentation.
1137    * 
1138    * @param value
1139    *    The new value for this property.
1140    *    <br>Can be <jk>null</jk> to unset the property.
1141    * @return This object (for method chaining).
1142    */
1143   public Swagger setExternalDocs(ExternalDocumentation value) {
1144      externalDocs = value;
1145      return this;
1146   }
1147
1148   /**
1149    * Same as {@link #setExternalDocs(ExternalDocumentation)}.
1150    * 
1151    * @param value 
1152    *    The new value for this property.
1153    *    <br>Valid types:
1154    *    <ul>
1155    *       <li>{@link ExternalDocumentation}
1156    *       <li><code>String</code> - JSON object representation of {@link ExternalDocumentation}
1157    *          <h5 class='figure'>Example:</h5>
1158    *          <p class='bcode'>
1159    *    externalDocs(<js>"{description:'description',url:'url'}"</js>);
1160    *          </p>
1161    *    </ul>
1162    *    <br>Can be <jk>null</jk> to unset the property.
1163    * @return This object (for method chaining).
1164    */
1165   public Swagger externalDocs(Object value) {
1166      return setExternalDocs(toType(value, ExternalDocumentation.class));
1167   }
1168
1169   @Override /* SwaggerElement */
1170   public <T> T get(String property, Class<T> type) {
1171      if (property == null)
1172         return null;
1173      switch (property) {
1174         case "swagger": return toType(getSwagger(), type);
1175         case "info": return toType(getInfo(), type);
1176         case "host": return toType(getHost(), type);
1177         case "basePath": return toType(getBasePath(), type);
1178         case "schemes": return toType(getSchemes(), type);
1179         case "consumes": return toType(getConsumes(), type);
1180         case "produces": return toType(getProduces(), type);
1181         case "paths": return toType(getPaths(), type);
1182         case "definitions": return toType(getDefinitions(), type);
1183         case "parameters": return toType(getParameters(), type);
1184         case "responses": return toType(getResponses(), type);
1185         case "securityDefinitions": return toType(getSecurityDefinitions(), type);
1186         case "security": return toType(getSecurity(), type);
1187         case "tags": return toType(getTags(), type);
1188         case "externalDocs": return toType(getExternalDocs(), type);
1189         default: return super.get(property, type);
1190      }
1191   }
1192
1193   @Override /* SwaggerElement */
1194   public Swagger set(String property, Object value) {
1195      if (property == null)
1196         return this;
1197      switch (property) {
1198         case "swagger": return swagger(value);
1199         case "info": return info(value);
1200         case "host": return host(value);
1201         case "basePath": return basePath(value);
1202         case "schemes": return setSchemes(null).schemes(value);
1203         case "consumes": return setConsumes(null).consumes(value);
1204         case "produces": return setProduces(null).produces(value);
1205         case "paths": return setPaths(null).paths(value);
1206         case "definitions": return setDefinitions(null).definitions(value);
1207         case "parameters": return setParameters(null).parameters(value);
1208         case "responses": return setResponses(null).responses(value);
1209         case "securityDefinitions": return setSecurityDefinitions(null).securityDefinitions(value);
1210         case "security": return setSecurity(null).securities(value);
1211         case "tags": return setTags(null).tags(value);
1212         case "externalDocs": return externalDocs(value);
1213         default: 
1214            super.set(property, value);
1215            return this;
1216      }
1217   }
1218
1219// static final class MethodSorter implements Comparator<String> {
1220//    private final Map<String,Integer> methods = new AMap<String,Integer>()
1221//       .append("get",7)
1222//       .append("put",6)
1223//       .append("post",5)
1224//       .append("delete",4)
1225//       .append("options",3)
1226//       .append("head",2)
1227//       .append("patch",1);
1228//
1229//    @Override
1230//    public int compare(String o1, String o2) {
1231//       Integer i1 = methods.get(o1);
1232//       Integer i2 = methods.get(o2);
1233//       if (i1 == null)
1234//          i1 = 0;
1235//       if (i2 == null)
1236//          i2 = 0;
1237//       return i2.compareTo(i1);
1238//    }
1239// }
1240
1241   @Override /* Object */
1242   public String toString() {
1243      return JsonSerializer.DEFAULT.toString(this);
1244   }
1245}