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