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