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