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