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.*;
026import org.apache.juneau.oapi.*;
027
028/**
029 * REST response annotation.
030 *
031 * <p>
032 * Identifies an interface to use to interact with HTTP parts of an HTTP response through a bean.
033 *
034 * <p>
035 * Can be used in the following locations:
036 *  <ul>
037 *    <li>Exception classes thrown from server-side <ja>@RestMethod</ja>-annotated methods.
038 *    <li>Return type classes of server-side <ja>@RestMethod</ja>-annotated methods.
039 *    <li>Arguments and argument-types of server-side <ja>@RestMethod</ja>-annotated methods.
040 *    <li>Return type classes of server-side <ja>@RemoteMethod</ja>-annotated methods.
041 *    <li>Client-side <ja>@RemoteMethod</ja>-annotated methods.
042 *    <li>Return type interfaces of client-side <ja>@RemoteMethod</ja>-annotated methods.
043 * </ul>
044 *
045 * <h5 class='section'>See Also:</h5>
046 * <ul>
047 *    <li class='link'>{@doc juneau-rest-server.HttpPartAnnotations.Response}
048 *    <li class='link'>{@doc juneau-rest-client.RestProxies.Response}
049 *    <li class='link'>{@doc juneau-rest-server.Swagger}
050 *    <li class='extlink'>{@doc SwaggerResponseObject}
051 * </ul>
052 */
053@Documented
054@Target({PARAMETER,TYPE,METHOD})
055@Retention(RUNTIME)
056@Inherited
057public @interface Response {
058
059   /**
060    * Specifies the {@link HttpPartParser} class used for parsing strings to values.
061    *
062    * <p>
063    * Overrides for this part the part parser defined on the REST resource which by default is {@link OpenApiParser}.
064    */
065   Class<? extends HttpPartParser> partParser() default HttpPartParser.Null.class;
066
067   /**
068    * Specifies the {@link HttpPartSerializer} class used for serializing values to strings.
069    *
070    * <p>
071    * Overrides for this part the part serializer defined on the REST resource which by default is {@link OpenApiSerializer}.
072    */
073   Class<? extends HttpPartSerializer> partSerializer() default HttpPartSerializer.Null.class;
074
075   /**
076    * The HTTP response code.
077    *
078    * The default value is <code>500</code> for exceptions and <code>200</code> for return types.
079    */
080   int[] code() default {};
081
082   /**
083    * A synonym for {@link #code()}.
084    *
085    * <p>
086    * Allows you to use shortened notation if you're only specifying the code.
087    *
088    * <p>
089    * The following are completely equivalent ways of defining the response code:
090    * <p class='bcode w800'>
091    *    <ja>@Response</ja>(code=404)
092    *    <jk>public class</jk> NotFound <jk>extends</jk> RestException {...}
093    * </p>
094    * <p class='bcode w800'>
095    *    <ja>@Response</ja>(404)
096    *    <jk>public class</jk> NotFound <jk>extends</jk> RestException {...}
097    * </p>
098    */
099   int[] value() default {};
100
101   /**
102    * <mk>description</mk> field of the {@doc SwaggerResponseObject}.
103    *
104    * <h5 class='section'>Used for:</h5>
105    * <ul class='spaced-list'>
106    *    <li>
107    *       Server-side generated Swagger documentation.
108    * </ul>
109    *
110    * <h5 class='section'>Notes:</h5>
111    * <ul class='spaced-list'>
112    *    <li>
113    *       The format is plain text.
114    *       <br>Multiple lines are concatenated with newlines.
115    *    <li>
116    *       Supports {@doc DefaultRestSvlVariables}
117    *       (e.g. <js>"$L{my.localized.variable}"</js>).
118    * </ul>
119    */
120   String[] description() default {};
121
122   /**
123    * <mk>schema</mk> field of the {@doc SwaggerResponseObject}.
124    *
125    * <h5 class='section'>Used for:</h5>
126    * <ul class='spaced-list'>
127    *    <li>
128    *       Server-side schema-based serializing and serializing validation.
129    *    <li>
130    *       Server-side generated Swagger documentation.
131    * </ul>
132    */
133   Schema schema() default @Schema;
134
135   /**
136    * <mk>headers</mk> field of the {@doc SwaggerResponseObject}.
137    *
138    * <h5 class='section'>Used for:</h5>
139    * <ul class='spaced-list'>
140    *    <li>
141    *       Server-side generated Swagger documentation.
142    * </ul>
143    */
144   ResponseHeader[] headers() default {};
145
146   /**
147    * A serialized example of the body of a response.
148    *
149    * <p>
150    * This is the {@doc juneau-marshall.JsonDetails.SimplifiedJson} of an example of the body.
151    *
152    * <p>
153    * This value is converted to a POJO and then serialized to all the registered serializers on the REST method to produce examples for all
154    * supported language types.
155    * <br>These values are then used to automatically populate the {@link #examples} field.
156    *
157    * <h5 class='section'>Example:</h5>
158    * <p class='bcode w800'>
159    *    <jc>// A JSON representation of a PetCreate object.</jc>
160    *    <ja>@Response</ja>(
161    *       example=<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>
162    *    )
163    * </p>
164    *
165    * <p>
166    * There are several other options for defining this example:
167    * <ul class='spaced-list'>
168    *    <li>
169    *       Defining an <js>"x-example"</js> field in the inherited Swagger JSON response object (classpath file or <code><ja>@ResourceSwagger</ja>(value)</code>/<code><ja>@MethodSwagger</ja>(value)</code>).
170    *    <li>
171    *       Defining an <js>"x-example"</js> field in the Swagger Schema Object for the response object (including referenced <js>"$ref"</js> schemas).
172    *    <li>
173    *       Allowing Juneau to auto-generate a code example.
174    * </ul>
175    *
176    * <p>
177    * 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
178    * options for auto-detecting and calculation POJO examples.
179    *
180    * <p>
181    * In particular, examples can be defined via static methods, fields, and annotations on the classes themselves.
182    *
183    * <p class='bcode w800'>
184    *    <jc>// Annotation on class.</jc>
185    *    <ja>@Example</ja>(<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>)
186    *    <jk>public class</jk> PetCreate {
187    *       ...
188    *    }
189    * </p>
190    * <p class='bcode w800'>
191    *    <jc>// Annotation on static method.</jc>
192    *    <jk>public class</jk> PetCreate {
193    *
194    *       <ja>@Example</ja>
195    *       <jk>public static</jk> PetCreate <jsm>sample</jsm>() {
196    *          <jk>return new</jk> PetCreate(<js>"Doggie"</js>, 9.99f, <js>"Dog"</js>, <jk>new</jk> String[] {<js>"friendly"</js>,<js>"cute"</js>});
197    *       }
198    *    }
199    * </p>
200    * <p class='bcode w800'>
201    *    <jc>// Static method with specific name 'example'.</jc>
202    *    <jk>public class</jk> PetCreate {
203    *
204    *       <jk>public static</jk> PetCreate <jsm>example</jsm>() {
205    *          <jk>return new</jk> PetCreate(<js>"Doggie"</js>, 9.99f, <js>"Dog"</js>, <jk>new</jk> String[] {<js>"friendly"</js>,<js>"cute"</js>});
206    *       }
207    *    }
208    * </p>
209    * <p class='bcode w800'>
210    *    <jc>// Static field.</jc>
211    *    <jk>public class</jk> PetCreate {
212    *
213    *       <ja>@Example</ja>
214    *       <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>});
215    *    }
216    * </p>
217    *
218    * <p>
219    * Examples can also be specified via generic properties as well using the {@link BeanContext#BEAN_examples} property at either the class or method level.
220    * <p class='bcode w800'>
221    *    <jc>// Examples defined at class level.</jc>
222    *    <ja>@RestResource</ja>(
223    *       properties={
224    *          <ja>@Property</ja>(
225    *             name=<jsf>BEAN_examples</jsf>,
226    *             value=<js>"{'org.apache.juneau.examples.rest.petstore.PetCreate': {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}}"</js>
227    *          )
228    *       }
229    *    )
230    * </p>
231    *
232    * <h5 class='section'>Used for:</h5>
233    * <ul class='spaced-list'>
234    *    <li>
235    *       Server-side generated Swagger documentation.
236    * </ul>
237    *
238    * <h5 class='section'>See also:</h5>
239    * <ul>
240    *    <li class='ja'>{@link Example}
241    *    <li class='jc'>{@link BeanContext}
242    *    <ul>
243    *       <li class='jf'>{@link BeanContext#BEAN_examples BEAN_examples}
244    *    </ul>
245    *    <li class='jc'>{@link JsonSchemaSerializer}
246    *    <ul>
247    *       <li class='jf'>{@link JsonSchemaGenerator#JSONSCHEMA_addExamplesTo JSONSCHEMA_addExamplesTo}
248    *       <li class='jf'>{@link JsonSchemaGenerator#JSONSCHEMA_allowNestedExamples JSONSCHEMA_allowNestedExamples}
249    *    </ul>
250    * </ul>
251    *
252    * <h5 class='section'>Notes:</h5>
253    * <ul class='spaced-list'>
254    *    <li>
255    *       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
256    *       has a schema associated with it meancan be converted from a String.
257    *       <br>Multiple lines are concatenated with newlines.
258    *    <li>
259    *       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.
260    *    <li>
261    *       Supports {@doc DefaultRestSvlVariables}
262    *       (e.g. <js>"$L{my.localized.variable}"</js>).
263    * </ul>
264    */
265   String[] example() default {};
266
267   /**
268    * Serialized examples of the body of a response.
269    *
270    * <p>
271    * This is a {@doc juneau-marshall.JsonDetails.SimplifiedJson} object whose keys are media types and values are string representations of that value.
272    *
273    * <p>
274    * 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.
275    * <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.
276    *
277    * <p class='bcode w800'>
278    *    <jc>// A JSON representation of a PetCreate object.</jc>
279    *    <ja>@Response</ja>(
280    *       examples={
281    *          <js>"'application/json':'{name:\\'Doggie\\',species:\\'Dog\\'}',"</js>,
282    *          <js>"'text/uon':'(name:Doggie,species=Dog)'"</js>
283    *       }
284    *    )
285    * </p>
286    *
287    * <h5 class='section'>Used for:</h5>
288    * <ul class='spaced-list'>
289    *    <li>
290    *       Server-side generated Swagger documentation.
291    * </ul>
292    *
293    * <h5 class='section'>Notes:</h5>
294    * <ul class='spaced-list'>
295    *    <li>
296    *       The format is a {@doc juneau-marshall.JsonDetails.SimplifiedJson} object with string keys (media type) and string values (example for that media type) .
297    *    <li>
298    *       The leading/trailing <code>{ }</code> characters are optional.
299    *    <li>
300    *       Multiple lines are concatenated with newlines so that you can format the value to be readable:
301    *    <li>
302    *       Supports {@doc DefaultRestSvlVariables}
303    *       (e.g. <js>"$L{my.localized.variable}"</js>).
304    *    <li>
305    *       Resolution of variables is delayed until request time and occurs before parsing.
306    *       <br>This allows you to, for example, pull in a JSON construct from a properties file based on the locale of the HTTP request.
307    * </ul>
308    */
309   String[] examples() default {};
310
311   /**
312    * Free-form value for the {@doc SwaggerResponseObject}.
313    *
314    * <p>
315    * This is a {@doc juneau-marshall.JsonDetails.SimplifiedJson} object that makes up the swagger information for this field.
316    *
317    * <p>
318    * The following are completely equivalent ways of defining the swagger description of the Response object:
319    * <p class='bcode w800'>
320    *    <jc>// Normal</jc>
321    *    <ja>@Response</ja>(
322    *       code=302,
323    *       description=<js>"Redirect"</js>,
324    *       headers={
325    *          <ja>@ResponseHeader</ja>(
326    *             name=<js>"Location"</js>,
327    *             type=<js>"string"</js>,
328    *             format=<js>"uri"</js>
329    *          )
330    *       }
331    *    )
332    * </p>
333    * <p class='bcode w800'>
334    *    <jc>// Free-form</jc>
335    *    <ja>@Response</ja>(
336    *       code=302,
337    *       api={
338    *          <js>"description: 'Redirect',"</js>,
339    *          <js>"headers: {"</js>,
340    *             <js>"Location: {"</js>,
341    *                <js>"type: 'string',"</js>,
342    *                <js>"format: 'uri'"</js>,
343    *             <js>"}"</js>,
344    *          <js>"}"</js>
345    *       }
346    *    )
347    * </p>
348    * <p class='bcode w800'>
349    *    <jc>// Free-form using variables</jc>
350    *    <ja>@Response</ja>(
351    *       code=302,
352    *       api=<js>"$L{redirectSwagger}"</js>
353    *    )
354    * </p>
355    * <p class='bcode w800'>
356    *    <mc>// Contents of MyResource.properties</mc>
357    *    <mk>redirectSwagger</mk> = <mv>{ description: "Redirect", headers: { Location: { type: "string", format: "uri" } } }</mv>
358    * </p>
359    *
360    * <p>
361    *    The reasons why you may want to use this field include:
362    * <ul>
363    *    <li>You want to pull in the entire Swagger JSON definition for this field from an external source such as a properties file.
364    *    <li>You want to add extra fields to the Swagger documentation that are not officially part of the Swagger specification.
365    * </ul>
366    *
367    * <h5 class='section'>Used for:</h5>
368    * <ul class='spaced-list'>
369    *    <li>
370    *       Server-side generated Swagger documentation.
371    * </ul>
372    *
373    * <h5 class='section'>Notes:</h5>
374    * <ul class='spaced-list'>
375    *    <li>
376    *       Note that the only swagger field you can't specify using this value is <js>"code"</js> whose value needs to be known during servlet initialization.
377    *    <li>
378    *       The format is a {@doc juneau-marshall.JsonDetails.SimplifiedJson} object.
379    *    <li>
380    *       The leading/trailing <code>{ }</code> characters are optional.
381    *       <br>The following two example are considered equivalent:
382    *       <p class='bcode w800'>
383    *    <ja>@Response</ja>(api=<js>"{description: 'Redirect'}"</js>)
384    *       </p>
385    *       <p class='bcode w800'>
386    *    <ja>@Response</ja>(api=<js>"description: 'Redirect''"</js>)
387    *       </p>
388    *    <li>
389    *       Multiple lines are concatenated with newlines so that you can format the value to be readable.
390    *    <li>
391    *       Supports {@doc DefaultRestSvlVariables}
392    *       (e.g. <js>"$L{my.localized.variable}"</js>).
393    *    <li>
394    *       Values defined in this field supersede values pulled from the Swagger JSON file and are superseded by individual values defined on this annotation.
395    * </ul>
396    */
397   String[] api() default {};
398}