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