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 * <ul class='seealso'>
103 *    <li class='link'>{@doc RestBodyAnnotation}
104 *    <li class='link'>{@doc RestSwagger}
105 *    <li class='extlink'>{@doc ExtSwaggerParameterObject}
106 * </ul>
107 *
108 * <h5 class='topic'>Arguments and argument-types of client-side @RemoteResource-annotated interfaces</h5>
109 *
110 * <ul class='seealso'>
111 *    <li class='link'>{@doc RestcBody}
112 * </ul>
113 *
114 * <h5 class='topic'>Methods and return types of server-side and client-side @Request-annotated interfaces</h5>
115 *
116 * <ul class='seealso'>
117 *    <li class='link'>{@doc RestRequestAnnotation}
118 *    <li class='link'>{@doc RestcRequest}
119 * </ul>
120 *
121 * <div class='warn'>
122 *    If using this annotation on a Spring bean, note that you are likely to encounter issues when using on parameterized
123 *    types such as <code>List&lt;MyBean&gt;</code>.  This is due to the fact that Spring uses CGLIB to recompile classes
124 *    at runtime, and CGLIB was written before generics were introduced into Java and is a virtually-unsupported library.
125 *    Therefore, parameterized types will often be stripped from class definitions and replaced with unparameterized types
126 * (e.g. <code>List</code>).  Under these circumstances, you are likely to get <code>ClassCastExceptions</code>
127 * when trying to access generalized <code>OMaps</code> as beans.  The best solution to this issue is to either
128 * specify the parameter as a bean array (e.g. <code>MyBean[]</code>) or declare the method as final so that CGLIB
129 * will not try to recompile it.
130 * </div>
131 */
132@Documented
133@Target({PARAMETER,FIELD,METHOD,TYPE})
134@Retention(RUNTIME)
135@Inherited
136public @interface Body {
137
138   //=================================================================================================================
139   // Attributes common to all Swagger Parameter objects
140   //=================================================================================================================
141
142   /**
143    * <mk>description</mk> field of the {@doc ExtSwaggerParameterObject}.
144    *
145    * <p>
146    * A brief description of the body. This could contain examples of use.
147    *
148    * <h5 class='section'>Examples:</h5>
149    * <p class='bcode w800'>
150    *    <jc>// Used on parameter</jc>
151    *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>)
152    *    <jk>public void</jk> addPet(
153    *       <ja>@Body</ja>(description=<js>"Pet object to add to the store"</js>) Pet input
154    *    ) {...}
155    * </p>
156    * <p class='bcode w800'>
157    *    <jc>// Used on class</jc>
158    *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>)
159    *    <jk>public void</jk> addPet(Pet input) {...}
160    *
161    *    <ja>@Body</ja>(description=<js>"Pet object to add to the store"</js>)
162    *    <jk>public class</jk> Pet {...}
163    * </p>
164    *
165    * <h5 class='section'>Used for:</h5>
166    * <ul class='spaced-list'>
167    *    <li>
168    *       Server-side generated Swagger documentation.
169    * </ul>
170    *
171    * <ul class='notes'>
172    *    <li>
173    *       The format is plain text.
174    *       <br>Multiple lines are concatenated with newlines.
175    *    <li>
176    *       Supports {@doc RestSvlVariables}
177    *       (e.g. <js>"$L{my.localized.variable}"</js>).
178    * </ul>
179    */
180   String[] description() default {};
181
182   /**
183    * Synonym for {@link #description()}.
184    */
185   String[] d() default {};
186
187   /**
188    * <mk>required</mk> field of the {@doc ExtSwaggerParameterObject}.
189    *
190    * <p>
191    * Determines whether the body is mandatory.
192    *
193    * <p>
194    * If validation fails during serialization or parsing, the part serializer/parser will throw a {@link SchemaValidationException}.
195    * <br>On the client-side, this gets converted to a <c>RestCallException</c> which is thrown before the connection is made.
196    * <br>On the server-side, this gets converted to a <c>BadRequest</c> (400).
197    *
198    * <h5 class='section'>Examples:</h5>
199    * <p class='bcode w800'>
200    *    <jc>// Used on parameter</jc>
201    *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>)
202    *    <jk>public void</jk> addPet(
203    *       <ja>@Body</ja>(required=<jk>true</jk>) Pet input
204    *    ) {...}
205    * </p>
206    * <p class='bcode w800'>
207    *    <jc>// Used on class</jc>
208    *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>)
209    *    <jk>public void</jk> addPet(Pet input) {...}
210    *
211    *    <ja>@Body</ja>(required=<jk>true</jk>)
212    *    <jk>public class</jk> Pet {...}
213    * </p>
214    *
215    * <h5 class='section'>Used for:</h5>
216    * <ul class='spaced-list'>
217    *    <li>
218    *       Server-side schema-based parsing validation.
219    *    <li>
220    *       Server-side generated Swagger documentation.
221    *    <li>
222    *       Client-side schema-based serializing validation.
223    * </ul>
224    *
225    * <ul class='notes'>
226    *    <li>
227    *       Supports {@doc RestSvlVariables}
228    *       (e.g. <js>"$L{my.localized.variable}"</js>).
229    * </ul>
230    */
231   boolean required() default false;
232
233   /**
234    * Synonym for {@link #required()}.
235    */
236   boolean r() default false;
237
238   //=================================================================================================================
239   // Attributes specific to in=body
240   //=================================================================================================================
241
242   /**
243    * <mk>schema</mk> field of the {@doc ExtSwaggerParameterObject}.
244    *
245    * <p>
246    * The schema defining the type used for the body parameter.
247    *
248    * <p>
249    * This is a required attribute per the swagger definition.
250    * However, if not explicitly specified, the value will be auto-generated using {@link JsonSchemaSerializer}.
251    *
252    * <h5 class='section'>Used for:</h5>
253    * <ul class='spaced-list'>
254    *    <li>
255    *       Server-side schema-based parsing and parsing validation.
256    *    <li>
257    *       Server-side generated Swagger documentation.
258    *    <li>
259    *       Client-side schema-based serializing and serializing validation.
260    * </ul>
261    *
262    * <ul class='notes'>
263    *    <li>
264    *       Supports {@doc RestSvlVariables}
265    *       (e.g. <js>"$L{my.localized.variable}"</js>).
266    * </ul>
267    */
268   Schema schema() default @Schema;
269
270   //=================================================================================================================
271   // Other
272   //=================================================================================================================
273
274   /**
275    * A serialized example of the body of a request.
276    *
277    * <p>
278    * This is the {@doc SimplifiedJson} of an example of the body.
279    *
280    * <p>
281    * This value is converted to a POJO and then serialized to all the registered serializers on the REST method to produce examples for all
282    * supported language types.
283    * <br>These values are then used to automatically populate the {@link #examples} field.
284    *
285    * <h5 class='section'>Example:</h5>
286    * <p class='bcode w800'>
287    *    <jc>// A JSON representation of a PetCreate object.</jc>
288    *    <ja>@Body</ja>(
289    *       example=<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>
290    *    )
291    * </p>
292    * <p>
293    * <img class='bordered' src='doc-files/Body_Example.png' style='width:860px'>
294    *
295    * <p>
296    * There are several other options for defining this example:
297    * <ul class='spaced-list'>
298    *    <li>
299    *       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>).
300    *    <li>
301    *       Defining an <js>"x-example"</js> field in the Swagger Schema Object for the body (including referenced <js>"$ref"</js> schemas).
302    *    <li>
303    *       Allowing Juneau to auto-generate a code example.
304    * </ul>
305    *
306    * <p>
307    * 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
308    * options for auto-detecting and calculation POJO examples.
309    *
310    * <p>
311    * In particular, examples can be defined via static methods, fields, and annotations on the classes themselves.
312    *
313    * <p class='bcode w800'>
314    *    <jc>// Annotation on class.</jc>
315    *    <ja>@Example</ja>(<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>)
316    *    <jk>public class</jk> PetCreate {
317    *       ...
318    *    }
319    * </p>
320    * <p class='bcode w800'>
321    *    <jc>// Annotation on static method.</jc>
322    *    <jk>public class</jk> PetCreate {
323    *
324    *       <ja>@Example</ja>
325    *       <jk>public static</jk> PetCreate <jsm>sample</jsm>() {
326    *          <jk>return new</jk> PetCreate(<js>"Doggie"</js>, 9.99f, <js>"Dog"</js>, <jk>new</jk> String[] {<js>"friendly"</js>,<js>"cute"</js>});
327    *       }
328    *    }
329    * </p>
330    * <p class='bcode w800'>
331    *    <jc>// Static method with specific name 'example'.</jc>
332    *    <jk>public class</jk> PetCreate {
333    *
334    *       <jk>public static</jk> PetCreate <jsm>example</jsm>() {
335    *          <jk>return new</jk> PetCreate(<js>"Doggie"</js>, 9.99f, <js>"Dog"</js>, <jk>new</jk> String[] {<js>"friendly"</js>,<js>"cute"</js>});
336    *       }
337    *    }
338    * </p>
339    * <p class='bcode w800'>
340    *    <jc>// Static field.</jc>
341    *    <jk>public class</jk> PetCreate {
342    *
343    *       <ja>@Example</ja>
344    *       <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>});
345    *    }
346    * </p>
347    *
348    * <p>
349    * Examples can also be specified via generic properties as well using the {@link BeanContext#BEAN_examples} property at either the class or method level.
350    * <p class='bcode w800'>
351    *    <jc>// Examples defined at class level.</jc>
352    *    <ja>@Rest</ja>(
353    *       properties={
354    *          <ja>@Property</ja>(
355    *             name=<jsf>BEAN_examples</jsf>,
356    *             value=<js>"{'org.apache.juneau.examples.rest.petstore.PetCreate': {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}}"</js>
357    *          )
358    *       }
359    *    )
360    * </p>
361    *
362    * <h5 class='section'>Used for:</h5>
363    * <ul class='spaced-list'>
364    *    <li>
365    *       Server-side generated Swagger documentation.
366    * </ul>
367    *
368    * <ul class='seealso'>
369    *    <li class='ja'>{@link Example}
370    *    <li class='jc'>{@link BeanContext}
371    *    <ul>
372    *       <li class='jf'>{@link BeanContext#BEAN_examples BEAN_examples}
373    *    </ul>
374    *    <li class='jc'>{@link JsonSchemaSerializer}
375    *    <ul>
376    *       <li class='jf'>{@link JsonSchemaGenerator#JSONSCHEMA_addExamplesTo JSONSCHEMA_addExamplesTo}
377    *       <li class='jf'>{@link JsonSchemaGenerator#JSONSCHEMA_allowNestedExamples JSONSCHEMA_allowNestedExamples}
378    *    </ul>
379    * </ul>
380    *
381    * <ul class='notes'>
382    *    <li>
383    *       The format is any {@doc SimplifiedJson} if the object can be converted to a POJO using {@link JsonParser#DEFAULT} or a simple String if the object
384    *       has a schema associated with it meancan be converted from a String.
385    *       <br>Multiple lines are concatenated with newlines.
386    *    <li>
387    *       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.
388    *    <li>
389    *       Supports {@doc RestSvlVariables}
390    *       (e.g. <js>"$L{my.localized.variable}"</js>).
391    * </ul>
392    */
393   String[] example() default {};
394
395   /**
396    * Synonym for {@link #example()}.
397    */
398   String[] ex() default {};
399
400   /**
401    * Serialized examples of the body of a request.
402    *
403    * <p>
404    * This is a {@doc SimplifiedJson} object whose keys are media types and values are string representations of that value.
405    *
406    * <p>
407    * 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.
408    * <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.
409    *
410    * <p class='bcode w800'>
411    *    <jc>// A JSON representation of a PetCreate object.</jc>
412    *    <ja>@Body</ja>(
413    *       examples={
414    *          <js>"'application/json':'{name:\\'Doggie\\',species:\\'Dog\\'}',"</js>,
415    *          <js>"'text/uon':'(name:Doggie,species=Dog)'"</js>
416    *       }
417    *    )
418    * </p>
419    *
420    * <h5 class='section'>Used for:</h5>
421    * <ul class='spaced-list'>
422    *    <li>
423    *       Server-side generated Swagger documentation.
424    * </ul>
425    *
426    * <ul class='notes'>
427    *    <li>
428    *       The format is a {@doc SimplifiedJson} object with string keys (media type) and string values (example for that media type) .
429    *    <li>
430    *       The leading/trailing <c>{ }</c> characters are optional.
431    *    <li>
432    *       Multiple lines are concatenated with newlines so that you can format the value to be readable:
433    *    <li>
434    *       Supports {@doc RestSvlVariables}
435    *       (e.g. <js>"$L{my.localized.variable}"</js>).
436    *    <li>
437    *       Resolution of variables is delayed until request time and occurs before parsing.
438    *       <br>This allows you to, for example, pull in a JSON construct from a properties file based on the locale of the HTTP request.
439    * </ul>
440    */
441   String[] examples() default {};
442
443   /**
444    * Synonym for {@link #examples()}.
445    */
446   String[] exs() default {};
447
448   /**
449    * Free-form value for the {@doc ExtSwaggerParameterObject}.
450    *
451    * <p>
452    * This is a {@doc SimplifiedJson} object that makes up the swagger information for this parameter-info.
453    *
454    * <p>
455    * The following are completely equivalent ways of defining the swagger description of the body:
456    * <p class='bcode w800'>
457    *    <jc>// Normal</jc>
458    *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>)
459    *    <jk>public void</jk> addPet(
460    *       <ja>@Body</ja>(
461    *          description=<js>"Pet object to add to the store"</js>,
462    *          required=<jk>true</jk>,
463    *          example=<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>
464    *       ) Pet input
465    *    ) {...}
466    * </p>
467    * <p class='bcode w800'>
468    *    <jc>// Free-form</jc>
469    *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>)
470    *    <jk>public void</jk> addPet(
471    *       <ja>@Body</ja>({
472    *          <js>"description: 'Pet object to add to the store',"</js>,
473    *          <js>"required: true,"</js>,
474    *          <js>"example: {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>
475    *       }) Pet input
476    *    ) {...}
477    * </p>
478    * <p class='bcode w800'>
479    *    <jc>// Free-form with variables</jc>
480    *    <ja>@RestMethod</ja>(name=<jsf>POST</jsf>)
481    *    <jk>public void</jk> addPet(
482    *       <ja>@Body</ja>(<js>"$L{petObjectSwagger}"</js>) Pet input
483    *    ) {...}
484    * </p>
485    * <p class='bcode w800'>
486    *    <mc>// Contents of MyResource.properties</mc>
487    *    <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>
488    * </p>
489    *
490    * <p>
491    *    The reasons why you may want to use this field include:
492    * <ul>
493    *    <li>You want to pull in the entire Swagger JSON definition for this body from an external source such as a properties file.
494    *    <li>You want to add extra fields to the Swagger documentation that are not officially part of the Swagger specification.
495    * </ul>
496    *
497    * <h5 class='section'>Used for:</h5>
498    * <ul class='spaced-list'>
499    *    <li>
500    *       Server-side generated Swagger documentation.
501    * </ul>
502    *
503    * <ul class='notes'>
504    *    <li>
505    *       The format is a {@doc SimplifiedJson} object.
506    *    <li>
507    *       Schema-based serialization is NOT affected by values defined in this annotation.
508    *       <br>It only affects the generated Swagger documentation.
509    *    <li>
510    *       The leading/trailing <c>{ }</c> characters are optional.
511    *       <br>The following two example are considered equivalent:
512    *       <p class='bcode w800'>
513    *    <ja>@Body</ja>(<js>"{description: 'Pet object to add to the store'}"</js>)
514    *       </p>
515    *       <p class='bcode w800'>
516    *    <ja>@Body</ja>(<js>"description: 'Pet object to add to the store'"</js>)
517    *       </p>
518    *    <li>
519    *       Multiple lines are concatenated with newlines so that you can format the value to be readable.
520    *    <li>
521    *       Supports {@doc RestSvlVariables}
522    *       (e.g. <js>"$L{my.localized.variable}"</js>).
523    *    <li>
524    *       Values defined in this field supersede values pulled from the Swagger JSON file and are superseded by individual values defined on this annotation.
525    * </ul>
526    */
527   String[] value() default {};
528
529   /**
530    * Equivalent to {@link #value()}.
531    *
532    * <p>
533    * The following are entirely equivalent:
534    *
535    * <p class='bcode w800'>
536    *    <ja>@Body</ja>({
537    *       <js>"description: 'Pet object to add to the store',"</js>,
538    *       <js>"required: true,"</js>,
539    *       <js>"example: {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>
540    *    })
541    * </p>
542    * <p class='bcode w800'>
543    *    <ja>@Body</ja>(api={
544    *       <js>"description: 'Pet object to add to the store',"</js>,
545    *       <js>"required: true,"</js>,
546    *       <js>"example: {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>
547    *    })
548    * </p>
549    *
550    * <h5 class='section'>Used for:</h5>
551    * <ul class='spaced-list'>
552    *    <li>
553    *       Server-side generated Swagger documentation.
554    * </ul>
555    *
556    * <ul class='notes'>
557    *    <li>
558    *       If you specify both {@link #value()} and {@link #api()}, {@link #value()} will be ignored.
559    * </ul>
560    */
561   String[] api() default {};
562}