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.common.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.internal.*; 024 025/** 026 * Describes a single API operation on a path. 027 * 028 * <h5 class='section'>Example:</h5> 029 * <p class='bjava'> 030 * <jc>// Construct using SwaggerBuilder.</jc> 031 * Operation <jv>operation</jv> = <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 <jv>json</jv> = JsonSerializer.<jsf>DEFAULT</jsf>.toString(<jv>operation</jv>); 064 * 065 * <jc>// Or just use toString() which does the same as above.</jc> 066 * <jv>json</jv> = <jv>operation</jv>.toString(); 067 * </p> 068 * <p class='bjson'> 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><ul> 127 * <li class='link'><a class="doclink" href="../../../../../index.html#jrs.Swagger">Overview > juneau-rest-server > Swagger</a> 128 * </ul> 129 */ 130@Bean(properties="operationId,summary,description,tags,externalDocs,consumes,produces,parameters,responses,schemes,deprecated,security,*") 131@FluentSetters 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 Set<String> 141 tags, 142 schemes; 143 private Set<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.consumes = copyOf(copyFrom.consumes); 164 this.deprecated = copyFrom.deprecated; 165 this.description = copyFrom.description; 166 this.externalDocs = copyFrom.externalDocs == null ? null : copyFrom.externalDocs.copy(); 167 this.operationId = copyFrom.operationId; 168 this.produces = copyOf(copyFrom.produces); 169 this.schemes = copyOf(copyFrom.schemes); 170 this.summary = copyFrom.summary; 171 this.tags = copyOf(copyFrom.tags); 172 173 if (copyFrom.parameters == null) { 174 this.parameters = null; 175 } else { 176 this.parameters = list(); 177 copyFrom.parameters.forEach(x -> this.parameters.add(x.copy())); 178 } 179 180 if (copyFrom.responses == null) { 181 this.responses = null; 182 } else { 183 this.responses = map(); 184 copyFrom.responses.forEach((k,v) -> this.responses.put(k, v.copy())); 185 } 186 187 if (copyFrom.security == null) { 188 this.security = null; 189 } else { 190 this.security = list(); 191 copyFrom.security.forEach(x -> { 192 Map<String,List<String>> m2 = map(); 193 x.forEach((k,v) -> m2.put(k, copyOf(v))); 194 this.security.add(m2); 195 }); 196 } 197 } 198 199 /** 200 * Make a deep copy of this object. 201 * 202 * @return A deep copy of this object. 203 */ 204 public Operation copy() { 205 return new Operation(this); 206 } 207 208 //----------------------------------------------------------------------------------------------------------------- 209 // Properties 210 //----------------------------------------------------------------------------------------------------------------- 211 212 /** 213 * Bean property getter: <property>consumes</property>. 214 * 215 * <p> 216 * A list of MIME types the operation can consume. 217 * 218 * @return The property value, or <jk>null</jk> if it is not set. 219 */ 220 public Set<MediaType> getConsumes() { 221 return consumes; 222 } 223 224 /** 225 * Bean property setter: <property>consumes</property>. 226 * 227 * <p> 228 * A list of MIME types the operation can consume. 229 * 230 * @param value 231 * The new value for this property. 232 * <br>Values MUST be as described under <a class="doclink" href="https://swagger.io/specification#mimeTypes">Swagger Mime Types</a>. 233 * <br>Can be <jk>null</jk> to unset the property. 234 * @return This object. 235 */ 236 public Operation setConsumes(Collection<MediaType> value) { 237 consumes = setFrom(value); 238 return this; 239 } 240 241 /** 242 * Bean property setter: <property>consumes</property>. 243 * 244 * <p> 245 * A list of MIME types the operation can consume. 246 * 247 * @param value 248 * The new value for this property. 249 * <br>Values MUST be as described under <a class="doclink" href="https://swagger.io/specification#mimeTypes">Swagger Mime Types</a>. 250 * @return This object. 251 */ 252 public Operation setConsumes(MediaType...value) { 253 return setConsumes(Arrays.asList(value)); 254 } 255 256 /** 257 * Bean property fluent setter: <property>consumes</property>. 258 * 259 * <p> 260 * A list of MIME types the operation can consume. 261 * 262 * @param value 263 * The new value for this property. 264 * @return This object. 265 */ 266 public Operation addConsumes(MediaType...value) { 267 setConsumes(setBuilder(MediaType.class).sparse().add(value).build()); 268 return this; 269 } 270 271 /** 272 * Bean property getter: <property>deprecated</property>. 273 * 274 * <p> 275 * Declares this operation to be deprecated. 276 * 277 * @return The property value, or <jk>null</jk> if it is not set. 278 */ 279 public Boolean getDeprecated() { 280 return deprecated; 281 } 282 283 /** 284 * Bean property getter: <property>deprecated</property>. 285 * 286 * <p> 287 * Declares this operation to be deprecated. 288 * 289 * @return The property value, or <jk>false</jk> if it is not set. 290 */ 291 public boolean isDeprecated() { 292 return deprecated != null && deprecated == true; 293 } 294 295 /** 296 * Bean property setter: <property>deprecated</property>. 297 * 298 * <p> 299 * Declares this operation to be deprecated. 300 * 301 * @param value The new value for this property. 302 * @return This object. 303 */ 304 public Operation setDeprecated(Boolean value) { 305 deprecated = value; 306 return this; 307 } 308 309 /** 310 * Bean property getter: <property>description</property>. 311 * 312 * <p> 313 * A verbose explanation of the operation behavior. 314 * 315 * @return The property value, or <jk>null</jk> if it is not set. 316 */ 317 public String getDescription() { 318 return description; 319 } 320 321 /** 322 * Bean property setter: <property>description</property>. 323 * 324 * <p> 325 * A verbose explanation of the operation behavior. 326 * 327 * @param value 328 * The new value for this property. 329 * <br><a class="doclink" href="https://help.github.com/articles/github-flavored-markdown">GFM syntax</a> can be used for rich text representation. 330 * <br>Can be <jk>null</jk> to unset the property. 331 * @return This object. 332 */ 333 public Operation setDescription(String value) { 334 description = value; 335 return this; 336 } 337 338 /** 339 * Bean property getter: <property>externalDocs</property>. 340 * 341 * <p> 342 * Additional external documentation for this operation. 343 * 344 * @return The property value, or <jk>null</jk> if it is not set. 345 */ 346 public ExternalDocumentation getExternalDocs() { 347 return externalDocs; 348 } 349 350 /** 351 * Bean property setter: <property>externalDocs</property>. 352 * 353 * <p> 354 * Additional external documentation for this operation. 355 * 356 * @param value 357 * The values to add to this property. 358 * <br>Can be <jk>null</jk> to unset the property. 359 * @return This object. 360 */ 361 public Operation setExternalDocs(ExternalDocumentation value) { 362 externalDocs = value; 363 return this; 364 } 365 366 /** 367 * Bean property getter: <property>operationId</property>. 368 * 369 * <p> 370 * Unique string used to identify the operation. 371 * 372 * @return The property value, or <jk>null</jk> if it is not set. 373 */ 374 public String getOperationId() { 375 return operationId; 376 } 377 378 /** 379 * Bean property setter: <property>operationId</property>. 380 * 381 * <p> 382 * Unique string used to identify the operation. 383 * 384 * @param value 385 * The new value for this property. 386 * <br>The id MUST be unique among all operations described in the API. 387 * <br>Tools and libraries MAY use the operationId to uniquely identify an operation, therefore, it is recommended to 388 * follow common programming naming conventions. 389 * <br>Can be <jk>null</jk> to unset the property. 390 * @return This object. 391 */ 392 public Operation setOperationId(String value) { 393 operationId = value; 394 return this; 395 } 396 397 /** 398 * Bean property getter: <property>parameters</property>. 399 * 400 * <p> 401 * A list of parameters that are applicable for this operation. 402 * 403 * <h5 class='section'>Notes:</h5><ul> 404 * <li class='note'> 405 * If a parameter is already defined at the <a class="doclink" href="https://swagger.io/specification#pathItemObject">Path Item</a>, 406 * the new definition will override it, but can never remove it. 407 * <li class='note'> 408 * The list MUST NOT include duplicated parameters. 409 * <li class='note'> 410 * A unique parameter is defined by a combination of a <c>name</c> and <c>location</c>. 411 * <li class='note'> 412 * The list can use the <a class="doclink" href="https://swagger.io/specification#referenceObject">Swagger Reference Object</a> 413 * to link to parameters that are defined at the <a class='doclink' href='https://swagger.io/specification/v2#parameterObject'>Swagger Object's parameters</a>. 414 * <li class='note'> 415 * There can be one <js>"body"</js> parameter at most. 416 * </ul> 417 * 418 * @return The property value, or <jk>null</jk> if it is not set. 419 */ 420 public List<ParameterInfo> getParameters() { 421 return parameters; 422 } 423 424 /** 425 * Returns the parameter with the specified type and name. 426 * 427 * @param in The parameter in. 428 * @param name The parameter name. Can be <jk>null</jk> for parameter type <c>body</c>. 429 * @return The matching parameter info, or <jk>null</jk> if not found. 430 */ 431 public ParameterInfo getParameter(String in, String name) { 432 if (parameters != null) 433 for (ParameterInfo pi : parameters) 434 if (eq(pi.getIn(), in)) 435 if (eq(pi.getName(), name) || "body".equals(pi.getIn())) 436 return pi; 437 return null; 438 } 439 440 /** 441 * Bean property setter: <property>parameters</property>. 442 * 443 * <p> 444 * A list of parameters that are applicable for this operation. 445 * 446 * @param value 447 * The new value for this property. 448 * <br>Can be <jk>null</jk> to unset the property. 449 * @return This object. 450 */ 451 public Operation setParameters(Collection<ParameterInfo> value) { 452 parameters = listFrom(value); 453 return this; 454 } 455 456 /** 457 * Bean property setter: <property>parameters</property>. 458 * 459 * <p> 460 * A list of parameters that are applicable for this operation. 461 * 462 * @param value 463 * The new value for this property. 464 * @return This object. 465 */ 466 public Operation setParameters(ParameterInfo...value) { 467 return setParameters(Arrays.asList(value)); 468 } 469 470 /** 471 * Bean property fluent setter: <property>parameters</property>. 472 * 473 * <p> 474 * A list of parameters that are applicable for this operation. 475 * 476 * @param value 477 * The new value for this property. 478 * @return This object. 479 */ 480 public Operation addParameters(ParameterInfo...value) { 481 setParameters(listBuilder(ParameterInfo.class).sparse().add(value).build()); 482 return this; 483 } 484 485 //----------------------------------------------------------------------------------------------------------------- 486 // produces 487 //----------------------------------------------------------------------------------------------------------------- 488 489 /** 490 * Bean property getter: <property>produces</property>. 491 * 492 * <p> 493 * A list of MIME types the operation can produce. 494 * 495 * @return The property value, or <jk>null</jk> if it is not set. 496 */ 497 public Set<MediaType> getProduces() { 498 return produces; 499 } 500 501 /** 502 * Bean property setter: <property>produces</property>. 503 * 504 * <p> 505 * A list of MIME types the operation can produce. 506 * 507 * @param value 508 * The new value for this property. 509 * <br>Value MUST be as described under <a class="doclink" href="https://swagger.io/specification#mimeTypes">Swagger Mime Types</a>. 510 * <br>Can be <jk>null</jk> to unset the property. 511 * @return This object. 512 */ 513 public Operation setProduces(Collection<MediaType> value) { 514 produces = setFrom(value); 515 return this; 516 } 517 518 /** 519 * Bean property setter: <property>produces</property>. 520 * 521 * <p> 522 * A list of MIME types the operation can produce. 523 * 524 * @param value 525 * The new value for this property. 526 * <br>Value MUST be as described under <a class="doclink" href="https://swagger.io/specification#mimeTypes">Swagger Mime Types</a>. 527 * @return This object. 528 */ 529 public Operation setProduces(MediaType...value) { 530 return setProduces(Arrays.asList(value)); 531 } 532 533 /** 534 * Bean property fluent setter: <property>produces</property>. 535 * 536 * <p> 537 * A list of MIME types the operation can produce. 538 * 539 * @param value 540 * The new value for this property. 541 * @return This object. 542 */ 543 public Operation addProduces(MediaType...value) { 544 setProduces(setBuilder(MediaType.class).sparse().add(value).build()); 545 return this; 546 } 547 548 /** 549 * Bean property getter: <property>responses</property>. 550 * 551 * <p> 552 * The list of possible responses as they are returned from executing this operation. 553 * 554 * @return The property value, or <jk>null</jk> if it is not set. 555 */ 556 public Map<String,ResponseInfo> getResponses() { 557 return responses; 558 } 559 560 /** 561 * Returns the response info with the given status code. 562 * 563 * @param status The HTTP status code. 564 * @return The response info, or <jk>null</jk> if not found. 565 */ 566 public ResponseInfo getResponse(String status) { 567 if (responses != null) 568 return responses.get(status); 569 return null; 570 } 571 572 /** 573 * Returns the response info with the given status code. 574 * 575 * @param status The HTTP status code. 576 * @return The response info, or <jk>null</jk> if not found. 577 */ 578 public ResponseInfo getResponse(int status) { 579 return getResponse(String.valueOf(status)); 580 } 581 582 /** 583 * Bean property setter: <property>responses</property>. 584 * 585 * <p> 586 * The list of possible responses as they are returned from executing this operation. 587 * 588 * @param value 589 * The new value for this property. 590 * <br>Property value is required. 591 * @return This object. 592 */ 593 public Operation setResponses(Map<String,ResponseInfo> value) { 594 responses = copyOf(value); 595 return this; 596 } 597 598 /** 599 * Adds a single value to the <property>responses</property> property. 600 * 601 * @param statusCode The HTTP status code. 602 * @param response The response description. 603 * @return This object. 604 */ 605 public Operation addResponse(String statusCode, ResponseInfo response) { 606 responses = mapBuilder(responses).add(statusCode, response).build(); 607 return this; 608 } 609 610 /** 611 * Bean property getter: <property>schemes</property>. 612 * 613 * <p> 614 * The transfer protocol for the operation. 615 * 616 * @return The property value, or <jk>null</jk> if it is not set. 617 */ 618 public Set<String> getSchemes() { 619 return schemes; 620 } 621 622 /** 623 * Bean property setter: <property>schemes</property>. 624 * 625 * <p> 626 * The transfer protocol for the operation. 627 * 628 * @param value 629 * The new value for this property. 630 * <br>Valid values: 631 * <ul> 632 * <li><js>"http"</js> 633 * <li><js>"https"</js> 634 * <li><js>"ws"</js> 635 * <li><js>"wss"</js> 636 * </ul> 637 * <br>Can be <jk>null</jk> to unset the property. 638 * @return This object. 639 */ 640 public Operation setSchemes(Collection<String> value) { 641 schemes = setFrom(value); 642 return this; 643 } 644 645 /** 646 * Bean property fluent setter: <property>schemes</property>. 647 * 648 * <p> 649 * The transfer protocol for the operation. 650 * 651 * @param value 652 * The new value for this property. 653 * <br>String values can also be JSON arrays. 654 * @return This object. 655 */ 656 public Operation addSchemes(String...value) { 657 setSchemes(setBuilder(String.class).sparse().addJson(value).build()); 658 return this; 659 } 660 661 /** 662 * Bean property getter: <property>security</property>. 663 * 664 * <p> 665 * A declaration of which security schemes are applied for this operation. 666 * 667 * @return The property value, or <jk>null</jk> if it is not set. 668 */ 669 public List<Map<String,List<String>>> getSecurity() { 670 return security; 671 } 672 673 /** 674 * Bean property setter: <property>security</property>. 675 * 676 * <p> 677 * A declaration of which security schemes are applied for this operation. 678 * 679 * @param value 680 * The new value for this property. 681 * <br>Can be <jk>null</jk> to unset the property. 682 * @return This object. 683 */ 684 public Operation setSecurity(Collection<Map<String,List<String>>> value) { 685 security = listFrom(value); 686 return this; 687 } 688 689 /** 690 * Same as {@link #addSecurity(String, String...)}. 691 * 692 * @param scheme 693 * The scheme name. 694 * @param alternatives 695 * The list of values describes alternative security schemes that can be used (that is, there is a logical OR 696 * between the security requirements). 697 * @return This object. 698 */ 699 public Operation addSecurity(String scheme, String...alternatives) { 700 Map<String,List<String>> m = map(); 701 m.put(scheme, alist(alternatives)); 702 security = listBuilder(security).add(m).build(); 703 return this; 704 } 705 706 /** 707 * Bean property getter: <property>summary</property>. 708 * 709 * <p> 710 * A short summary of what the operation does. 711 * 712 * @return The property value, or <jk>null</jk> if it is not set. 713 */ 714 public String getSummary() { 715 return summary; 716 } 717 718 /** 719 * Bean property setter: <property>summary</property>. 720 * 721 * <p> 722 * A short summary of what the operation does. 723 * 724 * @param value 725 * The new value for this property. 726 * <br>Can be <jk>null</jk> to unset the property. 727 * @return This object. 728 */ 729 public Operation setSummary(String value) { 730 summary = value; 731 return this; 732 } 733 734 /** 735 * Bean property getter: <property>tags</property>. 736 * 737 * <p> 738 * A list of tags for API documentation control. 739 * <br>Tags can be used for logical grouping of operations by resources or any other qualifier. 740 * 741 * @return The property value, or <jk>null</jk> if it is not set. 742 */ 743 public Set<String> getTags() { 744 return tags; 745 } 746 747 /** 748 * Bean property setter: <property>tags</property>. 749 * 750 * <p> 751 * A list of tags for API documentation control. 752 * <br>Tags can be used for logical grouping of operations by resources or any other qualifier. 753 * 754 * @param value 755 * The new value for this property. 756 * <br>Can be <jk>null</jk> to unset the property. 757 * @return This object. 758 */ 759 public Operation setTags(Collection<String> value) { 760 tags = setFrom(value); 761 return this; 762 } 763 764 /** 765 * Bean property fluent setter: <property>tags</property>. 766 * 767 * <p> 768 * A list of tags for API documentation control. 769 * <br>Tags can be used for logical grouping of operations by resources or any other qualifier. 770 * 771 * @param value 772 * The new value for this property. 773 * @return This object. 774 */ 775 public Operation setTags(String...value) { 776 setTags(setBuilder(String.class).sparse().add(value).build()); 777 return this; 778 } 779 780 /** 781 * Bean property fluent adder: <property>tags</property>. 782 * 783 * <p> 784 * A list of tags for API documentation control. 785 * <br>Tags can be used for logical grouping of operations by resources or any other qualifier. 786 * 787 * @param value 788 * The values to add to this property. 789 * @return This object. 790 */ 791 public Operation addTags(String...value) { 792 setTags(setBuilder(tags).sparse().add(value).build()); 793 return this; 794 } 795 796 // <FluentSetters> 797 798 // </FluentSetters> 799 800 @Override /* SwaggerElement */ 801 public <T> T get(String property, Class<T> type) { 802 if (property == null) 803 return null; 804 switch (property) { 805 case "consumes": return toType(getConsumes(), type); 806 case "deprecated": return toType(getDeprecated(), type); 807 case "description": return toType(getDescription(), type); 808 case "externalDocs": return toType(getExternalDocs(), type); 809 case "operationId": return toType(getOperationId(), type); 810 case "parameters": return toType(getParameters(), type); 811 case "produces": return toType(getProduces(), type); 812 case "responses": return toType(getResponses(), type); 813 case "schemes": return toType(getSchemes(), type); 814 case "security": return toType(getSecurity(), type); 815 case "summary": return toType(getSummary(), type); 816 case "tags": return toType(getTags(), type); 817 default: return super.get(property, type); 818 } 819 } 820 821 @SuppressWarnings({"unchecked","rawtypes"}) 822 @Override /* SwaggerElement */ 823 public Operation set(String property, Object value) { 824 if (property == null) 825 return this; 826 switch (property) { 827 case "consumes": return setConsumes(listBuilder(MediaType.class).sparse().addAny(value).build()); 828 case "deprecated": return setDeprecated(toBoolean(value)); 829 case "description": return setDescription(stringify(value)); 830 case "externalDocs": return setExternalDocs(toType(value, ExternalDocumentation.class)); 831 case "operationId": return setOperationId(stringify(value)); 832 case "parameters": return setParameters(listBuilder(ParameterInfo.class).sparse().addAny(value).build()); 833 case "produces": return setProduces(listBuilder(MediaType.class).sparse().addAny(value).build()); 834 case "responses": return setResponses(mapBuilder(String.class,ResponseInfo.class).sparse().addAny(value).build()); 835 case "schemes": return setSchemes(listBuilder(String.class).sparse().addAny(value).build()); 836 case "security": return setSecurity((List)listBuilder(Map.class,String.class,List.class,String.class).sparse().addAny(value).build()); 837 case "summary": return setSummary(stringify(value)); 838 case "tags": return setTags(listBuilder(String.class).sparse().addAny(value).build()); 839 default: 840 super.set(property, value); 841 return this; 842 } 843 } 844 845 @Override /* SwaggerElement */ 846 public Set<String> keySet() { 847 Set<String> s = setBuilder(String.class) 848 .addIf(consumes != null, "consumes") 849 .addIf(deprecated != null, "deprecated") 850 .addIf(description != null, "description") 851 .addIf(externalDocs != null, "externalDocs") 852 .addIf(operationId != null, "operationId") 853 .addIf(parameters != null, "parameters") 854 .addIf(produces != null, "produces") 855 .addIf(responses != null, "responses") 856 .addIf(schemes != null, "schemes") 857 .addIf(security != null, "security") 858 .addIf(summary != null, "summary") 859 .addIf(tags != null, "tags") 860 .build(); 861 return new MultiSet<>(s, super.keySet()); 862 } 863}