001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.rest.server; 018 019import static org.apache.juneau.commons.utils.Shorts.*; 020 021import java.lang.annotation.*; 022import java.util.function.*; 023 024import org.apache.juneau.commons.*; 025import org.apache.juneau.commons.reflect.*; 026import org.apache.juneau.marshall.encoders.*; 027import org.apache.juneau.marshall.serializer.*; 028import org.apache.juneau.rest.server.converter.*; 029import org.apache.juneau.rest.server.guard.*; 030import org.apache.juneau.rest.server.matcher.*; 031 032/** 033 * Utility classes and methods for the {@link RestOp @RestOp} annotation. 034 * 035 * <h5 class='section'>See Also:</h5><ul> 036 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestOpAnnotatedMethods">@RestOp-Annotated Method</a> 037 * </ul> 038 */ 039public class RestOpAnnotation { 040 041 /** 042 * Private constructor to prevent instantiation. 043 */ 044 private RestOpAnnotation() { 045 // Utility class - prevent instantiation 046 } 047 048 /** 049 * Builder class. 050 * 051 * <h5 class='section'>See Also:</h5><ul> 052 * <li class='jm'>{@link org.apache.juneau.marshall.MarshallingContext.Builder#annotations(Annotation...)} 053 * </ul> 054 */ 055 @SuppressWarnings({ 056 "unchecked" // Type erasure requires cast for Builder inheritance 057 }) 058 public static class Builder extends AnnotationObject.Builder { 059 060 private String[] description = {}; 061 private Class<? extends RestConverter>[] converters = new Class[0]; 062 private Class<? extends RestGuard>[] guards = new Class[0]; 063 private Class<? extends RestMatcher>[] matchers = new Class[0]; 064 private Class<? extends Encoder>[] encoders = new Class[0]; 065 private Class<? extends Serializer>[] serializers = new Class[0]; 066 private Class<?>[] parsers = {}; 067 private OpSwagger swagger = OpSwaggerAnnotation.DEFAULT; 068 private String clientVersion = ""; 069 private String defaultAccept = ""; 070 private String defaultCharset = ""; 071 private String defaultContentType = ""; 072 private String maxInput = ""; 073 private String method = ""; 074 private String observability = ""; 075 private String metricName = ""; 076 private String metricTags = ""; 077 private String problemDetails = ""; 078 private String debugMarshalling = ""; 079 private String virtualThreads = ""; 080 private String asyncTimeoutMillis = ""; 081 private String asyncCompletionExecutor = ""; 082 private String rolesDeclared = ""; 083 private String roleGuard = ""; 084 private String summary = ""; 085 private String value = ""; 086 private String[] consumes = {}; 087 private String[] defaultRequestFormData = {}; 088 private String[] defaultRequestQueryData = {}; 089 private String[] defaultRequestAttributes = {}; 090 private String[] defaultRequestHeaders = {}; 091 private String[] defaultResponseHeaders = {}; 092 private String[] path = {}; 093 private String[] produces = {}; 094 private String[] allowedSerializerOptions = {}; 095 private String[] allowedParserOptions = {}; 096 private String[] noInherit = {}; 097 private boolean read; 098 099 /** 100 * Constructor. 101 */ 102 protected Builder() { 103 super(RestOp.class); 104 } 105 106 /** 107 * Instantiates a new {@link RestOp @RestOp} object initialized with this builder. 108 * 109 * @return A new {@link RestOp @RestOp} object. 110 */ 111 public RestOp build() { 112 return new Object(this); 113 } 114 115 /** 116 * Sets the description property on this annotation. 117 * 118 * @param value The new value for this property. 119 * @return This object. 120 */ 121 public Builder description(String...value) { 122 description = value; 123 return this; 124 } 125 126 /** 127 * Sets the {@link RestOp#clientVersion()} property on this annotation. 128 * 129 * @param value The new value for this property. 130 * @return This object. 131 */ 132 public Builder clientVersion(String value) { 133 clientVersion = value; 134 return this; 135 } 136 137 /** 138 * Sets the {@link RestOp#consumes()} property on this annotation. 139 * 140 * @param value The new value for this property. 141 * @return This object. 142 */ 143 public Builder consumes(String...value) { 144 consumes = value; 145 return this; 146 } 147 148 /** 149 * Sets the {@link RestOp#converters()} property on this annotation. 150 * 151 * @param value The new value for this property. 152 * @return This object. 153 */ 154 @SafeVarargs 155 public final Builder converters(Class<? extends RestConverter>...value) { 156 converters = value; 157 return this; 158 } 159 160 /** 161 * Sets the {@link RestOp#defaultAccept()} property on this annotation. 162 * 163 * @param value The new value for this property. 164 * @return This object. 165 */ 166 public Builder defaultAccept(String value) { 167 defaultAccept = value; 168 return this; 169 } 170 171 /** 172 * Sets the {@link RestOp#defaultCharset()} property on this annotation. 173 * 174 * @param value The new value for this property. 175 * @return This object. 176 */ 177 public Builder defaultCharset(String value) { 178 defaultCharset = value; 179 return this; 180 } 181 182 /** 183 * Sets the {@link RestOp#defaultContentType()} property on this annotation. 184 * 185 * @param value The new value for this property. 186 * @return This object. 187 */ 188 public Builder defaultContentType(String value) { 189 defaultContentType = value; 190 return this; 191 } 192 193 /** 194 * Sets the {@link RestOp#defaultRequestAttributes()} property on this annotation. 195 * 196 * @param value The new value for this property. 197 * @return This object. 198 */ 199 public Builder defaultRequestAttributes(String...value) { 200 defaultRequestAttributes = value; 201 return this; 202 } 203 204 /** 205 * Sets the {@link RestOp#defaultRequestFormData()} property on this annotation. 206 * 207 * @param value The new value for this property. 208 * @return This object. 209 */ 210 public Builder defaultRequestFormData(String...value) { 211 defaultRequestFormData = value; 212 return this; 213 } 214 215 /** 216 * Sets the {@link RestOp#defaultRequestHeaders()} property on this annotation. 217 * 218 * @param value The new value for this property. 219 * @return This object. 220 */ 221 public Builder defaultRequestHeaders(String...value) { 222 defaultRequestHeaders = value; 223 return this; 224 } 225 226 /** 227 * Sets the {@link RestOp#defaultRequestQueryData()} property on this annotation. 228 * 229 * @param value The new value for this property. 230 * @return This object. 231 */ 232 public Builder defaultRequestQueryData(String...value) { 233 defaultRequestQueryData = value; 234 return this; 235 } 236 237 /** 238 * Sets the {@link RestOp#defaultResponseHeaders()} property on this annotation. 239 * 240 * @param value The new value for this property. 241 * @return This object. 242 */ 243 public Builder defaultResponseHeaders(String...value) { 244 defaultResponseHeaders = value; 245 return this; 246 } 247 248 /** 249 * Sets the {@link RestOp#encoders()} property on this annotation. 250 * 251 * @param value The new value for this property. 252 * @return This object. 253 */ 254 @SafeVarargs 255 public final Builder encoders(Class<? extends Encoder>...value) { 256 encoders = value; 257 return this; 258 } 259 260 /** 261 * Sets the {@link RestOp#guards()} property on this annotation. 262 * 263 * @param value The new value for this property. 264 * @return This object. 265 */ 266 @SafeVarargs 267 public final Builder guards(Class<? extends RestGuard>...value) { 268 guards = value; 269 return this; 270 } 271 272 /** 273 * Sets the {@link RestOp#matchers()} property on this annotation. 274 * 275 * @param value The new value for this property. 276 * @return This object. 277 */ 278 @SafeVarargs 279 public final Builder matchers(Class<? extends RestMatcher>...value) { 280 matchers = value; 281 return this; 282 } 283 284 /** 285 * Sets the {@link RestOp#maxInput()} property on this annotation. 286 * 287 * @param value The new value for this property. 288 * @return This object. 289 */ 290 public Builder maxInput(String value) { 291 maxInput = value; 292 return this; 293 } 294 295 /** 296 * Sets the {@link RestOp#method()} property on this annotation. 297 * 298 * @param value The new value for this property. 299 * @return This object. 300 */ 301 public Builder method(String value) { 302 method = value; 303 return this; 304 } 305 306 /** 307 * Sets the {@link RestOp#parsers()} property on this annotation. 308 * 309 * @param value The new value for this property. 310 * @return This object. 311 */ 312 public Builder parsers(Class<?>...value) { 313 parsers = value; 314 return this; 315 } 316 317 /** 318 * Sets the {@link RestOp#path()} property on this annotation. 319 * 320 * @param value The new value for this property. 321 * @return This object. 322 */ 323 public Builder path(String...value) { 324 path = value; 325 return this; 326 } 327 328 /** 329 * Sets the {@link RestOp#problemDetails()} property on this annotation. 330 * 331 * @param value The new value for this property. 332 * @return This object. 333 */ 334 public Builder problemDetails(String value) { 335 problemDetails = value; 336 return this; 337 } 338 339 /** 340 * Sets the {@link RestOp#debugMarshalling()} property on this annotation. 341 * 342 * @param value The new value for this property. 343 * @return This object. 344 */ 345 public Builder debugMarshalling(String value) { 346 debugMarshalling = value; 347 return this; 348 } 349 350 /** 351 * Sets the {@link RestOp#observability()} property on this annotation. 352 * 353 * @param value The new value for this property. 354 * @return This object. 355 */ 356 public Builder observability(String value) { 357 observability = value; 358 return this; 359 } 360 361 /** 362 * Sets the {@link RestOp#metricName()} property on this annotation. 363 * 364 * @param value The new value for this property. 365 * @return This object. 366 */ 367 public Builder metricName(String value) { 368 metricName = value; 369 return this; 370 } 371 372 /** 373 * Sets the {@link RestOp#metricTags()} property on this annotation. 374 * 375 * @param value The new value for this property. 376 * @return This object. 377 */ 378 public Builder metricTags(String value) { 379 metricTags = value; 380 return this; 381 } 382 383 /** 384 * Sets the {@link RestOp#virtualThreads()} property on this annotation. 385 * 386 * @param value The new value for this property. 387 * @return This object. 388 */ 389 public Builder virtualThreads(String value) { 390 virtualThreads = value; 391 return this; 392 } 393 394 /** 395 * Sets the {@link RestOp#asyncTimeoutMillis()} property on this annotation. 396 * 397 * @param value The new value for this property. 398 * @return This object. 399 */ 400 public Builder asyncTimeoutMillis(String value) { 401 asyncTimeoutMillis = value; 402 return this; 403 } 404 405 /** 406 * Sets the {@link RestOp#asyncCompletionExecutor()} property on this annotation. 407 * 408 * @param value The new value for this property. 409 * @return This object. 410 */ 411 public Builder asyncCompletionExecutor(String value) { 412 asyncCompletionExecutor = value; 413 return this; 414 } 415 416 /** 417 * Sets the {@link RestOp#produces()} property on this annotation. 418 * 419 * @param value The new value for this property. 420 * @return This object. 421 */ 422 public Builder produces(String...value) { 423 produces = value; 424 return this; 425 } 426 427 /** 428 * Sets the {@link RestOp#allowedSerializerOptions()} property on this annotation. 429 * 430 * @param value The new value for this property. 431 * @return This object. 432 */ 433 public Builder allowedSerializerOptions(String...value) { 434 allowedSerializerOptions = value; 435 return this; 436 } 437 438 /** 439 * Sets the {@link RestOp#allowedParserOptions()} property on this annotation. 440 * 441 * @param value The new value for this property. 442 * @return This object. 443 */ 444 public Builder allowedParserOptions(String...value) { 445 allowedParserOptions = value; 446 return this; 447 } 448 449 /** 450 * Sets the {@link RestOp#noInherit()} property on this annotation. 451 * 452 * @param value The new value for this property. 453 * @return This object. 454 */ 455 public Builder noInherit(String...value) { 456 noInherit = value; 457 return this; 458 } 459 460 /** 461 * Sets the {@link RestOp#read()} property on this annotation. 462 * 463 * @param value The new value for this property. 464 * @return This object. 465 * @since 10.0.0 466 */ 467 public Builder read(boolean value) { 468 read = value; 469 return this; 470 } 471 472 /** 473 * Sets the {@link RestOp#roleGuard()} property on this annotation. 474 * 475 * @param value The new value for this property. 476 * @return This object. 477 */ 478 public Builder roleGuard(String value) { 479 roleGuard = value; 480 return this; 481 } 482 483 /** 484 * Sets the {@link RestOp#rolesDeclared()} property on this annotation. 485 * 486 * @param value The new value for this property. 487 * @return This object. 488 */ 489 public Builder rolesDeclared(String value) { 490 rolesDeclared = value; 491 return this; 492 } 493 494 /** 495 * Sets the {@link RestOp#serializers()} property on this annotation. 496 * 497 * @param value The new value for this property. 498 * @return This object. 499 */ 500 @SafeVarargs 501 public final Builder serializers(Class<? extends Serializer>...value) { 502 serializers = value; 503 return this; 504 } 505 506 /** 507 * Sets the {@link RestOp#summary()} property on this annotation. 508 * 509 * @param value The new value for this property. 510 * @return This object. 511 */ 512 public Builder summary(String value) { 513 summary = value; 514 return this; 515 } 516 517 /** 518 * Sets the {@link RestOp#swagger()} property on this annotation. 519 * 520 * @param value The new value for this property. 521 * @return This object. 522 */ 523 public Builder swagger(OpSwagger value) { 524 swagger = value; 525 return this; 526 } 527 528 /** 529 * Sets the {@link RestOp#value()} property on this annotation. 530 * 531 * @param value The new value for this property. 532 * @return This object. 533 */ 534 public Builder value(String value) { 535 this.value = value; 536 return this; 537 } 538 } 539 540 @SuppressWarnings({ 541 "java:S2160" // equals() inherited from AnnotationObject compares all annotation interface methods; subclass fields are accessed via those methods 542 }) 543 private static class Object extends AnnotationObject implements RestOp { 544 545 private final String[] description; 546 private final Class<? extends RestConverter>[] converters; 547 private final Class<? extends RestGuard>[] guards; 548 private final Class<? extends RestMatcher>[] matchers; 549 private final Class<? extends Encoder>[] encoders; 550 private final Class<? extends Serializer>[] serializers; 551 private final Class<?>[] parsers; 552 private final OpSwagger swagger; 553 private final String clientVersion; 554 private final String defaultAccept; 555 private final String defaultCharset; 556 private final String defaultContentType; 557 private final String maxInput; 558 private final String method; 559 private final String observability; 560 private final String metricName; 561 private final String metricTags; 562 private final String problemDetails; 563 private final String debugMarshalling; 564 private final String virtualThreads; 565 private final String asyncTimeoutMillis; 566 private final String asyncCompletionExecutor; 567 private final String rolesDeclared; 568 private final String roleGuard; 569 private final String summary; 570 private final String value; 571 private final String[] consumes; 572 private final String[] defaultRequestFormData; 573 private final String[] defaultRequestQueryData; 574 private final String[] defaultRequestAttributes; 575 private final String[] defaultRequestHeaders; 576 private final String[] defaultResponseHeaders; 577 private final String[] path; 578 private final String[] produces; 579 private final String[] allowedSerializerOptions; 580 private final String[] allowedParserOptions; 581 private final String[] noInherit; 582 private final boolean read; 583 584 Object(RestOpAnnotation.Builder b) { 585 super(b); 586 description = cp(b.description); 587 clientVersion = b.clientVersion; 588 consumes = cp(b.consumes); 589 converters = cp(b.converters); 590 defaultAccept = b.defaultAccept; 591 defaultCharset = b.defaultCharset; 592 defaultContentType = b.defaultContentType; 593 defaultRequestFormData = cp(b.defaultRequestFormData); 594 defaultRequestQueryData = cp(b.defaultRequestQueryData); 595 defaultRequestAttributes = cp(b.defaultRequestAttributes); 596 defaultRequestHeaders = cp(b.defaultRequestHeaders); 597 defaultResponseHeaders = cp(b.defaultResponseHeaders); 598 encoders = cp(b.encoders); 599 guards = cp(b.guards); 600 matchers = cp(b.matchers); 601 maxInput = b.maxInput; 602 method = b.method; 603 parsers = cp(b.parsers); 604 path = cp(b.path); 605 observability = b.observability; 606 metricName = b.metricName; 607 metricTags = b.metricTags; 608 problemDetails = b.problemDetails; 609 debugMarshalling = b.debugMarshalling; 610 virtualThreads = b.virtualThreads; 611 asyncTimeoutMillis = b.asyncTimeoutMillis; 612 asyncCompletionExecutor = b.asyncCompletionExecutor; 613 produces = cp(b.produces); 614 allowedSerializerOptions = cp(b.allowedSerializerOptions); 615 allowedParserOptions = cp(b.allowedParserOptions); 616 noInherit = cp(b.noInherit); 617 read = b.read; 618 roleGuard = b.roleGuard; 619 rolesDeclared = b.rolesDeclared; 620 serializers = cp(b.serializers); 621 summary = b.summary; 622 swagger = b.swagger; 623 value = b.value; 624 } 625 626 @Override /* Overridden from RestOp */ 627 public String clientVersion() { 628 return clientVersion; 629 } 630 631 @Override /* Overridden from RestOp */ 632 public String[] consumes() { 633 return consumes; 634 } 635 636 @Override /* Overridden from RestOp */ 637 public Class<? extends RestConverter>[] converters() { 638 return converters; 639 } 640 641 @Override /* Overridden from RestOp */ 642 public String defaultAccept() { 643 return defaultAccept; 644 } 645 646 @Override /* Overridden from RestOp */ 647 public String defaultCharset() { 648 return defaultCharset; 649 } 650 651 @Override /* Overridden from RestOp */ 652 public String defaultContentType() { 653 return defaultContentType; 654 } 655 656 @Override /* Overridden from RestOp */ 657 public String[] defaultRequestAttributes() { 658 return defaultRequestAttributes; 659 } 660 661 @Override /* Overridden from RestOp */ 662 public String[] defaultRequestFormData() { 663 return defaultRequestFormData; 664 } 665 666 @Override /* Overridden from RestOp */ 667 public String[] defaultRequestHeaders() { 668 return defaultRequestHeaders; 669 } 670 671 @Override /* Overridden from RestOp */ 672 public String[] defaultRequestQueryData() { 673 return defaultRequestQueryData; 674 } 675 676 @Override /* Overridden from RestOp */ 677 public String[] defaultResponseHeaders() { 678 return defaultResponseHeaders; 679 } 680 681 @Override /* Overridden from RestOp */ 682 public Class<? extends Encoder>[] encoders() { 683 return encoders; 684 } 685 686 @Override /* Overridden from RestOp */ 687 public Class<? extends RestGuard>[] guards() { 688 return guards; 689 } 690 691 @Override /* Overridden from RestOp */ 692 public Class<? extends RestMatcher>[] matchers() { 693 return matchers; 694 } 695 696 @Override /* Overridden from RestOp */ 697 public String maxInput() { 698 return maxInput; 699 } 700 701 @Override /* Overridden from RestOp */ 702 public String method() { 703 return method; 704 } 705 706 @Override /* Overridden from RestOp */ 707 public Class<?>[] parsers() { 708 return parsers; 709 } 710 711 @Override /* Overridden from RestOp */ 712 public String[] path() { 713 return path; 714 } 715 716 @Override /* Overridden from RestOp */ 717 public String observability() { 718 return observability; 719 } 720 721 @Override /* Overridden from RestOp */ 722 public String metricName() { 723 return metricName; 724 } 725 726 @Override /* Overridden from RestOp */ 727 public String metricTags() { 728 return metricTags; 729 } 730 731 @Override /* Overridden from RestOp */ 732 public String problemDetails() { 733 return problemDetails; 734 } 735 736 @Override /* Overridden from RestOp */ 737 public String debugMarshalling() { 738 return debugMarshalling; 739 } 740 741 @Override /* Overridden from RestOp */ 742 public String virtualThreads() { 743 return virtualThreads; 744 } 745 746 @Override /* Overridden from RestOp */ 747 public String asyncTimeoutMillis() { 748 return asyncTimeoutMillis; 749 } 750 751 @Override /* Overridden from RestOp */ 752 public String asyncCompletionExecutor() { 753 return asyncCompletionExecutor; 754 } 755 756 @Override /* Overridden from RestOp */ 757 public String[] produces() { 758 return produces; 759 } 760 761 @Override /* Overridden from RestOp */ 762 public String[] allowedSerializerOptions() { 763 return allowedSerializerOptions; 764 } 765 766 @Override /* Overridden from RestOp */ 767 public String[] allowedParserOptions() { 768 return allowedParserOptions; 769 } 770 771 @Override /* Overridden from RestOp */ 772 public String[] noInherit() { 773 return noInherit; 774 } 775 776 @Override /* Overridden from RestOp */ 777 public boolean read() { 778 return read; 779 } 780 781 @Override /* Overridden from RestOp */ 782 public String roleGuard() { 783 return roleGuard; 784 } 785 786 @Override /* Overridden from RestOp */ 787 public String rolesDeclared() { 788 return rolesDeclared; 789 } 790 791 @Override /* Overridden from RestOp */ 792 public Class<? extends Serializer>[] serializers() { 793 return serializers; 794 } 795 796 @Override /* Overridden from RestOp */ 797 public String summary() { 798 return summary; 799 } 800 801 @Override /* Overridden from RestOp */ 802 public OpSwagger swagger() { 803 return swagger; 804 } 805 806 @Override /* Overridden from RestOp */ 807 public String value() { 808 return value; 809 } 810 811 @Override /* Overridden from annotation */ 812 public String[] description() { 813 return description; 814 } 815 } 816 817 /** Default value */ 818 public static final RestOp DEFAULT = create().build(); 819 /** 820 * Predicate that can be used to filter annotation streams. 821 * 822 * <p> 823 * Example: <c>classInfo.getAnnotations().stream().filter(REST_OP_GROUP)</c> 824 */ 825 public static final Predicate<AnnotationInfo<?>> REST_OP_GROUP = x -> x.isInGroup(RestOp.class); 826 827 /** 828 * Instantiates a new builder for this class. 829 * 830 * @return A new builder object. 831 */ 832 public static Builder create() { 833 return new Builder(); 834 } 835}