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