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