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.http.annotation;
014
015import static java.lang.annotation.ElementType.*;
016import static java.lang.annotation.RetentionPolicy.*;
017
018import java.lang.annotation.*;
019
020import org.apache.juneau.*;
021import org.apache.juneau.annotation.*;
022import org.apache.juneau.httppart.*;
023import org.apache.juneau.json.*;
024import org.apache.juneau.jsonschema.*;
025
026/**
027 * REST request body annotation.
028 *
029 * <p>
030 * Identifies a POJO to be used as the body of an HTTP request.
031 *
032 * <p>
033 * Can be used in the following locations:
034 * <ul>
035 *    <li>Arguments and argument-types of server-side <ja>@RestMethod</ja>-annotated methods.
036 *    <li>Arguments and argument-types of client-side <ja>@RemoteMethod</ja>-annotated interfaces.
037 *    <li>Methods and return types of server-side and client-side <ja>@Request</ja>-annotated interfaces.
038 * </ul>
039 *
040 * <h5 class='topic'>Arguments and argument-types of server-side @RestMethod-annotated methods</h5>
041 *
042 * <p>
043 * On server-side REST, this annotation can be applied to method parameters or parameter classes to identify them as the body of an HTTP request.
044 *
045 * <h5 class='section'>Examples:</h5>
046 * <p class='bcode w800'>
047 *    <jc>// Used on parameter</jc>
048 *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>,path=<js>"/pets"</js>)
049 *    <jk>public void</jk> addPet(<ja>@Body</ja> Pet pet) {...}
050 * </p>
051 * <p class='bcode w800'>
052 *    <jc>// Used on class</jc>
053 *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>,path=<js>"/pets"</js>)
054 *    <jk>public void</jk> addPet(Pet pet) {...}
055 *
056 *    <ja>@Body</ja>
057 *    <jk>public class</jk> Pet {...}
058 * </p>
059 *
060 * <p>
061 * This is functionally equivalent to the following code...
062 * <p class='bcode w800'>
063 *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>,path=<js>"/pets"</js>)
064 *    <jk>public void</jk> addPet(RestRequest req) {
065 *       Pet pet = req.getBody().asType(Pet.<jk>class</jk>);
066 *       ...
067 *    }
068 * </p>
069 *
070 * <p>
071 * Also used to populate the auto-generated Swagger documentation.
072 *
073 * <h5 class='section'>Examples:</h5>
074 * <p class='bcode w800'>
075 *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>,path=<js>"/pets"</js>)
076 *    <jk>public void</jk> addPet(Pet pet) {...}
077 *
078 *    <ja>@Body</ja>(
079 *       description=<js>"Pet object to add to the store"</js>,
080 *       required=<jk>true</jk>,
081 *       example=<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>
082 *    )
083 *    <jk>public class</jk> Pet {...}
084 * </p>
085 *
086 * <p>
087 * Swagger documentation values are coalesced from multiple sources in the following order of precedence:
088 * <ol>
089 *    <li><ja>@Body</ja> annotation on parameter.
090 *    <li><ja>@Body</ja> annotation on parameter class.
091 *    <li><ja>@Body</ja> annotation on parent classes and interfaces.
092 *    <li><ja>@MethodSwagger(value)</ja> annotation.
093 *    <li>Localized resource bundle property <js>"[method-name].produces"</js>.
094 *    <li><ja>@ResourceSwagger(value)</ja> annotation.
095 *    <li>Localized classpath resource file <js>"[enclosing-class].[simple-class-name]_[locale].json"</js> (if it's an inner or member class).
096 *    <li>Default classpath resource file <js>"[enclosing-class].[simple-class-name].json"</js> (if it's an inner or member class).
097 *    <li>Localized classpath resource file <js>"[simple-class-name]_[locale].json"</js>.
098 *    <li>Default classpath resource file <js>"[simple-class-name].json"</js>.
099 * </ol>
100 *
101 * <h5 class='section'>See Also:</h5>
102 * <ul>
103 *    <li class='link'>{@doc juneau-rest-server.HttpPartAnnotations.Body}
104 *    <li class='link'>{@doc juneau-rest-server.Swagger}
105 *    <li class='extlink'>{@doc SwaggerParameterObject}
106 * </ul>
107 *
108 * <h5 class='topic'>Arguments and argument-types of client-side @RemoteResource-annotated interfaces</h5>
109 *
110 * <h5 class='section'>See Also:</h5>
111 * <ul class='doctree'>
112 *    <li class='link'>{@doc juneau-rest-client.RestProxies.Body}
113 * </ul>
114 *
115 * <h5 class='topic'>Methods and return types of server-side and client-side @Request-annotated interfaces</h5>
116 *
117 * <h5 class='section'>See Also:</h5>
118 * <ul class='doctree'>
119 *    <li class='link'>{@doc juneau-rest-server.HttpPartAnnotations.Request}
120 *    <li class='link'>{@doc juneau-rest-client.RestProxies.Request}
121 * </ul>
122 */
123@Documented
124@Target({PARAMETER,FIELD,METHOD,TYPE})
125@Retention(RUNTIME)
126@Inherited
127public @interface Body {
128
129   //=================================================================================================================
130   // Attributes common to all Swagger Parameter objects
131   //=================================================================================================================
132
133   /**
134    * <mk>description</mk> field of the {@doc SwaggerParameterObject}.
135    *
136    * <p>
137    * A brief description of the body. This could contain examples of use.
138    *
139    * <h5 class='section'>Examples:</h5>
140    * <p class='bcode w800'>
141    *    <jc>// Used on parameter</jc>
142    *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>)
143    *    <jk>public void</jk> addPet(
144    *       <ja>@Body</ja>(description=<js>"Pet object to add to the store"</js>) Pet input
145    *    ) {...}
146    * </p>
147    * <p class='bcode w800'>
148    *    <jc>// Used on class</jc>
149    *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>)
150    *    <jk>public void</jk> addPet(Pet input) {...}
151    *
152    *    <ja>@Body</ja>(description=<js>"Pet object to add to the store"</js>)
153    *    <jk>public class</jk> Pet {...}
154    * </p>
155    *
156    * <h5 class='section'>Used for:</h5>
157    * <ul class='spaced-list'>
158    *    <li>
159    *       Server-side generated Swagger documentation.
160    * </ul>
161    *
162    * <h5 class='section'>Notes:</h5>
163    * <ul class='spaced-list'>
164    *    <li>
165    *       The format is plain text.
166    *       <br>Multiple lines are concatenated with newlines.
167    *    <li>
168    *       Supports {@doc DefaultRestSvlVariables}
169    *       (e.g. <js>"$L{my.localized.variable}"</js>).
170    * </ul>
171    */
172   String[] description() default {};
173
174   /**
175    * <mk>required</mk> field of the {@doc SwaggerParameterObject}.
176    *
177    * <p>
178    * Determines whether the body is mandatory.
179    *
180    * <p>
181    * If validation fails during serialization or parsing, the part serializer/parser will throw a {@link SchemaValidationException}.
182    * <br>On the client-side, this gets converted to a <code>RestCallException</code> which is thrown before the connection is made.
183    * <br>On the server-side, this gets converted to a <code>BadRequest</code> (400).
184    *
185    * <h5 class='section'>Examples:</h5>
186    * <p class='bcode w800'>
187    *    <jc>// Used on parameter</jc>
188    *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>)
189    *    <jk>public void</jk> addPet(
190    *       <ja>@Body</ja>(required=<jk>true</jk>) Pet input
191    *    ) {...}
192    * </p>
193    * <p class='bcode w800'>
194    *    <jc>// Used on class</jc>
195    *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>)
196    *    <jk>public void</jk> addPet(Pet input) {...}
197    *
198    *    <ja>@Body</ja>(required=<jk>true</jk>)
199    *    <jk>public class</jk> Pet {...}
200    * </p>
201    *
202    * <h5 class='section'>Used for:</h5>
203    * <ul class='spaced-list'>
204    *    <li>
205    *       Server-side schema-based parsing validation.
206    *    <li>
207    *       Server-side generated Swagger documentation.
208    *    <li>
209    *       Client-side schema-based serializing validation.
210    * </ul>
211    *
212    * <h5 class='section'>Notes:</h5>
213    * <ul class='spaced-list'>
214    *    <li>
215    *       Supports {@doc DefaultRestSvlVariables}
216    *       (e.g. <js>"$L{my.localized.variable}"</js>).
217    * </ul>
218    */
219   boolean required() default false;
220
221   //=================================================================================================================
222   // Attributes specific to in=body
223   //=================================================================================================================
224
225   /**
226    * <mk>schema</mk> field of the {@doc SwaggerParameterObject}.
227    *
228    * <p>
229    * The schema defining the type used for the body parameter.
230    *
231    * <p>
232    * This is a required attribute per the swagger definition.
233    * However, if not explicitly specified, the value will be auto-generated using {@link JsonSchemaSerializer}.
234    *
235    * <h5 class='section'>Used for:</h5>
236    * <ul class='spaced-list'>
237    *    <li>
238    *       Server-side schema-based parsing and parsing validation.
239    *    <li>
240    *       Server-side generated Swagger documentation.
241    *    <li>
242    *       Client-side schema-based serializing and serializing validation.
243    * </ul>
244    *
245    * <h5 class='section'>Notes:</h5>
246    * <ul class='spaced-list'>
247    *    <li>
248    *       Supports {@doc DefaultRestSvlVariables}
249    *       (e.g. <js>"$L{my.localized.variable}"</js>).
250    * </ul>
251    */
252   Schema schema() default @Schema;
253
254   //=================================================================================================================
255   // Other
256   //=================================================================================================================
257
258   /**
259    * A serialized example of the body of a request.
260    *
261    * <p>
262    * This is the {@doc juneau-marshall.JsonDetails.SimplifiedJson} of an example of the body.
263    *
264    * <p>
265    * This value is converted to a POJO and then serialized to all the registered serializers on the REST method to produce examples for all
266    * supported language types.
267    * <br>These values are then used to automatically populate the {@link #examples} field.
268    *
269    * <h5 class='section'>Example:</h5>
270    * <p class='bcode w800'>
271    *    <jc>// A JSON representation of a PetCreate object.</jc>
272    *    <ja>@Body</ja>(
273    *       example=<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>
274    *    )
275    * </p>
276    * <p>
277    * <img class='bordered' src='doc-files/Body_Example.png' style='width:860px'>
278    *
279    * <p>
280    * There are several other options for defining this example:
281    * <ul class='spaced-list'>
282    *    <li>
283    *       Defining an <js>"x-example"</js> field in the inherited Swagger JSON body field (classpath file or <code><ja>@ResourceSwagger</ja>(value)</code>/<code><ja>@MethodSwagger</ja>(value)</code>).
284    *    <li>
285    *       Defining an <js>"x-example"</js> field in the Swagger Schema Object for the body (including referenced <js>"$ref"</js> schemas).
286    *    <li>
287    *       Allowing Juneau to auto-generate a code example.
288    * </ul>
289    *
290    * <p>
291    * The latter is important because Juneau also supports auto-generation of JSON-Schema from POJO classes using {@link JsonSchemaSerializer} which has several of it's own
292    * options for auto-detecting and calculation POJO examples.
293    *
294    * <p>
295    * In particular, examples can be defined via static methods, fields, and annotations on the classes themselves.
296    *
297    * <p class='bcode w800'>
298    *    <jc>// Annotation on class.</jc>
299    *    <ja>@Example</ja>(<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>)
300    *    <jk>public class</jk> PetCreate {
301    *       ...
302    *    }
303    * </p>
304    * <p class='bcode w800'>
305    *    <jc>// Annotation on static method.</jc>
306    *    <jk>public class</jk> PetCreate {
307    *
308    *       <ja>@Example</ja>
309    *       <jk>public static</jk> PetCreate <jsm>sample</jsm>() {
310    *          <jk>return new</jk> PetCreate(<js>"Doggie"</js>, 9.99f, <js>"Dog"</js>, <jk>new</jk> String[] {<js>"friendly"</js>,<js>"cute"</js>});
311    *       }
312    *    }
313    * </p>
314    * <p class='bcode w800'>
315    *    <jc>// Static method with specific name 'example'.</jc>
316    *    <jk>public class</jk> PetCreate {
317    *
318    *       <jk>public static</jk> PetCreate <jsm>example</jsm>() {
319    *          <jk>return new</jk> PetCreate(<js>"Doggie"</js>, 9.99f, <js>"Dog"</js>, <jk>new</jk> String[] {<js>"friendly"</js>,<js>"cute"</js>});
320    *       }
321    *    }
322    * </p>
323    * <p class='bcode w800'>
324    *    <jc>// Static field.</jc>
325    *    <jk>public class</jk> PetCreate {
326    *
327    *       <ja>@Example</ja>
328    *       <jk>public static</jk> PetCreate <jsf>EXAMPLE</jsf> = <jk>new</jk> PetCreate(<js>"Doggie"</js>, 9.99f, <js>"Dog"</js>, <jk>new</jk> String[] {<js>"friendly"</js>,<js>"cute"</js>});
329    *    }
330    * </p>
331    *
332    * <p>
333    * Examples can also be specified via generic properties as well using the {@link BeanContext#BEAN_examples} property at either the class or method level.
334    * <p class='bcode w800'>
335    *    <jc>// Examples defined at class level.</jc>
336    *    <ja>@RestResource</ja>(
337    *       properties={
338    *          <ja>@Property</ja>(
339    *             name=<jsf>BEAN_examples</jsf>,
340    *             value=<js>"{'org.apache.juneau.examples.rest.petstore.PetCreate': {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}}"</js>
341    *          )
342    *       }
343    *    )
344    * </p>
345    *
346    * <h5 class='section'>Used for:</h5>
347    * <ul class='spaced-list'>
348    *    <li>
349    *       Server-side generated Swagger documentation.
350    * </ul>
351    *
352    * <h5 class='section'>See also:</h5>
353    * <ul>
354    *    <li class='ja'>{@link Example}
355    *    <li class='jc'>{@link BeanContext}
356    *    <ul>
357    *       <li class='jf'>{@link BeanContext#BEAN_examples BEAN_examples}
358    *    </ul>
359    *    <li class='jc'>{@link JsonSchemaSerializer}
360    *    <ul>
361    *       <li class='jf'>{@link JsonSchemaGenerator#JSONSCHEMA_addExamplesTo JSONSCHEMA_addExamplesTo}
362    *       <li class='jf'>{@link JsonSchemaGenerator#JSONSCHEMA_allowNestedExamples JSONSCHEMA_allowNestedExamples}
363    *    </ul>
364    * </ul>
365    *
366    * <h5 class='section'>Notes:</h5>
367    * <ul class='spaced-list'>
368    *    <li>
369    *       The format is any {@doc juneau-marshall.JsonDetails.SimplifiedJson} if the object can be converted to a POJO using {@link JsonParser#DEFAULT} or a simple String if the object
370    *       has a schema associated with it meancan be converted from a String.
371    *       <br>Multiple lines are concatenated with newlines.
372    *    <li>
373    *       The format of this object can also be a simple String if the body has a schema associated with it, meaning it's meant to be treated as an HTTP part.
374    *    <li>
375    *       Supports {@doc DefaultRestSvlVariables}
376    *       (e.g. <js>"$L{my.localized.variable}"</js>).
377    * </ul>
378    */
379   String[] example() default {};
380
381   /**
382    * Serialized examples of the body of a request.
383    *
384    * <p>
385    * This is a {@doc juneau-marshall.JsonDetails.SimplifiedJson} object whose keys are media types and values are string representations of that value.
386    *
387    * <p>
388    * In general you won't need to populate this value directly since it will automatically be calculated based on the value provided in the {@link #example()} field.
389    * <br>However, this field allows you to override the behavior and show examples for only specified media types or different examples for different media types.
390    *
391    * <p class='bcode w800'>
392    *    <jc>// A JSON representation of a PetCreate object.</jc>
393    *    <ja>@Body</ja>(
394    *       examples={
395    *          <js>"'application/json':'{name:\\'Doggie\\',species:\\'Dog\\'}',"</js>,
396    *          <js>"'text/uon':'(name:Doggie,species=Dog)'"</js>
397    *       }
398    *    )
399    * </p>
400    *
401    * <h5 class='section'>Used for:</h5>
402    * <ul class='spaced-list'>
403    *    <li>
404    *       Server-side generated Swagger documentation.
405    * </ul>
406    *
407    * <h5 class='section'>Notes:</h5>
408    * <ul class='spaced-list'>
409    *    <li>
410    *       The format is a {@doc juneau-marshall.JsonDetails.SimplifiedJson} object with string keys (media type) and string values (example for that media type) .
411    *    <li>
412    *       The leading/trailing <code>{ }</code> characters are optional.
413    *    <li>
414    *       Multiple lines are concatenated with newlines so that you can format the value to be readable:
415    *    <li>
416    *       Supports {@doc DefaultRestSvlVariables}
417    *       (e.g. <js>"$L{my.localized.variable}"</js>).
418    *    <li>
419    *       Resolution of variables is delayed until request time and occurs before parsing.
420    *       <br>This allows you to, for example, pull in a JSON construct from a properties file based on the locale of the HTTP request.
421    * </ul>
422    */
423   String[] examples() default {};
424
425   /**
426    * Free-form value for the {@doc SwaggerParameterObject}.
427    *
428    * <p>
429    * This is a {@doc juneau-marshall.JsonDetails.SimplifiedJson} object that makes up the swagger information for this parameter-info.
430    *
431    * <p>
432    * The following are completely equivalent ways of defining the swagger description of the body:
433    * <p class='bcode w800'>
434    *    <jc>// Normal</jc>
435    *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>)
436    *    <jk>public void</jk> addPet(
437    *       <ja>@Body</ja>(
438    *          description=<js>"Pet object to add to the store"</js>,
439    *          required=<jk>true</jk>,
440    *          example=<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>
441    *       ) Pet input
442    *    ) {...}
443    * </p>
444    * <p class='bcode w800'>
445    *    <jc>// Free-form</jc>
446    *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>)
447    *    <jk>public void</jk> addPet(
448    *       <ja>@Body</ja>({
449    *          <js>"description: 'Pet object to add to the store',"</js>,
450    *          <js>"required: true,"</js>,
451    *          <js>"example: {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>
452    *       }) Pet input
453    *    ) {...}
454    * </p>
455    * <p class='bcode w800'>
456    *    <jc>// Free-form with variables</jc>
457    *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>)
458    *    <jk>public void</jk> addPet(
459    *       <ja>@Body</ja>(<js>"$L{petObjectSwagger}"</js>) Pet input
460    *    ) {...}
461    * </p>
462    * <p class='bcode w800'>
463    *    <mc>// Contents of MyResource.properties</mc>
464    *    <mk>petObjectSwagger</mk> = <mv>{ description: "Pet object to add to the store", required: true, example: {name:"Doggie",price:9.99,species:"Dog",tags:["friendly","cute"]} }</mv>
465    * </p>
466    *
467    * <p>
468    *    The reasons why you may want to use this field include:
469    * <ul>
470    *    <li>You want to pull in the entire Swagger JSON definition for this body from an external source such as a properties file.
471    *    <li>You want to add extra fields to the Swagger documentation that are not officially part of the Swagger specification.
472    * </ul>
473    *
474    * <h5 class='section'>Used for:</h5>
475    * <ul class='spaced-list'>
476    *    <li>
477    *       Server-side generated Swagger documentation.
478    * </ul>
479    *
480    * <h5 class='section'>Notes:</h5>
481    * <ul class='spaced-list'>
482    *    <li>
483    *       The format is a {@doc juneau-marshall.JsonDetails.SimplifiedJson} object.
484    *    <li>
485    *       Schema-based serialization is NOT affected by values defined in this annotation.
486    *       <br>It only affects the generated Swagger documentation.
487    *    <li>
488    *       The leading/trailing <code>{ }</code> characters are optional.
489    *       <br>The following two example are considered equivalent:
490    *       <p class='bcode w800'>
491    *    <ja>@Body</ja>(<js>"{description: 'Pet object to add to the store'}"</js>)
492    *       </p>
493    *       <p class='bcode w800'>
494    *    <ja>@Body</ja>(<js>"description: 'Pet object to add to the store'"</js>)
495    *       </p>
496    *    <li>
497    *       Multiple lines are concatenated with newlines so that you can format the value to be readable.
498    *    <li>
499    *       Supports {@doc DefaultRestSvlVariables}
500    *       (e.g. <js>"$L{my.localized.variable}"</js>).
501    *    <li>
502    *       Values defined in this field supersede values pulled from the Swagger JSON file and are superseded by individual values defined on this annotation.
503    * </ul>
504    */
505   String[] value() default {};
506
507   /**
508    * Equivalent to {@link #value()}.
509    *
510    * <p>
511    * The following are entirely equivalent:
512    *
513    * <p class='bcode w800'>
514    *    <ja>@Body</ja>({
515    *       <js>"description: 'Pet object to add to the store',"</js>,
516    *       <js>"required: true,"</js>,
517    *       <js>"example: {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>
518    *    })
519    * </p>
520    * <p class='bcode w800'>
521    *    <ja>@Body</ja>(api={
522    *       <js>"description: 'Pet object to add to the store',"</js>,
523    *       <js>"required: true,"</js>,
524    *       <js>"example: {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>
525    *    })
526    * </p>
527    *
528    * <h5 class='section'>Used for:</h5>
529    * <ul class='spaced-list'>
530    *    <li>
531    *       Server-side generated Swagger documentation.
532    * </ul>
533    *
534    * <h5 class='section'>Notes:</h5>
535    * <ul class='spaced-list'>
536    *    <li>
537    *       If you specify both {@link #value()} and {@link #api()}, {@link #value()} will be ignored.
538    * </ul>
539    */
540   String[] api() default {};
541}