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.rest.*; 030import org.apache.juneau.rest.converter.*; 031import org.apache.juneau.rest.guard.*; 032import org.apache.juneau.rest.httppart.*; 033import org.apache.juneau.rest.matcher.*; 034import org.apache.juneau.rest.servlet.*; 035import org.apache.juneau.rest.swagger.*; 036import org.apache.juneau.serializer.*; 037 038/** 039 * Identifies a REST OPTIONS operation Java method on a {@link RestServlet} implementation class. 040 * 041 * <p> 042 * This is a specialized subtype of <c><ja>{@link RestOp @RestOp}(method=<jsf>OPTIONS</jsf>)</c>. 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(RestOptionsAnnotation.RestOpContextApply.class) 053@AnnotationGroup(RestOp.class) 054public @interface RestOptions { 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>@RestOptions</ja>(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>@RestOptions</ja>(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>@RestOptions</ja>(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>@RestOptions</ja>(path=<js>"/foobar"</js>, clientVersion=<js>"2.0"</js>) 093 * <jk>public</jk> NewPojo newMethod() {...} 094 * 095 * <jc>// Call this method if Client-Version is at least 1.1, but less than 2.0.</jc> 096 * <ja>@RestOptions</ja>(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 * </p> 102 * 103 * <p> 104 * Note that in the previous example, we're returning the exact same POJO, but using a transform to convert it into 105 * an older form. 106 * The old method could also just return back a completely different object. 107 * The range can be any of the following: 108 * <ul> 109 * <li><js>"[0,1.0)"</js> = Less than 1.0. 1.0 and 1.0.0 does not match. 110 * <li><js>"[0,1.0]"</js> = Less than or equal to 1.0. Note that 1.0.1 will match. 111 * <li><js>"1.0"</js> = At least 1.0. 1.0 and 2.0 will match. 112 * </ul> 113 * 114 * <h5 class='section'>See Also:</h5><ul> 115 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#clientVersionHeader(String)} 116 * </ul> 117 * 118 * @return The annotation value. 119 */ 120 String clientVersion() default ""; 121 122 /** 123 * Class-level response converters. 124 * 125 * <p> 126 * Associates one or more {@link RestConverter converters} with this method. 127 * 128 * <h5 class='section'>See Also:</h5><ul> 129 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#converters()} - Registering converters with REST resources. 130 * </ul> 131 * 132 * @return The annotation value. 133 */ 134 Class<? extends RestConverter>[] converters() default {}; 135 136 /** 137 * Enable debug mode. 138 * 139 * <p> 140 * Enables the following: 141 * <ul class='spaced-list'> 142 * <li> 143 * HTTP request/response bodies are cached in memory for logging purposes. 144 * <li> 145 * Request/response messages are automatically logged. 146 * </ul> 147 * 148 * <ul class='values'> 149 * <li><js>"true"</js> - Debug is enabled for all requests. 150 * <li><js>"false"</js> - Debug is disabled for all requests. 151 * <li><js>"conditional"</js> - Debug is enabled only for requests that have a <c class='snippet'>Debug: true</c> header. 152 * <li><js>""</js> (or anything else) - Debug mode is inherited from class. 153 * </ul> 154 * 155 * <h5 class='section'>Notes:</h5><ul> 156 * <li class='note'> 157 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 158 * (e.g. <js>"$L{my.localized.variable}"</js>). 159 * </ul> 160 * 161 * <h5 class='section'>See Also:</h5><ul> 162 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#debugEnablement()} 163 * </ul> 164 * 165 * @return The annotation value. 166 */ 167 String debug() default ""; 168 169 /** 170 * Default <c>Accept</c> header. 171 * 172 * <p> 173 * The default value for the <c>Accept</c> header if not specified on a request. 174 * 175 * <p> 176 * This is a shortcut for using {@link #defaultRequestHeaders()} for just this specific header. 177 * 178 * @return The annotation value. 179 */ 180 String defaultAccept() default ""; 181 182 /** 183 * Default character encoding. 184 * 185 * <p> 186 * The default character encoding for the request and response if not specified on the request. 187 * 188 * <h5 class='section'>Notes:</h5><ul> 189 * <li class='note'> 190 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 191 * (e.g. <js>"$S{mySystemProperty}"</js>). 192 * </ul> 193 * 194 * <h5 class='section'>See Also:</h5><ul> 195 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#defaultCharset(Charset)} 196 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#defaultCharset(Charset)} 197 * <li class='ja'>{@link Rest#defaultCharset} 198 * </ul> 199 * 200 * @return The annotation value. 201 */ 202 String defaultCharset() default ""; 203 204 /** 205 * Specifies default values for query parameters. 206 * 207 * <p> 208 * Strings are of the format <js>"name=value"</js>. 209 * 210 * <p> 211 * Affects values returned by {@link RestRequest#getQueryParam(String)} when the parameter is not present on the request. 212 * 213 * <h5 class='section'>Example:</h5> 214 * <p class='bjava'> 215 * <ja>@RestOptions</ja>(path=<js>"/*"</js>, defaultRequestQueryData={<js>"foo=bar"</js>}) 216 * <jk>public</jk> String doGet(<ja>@Query</ja>(<js>"foo"</js>) String <jv>foo</jv>) {...} 217 * </p> 218 * 219 * <h5 class='section'>Notes:</h5><ul> 220 * <li class='note'> 221 * You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter. 222 * <li class='note'> 223 * Key and value is trimmed of whitespace. 224 * <li class='note'> 225 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 226 * (e.g. <js>"$S{mySystemProperty}"</js>). 227 * </ul> 228 * 229 * @return The annotation value. 230 */ 231 String[] defaultRequestQueryData() default {}; 232 233 /** 234 * Default request attributes. 235 * 236 * <p> 237 * Specifies default values for request attributes if they're not already set on the request. 238 * 239 * <p> 240 * Affects values returned by the following methods: 241 * <ul> 242 * <li class='jm'>{@link RestRequest#getAttribute(String)}. 243 * <li class='jm'>{@link RestRequest#getAttributes()}. 244 * </ul> 245 * 246 * <h5 class='section'>Example:</h5> 247 * <p class='bjava'> 248 * <jc>// Defined via annotation resolving to a config file setting with default value.</jc> 249 * <ja>@Rest</ja>(defaultRequestAttributes={<js>"Foo=bar"</js>, <js>"Baz: $C{REST/myAttributeValue}"</js>}) 250 * <jk>public class</jk> MyResource { 251 * 252 * <jc>// Override at the method level.</jc> 253 * <ja>@RestOptions</ja>(defaultRequestAttributes={<js>"Foo: bar"</js>}) 254 * <jk>public</jk> Object myMethod() {...} 255 * } 256 * </p> 257 * 258 * </ul> 259 * <h5 class='section'>Notes:</h5><ul> 260 * <li class='note'> 261 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 262 * (e.g. <js>"$L{my.localized.variable}"</js>). 263 * </ul> 264 * 265 * <h5 class='section'>See Also:</h5><ul> 266 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#defaultRequestAttributes(NamedAttribute...)} 267 * <li class='ja'>{@link Rest#defaultRequestAttributes()} 268 * </ul> 269 * 270 * @return The annotation value. 271 */ 272 String[] defaultRequestAttributes() default {}; 273 274 /** 275 * Default request headers. 276 * 277 * <p> 278 * Specifies default values for request headers if they're not passed in through the request. 279 * 280 * <h5 class='section'>Example:</h5> 281 * <p class='bjava'> 282 * <jc>// Assume "text/json" Accept value when Accept not specified</jc> 283 * <ja>@RestOptions</ja>(path=<js>"/*"</js>, defaultRequestHeaders={<js>"Accept: text/json"</js>}) 284 * <jk>public</jk> String doGet() {...} 285 * </p> 286 * 287 * <h5 class='section'>Notes:</h5><ul> 288 * <li class='note'> 289 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 290 * (e.g. <js>"$S{mySystemProperty}"</js>). 291 * </ul> 292 * 293 * <h5 class='section'>See Also:</h5><ul> 294 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#defaultRequestHeaders(org.apache.http.Header...)} 295 * </ul> 296 * 297 * @return The annotation value. 298 */ 299 String[] defaultRequestHeaders() default {}; 300 301 /** 302 * Default response headers. 303 * 304 * <p> 305 * Specifies default values for response headers if they're not overwritten during the request. 306 * 307 * <h5 class='section'>Example:</h5> 308 * <p class='bjava'> 309 * <jc>// Assume "text/json" Accept value when Accept not specified</jc> 310 * <ja>@RestOptions</ja>(path=<js>"/*"</js>, defaultResponseHeaders={<js>"Content-Type: text/json"</js>}) 311 * <jk>public</jk> String doGet() {...} 312 * </p> 313 * 314 * <h5 class='section'>Notes:</h5><ul> 315 * <li class='note'> 316 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 317 * (e.g. <js>"$S{mySystemProperty}"</js>). 318 * </ul> 319 * 320 * <h5 class='section'>See Also:</h5><ul> 321 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#defaultResponseHeaders(org.apache.http.Header...)} 322 * </ul> 323 * 324 * @return The annotation value. 325 */ 326 String[] defaultResponseHeaders() default {}; 327 328 /** 329 * Optional description for the exposed API. 330 * 331 * <p> 332 * This description is used in the following locations: 333 * <ul class='spaced-list'> 334 * <li> 335 * The value returned by {@link Operation#getDescription()} in the auto-generated swagger. 336 * <li> 337 * The <js>"$RS{operationDescription}"</js> variable. 338 * <li> 339 * The description of the method in the Swagger page. 340 * </ul> 341 * 342 * <h5 class='section'>Notes:</h5><ul> 343 * <li class='note'> 344 * Corresponds to the swagger field <c>/paths/{path}/{method}/description</c>. 345 * <li class='note'> 346 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 347 * (e.g. <js>"$L{my.localized.variable}"</js>). 348 * </ul> 349 * 350 * @return The annotation value. 351 */ 352 String[] description() default {}; 353 354 /** 355 * Specifies the compression encoders for this method. 356 * 357 * <p> 358 * Encoders are used to enable various kinds of compression (e.g. <js>"gzip"</js>) on requests and responses. 359 * 360 * <p> 361 * This value overrides encoders specified at the class level using {@link Rest#encoders()}. 362 * The {@link org.apache.juneau.encoders.EncoderSet.Inherit} class can be used to include values from the parent class. 363 * 364 * <h5 class='section'>Example:</h5> 365 * <p class='bjava'> 366 * <jc>// Define a REST resource that handles GZIP compression.</jc> 367 * <ja>@Rest</ja>( 368 * encoders={ 369 * GzipEncoder.<jk>class</jk> 370 * } 371 * ) 372 * <jk>public class</jk> MyResource { 373 * 374 * <jc>// Define a REST method that can also use a custom encoder.</jc> 375 * <ja>@RestOptions</ja>( 376 * method=<jsf>GET</jsf>, 377 * encoders={ 378 * EncoderSet.Inherit.<jk>class</jk>, MyEncoder.<jk>class</jk> 379 * } 380 * ) 381 * <jk>public</jk> MyBean doGet() { 382 * ... 383 * } 384 * } 385 * </p> 386 * 387 * <p> 388 * The programmatic equivalent to this annotation is: 389 * <p class='bjava'> 390 * RestOpContext.Builder <jv>builder</jv> = RestOpContext.<jsm>create</jsm>(<jv>method</jv>,<jv>restContext</jv>); 391 * <jv>builder</jv>.getEncoders().set(<jv>classes</jv>); 392 * </p> 393 * 394 * <h5 class='section'>See Also:</h5><ul> 395 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerEncoders">Encoders</a> 396 * </ul> 397 * 398 * @return The annotation value. 399 */ 400 Class<? extends Encoder>[] encoders() default {}; 401 402 /** 403 * Method-level guards. 404 * 405 * <p> 406 * Associates one or more {@link RestGuard RestGuards} with this method. 407 * 408 * <h5 class='section'>See Also:</h5><ul> 409 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#guards()} 410 * </ul> 411 * 412 * @return The annotation value. 413 */ 414 Class<? extends RestGuard>[] guards() default {}; 415 416 /** 417 * Method matchers. 418 * 419 * <p> 420 * Associates one more more {@link RestMatcher RestMatchers} with this method. 421 * 422 * <p> 423 * Matchers are used to allow multiple Java methods to handle requests assigned to the same URL path pattern, but 424 * differing based on some request attribute, such as a specific header value. 425 * 426 * <h5 class='section'>See Also:</h5><ul> 427 * <li class='jac'>{@link RestMatcher} 428 * </ul> 429 * 430 * @return The annotation value. 431 */ 432 Class<? extends RestMatcher>[] matchers() default {}; 433 434 /** 435 * Dynamically apply this annotation to the specified methods. 436 * 437 * <h5 class='section'>See Also:</h5><ul> 438 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a> 439 * </ul> 440 * 441 * @return The annotation value. 442 */ 443 String[] on() default {}; 444 445 /** 446 * Optional path pattern for the specified method. 447 * 448 * <p> 449 * Appending <js>"/*"</js> to the end of the path pattern will make it match any remainder too. 450 * <br>Not appending <js>"/*"</js> to the end of the pattern will cause a 404 (Not found) error to occur if the exact 451 * pattern is not found. 452 * 453 * <p> 454 * The path can contain variables that get resolved to {@link org.apache.juneau.http.annotation.Path @Path} parameters. 455 * 456 * <h5 class='figure'>Examples:</h5> 457 * <p class='bjava'> 458 * <ja>@RestOptions</ja>(path=<js>"/myurl/{foo}/{bar}/{baz}/*"</js>) 459 * </p> 460 * <p class='bjava'> 461 * <ja>@RestOptions</ja>(path=<js>"/myurl/{0}/{1}/{2}/*"</js>) 462 * </p> 463 * 464 * <p> 465 * Note that you can also use {@link #value()} to specify the path. 466 * 467 * <h5 class='section'>See Also:</h5><ul> 468 * <li class='ja'>{@link org.apache.juneau.http.annotation.Path} 469 * </ul> 470 * 471 * @return The annotation value. 472 */ 473 String[] path() default {}; 474 475 /** 476 * Supported accept media types. 477 * 478 * <p> 479 * Overrides the media types inferred from the serializers that identify what media types can be produced by the resource. 480 * 481 * <h5 class='section'>Notes:</h5><ul> 482 * <li class='note'> 483 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 484 * (e.g. <js>"$S{mySystemProperty}"</js>). 485 * </ul> 486 * 487 * <h5 class='section'>See Also:</h5><ul> 488 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#produces(MediaType...)} 489 * </ul> 490 * 491 * @return The annotation value. 492 */ 493 String[] produces() default {}; 494 495 /** 496 * Role guard. 497 * 498 * <p> 499 * An expression defining if a user with the specified roles are allowed to access this method. 500 * 501 * <h5 class='section'>Example:</h5> 502 * <p class='bjava'> 503 * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet { 504 * 505 * <ja>@RestOptions</ja>( 506 * path=<js>"/foo"</js>, 507 * roleGuard=<js>"ROLE_ADMIN || (ROLE_READ_WRITE && ROLE_SPECIAL)"</js> 508 * ) 509 * <jk>public</jk> Object doGet() { 510 * } 511 * } 512 * </p> 513 * 514 * <h5 class='section'>Notes:</h5><ul> 515 * <li class='note'> 516 * Supports any of the following expression constructs: 517 * <ul> 518 * <li><js>"foo"</js> - Single arguments. 519 * <li><js>"foo,bar,baz"</js> - Multiple OR'ed arguments. 520 * <li><js>"foo | bar | baz"</js> - Multiple OR'ed arguments, pipe syntax. 521 * <li><js>"foo || bar || baz"</js> - Multiple OR'ed arguments, Java-OR syntax. 522 * <li><js>"fo*"</js> - Patterns including <js>'*'</js> and <js>'?'</js>. 523 * <li><js>"fo* & *oo"</js> - Multiple AND'ed arguments, ampersand syntax. 524 * <li><js>"fo* && *oo"</js> - Multiple AND'ed arguments, Java-AND syntax. 525 * <li><js>"fo* || (*oo || bar)"</js> - Parenthesis. 526 * </ul> 527 * <li class='note'> 528 * AND operations take precedence over OR operations (as expected). 529 * <li class='note'> 530 * Whitespace is ignored. 531 * <li class='note'> 532 * <jk>null</jk> or empty expressions always match as <jk>false</jk>. 533 * <li class='note'> 534 * 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...)}. 535 * <li class='note'> 536 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 537 * (e.g. <js>"$L{my.localized.variable}"</js>). 538 * <li class='note'> 539 * When defined on parent/child classes and methods, ALL guards within the hierarchy must pass. 540 * </ul> 541 * 542 * <h5 class='section'>See Also:</h5><ul> 543 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#roleGuard(String)} 544 * </ul> 545 * 546 * @return The annotation value. 547 */ 548 String roleGuard() default ""; 549 550 /** 551 * Declared roles. 552 * 553 * <p> 554 * A comma-delimited list of all possible user roles. 555 * 556 * <p> 557 * Used in conjunction with {@link #roleGuard()} is used with patterns. 558 * 559 * <h5 class='section'>Example:</h5> 560 * <p class='bjava'> 561 * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet { 562 * 563 * <ja>@RestOptions</ja>( 564 * path=<js>"/foo"</js>, 565 * rolesDeclared=<js>"ROLE_ADMIN,ROLE_READ_WRITE,ROLE_READ_ONLY,ROLE_SPECIAL"</js>, 566 * roleGuard=<js>"ROLE_ADMIN || (ROLE_READ_WRITE && ROLE_SPECIAL)"</js> 567 * ) 568 * <jk>public</jk> Object doGet() { 569 * } 570 * } 571 * </p> 572 * 573 * <h5 class='section'>See Also:</h5><ul> 574 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#rolesDeclared(String...)} 575 * </ul> 576 * 577 * @return The annotation value. 578 */ 579 String rolesDeclared() default ""; 580 581 /** 582 * Specifies the serializers for marshalling POJOs into response bodies for this method. 583 * 584 * <p> 585 * Serializer are used to convert POJOs to HTTP response bodies. 586 * <br>Any of the Juneau framework serializers can be used in this setting. 587 * <br>The serializer selected is based on the request <c>Accept</c> header matched against the values returned by the following method 588 * using a best-match algorithm: 589 * <ul class='javatree'> 590 * <li class='jm'>{@link Serializer#getMediaTypeRanges()} 591 * </ul> 592 * 593 * <p> 594 * This value overrides serializers specified at the class level using {@link Rest#serializers()}. 595 * The {@link org.apache.juneau.serializer.SerializerSet.Inherit} class can be used to include values from the parent class. 596 * 597 * <h5 class='section'>Example:</h5> 598 * <p class='bjava'> 599 * <jc>// Define a REST resource that can produce JSON and HTML.</jc> 600 * <ja>@Rest</ja>( 601 * serializers={ 602 * JsonParser.<jk>class</jk>, 603 * HtmlParser.<jk>class</jk> 604 * } 605 * ) 606 * <jk>public class</jk> MyResource { 607 * 608 * <jc>// Define a REST method that can also produce XML.</jc> 609 * <ja>@RestOptions</ja>( 610 * parsers={ 611 * SerializerSet.Inherit.<jk>class</jk>, XmlParser.<jk>class</jk> 612 * } 613 * ) 614 * <jk>public</jk> MyBean doGet() { 615 * ... 616 * } 617 * } 618 * </p> 619 * 620 * <p> 621 * The programmatic equivalent to this annotation is: 622 * <p class='bjava'> 623 * RestOpContext.Builder <jv>builder</jv> = RestOpContext.<jsm>create</jsm>(<jv>method</jv>,<jv>restContext</jv>); 624 * <jv>builder</jv>.getSerializers().set(<jv>classes</jv>); 625 * </p> 626 * 627 * <h5 class='section'>See Also:</h5><ul> 628 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/Marshalling">Marshalling</a> 629 * </ul> 630 * 631 * @return The annotation value. 632 */ 633 Class<? extends Serializer>[] serializers() default {}; 634 635 /** 636 * Optional summary for the exposed API. 637 * 638 * <p> 639 * This summary is used in the following locations: 640 * <ul class='spaced-list'> 641 * <li> 642 * The value returned by {@link Operation#getSummary()} in the auto-generated swagger. 643 * <li> 644 * The <js>"$RS{operationSummary}"</js> variable. 645 * <li> 646 * The summary of the method in the Swagger page. 647 * </ul> 648 * 649 * <h5 class='section'>Notes:</h5><ul> 650 * <li class='note'> 651 * Corresponds to the swagger field <c>/paths/{path}/{method}/summary</c>. 652 * <li class='note'> 653 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 654 * (e.g. <js>"$L{my.localized.variable}"</js>). 655 * </ul> 656 * 657 * @return The annotation value. 658 */ 659 String summary() default ""; 660 661 /** 662 * Provides swagger-specific metadata on this method. 663 * 664 * <p> 665 * Used to populate the auto-generated OPTIONS swagger documentation. 666 * 667 * <p> 668 * The format of this annotation is JSON when all individual parts are concatenated. 669 * <br>The starting and ending <js>'{'</js>/<js>'}'</js> characters around the entire value are optional. 670 * 671 * <h5 class='section'>Example:</h5> 672 * <p class='bjava'> 673 * <ja>@RestOptions</ja>( 674 * path=<js>"/{propertyName}"</js>, 675 * 676 * <jc>// Swagger info.</jc> 677 * swagger={ 678 * <js>"parameters:["</js>, 679 * <js>"{name:'propertyName',in:'path',description:'The system property name.'},"</js>, 680 * <js>"{in:'body',description:'The new system property value.'}"</js>, 681 * <js>"],"</js>, 682 * <js>"responses:{"</js>, 683 * <js>"302: {headers:{Location:{description:'The root URL of this resource.'}}},"</js>, 684 * <js>"403: {description:'User is not an admin.'}"</js>, 685 * <js>"}"</js> 686 * } 687 * ) 688 * </p> 689 * 690 * <h5 class='section'>Notes:</h5><ul> 691 * <li class='note'> 692 * The format is <a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanSwagger2">juneau-bean-swagger-v2</a>. 693 * <br>Multiple lines are concatenated with newlines. 694 * <li class='note'> 695 * The starting and ending <js>'{'</js>/<js>'}'</js> characters around the entire value are optional. 696 * <li class='note'> 697 * These values are superimposed on top of any Swagger JSON file present for the resource in the classpath. 698 * <li class='note'> 699 * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a> 700 * (e.g. <js>"$L{my.localized.variable}"</js>). 701 * </ul> 702 * 703 * <h5 class='section'>See Also:</h5><ul> 704 * <li class='ja'>{@link OpSwagger} 705 * <li class='jc'>{@link SwaggerProvider} 706 * </ul> 707 * 708 * @return The annotation value. 709 */ 710 OpSwagger swagger() default @OpSwagger; 711 712 /** 713 * REST method path. 714 * 715 * <p> 716 * Can be used to provide a shortened form for the {@link #path()} value. 717 * 718 * <p> 719 * The following examples are considered equivalent. 720 * <p class='bjava'> 721 * <jc>// Normal form</jc> 722 * <ja>@RestOptions</ja>(path=<js>"/{propertyName}"</js>) 723 * 724 * <jc>// Shortened form</jc> 725 * <ja>@RestOptions</ja>(<js>"/{propertyName}"</js>) 726 * </p> 727 * 728 * @return The annotation value. 729 */ 730 String value() default ""; 731}