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