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