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.annotation; 018 019import static java.lang.annotation.ElementType.*; 020import static java.lang.annotation.RetentionPolicy.*; 021 022import java.lang.annotation.*; 023import java.nio.charset.*; 024 025import org.apache.juneau.*; 026import org.apache.juneau.annotation.*; 027import org.apache.juneau.bean.swagger.*; 028import org.apache.juneau.commons.annotation.*; 029import org.apache.juneau.encoders.*; 030import org.apache.juneau.http.remote.*; 031import org.apache.juneau.parser.*; 032import org.apache.juneau.rest.*; 033import org.apache.juneau.rest.converter.*; 034import org.apache.juneau.rest.guard.*; 035import org.apache.juneau.rest.httppart.*; 036import org.apache.juneau.rest.matcher.*; 037import org.apache.juneau.rest.servlet.*; 038import org.apache.juneau.rest.swagger.*; 039import org.apache.juneau.serializer.*; 040 041/** 042 * Identifies a REST operation Java method on a {@link RestServlet} implementation class. 043 * 044 * <h5 class='section'>See Also:</h5><ul> 045 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestOpAnnotatedMethodBasics">@RestOp-Annotated Method Basics</a> 046 047 * </ul> 048 */ 049@Target(METHOD) 050@Retention(RUNTIME) 051@Inherited 052@ContextApply(RestOpAnnotation.RestOpContextApply.class) 053@AnnotationGroup(RestOp.class) 054public @interface RestOp { 055 056 /** 057 * Specifies whether this method can be called based on the client version. 058 * 059 * <p> 060 * The client version is identified via the HTTP request header identified by 061 * {@link Rest#clientVersionHeader() @Rest(clientVersionHeader)} which by default is <js>"Client-Version"</js>. 062 * 063 * <p> 064 * This is a specialized kind of {@link RestMatcher} that allows you to invoke different Java methods for the same 065 * method/path based on the client version. 066 * 067 * <p> 068 * The format of the client version range is similar to that of OSGi versions. 069 * 070 * <p> 071 * In the following example, the Java methods are mapped to the same HTTP method and URL <js>"/foobar"</js>. 072 * <p class='bjava'> 073 * <jc>// Call this method if Client-Version is at least 2.0. 074 * // Note that this also matches 2.0.1.</jc> 075 * <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"2.0"</js>) 076 * <jk>public</jk> Object method1() {...} 077 * 078 * <jc>// Call this method if Client-Version is at least 1.1, but less than 2.0.</jc> 079 * <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"[1.1,2.0)"</js>) 080 * <jk>public</jk> Object method2() {...} 081 * 082 * <jc>// Call this method if Client-Version is less than 1.1.</jc> 083 * <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"[0,1.1)"</js>) 084 * <jk>public</jk> Object method3() {...} 085 * </p> 086 * 087 * <p> 088 * It's common to combine the client version with transforms that will convert new POJOs into older POJOs for 089 * backwards compatibility. 090 * <p class='bjava'> 091 * <jc>// Call this method if Client-Version is at least 2.0.</jc> 092 * <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"2.0"</js>) 093 * <jk>public</jk> NewPojo newMethod() {...} 094 * 095 * <jc>// Call this method if X-Client-Version is at least 1.1, but less than 2.0.</jc> 096 * <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"[1.1,2.0)"</js>) 097 * <ja>@BeanConfig(swaps=NewToOldSwap.<jk>class</jk>) 098 * <jk>public</jk> NewPojo oldMethod() { 099 * <jk>return</jk> newMethod(); 100 * } 101 * 102 * <p> 103 * Note that in the previous example, we're returning the exact same POJO, but using a transform to convert it into 104 * an older form. 105 * The old method could also just return back a completely different object. 106 * The range can be any of the following: 107 * <ul> 108 * <li><js>"[0,1.0)"</js> = Less than 1.0. 1.0 and 1.0.0 does not match. 109 * <li><js>"[0,1.0]"</js> = Less than or equal to 1.0. Note that 1.0.1 will match. 110 * <li><js>"1.0"</js> = At least 1.0. 1.0 and 2.0 will match. 111 * </ul> 112 * 113 * <h5 class='section'>See Also:</h5><ul> 114 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#clientVersionHeader(String)} 115 * </ul> 116 * 117 * @return The annotation value. 118 */ 119 String clientVersion() default ""; 120 121 /** 122 * Supported content media types. 123 * 124 * <p> 125 * Overrides the media types inferred from the parsers that identify what media types can be consumed by the resource. 126 * 127 * <h5 class='section'>Notes:</h5><ul> 128 * <li class='note'> 129 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 130 * (e.g. <js>"$S{mySystemProperty}"</js>). 131 * </ul> 132 * 133 * <h5 class='section'>See Also:</h5><ul> 134 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#consumes(MediaType...)} 135 * </ul> 136 * 137 * @return The annotation value. 138 */ 139 String[] consumes() default {}; 140 141 /** 142 * Class-level response converters. 143 * 144 * <p> 145 * Associates one or more {@link RestConverter converters} with this method. 146 * 147 * <h5 class='section'>See Also:</h5><ul> 148 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#converters()} - Registering converters with REST resources. 149 * </ul> 150 * 151 * @return The annotation value. 152 */ 153 Class<? extends RestConverter>[] converters() default {}; 154 155 /** 156 * Enable debug mode. 157 * 158 * <p> 159 * Enables the following: 160 * <ul class='spaced-list'> 161 * <li> 162 * HTTP request/response bodies are cached in memory for logging purposes. 163 * <li> 164 * Request/response messages are automatically logged. 165 * </ul> 166 * 167 * <ul class='values'> 168 * <li><js>"true"</js> - Debug is enabled for all requests. 169 * <li><js>"false"</js> - Debug is disabled for all requests. 170 * <li><js>"conditional"</js> - Debug is enabled only for requests that have a <c class='snippet'>Debug: true</c> header. 171 * <li><js>""</js> (or anything else) - Debug mode is inherited from class. 172 * </ul> 173 * 174 * <h5 class='section'>Notes:</h5><ul> 175 * <li class='note'> 176 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 177 * (e.g. <js>"$L{my.localized.variable}"</js>). 178 * </ul> 179 * 180 * <h5 class='section'>See Also:</h5><ul> 181 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#debugEnablement()} 182 * </ul> 183 * 184 * @return The annotation value. 185 */ 186 String debug() default ""; 187 188 /** 189 * Default <c>Accept</c> header. 190 * 191 * <p> 192 * The default value for the <c>Accept</c> header if not specified on a request. 193 * 194 * <p> 195 * This is a shortcut for using {@link #defaultRequestHeaders()} for just this specific header. 196 * 197 * @return The annotation value. 198 */ 199 String defaultAccept() default ""; 200 201 /** 202 * Default character encoding. 203 * 204 * <p> 205 * The default character encoding for the request and response if not specified on the request. 206 * 207 * <h5 class='section'>Notes:</h5><ul> 208 * <li class='note'> 209 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 210 * (e.g. <js>"$S{mySystemProperty}"</js>). 211 * </ul> 212 * 213 * <h5 class='section'>See Also:</h5><ul> 214 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#defaultCharset(Charset)} 215 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#defaultCharset(Charset)} 216 * <li class='ja'>{@link Rest#defaultCharset} 217 * </ul> 218 * 219 * @return The annotation value. 220 */ 221 String defaultCharset() default ""; 222 223 /** 224 * Default <c>Content-Type</c> header. 225 * 226 * <p> 227 * The default value for the <c>Content-Type</c> header if not specified on a request. 228 * 229 * <p> 230 * This is a shortcut for using {@link #defaultRequestHeaders()} for just this specific header. 231 * 232 * @return The annotation value. 233 */ 234 String defaultContentType() default ""; 235 236 /** 237 * Default request attributes. 238 * 239 * <p> 240 * Specifies default values for request attributes if they're not already set on the request. 241 * 242 * <p> 243 * Affects values returned by the following methods: 244 * <ul> 245 * <li class='jm'>{@link RestRequest#getAttribute(String)}. 246 * <li class='jm'>{@link RestRequest#getAttributes()}. 247 * </ul> 248 * 249 * <h5 class='section'>Example:</h5> 250 * <p class='bjava'> 251 * <jc>// Defined via annotation resolving to a config file setting with default value.</jc> 252 * <ja>@Rest</ja>(defaultRequestAttributes={<js>"Foo=bar"</js>, <js>"Baz: $C{REST/myAttributeValue}"</js>}) 253 * <jk>public class</jk> MyResource { 254 * 255 * <jc>// Override at the method level.</jc> 256 * <ja>@RestGet</ja>(defaultRequestAttributes={<js>"Foo: bar"</js>}) 257 * <jk>public</jk> Object myMethod() {...} 258 * } 259 * </p> 260 * 261 * </ul> 262 * <h5 class='section'>Notes:</h5><ul> 263 * <li class='note'> 264 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 265 * (e.g. <js>"$L{my.localized.variable}"</js>). 266 * </ul> 267 * 268 * <h5 class='section'>See Also:</h5><ul> 269 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#defaultRequestAttributes(NamedAttribute...)} 270 * <li class='ja'>{@link Rest#defaultRequestAttributes()} 271 * </ul> 272 * 273 * @return The annotation value. 274 */ 275 String[] defaultRequestAttributes() default {}; 276 277 /** 278 * Specifies default values for form-data parameters. 279 * 280 * <p> 281 * Strings are of the format <js>"name=value"</js>. 282 * 283 * <p> 284 * Affects values returned by {@link RestRequest#getFormParam(String)} when the parameter is not present on the 285 * request. 286 * 287 * <h5 class='section'>Example:</h5> 288 * <p class='bjava'> 289 * <ja>@RestOp</ja>(method=<jsf>POST</jsf>, path=<js>"/*"</js>, defaultRequestFormData={<js>"foo=bar"</js>}) 290 * <jk>public</jk> String doPost(<ja>@FormData</ja>(<js>"foo"</js>) String <jv>foo</jv>) {...} 291 * </p> 292 * 293 * <h5 class='section'>Notes:</h5><ul> 294 * <li class='note'> 295 * You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter. 296 * <li class='note'> 297 * Key and value is trimmed of whitespace. 298 * <li class='note'> 299 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 300 * (e.g. <js>"$S{mySystemProperty}"</js>). 301 * </ul> 302 * 303 * @return The annotation value. 304 */ 305 String[] defaultRequestFormData() default {}; 306 307 /** 308 * Default request headers. 309 * 310 * <p> 311 * Specifies default values for request headers if they're not passed in through the request. 312 * 313 * <h5 class='section'>Example:</h5> 314 * <p class='bjava'> 315 * <jc>// Assume "text/json" Accept value when Accept not specified</jc> 316 * <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/*"</js>, defaultRequestHeaders={<js>"Accept: text/json"</js>}) 317 * <jk>public</jk> String doGet() {...} 318 * </p> 319 * 320 * <h5 class='section'>Notes:</h5><ul> 321 * <li class='note'> 322 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 323 * (e.g. <js>"$S{mySystemProperty}"</js>). 324 * </ul> 325 * 326 * <h5 class='section'>See Also:</h5><ul> 327 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#defaultRequestHeaders(org.apache.http.Header...)} 328 * </ul> 329 * 330 * @return The annotation value. 331 */ 332 String[] defaultRequestHeaders() default {}; 333 334 /** 335 * Specifies default values for query parameters. 336 * 337 * <p> 338 * Strings are of the format <js>"name=value"</js>. 339 * 340 * <p> 341 * Affects values returned by {@link RestRequest#getQueryParam(String)} when the parameter is not present on the request. 342 * 343 * <h5 class='section'>Example:</h5> 344 * <p class='bjava'> 345 * <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/*"</js>, defaultRequestQueryData={<js>"foo=bar"</js>}) 346 * <jk>public</jk> String doGet(<ja>@Query</ja>(<js>"foo"</js>) String <jv>foo</jv>) {...} 347 * </p> 348 * 349 * <h5 class='section'>Notes:</h5><ul> 350 * <li class='note'> 351 * You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter. 352 * <li class='note'> 353 * Key and value is trimmed of whitespace. 354 * <li class='note'> 355 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 356 * (e.g. <js>"$S{mySystemProperty}"</js>). 357 * </ul> 358 * 359 * @return The annotation value. 360 */ 361 String[] defaultRequestQueryData() default {}; 362 363 /** 364 * Default response headers. 365 * 366 * <p> 367 * Specifies default values for response headers if they're not overwritten during the request. 368 * 369 * <h5 class='section'>Example:</h5> 370 * <p class='bjava'> 371 * <jc>// Assume "text/json" Accept value when Accept not specified</jc> 372 * <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/*"</js>, defaultResponseHeaders={<js>"Content-Type: text/json"</js>}) 373 * <jk>public</jk> String doGet() {...} 374 * </p> 375 * 376 * <h5 class='section'>Notes:</h5><ul> 377 * <li class='note'> 378 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 379 * (e.g. <js>"$S{mySystemProperty}"</js>). 380 * </ul> 381 * 382 * <h5 class='section'>See Also:</h5><ul> 383 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#defaultResponseHeaders(org.apache.http.Header...)} 384 * </ul> 385 * 386 * @return The annotation value. 387 */ 388 String[] defaultResponseHeaders() default {}; 389 390 /** 391 * Optional description for the exposed API. 392 * 393 * <p> 394 * This description is used in the following locations: 395 * <ul class='spaced-list'> 396 * <li> 397 * The value returned by {@link Operation#getDescription()} in the auto-generated swagger. 398 * <li> 399 * The <js>"$RS{operationDescription}"</js> variable. 400 * <li> 401 * The description of the method in the Swagger page. 402 * </ul> 403 * 404 * <h5 class='section'>Notes:</h5><ul> 405 * <li class='note'> 406 * Corresponds to the swagger field <c>/paths/{path}/{method}/description</c>. 407 * <li class='note'> 408 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 409 * (e.g. <js>"$L{my.localized.variable}"</js>). 410 * </ul> 411 * 412 * @return The annotation value. 413 */ 414 String[] description() default {}; 415 416 /** 417 * Specifies the compression encoders for this method. 418 * 419 * <p> 420 * Encoders are used to enable various kinds of compression (e.g. <js>"gzip"</js>) on requests and responses. 421 * 422 * <p> 423 * This value overrides encoders specified at the class level using {@link Rest#encoders()}. 424 * The {@link org.apache.juneau.encoders.EncoderSet.Inherit} class can be used to include values from the parent class. 425 * 426 * <h5 class='section'>Example:</h5> 427 * <p class='bjava'> 428 * <jc>// Define a REST resource that handles GZIP compression.</jc> 429 * <ja>@Rest</ja>( 430 * encoders={ 431 * GzipEncoder.<jk>class</jk> 432 * } 433 * ) 434 * <jk>public class</jk> MyResource { 435 * 436 * <jc>// Define a REST method that can also use a custom encoder.</jc> 437 * <ja>@RestOp</ja>( 438 * method=<jsf>GET</jsf>, 439 * encoders={ 440 * EncoderSet.Inherit.<jk>class</jk>, MyEncoder.<jk>class</jk> 441 * } 442 * ) 443 * <jk>public</jk> MyBean doGet() { 444 * ... 445 * } 446 * } 447 * </p> 448 * 449 * <p> 450 * The programmatic equivalent to this annotation is: 451 * <p class='bjava'> 452 * RestOpContext.Builder <jv>builder</jv> = RestOpContext.<jsm>create</jsm>(<jv>method</jv>,<jv>restContext</jv>); 453 * <jv>builder</jv>.getEncoders().set(<jv>classes</jv>); 454 * </p> 455 * 456 * <h5 class='section'>See Also:</h5><ul> 457 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerEncoders">Encoders</a> 458 * </ul> 459 * 460 * @return The annotation value. 461 */ 462 Class<? extends Encoder>[] encoders() default {}; 463 464 /** 465 * Method-level guards. 466 * 467 * <p> 468 * Associates one or more {@link RestGuard RestGuards} with this method. 469 * 470 * <h5 class='section'>See Also:</h5><ul> 471 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#guards()} 472 * </ul> 473 * 474 * @return The annotation value. 475 */ 476 Class<? extends RestGuard>[] guards() default {}; 477 478 /** 479 * Method matchers. 480 * 481 * <p> 482 * Associates one more more {@link RestMatcher RestMatchers} with this method. 483 * 484 * <p> 485 * Matchers are used to allow multiple Java methods to handle requests assigned to the same URL path pattern, but 486 * differing based on some request attribute, such as a specific header value. 487 * 488 * <h5 class='section'>See Also:</h5><ul> 489 * <li class='jac'>{@link RestMatcher} 490 * </ul> 491 * 492 * @return The annotation value. 493 */ 494 Class<? extends RestMatcher>[] matchers() default {}; 495 496 /** 497 * The maximum allowed input size (in bytes) on HTTP requests. 498 * 499 * <p> 500 * Useful for alleviating DoS attacks by throwing an exception when too much input is received instead of resulting 501 * in out-of-memory errors which could affect system stability. 502 * 503 * <h5 class='section'>Example:</h5> 504 * <p class='bjava'> 505 * <ja>@RestOp</ja>( 506 * maxInput=<js>"100M"</js> 507 * ) 508 * </p> 509 * 510 * <h5 class='section'>Notes:</h5><ul> 511 * <li> 512 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 513 * (e.g. <js>"$S{mySystemProperty}"</js>). 514 * </ul> 515 * 516 * <h5 class='section'>See Also:</h5><ul> 517 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#maxInput(String)} 518 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#maxInput(String)} 519 * <li class='ja'>{@link Rest#maxInput} 520 * </ul> 521 * 522 * @return The annotation value. 523 */ 524 String maxInput() default ""; 525 526 /** 527 * REST method name. 528 * 529 * <p> 530 * Typically <js>"GET"</js>, <js>"PUT"</js>, <js>"POST"</js>, <js>"DELETE"</js>, or <js>"OPTIONS"</js>. 531 * 532 * <p> 533 * Method names are case-insensitive (always folded to upper-case). 534 * 535 * <p> 536 * Note that you can use {@link org.apache.juneau.http.HttpMethod} for constant values. 537 * 538 * <p> 539 * Note that you can also use {@link #value()} to specify the method name and path in shortened form. 540 * 541 * <p> 542 * Besides the standard HTTP method names, the following can also be specified: 543 * <ul class='spaced-list'> 544 * <li> 545 * <js>"*"</js> 546 * - Denotes any method. 547 * <br>Use this if you want to capture any HTTP methods in a single Java method. 548 * <br>The {@link Method @Method} annotation and/or {@link RestRequest#getMethod()} method can be used to 549 * distinguish the actual HTTP method name. 550 * <li> 551 * <js>""</js> 552 * - Auto-detect. 553 * <br>The method name is determined based on the Java method name. 554 * <br>For example, if the method is <c>doPost(...)</c>, then the method name is automatically detected 555 * as <js>"POST"</js>. 556 * <br>Otherwise, defaults to <js>"GET"</js>. 557 * <li> 558 * <js>"RRPC"</js> 559 * - Remote-proxy interface. 560 * <br>This denotes a Java method that returns an object (usually an interface, often annotated with the 561 * {@link Remote @Remote} annotation) to be used as a remote proxy using 562 * <c>RestClient.getRemoteInterface(Class<T> interfaceClass, String url)</c>. 563 * <br>This allows you to construct client-side interface proxies using REST as a transport medium. 564 * <br>Conceptually, this is simply a fancy <c>POST</c> against the url <js>"/{path}/{javaMethodName}"</js> 565 * where the arguments are marshalled from the client to the server as an HTTP content containing an array of 566 * objects, passed to the method as arguments, and then the resulting object is marshalled back to the client. 567 * <li> 568 * Anything else 569 * - Overloaded non-HTTP-standard names that are passed in through a <c>&method=methodName</c> URL 570 * parameter. 571 * </ul> 572 * 573 * @return The annotation value. 574 */ 575 String method() default ""; 576 577 /** 578 * Dynamically apply this annotation to the specified methods. 579 * 580 * <h5 class='section'>See Also:</h5><ul> 581 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a> 582 * </ul> 583 * 584 * @return The annotation value. 585 */ 586 String[] on() default {}; 587 588 /** 589 * Specifies the parsers for converting HTTP request bodies into POJOs for this method. 590 * 591 * <p> 592 * Parsers are used to convert the content of HTTP requests into POJOs. 593 * <br>Any of the Juneau framework parsers can be used in this setting. 594 * <br>The parser selected is based on the request <c>Content-Type</c> header matched against the values returned by the following method 595 * using a best-match algorithm: 596 * <ul class='javatree'> 597 * <li class='jm'>{@link Parser#getMediaTypes()} 598 * </ul> 599 * 600 * <p> 601 * This value overrides parsers specified at the class level using {@link Rest#parsers()}. 602 * The {@link org.apache.juneau.parser.ParserSet.Inherit} class can be used to include values from the parent class. 603 * 604 * <h5 class='section'>Example:</h5> 605 * <p class='bjava'> 606 * <jc>// Define a REST resource that can consume JSON and HTML.</jc> 607 * <ja>@Rest</ja>( 608 * parsers={ 609 * JsonParser.<jk>class</jk>, 610 * HtmlParser.<jk>class</jk> 611 * } 612 * ) 613 * <jk>public class</jk> MyResource { 614 * 615 * <jc>// Define a REST method that can also consume XML.</jc> 616 * <ja>@RestOp</ja>( 617 * method=<jsf>POST</jsf>, 618 * parsers={ 619 * ParserSet.Inherit.<jk>class</jk>, XmlParser.<jk>class</jk> 620 * } 621 * ) 622 * <jk>public void</jk> doPost(MyBean <jv>bean</jv>) { 623 * ... 624 * } 625 * } 626 * </p> 627 * 628 * <p> 629 * The programmatic equivalent to this annotation is: 630 * <p class='bjava'> 631 * RestOpContext.Builder <jv>builder</jv> = RestOpContext.<jsm>create</jsm>(<jv>method</jv>,<jv>restContext</jv>); 632 * <jv>builder</jv>.getParsers().set(<jv>classes</jv>); 633 * </p> 634 * 635 * <h5 class='section'>See Also:</h5><ul> 636 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/Marshalling">Marshalling</a> 637 * </ul> 638 * 639 * @return The annotation value. 640 */ 641 Class<?>[] parsers() default {}; 642 643 /** 644 * Optional path pattern for the specified method. 645 * 646 * <p> 647 * Appending <js>"/*"</js> to the end of the path pattern will make it match any remainder too. 648 * <br>Not appending <js>"/*"</js> to the end of the pattern will cause a 404 (Not found) error to occur if the exact 649 * pattern is not found. 650 * 651 * <p> 652 * The path can contain variables that get resolved to {@link org.apache.juneau.http.annotation.Path @Path} parameters. 653 * 654 * <h5 class='figure'>Examples:</h5> 655 * <p class='bjava'> 656 * <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/myurl/{foo}/{bar}/{baz}/*"</js>) 657 * </p> 658 * <p class='bjava'> 659 * <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/myurl/{0}/{1}/{2}/*"</js>) 660 * </p> 661 * 662 * <p> 663 * If you do not specify a path name, then the path name is inferred from the Java method name. 664 * 665 * <h5 class='figure'>Example:</h5> 666 * <p class='bjava'> 667 * <jc>// Path is assumed to be "/foo".</jc> 668 * <ja>@RestOp</ja>(method=<jsf>GET</jsf>) 669 * <jk>public void</jk> foo() {...} 670 * </p> 671 * 672 * <p> 673 * If you also do not specify the {@link #method()} and the Java method name starts with <js>"get"</js>, <js>"put"</js>, <js>"post"</js>, or <js>"deleted"</js>, 674 * then the HTTP method name is stripped from the inferred path. 675 * 676 * <h5 class='figure'>Examples:</h5> 677 * <p class='bjava'> 678 * <jc>// Method is GET, path is "/foo".</jc> 679 * <ja>@RestOp</ja> 680 * <jk>public void</jk> getFoo() {...} 681 * </p> 682 * <p class='bjava'> 683 * <jc>// Method is DELETE, path is "/bar".</jc> 684 * <ja>@RestOp</ja> 685 * <jk>public void</jk> deleteBar() {...} 686 * </p> 687 * <p class='bjava'> 688 * <jc>// Method is GET, path is "/foobar".</jc> 689 * <ja>@RestOp</ja> 690 * <jk>public void</jk> foobar() {...} 691 * </p> 692 * <p class='bjava'> 693 * <jc>// Method is GET, path is "/".</jc> 694 * <ja>@RestOp</ja> 695 * <jk>public void</jk> get() {...} 696 * </p> 697 * 698 * <p> 699 * Note that you can also use {@link #value()} to specify the method name and path in shortened form. 700 * 701 * <h5 class='section'>See Also:</h5><ul> 702 * <li class='ja'>{@link org.apache.juneau.http.annotation.Path} 703 * </ul> 704 * 705 * @return The annotation value. 706 */ 707 String[] path() default {}; 708 709 /** 710 * Supported accept media types. 711 * 712 * <p> 713 * Overrides the media types inferred from the serializers that identify what media types can be produced by the resource. 714 * 715 * <h5 class='section'>Notes:</h5><ul> 716 * <li class='note'> 717 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 718 * (e.g. <js>"$S{mySystemProperty}"</js>). 719 * </ul> 720 * 721 * <h5 class='section'>See Also:</h5><ul> 722 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#produces(MediaType...)} 723 * </ul> 724 * 725 * @return The annotation value. 726 */ 727 String[] produces() default {}; 728 729 /** 730 * Role guard. 731 * 732 * <p> 733 * An expression defining if a user with the specified roles are allowed to access this method. 734 * 735 * <h5 class='section'>Example:</h5> 736 * <p class='bjava'> 737 * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet { 738 * 739 * <ja>@RestOp</ja>( 740 * method=<jsf>GET</jsf>, 741 * path=<js>"/foo"</js>, 742 * roleGuard=<js>"ROLE_ADMIN || (ROLE_READ_WRITE && ROLE_SPECIAL)"</js> 743 * ) 744 * <jk>public</jk> Object doGet() { 745 * } 746 * } 747 * </p> 748 * 749 * <h5 class='section'>Notes:</h5><ul> 750 * <li class='note'> 751 * Supports any of the following expression constructs: 752 * <ul> 753 * <li><js>"foo"</js> - Single arguments. 754 * <li><js>"foo,bar,baz"</js> - Multiple OR'ed arguments. 755 * <li><js>"foo | bar | baz"</js> - Multiple OR'ed arguments, pipe syntax. 756 * <li><js>"foo || bar || baz"</js> - Multiple OR'ed arguments, Java-OR syntax. 757 * <li><js>"fo*"</js> - Patterns including <js>'*'</js> and <js>'?'</js>. 758 * <li><js>"fo* & *oo"</js> - Multiple AND'ed arguments, ampersand syntax. 759 * <li><js>"fo* && *oo"</js> - Multiple AND'ed arguments, Java-AND syntax. 760 * <li><js>"fo* || (*oo || bar)"</js> - Parenthesis. 761 * </ul> 762 * <li class='note'> 763 * AND operations take precedence over OR operations (as expected). 764 * <li class='note'> 765 * Whitespace is ignored. 766 * <li class='note'> 767 * <jk>null</jk> or empty expressions always match as <jk>false</jk>. 768 * <li class='note'> 769 * If patterns are used, you must specify the list of declared roles using {@link #rolesDeclared()} or {@link org.apache.juneau.rest.RestOpContext.Builder#rolesDeclared(String...)}. 770 * <li class='note'> 771 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 772 * (e.g. <js>"$L{my.localized.variable}"</js>). 773 * <li class='note'> 774 * When defined on parent/child classes and methods, ALL guards within the hierarchy must pass. 775 * </ul> 776 * 777 * <h5 class='section'>See Also:</h5><ul> 778 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#roleGuard(String)} 779 * </ul> 780 * 781 * @return The annotation value. 782 */ 783 String roleGuard() default ""; 784 785 /** 786 * Declared roles. 787 * 788 * <p> 789 * A comma-delimited list of all possible user roles. 790 * 791 * <p> 792 * Used in conjunction with {@link #roleGuard()} is used with patterns. 793 * 794 * <h5 class='section'>Example:</h5> 795 * <p class='bjava'> 796 * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet { 797 * 798 * <ja>@RestOp</ja>( 799 * method=<jsf>GET</jsf>, 800 * path=<js>"/foo"</js>, 801 * rolesDeclared=<js>"ROLE_ADMIN,ROLE_READ_WRITE,ROLE_READ_ONLY,ROLE_SPECIAL"</js>, 802 * roleGuard=<js>"ROLE_ADMIN || (ROLE_READ_WRITE && ROLE_SPECIAL)"</js> 803 * ) 804 * <jk>public</jk> Object doGet() { 805 * } 806 * } 807 * </p> 808 * 809 * <h5 class='section'>See Also:</h5><ul> 810 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#rolesDeclared(String...)} 811 * </ul> 812 * 813 * @return The annotation value. 814 */ 815 String rolesDeclared() default ""; 816 817 /** 818 * Specifies the serializers for marshalling POJOs into response bodies for this method. 819 * 820 * <p> 821 * Serializer are used to convert POJOs to HTTP response bodies. 822 * <br>Any of the Juneau framework serializers can be used in this setting. 823 * <br>The serializer selected is based on the request <c>Accept</c> header matched against the values returned by the following method 824 * using a best-match algorithm: 825 * <ul class='javatree'> 826 * <li class='jm'>{@link Serializer#getMediaTypeRanges()} 827 * </ul> 828 * 829 * <p> 830 * This value overrides serializers specified at the class level using {@link Rest#serializers()}. 831 * The {@link org.apache.juneau.serializer.SerializerSet.Inherit} class can be used to include values from the parent class. 832 * 833 * <h5 class='section'>Example:</h5> 834 * <p class='bjava'> 835 * <jc>// Define a REST resource that can produce JSON and HTML.</jc> 836 * <ja>@Rest</ja>( 837 * serializers={ 838 * JsonParser.<jk>class</jk>, 839 * HtmlParser.<jk>class</jk> 840 * } 841 * ) 842 * <jk>public class</jk> MyResource { 843 * 844 * <jc>// Define a REST method that can also produce XML.</jc> 845 * <ja>@RestOp</ja>( 846 * method=<jsf>POST</jsf>, 847 * parsers={ 848 * SerializerSet.Inherit.<jk>class</jk>, XmlParser.<jk>class</jk> 849 * } 850 * ) 851 * <jk>public void</jk> doPost(MyBean <jv>bean</jv>) { 852 * ... 853 * } 854 * } 855 * </p> 856 * 857 * <p> 858 * The programmatic equivalent to this annotation is: 859 * <p class='bjava'> 860 * RestOpContext.Builder <jv>builder</jv> = RestOpContext.<jsm>create</jsm>(<jv>method</jv>,<jv>restContext</jv>); 861 * <jv>builder</jv>.getSerializers().set(<jv>classes</jv>); 862 * </p> 863 * 864 * <h5 class='section'>See Also:</h5><ul> 865 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/Marshalling">Marshalling</a> 866 * </ul> 867 * 868 * @return The annotation value. 869 */ 870 Class<? extends Serializer>[] serializers() default {}; 871 872 /** 873 * Optional summary for the exposed API. 874 * 875 * <p> 876 * This summary is used in the following locations: 877 * <ul class='spaced-list'> 878 * <li> 879 * The value returned by {@link Operation#getSummary()} in the auto-generated swagger. 880 * <li> 881 * The <js>"$RS{operationSummary}"</js> variable. 882 * <li> 883 * The summary of the method in the Swagger page. 884 * </ul> 885 * 886 * <h5 class='section'>Notes:</h5><ul> 887 * <li class='note'> 888 * Corresponds to the swagger field <c>/paths/{path}/{method}/summary</c>. 889 * <li class='note'> 890 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 891 * (e.g. <js>"$L{my.localized.variable}"</js>). 892 * </ul> 893 * 894 * @return The annotation value. 895 */ 896 String summary() default ""; 897 898 /** 899 * Provides swagger-specific metadata on this method. 900 * 901 * <p> 902 * Used to populate the auto-generated OPTIONS swagger documentation. 903 * 904 * <p> 905 * The format of this annotation is JSON when all individual parts are concatenated. 906 * <br>The starting and ending <js>'{'</js>/<js>'}'</js> characters around the entire value are optional. 907 * 908 * <h5 class='section'>Example:</h5> 909 * <p class='bjava'> 910 * <ja>@RestOp</ja>( 911 * method=<jsf>PUT</jsf>, 912 * path=<js>"/{propertyName}"</js>, 913 * 914 * <jc>// Swagger info.</jc> 915 * swagger={ 916 * <js>"parameters:["</js>, 917 * <js>"{name:'propertyName',in:'path',description:'The system property name.'},"</js>, 918 * <js>"{in:'body',description:'The new system property value.'}"</js>, 919 * <js>"],"</js>, 920 * <js>"responses:{"</js>, 921 * <js>"302: {headers:{Location:{description:'The root URL of this resource.'}}},"</js>, 922 * <js>"403: {description:'User is not an admin.'}"</js>, 923 * <js>"}"</js> 924 * } 925 * ) 926 * </p> 927 * 928 * <h5 class='section'>Notes:</h5><ul> 929 * <li class='note'> 930 * The format is <a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanSwagger2">juneau-bean-swagger-v2</a>. 931 * <br>Multiple lines are concatenated with newlines. 932 * <li class='note'> 933 * The starting and ending <js>'{'</js>/<js>'}'</js> characters around the entire value are optional. 934 * <li class='note'> 935 * These values are superimposed on top of any Swagger JSON file present for the resource in the classpath. 936 * <li class='note'> 937 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 938 * (e.g. <js>"$L{my.localized.variable}"</js>). 939 * </ul> 940 * 941 * <h5 class='section'>See Also:</h5><ul> 942 * <li class='ja'>{@link OpSwagger} 943 * <li class='jc'>{@link SwaggerProvider} 944 * </ul> 945 * 946 * @return The annotation value. 947 */ 948 OpSwagger swagger() default @OpSwagger; 949 950 /** 951 * REST method name and path. 952 * 953 * <p> 954 * Can be used to provide a shortened combined form for the {@link #method()} and {@link #path()} values. 955 * 956 * <p> 957 * The following examples are considered equivalent. 958 * <p class='bjava'> 959 * <jc>// Normal form</jc> 960 * <ja>@RestOp</ja>(method=<jsf>PUT</jsf>, path=<js>"/{propertyName}"</js>) 961 * 962 * <jc>// Shortened form</jc> 963 * <ja>@RestOp</ja>(<js>"PUT /{propertyName}"</js>) 964 * </p> 965 * 966 * <h5 class='section'>Notes:</h5><ul> 967 * <li class='note'> 968 * The path portion is optional. 969 * </ul> 970 * 971 * @return The annotation value. 972 */ 973 String value() default ""; 974}