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.annotation.*;
021import org.apache.juneau.json.*;
022
023/**
024 * REST request body annotation.
025 *
026 * <p>
027 * Identifies a POJO to be used as the body of an HTTP request.
028 *
029 * <p>
030 * Can be used in the following locations:
031 * <ul>
032 *    <li>Arguments and argument-types of server-side <ja>@RestOp</ja>-annotated methods.
033 *    <li>Arguments and argument-types of client-side <ja>@RemoteOp</ja>-annotated interfaces.
034 *    <li>Methods and return types of server-side and client-side <ja>@Request</ja>-annotated interfaces.
035 * </ul>
036 *
037 * <h5 class='topic'>Arguments and argument-types of server-side @RestOp-annotated methods</h5>
038 *
039 * <p>
040 * 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.
041 *
042 * <h5 class='section'>Examples:</h5>
043 * <p class='bjava'>
044 *    <jc>// Used on parameter</jc>
045 *    <ja>@RestPost</ja>(<js>"/pets"</js>)
046 *    <jk>public void</jk> addPet(<ja>@Content</ja> Pet <jv>pet</jv>) {...}
047 * </p>
048 * <p class='bjava'>
049 *    <jc>// Used on class</jc>
050 *    <ja>@RestPost</ja>(<js>"/pets"</js>)
051 *    <jk>public void</jk> addPet(Pet <jv>pet</jv>) {...}
052 *
053 *    <ja>@Content</ja>
054 *    <jk>public class</jk> Pet {...}
055 * </p>
056 *
057 * <p>
058 * This is functionally equivalent to the following code...
059 * <p class='bjava'>
060 *    <ja>@RestPost</ja>(<js>"/pets"</js>)
061 *    <jk>public void</jk> addPet(RestRequest <jv>req</jv>) {
062 *       Pet <jv>pet</jv> = <jv>req</jv>.getContent().as(Pet.<jk>class</jk>);
063 *       ...
064 *    }
065 * </p>
066 *
067 * <h5 class='topic'>Arguments and argument-types of client-side @RemoteResource-annotated interfaces</h5>
068 *
069 * <h5 class='section'>See Also:</h5><ul>
070 *    <li class='link'><a class="doclink" href="../../../../../index.html#jrc.Content">@Content</a>
071 * </ul>
072 *
073 * <h5 class='topic'>Methods and return types of server-side and client-side @Request-annotated interfaces</h5>
074 *
075 * <h5 class='section'>See Also:</h5><ul>
076 *    <li class='link'><a class="doclink" href="../../../../../index.html#jrc.Request">@Request</a>
077 * </ul>
078 *
079 * <h5 class='section'>Notes:</h5><ul>
080 *    <li class='note'>
081 *       Annotation parameter values will be aggregated when used on POJO parent and child classes.
082 *       <br>Values on child classes override values on parent classes.
083 *    <li class='note'>
084 *       Annotation parameter values will be aggregated when used on both POJOs and REST methods.
085 *       <br>Values on methods override values on POJO classes.
086 *    <li class='warn'>
087 *       If using this annotation on a Spring bean, note that you are likely to encounter issues when using on parameterized
088 *       types such as <code>List&lt;MyBean&gt;</code>.  This is due to the fact that Spring uses CGLIB to recompile classes
089 *       at runtime, and CGLIB was written before generics were introduced into Java and is a virtually-unsupported library.
090 *       Therefore, parameterized types will often be stripped from class definitions and replaced with unparameterized types
091 *    (e.g. <code>List</code>).  Under these circumstances, you are likely to get <code>ClassCastExceptions</code>
092 *    when trying to access generalized <code>JsonMaps</code> as beans.  The best solution to this issue is to either
093 *    specify the parameter as a bean array (e.g. <code>MyBean[]</code>) or declare the method as final so that CGLIB
094 *    will not try to recompile it.
095 * </ul>
096 *
097 * <h5 class='section'>See Also:</h5><ul>
098
099 * </ul>
100 */
101@Documented
102@Target({PARAMETER,METHOD,TYPE})
103@Retention(RUNTIME)
104@Inherited
105@Repeatable(ContentAnnotation.Array.class)
106@ContextApply(ContentAnnotation.Applier.class)
107public @interface Content {
108
109   /**
110    * Dynamically apply this annotation to the specified classes.
111    *
112    * <h5 class='section'>See Also:</h5><ul>
113    *    <li class='link'><a class="doclink" href="../../../../../index.html#jm.DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a>
114    * </ul>
115    *
116    * @return The annotation value.
117    */
118   String[] on() default {};
119
120   /**
121    * Dynamically apply this annotation to the specified classes.
122    *
123    * <p>
124    * Identical to {@link #on()} except allows you to specify class objects instead of a strings.
125    *
126    * <h5 class='section'>See Also:</h5><ul>
127    *    <li class='link'><a class="doclink" href="../../../../../index.html#jm.DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a>
128    * </ul>
129    *
130    * @return The annotation value.
131    */
132   Class<?>[] onClass() default {};
133
134   /**
135    * <mk>schema</mk> field of the <a class='doclink' href='https://swagger.io/specification/v2#parameterObject'>Swagger Parameter Object</a>.
136    *
137    * <p>
138    * The schema defining the type used for parameter.
139    *
140    * <p>
141    * This is a required attribute per the swagger definition.
142    * However, if not explicitly specified, the value will be auto-generated using {@link JsonSchemaSerializer}.
143    *
144    * <p>
145    * The {@link Schema @Schema} annotation can also be used standalone on the parameter or type.
146    * Values specified on this field override values specified on the type, and values specified on child types override values
147    * specified on parent types.
148    *
149    * <h5 class='section'>Used for:</h5>
150    * <ul class='spaced-list'>
151    *    <li>
152    *       Server-side schema-based parsing and parsing validation.
153    *    <li>
154    *       Server-side generated Swagger documentation.
155    *    <li>
156    *       Client-side schema-based serializing and serializing validation.
157    * </ul>
158    *
159    * @return The annotation value.
160    */
161   Schema schema() default @Schema;
162}