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.server;
018
019import static java.lang.annotation.ElementType.*;
020import static java.lang.annotation.RetentionPolicy.*;
021
022import java.lang.annotation.*;
023
024import org.apache.juneau.bean.swagger.*;
025import org.apache.juneau.commons.*;
026import org.apache.juneau.commons.inject.*;
027import org.apache.juneau.http.remote.*;
028import org.apache.juneau.marshall.encoders.*;
029import org.apache.juneau.marshall.parser.*;
030import org.apache.juneau.marshall.serializer.*;
031import org.apache.juneau.rest.server.converter.*;
032import org.apache.juneau.rest.server.guard.*;
033import org.apache.juneau.rest.server.matcher.*;
034import org.apache.juneau.rest.server.metrics.*;
035import org.apache.juneau.rest.server.servlet.*;
036import org.apache.juneau.rest.server.swagger.*;
037
038/**
039 * Identifies a REST operation Java method on a {@link RestServlet} implementation class.
040 *
041 * <h5 class='section'>See Also:</h5><ul>
042 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestOpAnnotatedMethods">@RestOp-Annotated Method</a>
043
044 * </ul>
045 */
046@Target(METHOD)
047@Retention(RUNTIME)
048@Inherited
049@AnnotationGroup(RestOp.class)
050public @interface RestOp {
051
052   /**
053    * Specifies whether this method can be called based on the client version.
054    *
055    * <p>
056    * The client version is identified via the HTTP request header identified by
057    * {@link Rest#clientVersionHeader() @Rest(clientVersionHeader)} which by default is <js>"Client-Version"</js>.
058    *
059    * <p>
060    * This is a specialized kind of {@link RestMatcher} that allows you to invoke different Java methods for the same
061    * method/path based on the client version.
062    *
063    * <p>
064    * The format of the client version range is similar to that of OSGi versions.
065    *
066    * <p>
067    * In the following example, the Java methods are mapped to the same HTTP method and URL <js>"/foobar"</js>.
068    * <p class='bjava'>
069    *    <jc>// Call this method if Client-Version is at least 2.0.
070    *    // Note that this also matches 2.0.1.</jc>
071    *    <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"2.0"</js>)
072    *    <jk>public</jk> Object method1()  {...}
073    *
074    *    <jc>// Call this method if Client-Version is at least 1.1, but less than 2.0.</jc>
075    *    <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"[1.1,2.0)"</js>)
076    *    <jk>public</jk> Object method2()  {...}
077    *
078    *    <jc>// Call this method if Client-Version is less than 1.1.</jc>
079    *    <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"[0,1.1)"</js>)
080    *    <jk>public</jk> Object method3()  {...}
081    * </p>
082    *
083    * <p>
084    * It's common to combine the client version with transforms that will convert new POJOs into older POJOs for
085    * backwards compatibility.
086    * <p class='bjava'>
087    *    <jc>// Call this method if Client-Version is at least 2.0.</jc>
088    *    <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"2.0"</js>)
089    *    <jk>public</jk> NewPojo newMethod()  {...}
090    *
091    *    <jc>// Call this method if X-Client-Version is at least 1.1, but less than 2.0.</jc>
092    *    <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/foobar"</js>, clientVersion=<js>"[1.1,2.0)"</js>)
093    *    <ja>@MarshalledConfig(swaps=NewToOldSwap.<jk>class</jk>)
094    *    <jk>public</jk> NewPojo oldMethod() {
095    *       <jk>return</jk> newMethod();
096    *    }
097    *
098    * <p>
099    * Note that in the previous example, we're returning the exact same POJO, but using a transform to convert it into
100    * an older form.
101    * The old method could also just return back a completely different object.
102    * The range can be any of the following:
103    * <ul>
104    *    <li><js>"[0,1.0)"</js> = Less than 1.0.  1.0 and 1.0.0 does not match.
105    *    <li><js>"[0,1.0]"</js> = Less than or equal to 1.0.  Note that 1.0.1 will match.
106    *    <li><js>"1.0"</js> = At least 1.0.  1.0 and 2.0 will match.
107    * </ul>
108    *
109    * <h5 class='section'>See Also:</h5><ul>
110    *    <li class='ja'>{@link Rest#clientVersionHeader()}
111    * </ul>
112    *
113    * @return The annotation value.
114    */
115   String clientVersion() default "";
116
117   /**
118    * Supported content media types.
119    *
120    * <p>
121    * Overrides the media types inferred from the parsers that identify what media types can be consumed by the resource.
122    *
123    * <h5 class='section'>Notes:</h5><ul>
124    *    <li class='note'>
125    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>
126    *       (e.g. <js>"$S{mySystemProperty}"</js>).
127    * </ul>
128    *
129    * <h5 class='section'>See Also:</h5><ul>
130    *    <li class='jm'>{@link RestOpContext#getSupportedContentTypes()}
131    * </ul>
132    *
133    * @return The annotation value.
134    */
135   String[] consumes() default {};
136
137   /**
138    * Class-level response converters.
139    *
140    * <p>
141    * Associates one or more {@link RestConverter converters} with this method.
142    *
143    * @return The annotation value.
144    */
145   Class<? extends RestConverter>[] converters() default {};
146
147   /**
148    * Default <c>Accept</c> header.
149    *
150    * <p>
151    * The default value for the <c>Accept</c> header if not specified on a request.
152    *
153    * <p>
154    * This is a shortcut for using {@link #defaultRequestHeaders()} for just this specific header.
155    *
156    * @return The annotation value.
157    */
158   String defaultAccept() default "";
159
160   /**
161    * Default character encoding.
162    *
163    * <p>
164    * The default character encoding for the request and response if not specified on the request.
165    *
166    * <h5 class='section'>Notes:</h5><ul>
167    *    <li class='note'>
168    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>
169    *       (e.g. <js>"$S{mySystemProperty}"</js>).
170    * </ul>
171    *
172    * <h5 class='section'>See Also:</h5><ul>
173    *    <li class='ja'>{@link Rest#defaultCharset}
174    * </ul>
175    *
176    * @return The annotation value.
177    */
178   String defaultCharset() default "";
179
180   /**
181    * Default <c>Content-Type</c> header.
182    *
183    * <p>
184    * The default value for the <c>Content-Type</c> header if not specified on a request.
185    *
186    * <p>
187    * This is a shortcut for using {@link #defaultRequestHeaders()} for just this specific header.
188    *
189    * @return The annotation value.
190    */
191   String defaultContentType() default "";
192
193   /**
194    * Default request attributes.
195    *
196    * <p>
197    * Specifies default values for request attributes if they're not already set on the request.
198    *
199    * <p>
200    * Affects values returned by the following methods:
201    *    <ul>
202    *       <li class='jm'>{@link RestRequest#getAttribute(String)}.
203    *       <li class='jm'>{@link RestRequest#getAttributes()}.
204    *    </ul>
205    *
206    * <h5 class='section'>Example:</h5>
207    * <p class='bjava'>
208    *    <jc>// Defined via annotation resolving to a config file setting with default value.</jc>
209    *    <ja>@Rest</ja>(defaultRequestAttributes={<js>"Foo=bar"</js>, <js>"Baz: $C{REST/myAttributeValue}"</js>})
210    *    <jk>public class</jk> MyResource {
211    *
212    *       <jc>// Override at the method level.</jc>
213    *       <ja>@RestGet</ja>(defaultRequestAttributes={<js>"Foo: bar"</js>})
214    *       <jk>public</jk> Object myMethod() {...}
215    *    }
216    * </p>
217    *
218    * </ul>
219    * <h5 class='section'>Notes:</h5><ul>
220    *    <li class='note'>
221    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>
222    *       (e.g. <js>"$L{my.localized.variable}"</js>).
223    * </ul>
224    *
225    * <h5 class='section'>See Also:</h5><ul>
226    *    <li class='ja'>{@link Rest#defaultRequestAttributes()}
227    * </ul>
228    *
229    * @return The annotation value.
230    */
231   String[] defaultRequestAttributes() default {};
232
233   /**
234    * Specifies default values for form-data parameters.
235    *
236    * <p>
237    * Strings are of the format <js>"name=value"</js>.
238    *
239    * <p>
240    * Affects values returned by {@link RestRequest#getFormParam(String)} when the parameter is not present on the
241    * request.
242    *
243    * <h5 class='section'>Example:</h5>
244    * <p class='bjava'>
245    *    <ja>@RestOp</ja>(method=<jsf>POST</jsf>, path=<js>"/*"</js>, defaultRequestFormData={<js>"foo=bar"</js>})
246    *    <jk>public</jk> String doPost(<ja>@FormData</ja>(<js>"foo"</js>) String <jv>foo</jv>)  {...}
247    * </p>
248    *
249    * <h5 class='section'>Notes:</h5><ul>
250    *    <li class='note'>
251    *       You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter.
252    *    <li class='note'>
253    *       Key and value is trimmed of whitespace.
254    *    <li class='note'>
255    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>
256    *       (e.g. <js>"$S{mySystemProperty}"</js>).
257    * </ul>
258    *
259    * @return The annotation value.
260    */
261   String[] defaultRequestFormData() default {};
262
263   /**
264    * Default request headers.
265    *
266    * <p>
267    * Specifies default values for request headers if they're not passed in through the request.
268    *
269    * <h5 class='section'>Example:</h5>
270    * <p class='bjava'>
271    *    <jc>// Assume "text/json" Accept value when Accept not specified</jc>
272    *    <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/*"</js>, defaultRequestHeaders={<js>"Accept: text/json"</js>})
273    *    <jk>public</jk> String doGet()  {...}
274    * </p>
275    *
276    * <h5 class='section'>Notes:</h5><ul>
277    *    <li class='note'>
278    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>
279    *       (e.g. <js>"$S{mySystemProperty}"</js>).
280    * </ul>
281    *
282    * @return The annotation value.
283    */
284   String[] defaultRequestHeaders() default {};
285
286   /**
287    * Specifies default values for query parameters.
288    *
289    * <p>
290    * Strings are of the format <js>"name=value"</js>.
291    *
292    * <p>
293    * Affects values returned by {@link RestRequest#getQueryParam(String)} when the parameter is not present on the request.
294    *
295    * <h5 class='section'>Example:</h5>
296    * <p class='bjava'>
297    *    <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/*"</js>, defaultRequestQueryData={<js>"foo=bar"</js>})
298    *    <jk>public</jk> String doGet(<ja>@Query</ja>(<js>"foo"</js>) String <jv>foo</jv>)  {...}
299    * </p>
300    *
301    * <h5 class='section'>Notes:</h5><ul>
302    *    <li class='note'>
303    *       You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter.
304    *    <li class='note'>
305    *       Key and value is trimmed of whitespace.
306    *    <li class='note'>
307    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>
308    *       (e.g. <js>"$S{mySystemProperty}"</js>).
309    * </ul>
310    *
311    * @return The annotation value.
312    */
313   String[] defaultRequestQueryData() default {};
314
315   /**
316    * Default response headers.
317    *
318    * <p>
319    * Specifies default values for response headers if they're not overwritten during the request.
320    *
321    * <h5 class='section'>Example:</h5>
322    * <p class='bjava'>
323    *    <jc>// Assume "text/json" Accept value when Accept not specified</jc>
324    *    <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/*"</js>, defaultResponseHeaders={<js>"Content-Type: text/json"</js>})
325    *    <jk>public</jk> String doGet()  {...}
326    * </p>
327    *
328    * <h5 class='section'>Notes:</h5><ul>
329    *    <li class='note'>
330    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>
331    *       (e.g. <js>"$S{mySystemProperty}"</js>).
332    * </ul>
333    *
334    * @return The annotation value.
335    */
336   String[] defaultResponseHeaders() default {};
337
338   /**
339    * Optional description for the exposed API.
340    *
341    * <p>
342    * This description is used in the following locations:
343    * <ul class='spaced-list'>
344    *    <li>
345    *       The value returned by {@link Operation#getDescription()} in the auto-generated swagger.
346    *    <li>
347    *       The <js>"$RS{operationDescription}"</js> variable.
348    *    <li>
349    *       The description of the method in the Swagger page.
350    * </ul>
351    *
352    * <h5 class='section'>Notes:</h5><ul>
353    *    <li class='note'>
354    *       Corresponds to the swagger field <c>/paths/{path}/{method}/description</c>.
355    *    <li class='note'>
356    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>
357    *       (e.g. <js>"$L{my.localized.variable}"</js>).
358    * </ul>
359    *
360    * @return The annotation value.
361    */
362   String[] description() default {};
363
364   /**
365    * Specifies the compression encoders for this method.
366    *
367    * <p>
368    * Encoders are used to enable various kinds of compression (e.g. <js>"gzip"</js>) on requests and responses.
369    *
370    * <p>
371    * This value overrides encoders specified at the class level using {@link Rest#encoders()}.
372    * The {@link org.apache.juneau.marshall.encoders.EncoderSet.Inherit EncoderSet.Inherit} class can be used to include values from the parent class.
373    *
374    * <h5 class='section'>Example:</h5>
375    * <p class='bjava'>
376    *    <jc>// Define a REST resource that handles GZIP compression.</jc>
377    *    <ja>@Rest</ja>(
378    *       encoders={
379    *          GzipEncoder.<jk>class</jk>
380    *       }
381    *    )
382    *    <jk>public class</jk> MyResource {
383    *
384    *       <jc>// Define a REST method that can also use a custom encoder.</jc>
385    *       <ja>@RestOp</ja>(
386    *          method=<jsf>GET</jsf>,
387    *          encoders={
388    *             EncoderSet.Inherit.<jk>class</jk>, MyEncoder.<jk>class</jk>
389    *          }
390    *       )
391    *       <jk>public</jk> MyBean doGet() {
392    *          ...
393    *       }
394    *    }
395    * </p>
396    *
397    * <p>
398    * For programmatic equivalents, contribute a {@link EncoderSet} bean via
399    * {@link Bean @Bean(name="encoders")} (use methodScope to scope to specific operation methods).
400    *
401    * <h5 class='section'>See Also:</h5><ul>
402    *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerEncoders">Encoders in REST servers</a>
403    * </ul>
404    *
405    * @return The annotation value.
406    */
407   Class<? extends Encoder>[] encoders() default {};
408
409   /**
410    * Method-level guards.
411    *
412    * <p>
413    * Associates one or more {@link RestGuard RestGuards} with this method.
414    *
415    * @return The annotation value.
416    */
417   Class<? extends RestGuard>[] guards() default {};
418
419   /**
420    * Method matchers.
421    *
422    * <p>
423    * Associates one more more {@link RestMatcher RestMatchers} with this method.
424    *
425    * <p>
426    * Matchers are used to allow multiple Java methods to handle requests assigned to the same URL path pattern, but
427    * differing based on some request attribute, such as a specific header value.
428    *
429    * <h5 class='section'>See Also:</h5><ul>
430    *    <li class='jac'>{@link RestMatcher}
431    * </ul>
432    *
433    * @return The annotation value.
434    */
435   Class<? extends RestMatcher>[] matchers() default {};
436
437   /**
438    * The maximum allowed input size (in bytes) on HTTP requests.
439    *
440    * <p>
441    * Useful for alleviating DoS attacks by throwing an exception when too much input is received instead of resulting
442    * in out-of-memory errors which could affect system stability.
443    *
444    * <h5 class='section'>Example:</h5>
445    * <p class='bjava'>
446    *    <ja>@RestOp</ja>(
447    *       maxInput=<js>"100M"</js>
448    *    )
449    * </p>
450    *
451    * <h5 class='section'>Notes:</h5><ul>
452    *    <li>
453    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>
454    *       (e.g. <js>"$S{mySystemProperty}"</js>).
455    * </ul>
456    *
457    * <h5 class='section'>See Also:</h5><ul>
458    *    <li class='ja'>{@link Rest#maxInput}
459    * </ul>
460    *
461    * @return The annotation value.
462    */
463   String maxInput() default "";
464
465   /**
466    * REST method name.
467    *
468    * <p>
469    * Typically <js>"GET"</js>, <js>"PUT"</js>, <js>"POST"</js>, <js>"DELETE"</js>, or <js>"OPTIONS"</js>.
470    *
471    * <p>
472    * Method names are case-insensitive (always folded to upper-case).
473    *
474    * <p>
475    * Note that you can use {@link org.apache.juneau.http.HttpMethod} for constant values.
476    *
477    * <p>
478    * Note that you can also use {@link #value()} to specify the method name and path in shortened form.
479    *
480    * <p>
481    * Besides the standard HTTP method names, the following can also be specified:
482    * <ul class='spaced-list'>
483    *    <li>
484    *       <js>"*"</js>
485    *       - Denotes any method.
486    *       <br>Use this if you want to capture any HTTP methods in a single Java method.
487    *       <br>The {@link Method @Method} annotation and/or {@link RestRequest#getMethod()} method can be used to
488    *       distinguish the actual HTTP method name.
489    *    <li>
490    *       <js>""</js>
491    *       - Auto-detect.
492    *       <br>The method name is determined based on the Java method name.
493    *       <br>For example, if the method is <c>doPost(...)</c>, then the method name is automatically detected
494    *       as <js>"POST"</js>.
495    *       <br>Otherwise, defaults to <js>"GET"</js>.
496    *    <li>
497    *       <js>"RRPC"</js>
498    *       - Remote-proxy interface.
499    *       <br>This denotes a Java method that returns an object (usually an interface, often annotated with the
500    *       {@link Remote @Remote} annotation) to be used as a remote proxy using
501    *       <c>RestClient.getRemoteInterface(Class&lt;T&gt; interfaceClass, String url)</c>.
502    *       <br>This allows you to construct client-side interface proxies using REST as a transport medium.
503    *       <br>Conceptually, this is simply a fancy <c>POST</c> against the url <js>"/{path}/{javaMethodName}"</js>
504    *       where the arguments are marshalled from the client to the server as an HTTP content containing an array of
505    *       objects, passed to the method as arguments, and then the resulting object is marshalled back to the client.
506    *    <li>
507    *       Anything else
508    *       - Overloaded non-HTTP-standard names that are passed in through a <c>&amp;method=methodName</c> URL
509    *       parameter.
510    *       <br>On a safe request (<c>GET</c>, <c>HEAD</c>, <c>OPTIONS</c>, <c>TRACE</c>), only when the operation is
511    *       declared {@link #read() read=true}.
512    * </ul>
513    *
514    * @return The annotation value.
515    */
516   String method() default "";
517
518   /**
519    * Specifies the parsers for converting HTTP request bodies into POJOs for this method.
520    *
521    * <p>
522    * Parsers are used to convert the content of HTTP requests into POJOs.
523    * <br>Any of the Juneau framework parsers can be used in this setting.
524    * <br>The parser selected is based on the request <c>Content-Type</c> header matched against the values returned by the following method
525    * using a best-match algorithm:
526    * <ul class='javatree'>
527    *    <li class='jm'>{@link Parser#getMediaTypes()}
528    * </ul>
529    *
530    * <p>
531    * This value overrides parsers specified at the class level using {@link Rest#parsers()}.
532    * The {@link org.apache.juneau.marshall.parser.ParserSet.Inherit ParserSet.Inherit} class can be used to include values from the parent class.
533    *
534    * <h5 class='section'>Example:</h5>
535    * <p class='bjava'>
536    *    <jc>// Define a REST resource that can consume JSON and HTML.</jc>
537    *    <ja>@Rest</ja>(
538    *       parsers={
539    *          JsonParser.<jk>class</jk>,
540    *          HtmlParser.<jk>class</jk>
541    *       }
542    *    )
543    *    <jk>public class</jk> MyResource {
544    *
545    *       <jc>// Define a REST method that can also consume XML.</jc>
546    *       <ja>@RestOp</ja>(
547    *          method=<jsf>POST</jsf>,
548    *          parsers={
549    *             ParserSet.Inherit.<jk>class</jk>, XmlParser.<jk>class</jk>
550    *          }
551    *       )
552    *       <jk>public void</jk> doPost(MyBean <jv>bean</jv>) {
553    *          ...
554    *       }
555    *    }
556    * </p>
557    *
558    * <p>
559    * For programmatic equivalents, contribute a {@link ParserSet} bean via
560    * {@link Bean @Bean(name="parsers")} (use methodScope to scope to specific operation methods).
561    *
562    * <h5 class='section'>See Also:</h5><ul>
563    *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/Marshalling">Marshalling</a>
564    * </ul>
565    *
566    * @return The annotation value.
567    */
568   Class<?>[] parsers() default {};
569
570   /**
571    * Optional path pattern for the specified method.
572    *
573    * <p>
574    * Appending <js>"/*"</js> to the end of the path pattern will make it match any remainder too.
575    * <br>Not appending <js>"/*"</js> to the end of the pattern will cause a 404 (Not found) error to occur if the exact
576    * pattern is not found.
577    *
578    * <p>
579    * The path can contain variables that get resolved to {@link org.apache.juneau.http.Path @Path} parameters.
580    *
581    * <h5 class='figure'>Examples:</h5>
582    * <p class='bjava'>
583    *    <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/myurl/{foo}/{bar}/{baz}/*"</js>)
584    * </p>
585    * <p class='bjava'>
586    *    <ja>@RestOp</ja>(method=<jsf>GET</jsf>, path=<js>"/myurl/{0}/{1}/{2}/*"</js>)
587    * </p>
588    *
589    * <p>
590    * If you do not specify a path name, then the path name is inferred from the Java method name.
591    *
592    * <h5 class='figure'>Example:</h5>
593    * <p class='bjava'>
594    *    <jc>// Path is assumed to be "/foo".</jc>
595    *    <ja>@RestOp</ja>(method=<jsf>GET</jsf>)
596    *    <jk>public void</jk> foo() {...}
597    * </p>
598    *
599    * <p>
600    * 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>"delete"</js>,
601    * then the HTTP method name is stripped from the inferred path.
602    *
603    * <h5 class='figure'>Examples:</h5>
604    * <p class='bjava'>
605    *    <jc>// Method is GET, path is "/foo".</jc>
606    *    <ja>@RestOp</ja>
607    *    <jk>public void</jk> getFoo() {...}
608    * </p>
609    * <p class='bjava'>
610    *    <jc>// Method is DELETE, path is "/bar".</jc>
611    *    <ja>@RestOp</ja>
612    *    <jk>public void</jk> deleteBar() {...}
613    * </p>
614    * <p class='bjava'>
615    *    <jc>// Method is GET, path is "/foobar".</jc>
616    *    <ja>@RestOp</ja>
617    *    <jk>public void</jk> foobar() {...}
618    * </p>
619    * <p class='bjava'>
620    *    <jc>// Method is GET, path is "/".</jc>
621    *    <ja>@RestOp</ja>
622    *    <jk>public void</jk> get() {...}
623    * </p>
624    *
625    * <p>
626    * Note that you can also use {@link #value()} to specify the method name and path in shortened form.
627    *
628    * <h5 class='section'>See Also:</h5><ul>
629    *    <li class='ja'>{@link org.apache.juneau.http.Path}
630    * </ul>
631    *
632    * @return The annotation value.
633    */
634   String[] path() default {};
635
636   /**
637    * Per-operation override for {@link Rest#problemDetails() @Rest(problemDetails)}.
638    *
639    * <p>
640    * When set on a {@code @RestOp} method, this value takes precedence over the resource-level
641    * {@code @Rest(problemDetails)} attribute for this operation. Tri-state semantics:
642    *
643    * <ul class='values'>
644    *    <li><js>"true"</js> &mdash; enable problem-details responses for this operation.
645    *    <li><js>"false"</js> &mdash; disable problem-details responses for this operation (overrides an
646    *       opted-in resource).
647    *    <li><js>""</js> (default) &mdash; inherit from {@link Rest#problemDetails()}.
648    * </ul>
649    *
650    * <h5 class='section'>Notes:</h5><ul>
651    *    <li class='note'>
652    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>
653    *       (e.g. <js>"$L{my.localized.variable}"</js>).
654    * </ul>
655    *
656    * <h5 class='section'>See Also:</h5><ul>
657    *    <li class='ja'>{@link Rest#problemDetails()}
658    * </ul>
659    *
660    * @return The annotation value.
661    */
662   String problemDetails() default "";
663
664   /**
665    * Per-operation override for {@link Rest#debugMarshalling() @Rest(debugMarshalling)}.
666    *
667    * <p>
668    * When set on a {@code @RestOp} method, this value takes precedence over the resource-level
669    * {@code @Rest(debugMarshalling)} attribute for this operation. Tri-state semantics:
670    *
671    * <ul class='values'>
672    *    <li><js>"true"</js> &mdash; enable marshalling debug for this operation.
673    *    <li><js>"false"</js> &mdash; disable marshalling debug for this operation (overrides an opted-in resource).
674    *    <li><js>""</js> (default) &mdash; inherit from {@link Rest#debugMarshalling()}.
675    * </ul>
676    *
677    * <h5 class='section'>Notes:</h5><ul>
678    *    <li class='note'>
679    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>.
680    * </ul>
681    *
682    * <h5 class='section'>See Also:</h5><ul>
683    *    <li class='ja'>{@link Rest#debugMarshalling()}
684    * </ul>
685    *
686    * @return The annotation value.
687    */
688   String debugMarshalling() default "";
689
690   /**
691    * Per-operation override for {@link Rest#virtualThreads() @Rest(virtualThreads)}.
692    *
693    * <p>
694    * When set, this value takes precedence over the resource-level setting for this operation. Tri-state
695    * semantics:
696    *
697    * <ul class='values'>
698    *    <li><js>"true"</js> &mdash; enable virtual-thread dispatch for this operation (Java 21+ only;
699    *       gracefully ignored on older JVMs).
700    *    <li><js>"false"</js> &mdash; disable virtual-thread dispatch for this operation (overrides an
701    *       opted-in resource).
702    *    <li><js>""</js> (default) &mdash; inherit from {@link Rest#virtualThreads()}.
703    * </ul>
704    *
705    * <h5 class='section'>Notes:</h5><ul>
706    *    <li class='note'>
707    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>
708    *       (e.g. <js>"$E{ENABLE_VT,false}"</js>).
709    * </ul>
710    *
711    * <h5 class='section'>See Also:</h5><ul>
712    *    <li class='ja'>{@link Rest#virtualThreads()}
713    * </ul>
714    *
715    * @return The annotation value.
716    */
717   String virtualThreads() default "";
718
719   /**
720    * Per-operation observability opt-in / opt-out control.
721    *
722    * <p>
723    * Overrides the resource-level {@link Rest#observability()} setting for this specific operation.
724    * Controls whether the observability block ({@link MetricsRecorder} /
725    * {@link org.apache.juneau.rest.server.tracing.TracerHook}) fires for this operation.
726    *
727    * <ul class='values'>
728    *    <li><js>"true"</js> &mdash; strict opt-in: this operation <em>requires</em> a wired observability backend.
729    *       If neither a {@code @Bean MetricsRecorder} nor a {@code @Bean TracerHook} is registered when the
730    *       {@link RestContext} is built, construction fails with a precise error.
731    *    <li><js>"false"</js> &mdash; explicit opt-out: the observability block is short-circuited for this operation,
732    *       even when a wired backend is present. Also suppresses
733    *       {@link org.apache.juneau.rest.server.tracing.TraceContextResponseProcessor} header injection.
734    *    <li><js>""</js> (default) &mdash; inherits the resource-level {@link Rest#observability()} setting.
735    *       If the resource-level setting is also empty, uses the existing behavior: the observability block
736    *       runs per-op, but a missing backend silently falls back to the NoOp singleton.
737    * </ul>
738    *
739    * <h5 class='section'>Notes:</h5><ul>
740    *    <li class='note'>
741    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>
742    *       (e.g. <js>"$E{ENABLE_OP_OBSERVABILITY,false}"</js>).
743    *    <li class='note'>
744    *       This per-operation setting takes full precedence over {@link Rest#observability()}.
745    * </ul>
746    *
747    * <h5 class='section'>See Also:</h5><ul>
748    *    <li class='ja'>{@link Rest#observability()}
749    *    <li class='jc'>{@link MetricsRecorder}
750    *    <li class='jc'>{@link org.apache.juneau.rest.server.tracing.TracerHook}
751    * </ul>
752    *
753    * @return The annotation value.
754    * @since 10.0.0
755    */
756   String observability() default "";
757
758   /**
759    * Per-operation metric name override.
760    *
761    * <p>
762    * Overrides the metric name passed to {@link MetricsRecorder#record(String, String, String, int, java.time.Duration, Throwable, String, String) record()}
763    * for this operation.  When empty (default), the recorder uses its own default name derivation (typically the
764    * fully-qualified operation name).
765    *
766    * <h5 class='section'>Notes:</h5><ul>
767    *    <li class='note'>
768    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>.
769    *    <li class='note'>
770    *       Has no effect when observability is disabled for this operation.
771    * </ul>
772    *
773    * @return The annotation value.
774    * @since 10.0.0
775    */
776   String metricName() default "";
777
778   /**
779    * Per-operation metric tags.
780    *
781    * <p>
782    * Additional metric tags to pass to {@link MetricsRecorder#record(String, String, String, int, java.time.Duration, Throwable, String, String) record()}.
783    * Format: comma-separated {@code key=value} pairs, e.g. {@code "team=payments,region=us-east"}.
784    * When empty (default), no additional tags are passed.
785    *
786    * <h5 class='section'>Notes:</h5><ul>
787    *    <li class='note'>
788    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>.
789    *    <li class='note'>
790    *       The recorder implementation is responsible for parsing the comma-separated {@code key=value} string.
791    *    <li class='note'>
792    *       Has no effect when observability is disabled for this operation.
793    * </ul>
794    *
795    * @return The annotation value.
796    * @since 10.0.0
797    */
798   String metricTags() default "";
799
800   /**
801    * Per-operation override for {@link Rest#asyncTimeoutMillis() @Rest(asyncTimeoutMillis)}.
802    *
803    * <p>
804    * Configurable timeout (milliseconds) applied to {@link java.util.concurrent.CompletableFuture}-returning
805    * handlers. Default is 30,000 ms inherited from the resource. Set to {@code "0"} to disable the timeout.
806    *
807    * <h5 class='section'>Notes:</h5><ul>
808    *    <li class='note'>
809    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>.
810    * </ul>
811    *
812    * <h5 class='section'>See Also:</h5><ul>
813    *    <li class='ja'>{@link Rest#asyncTimeoutMillis()}
814    * </ul>
815    *
816    * @return The annotation value.
817    */
818   String asyncTimeoutMillis() default "";
819
820   /**
821    * Per-operation override for {@link Rest#asyncCompletionExecutor() @Rest(asyncCompletionExecutor)}.
822    *
823    * <p>
824    * Names the {@link java.util.concurrent.Executor} bean used to route completion callbacks for this
825    * specific operation through a dedicated thread pool. Empty string (default) inherits from
826    * {@link Rest#asyncCompletionExecutor()}.
827    *
828    * <h5 class='section'>See Also:</h5><ul>
829    *    <li class='ja'>{@link Rest#asyncCompletionExecutor()}
830    * </ul>
831    *
832    * @return The annotation value.
833    * @since 10.0.0
834    */
835   String asyncCompletionExecutor() default "";
836
837   /**
838    * Supported accept media types.
839    *
840    * <p>
841    * Overrides the media types inferred from the serializers that identify what media types can be produced by the resource.
842    *
843    * <h5 class='section'>Notes:</h5><ul>
844    *    <li class='note'>
845    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>
846    *       (e.g. <js>"$S{mySystemProperty}"</js>).
847    * </ul>
848    *
849    * <h5 class='section'>See Also:</h5><ul>
850    *    <li class='jm'>{@link RestOpContext#getSupportedAcceptTypes()}
851    * </ul>
852    *
853    * @return The annotation value.
854    */
855   String[] produces() default {};
856
857   /**
858    * Allowed serializer session option keys for this operation (ordered merge, prefix {@code -key} removes a key).
859    *
860    * <p>
861    * Comma-delimited list of session property keys that clients may send via the <js>"X-Juneau-Serializer-Options"</js>
862    * header or <js>"juneauSerializerOptions"</js> query parameter.
863    * Merged on top of resource-level {@link Rest#allowedSerializerOptions()} values.
864    * Use {@link #noInherit()} to replace rather than extend the resource-level list.
865    *
866    * <h5 class='section'>See Also:</h5><ul>
867    *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/SessionOptions#safe-properties">Safe Properties</a>
868    * </ul>
869    *
870    * @return The annotation value.
871    */
872   String[] allowedSerializerOptions() default {};
873
874   /**
875    * Allowed parser session option keys for this operation (ordered merge, prefix {@code -key} removes a key).
876    *
877    * <p>
878    * Comma-delimited list of session property keys that clients may send via the <js>"X-Juneau-Parser-Options"</js>
879    * header or <js>"juneauParserOptions"</js> query parameter.
880    * Merged on top of resource-level {@link Rest#allowedParserOptions()} values.
881    * Use {@link #noInherit()} to replace rather than extend the resource-level list.
882    *
883    * <h5 class='section'>See Also:</h5><ul>
884    *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/SessionOptions#safe-properties">Safe Properties</a>
885    * </ul>
886    *
887    * @return The annotation value.
888    */
889   String[] allowedParserOptions() default {};
890
891   /**
892    * Property names for which less-derived contributions are NOT inherited.
893    *
894    * <p>
895    * Accepted values: {@code "allowedSerializerOptions"}, {@code "allowedParserOptions"},
896    * {@code "problemDetails"}, {@code "debugMarshalling"}.
897    * Prevents the named property from inheriting values from the enclosing {@code @Rest} annotation.
898    * The {@code noInherit} attribute itself is never inherited.
899    *
900    * <h5 class='section'>See Also:</h5><ul>
901    *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/SessionOptions">Session Options via HTTP</a>
902    * </ul>
903    *
904    * @return The annotation value.
905    */
906   String[] noInherit() default {};
907
908   /**
909    * Declares that this operation's custom method is a read.
910    *
911    * <p>
912    * A request whose request line is safe (<c>GET</c>, <c>HEAD</c>, <c>OPTIONS</c> or <c>TRACE</c>) may be overridden
913    * (through the {@code method} query parameter or an override header, see {@link Rest#allowedMethodParams()} and
914    * {@link Rest#allowedMethodHeaders()}) only to another safe method, or to the method of an operation declared
915    * <c>read=<jk>true</jk></c>.  Any other override of a safe request is refused with <c>405 Method Not Allowed</c>,
916    * so a link, a crawler or a prefetcher following a plain <c>GET</c> can never reach an operation that changes state.
917    *
918    * <h5 class='section'>Example:</h5>
919    * <p class='bjava'>
920    *    <jc>// Reachable as GET /files/foo.txt?method=VIEW, as well as VIEW /files/foo.txt.</jc>
921    *    <ja>@RestOp</ja>(method=<js>"VIEW"</js>, path=<js>"/files/*"</js>, read=<jk>true</jk>)
922    *    <jk>public</jk> Reader view(...) {...}
923    * </p>
924    *
925    * <p>
926    * The declaration is the developer's promise that the operation does not change state, exactly as <c>GET</c>
927    * promises.  Nothing can verify it.  {@link Mutating @Mutating} is the opposite promise.
928    *
929    * <h5 class='section'>Notes:</h5><ul>
930    *    <li class='note'>
931    *       The attribute is read from the annotation that supplies the operation's method (or, when the method is
932    *       inferred from the Java method name, from the nearest <ja>@RestOp</ja>).  A subclass that re-declares the method
933    *       therefore also re-declares whether it is a read: <c>read=<jk>true</jk></c> on an overridden annotation that
934    *       names its own method is replaced along with that method.  <c>read=<jk>true</jk></c> on another
935    *       <ja>@RestOp</ja> in the chain that names no method would be silently ignored, so it fails the resource when
936    *       its operations are assembled.
937    *    <li class='note'>
938    *       <c>read=<jk>true</jk></c> fails the resource when the method is <c>POST</c>, <c>PUT</c>, <c>PATCH</c>,
939    *       <c>DELETE</c>, <c>CONNECT</c>, <js>"*"</js> or <js>"RRPC"</js>, or when the Java method is also
940    *       {@link Mutating @Mutating}.  On a safe method it is redundant and has no effect.
941    *    <li class='note'>
942    *       A CSRF or loopback boundary filter still judges a request on the method it claims, so behind a boundary a
943    *       <c>GET ?method=VIEW</c> is treated as a write.  Prefer path-based links (<c>/view/{file}</c>) for reads.
944    * </ul>
945    *
946    * <h5 class='section'>See Also:</h5><ul>
947    *    <li class='ja'>{@link Mutating}
948    *    <li class='jm'>{@link MethodSafety#check(java.util.List)}
949    * </ul>
950    *
951    * @return The annotation value.
952    * @since 10.0.0
953    */
954   boolean read() default false;
955
956   /**
957    * Role guard.
958    *
959    * <p>
960    * An expression defining if a user with the specified roles are allowed to access this method.
961    *
962    * <h5 class='section'>Example:</h5>
963    * <p class='bjava'>
964    *    <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet {
965    *
966    *       <ja>@RestOp</ja>(
967    *          method=<jsf>GET</jsf>,
968    *          path=<js>"/foo"</js>,
969    *          roleGuard=<js>"ROLE_ADMIN || (ROLE_READ_WRITE &amp;&amp; ROLE_SPECIAL)"</js>
970    *       )
971    *       <jk>public</jk> Object doGet() {
972    *       }
973    *    }
974    * </p>
975    *
976    * <h5 class='section'>Notes:</h5><ul>
977    *    <li class='note'>
978    *       Supports any of the following expression constructs:
979    *       <ul>
980    *          <li><js>"foo"</js> - Single arguments.
981    *          <li><js>"foo,bar,baz"</js> - Multiple OR'ed arguments.
982    *          <li><js>"foo | bar | baz"</js> - Multiple OR'ed arguments, pipe syntax.
983    *          <li><js>"foo || bar || baz"</js> - Multiple OR'ed arguments, Java-OR syntax.
984    *          <li><js>"fo*"</js> - Patterns including <js>'*'</js> and <js>'?'</js>.
985    *          <li><js>"fo* &amp; *oo"</js> - Multiple AND'ed arguments, ampersand syntax.
986    *          <li><js>"fo* &amp;&amp; *oo"</js> - Multiple AND'ed arguments, Java-AND syntax.
987    *          <li><js>"fo* || (*oo || bar)"</js> - Parenthesis.
988    *       </ul>
989    *    <li class='note'>
990    *       AND operations take precedence over OR operations (as expected).
991    *    <li class='note'>
992    *       Whitespace is ignored.
993    *    <li class='note'>
994    *       <jk>null</jk> or empty expressions always match as <jk>false</jk>.
995    *    <li class='note'>
996    *       If patterns are used, you must specify the list of declared roles using {@link #rolesDeclared()}.
997    *    <li class='note'>
998    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>
999    *       (e.g. <js>"$L{my.localized.variable}"</js>).
1000    *    <li class='note'>
1001    *       When defined on parent/child classes and methods, ALL guards within the hierarchy must pass.
1002    * </ul>
1003    *
1004    * @return The annotation value.
1005    */
1006   String roleGuard() default "";
1007
1008   /**
1009    * Declared roles.
1010    *
1011    * <p>
1012    * A comma-delimited list of all possible user roles.
1013    *
1014    * <p>
1015    * Used in conjunction with {@link #roleGuard()} is used with patterns.
1016    *
1017    * <h5 class='section'>Example:</h5>
1018    * <p class='bjava'>
1019    *    <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet {
1020    *
1021    *       <ja>@RestOp</ja>(
1022    *          method=<jsf>GET</jsf>,
1023    *          path=<js>"/foo"</js>,
1024    *          rolesDeclared=<js>"ROLE_ADMIN,ROLE_READ_WRITE,ROLE_READ_ONLY,ROLE_SPECIAL"</js>,
1025    *          roleGuard=<js>"ROLE_ADMIN || (ROLE_READ_WRITE &amp;&amp; ROLE_SPECIAL)"</js>
1026    *       )
1027    *       <jk>public</jk> Object doGet() {
1028    *       }
1029    *    }
1030    * </p>
1031    *
1032    * @return The annotation value.
1033    */
1034   String rolesDeclared() default "";
1035
1036   /**
1037    * Specifies the serializers for marshalling POJOs into response bodies for this method.
1038    *
1039    * <p>
1040    * Serializer are used to convert POJOs to HTTP response bodies.
1041    * <br>Any of the Juneau framework serializers can be used in this setting.
1042    * <br>The serializer selected is based on the request <c>Accept</c> header matched against the values returned by the following method
1043    * using a best-match algorithm:
1044    * <ul class='javatree'>
1045    *    <li class='jm'>{@link Serializer#getMediaTypeRanges()}
1046    * </ul>
1047    *
1048    * <p>
1049    * This value overrides serializers specified at the class level using {@link Rest#serializers()}.
1050    * The {@link org.apache.juneau.marshall.serializer.SerializerSet.Inherit SerializerSet.Inherit} class can be used to include values from the parent class.
1051    *
1052    * <h5 class='section'>Example:</h5>
1053    * <p class='bjava'>
1054    *    <jc>// Define a REST resource that can produce JSON and HTML.</jc>
1055    *    <ja>@Rest</ja>(
1056    *       serializers={
1057    *          JsonParser.<jk>class</jk>,
1058    *          HtmlParser.<jk>class</jk>
1059    *       }
1060    *    )
1061    *    <jk>public class</jk> MyResource {
1062    *
1063    *       <jc>// Define a REST method that can also produce XML.</jc>
1064    *       <ja>@RestOp</ja>(
1065    *          method=<jsf>POST</jsf>,
1066    *          parsers={
1067    *             SerializerSet.Inherit.<jk>class</jk>, XmlParser.<jk>class</jk>
1068    *          }
1069    *       )
1070    *       <jk>public void</jk> doPost(MyBean <jv>bean</jv>) {
1071    *          ...
1072    *       }
1073    *    }
1074    * </p>
1075    *
1076    * <p>
1077    * For programmatic equivalents, contribute a {@link SerializerSet} bean via
1078    * {@link Bean @Bean(name="serializers")} (use methodScope to scope to specific operation methods).
1079    *
1080    * <h5 class='section'>See Also:</h5><ul>
1081    *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/Marshalling">Marshalling</a>
1082    * </ul>
1083    *
1084    * @return The annotation value.
1085    */
1086   Class<? extends Serializer>[] serializers() default {};
1087
1088   /**
1089    * Optional summary for the exposed API.
1090    *
1091    * <p>
1092    * This summary is used in the following locations:
1093    * <ul class='spaced-list'>
1094    *    <li>
1095    *       The value returned by {@link Operation#getSummary()} in the auto-generated swagger.
1096    *    <li>
1097    *       The <js>"$RS{operationSummary}"</js> variable.
1098    *    <li>
1099    *       The summary of the method in the Swagger page.
1100    * </ul>
1101    *
1102    * <h5 class='section'>Notes:</h5><ul>
1103    *    <li class='note'>
1104    *       Corresponds to the swagger field <c>/paths/{path}/{method}/summary</c>.
1105    *    <li class='note'>
1106    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>
1107    *       (e.g. <js>"$L{my.localized.variable}"</js>).
1108    * </ul>
1109    *
1110    * @return The annotation value.
1111    */
1112   String summary() default "";
1113
1114   /**
1115    * Provides swagger-specific metadata on this method.
1116    *
1117    * <p>
1118    * Used to populate the auto-generated OPTIONS swagger documentation.
1119    *
1120    * <p>
1121    * The format of this annotation is JSON when all individual parts are concatenated.
1122    * <br>The starting and ending <js>'{'</js>/<js>'}'</js> characters around the entire value are optional.
1123    *
1124    * <h5 class='section'>Example:</h5>
1125    * <p class='bjava'>
1126    *    <ja>@RestOp</ja>(
1127    *       method=<jsf>PUT</jsf>,
1128    *       path=<js>"/{propertyName}"</js>,
1129    *
1130    *       <jc>// Swagger info.</jc>
1131    *       swagger={
1132    *          <js>"parameters:["</js>,
1133    *             <js>"{name:'propertyName',in:'path',description:'The system property name.'},"</js>,
1134    *             <js>"{in:'body',description:'The new system property value.'}"</js>,
1135    *          <js>"],"</js>,
1136    *          <js>"responses:{"</js>,
1137    *             <js>"302: {headers:{Location:{description:'The root URL of this resource.'}}},"</js>,
1138    *             <js>"403: {description:'User is not an admin.'}"</js>,
1139    *          <js>"}"</js>
1140    *       }
1141    *    )
1142    * </p>
1143    *
1144    * <h5 class='section'>Notes:</h5><ul>
1145    *    <li class='note'>
1146    *       The format is <a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanSwagger2">juneau-bean-swagger-v2</a>.
1147    *       <br>Multiple lines are concatenated with newlines.
1148    *    <li class='note'>
1149    *       The starting and ending <js>'{'</js>/<js>'}'</js> characters around the entire value are optional.
1150    *    <li class='note'>
1151    *       These values are superimposed on top of any Swagger JSON file present for the resource in the classpath.
1152    *    <li class='note'>
1153    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">REST Server SVL Variables</a>
1154    *       (e.g. <js>"$L{my.localized.variable}"</js>).
1155    * </ul>
1156    *
1157    * <h5 class='section'>See Also:</h5><ul>
1158    *    <li class='ja'>{@link OpSwagger}
1159    *    <li class='jc'>{@link SwaggerProvider}
1160    * </ul>
1161    *
1162    * @return The annotation value.
1163    */
1164   OpSwagger swagger() default @OpSwagger;
1165
1166   /**
1167    * REST method name and path.
1168    *
1169    * <p>
1170    * Can be used to provide a shortened combined form for the {@link #method()} and {@link #path()} values.
1171    *
1172    * <p>
1173    * The following examples are considered equivalent.
1174    * <p class='bjava'>
1175    *    <jc>// Normal form</jc>
1176    *    <ja>@RestOp</ja>(method=<jsf>PUT</jsf>, path=<js>"/{propertyName}"</js>)
1177    *
1178    *    <jc>// Shortened form</jc>
1179    *    <ja>@RestOp</ja>(<js>"PUT /{propertyName}"</js>)
1180    * </p>
1181    *
1182    * <h5 class='section'>Notes:</h5><ul>
1183    *    <li class='note'>
1184    *       The path portion is optional.
1185    * </ul>
1186    *
1187    * @return The annotation value.
1188    */
1189   String value() default "";
1190}