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.jsonschema.annotation;
014
015import static java.lang.annotation.RetentionPolicy.*;
016
017import java.lang.annotation.*;
018
019import org.apache.juneau.oapi.*;
020
021/**
022 * Swagger items annotation.
023 *
024 * <p>
025 * A limited subset of JSON-Schema's items object.
026 *
027 * <p>
028 * Used to populate the auto-generated Swagger documentation and UI for server-side <ja>@RestResource</ja>-annotated classes.
029 * <br>Also used to define OpenAPI schema information for POJOs serialized through {@link OpenApiSerializer} and parsed through {@link OpenApiParser}.
030 *
031 * <h5 class='section'>Examples:</h5>
032 * <p class='bcode w800'>
033 *    <jc>// Items have a specific set of enumerated string values</jc>
034 *    <ja>@Query</ja>(
035 *       name=<js>"status"</js>,
036 *       type=<js>"array"</js>,
037 *       collectionFormat=<js>"csv"</js>,
038 *       items=<ja>@Items</ja>(
039 *          type=<js>"string"</js>,
040 *          _enum=<js>"AVAILABLE,PENDING,SOLD"</js>,
041 *          _default=<js>"AVAILABLE"</js>
042 *    )
043 *    )
044 * </p>
045 * <p class='bcode w800'>
046 *    <jc>// Same but defined free-form</jc>
047 *    <ja>@Query</ja>(
048 *       name=<js>"status"</js>,
049 *       type=<js>"array"</js>,
050 *       collectionFormat=<js>"csv"</js>,
051 *       items=<ja>@Items</ja>({
052 *          <js>"type:'string',"</js>,
053 *          <js>"enum:'AVAILABLE,PENDING,SOLD',"</js>,
054 *          <js>"default:'AVAILABLE'"</js>
055 *    })
056 *    )
057 * </p>
058 * <p class='bcode w800'>
059 *    <jc>// An array of arrays, the internal array being of type integer, numbers must be between 0 and 63 (inclusive)</jc>
060 *    <ja>@Query</ja>(
061 *       name=<js>"status"</js>,
062 *       type=<js>"array"</js>,
063 *       collectionFormat=<js>"csv"</js>,
064 *       items=<ja>@Items</ja>(
065 *          type=<js>"array"</js>,
066 *          items=<ja>@SubItems</ja>(
067 *             type=<js>"integer"</js>,
068 *             minimum=<js>"0"</js>,
069 *             maximum=<js>"63"</js>
070 *          )
071 *    )
072 *    )
073 * </p>
074 *
075 * <ul class='seealso'>
076 *    <li class='link'>{@doc juneau-rest-server.Swagger}
077 *    <li class='extlink'>{@doc SwaggerItemsObject}
078 * </ul>
079 */
080@Documented
081@Retention(RUNTIME)
082public @interface Items {
083
084   /**
085    * <mk>type</mk> field of the {@doc SwaggerItemsObject}.
086    *
087    * <ul class='notes'>
088    *    <li>
089    *       The format is a plain-text string.
090    *    <li>
091    *       Supports {@doc DefaultRestSvlVariables}
092    *       (e.g. <js>"$L{my.localized.variable}"</js>).
093    * </ul>
094    */
095   String type() default "";
096
097   /**
098    * <mk>format</mk> field of the {@doc SwaggerItemsObject}.
099    *
100    * <ul class='notes'>
101    *    <li>
102    *       The format is a plain-text string.
103    *    <li>
104    *       Supports {@doc DefaultRestSvlVariables}
105    *       (e.g. <js>"$L{my.localized.variable}"</js>).
106    * </ul>
107    */
108   String format() default "";
109
110   /**
111    * <mk>collectionFormat</mk> field of the {@doc SwaggerItemsObject}.
112    *
113    * <ul class='notes'>
114    *    <li>
115    *       The format is a plain-text string.
116    *    <li>
117    *       Supports {@doc DefaultRestSvlVariables}
118    *       (e.g. <js>"$L{my.localized.variable}"</js>).
119    * </ul>
120    */
121   String collectionFormat() default "";
122
123   /**
124    * <mk>pattern</mk> field of the {@doc SwaggerItemsObject}.
125    *
126    * <ul class='notes'>
127    *    <li>
128    *       The format is a plain-text string.
129    *    <li>
130    *       Supports {@doc DefaultRestSvlVariables}
131    *       (e.g. <js>"$L{my.localized.variable}"</js>).
132    * </ul>
133    */
134   String pattern() default "";
135
136   /**
137    * <mk>maximum</mk> field of the {@doc SwaggerItemsObject}.
138    *
139    * <ul class='notes'>
140    *    <li>
141    *       The format is a plain-text string.
142    *    <li>
143    *       Supports {@doc DefaultRestSvlVariables}
144    *       (e.g. <js>"$L{my.localized.variable}"</js>).
145    * </ul>
146    */
147   String maximum() default "";
148
149   /**
150    * <mk>minimum</mk> field of the {@doc SwaggerItemsObject}.
151    *
152    * <ul class='notes'>
153    *    <li>
154    *       The format is a plain-text string.
155    *    <li>
156    *       Supports {@doc DefaultRestSvlVariables}
157    *       (e.g. <js>"$L{my.localized.variable}"</js>).
158    * </ul>
159    */
160   String minimum() default "";
161
162   /**
163    * <mk>multipleOf</mk> field of the {@doc SwaggerItemsObject}.
164    *
165    * <ul class='notes'>
166    *    <li>
167    *       The format is a plain-text string.
168    *    <li>
169    *       Supports {@doc DefaultRestSvlVariables}
170    *       (e.g. <js>"$L{my.localized.variable}"</js>).
171    * </ul>
172    */
173   String multipleOf() default "";
174
175   /**
176    * <mk>maxLength</mk> field of the {@doc SwaggerItemsObject}.
177    *
178    * <ul class='notes'>
179    *    <li>
180    *       The format is a plain-text string.
181    *    <li>
182    *       Supports {@doc DefaultRestSvlVariables}
183    *       (e.g. <js>"$L{my.localized.variable}"</js>).
184    * </ul>
185    */
186   long maxLength() default -1;
187
188   /**
189    * <mk>minLength</mk> field of the {@doc SwaggerItemsObject}.
190    *
191    * <ul class='notes'>
192    *    <li>
193    *       The format is a plain-text string.
194    *    <li>
195    *       Supports {@doc DefaultRestSvlVariables}
196    *       (e.g. <js>"$L{my.localized.variable}"</js>).
197    * </ul>
198    */
199   long minLength() default -1;
200
201   /**
202    * <mk>maxItems</mk> field of the {@doc SwaggerItemsObject}.
203    *
204    * <ul class='notes'>
205    *    <li>
206    *       The format is a plain-text string.
207    *    <li>
208    *       Supports {@doc DefaultRestSvlVariables}
209    *       (e.g. <js>"$L{my.localized.variable}"</js>).
210    * </ul>
211    */
212   long maxItems() default -1;
213
214   /**
215    * <mk>minItems</mk> field of the {@doc SwaggerItemsObject}.
216    *
217    * <ul class='notes'>
218    *    <li>
219    *       The format is a plain-text string.
220    *    <li>
221    *       Supports {@doc DefaultRestSvlVariables}
222    *       (e.g. <js>"$L{my.localized.variable}"</js>).
223    * </ul>
224    */
225   long minItems() default -1;
226
227   /**
228    * <mk>exclusiveMaximum</mk> field of the {@doc SwaggerItemsObject}.
229    *
230    * <ul class='notes'>
231    *    <li>
232    *       The format is a plain-text string.
233    *    <li>
234    *       Supports {@doc DefaultRestSvlVariables}
235    *       (e.g. <js>"$L{my.localized.variable}"</js>).
236    * </ul>
237    */
238   boolean exclusiveMaximum() default false;
239
240   /**
241    * <mk>exclusiveMinimum</mk> field of the {@doc SwaggerItemsObject}.
242    *
243    * <ul class='notes'>
244    *    <li>
245    *       The format is a plain-text string.
246    *    <li>
247    *       Supports {@doc DefaultRestSvlVariables}
248    *       (e.g. <js>"$L{my.localized.variable}"</js>).
249    * </ul>
250    */
251   boolean exclusiveMinimum() default false;
252
253   /**
254    * <mk>uniqueItems</mk> field of the {@doc SwaggerItemsObject}.
255    *
256    * <ul class='notes'>
257    *    <li>
258    *       The format is a plain-text string.
259    *    <li>
260    *       Supports {@doc DefaultRestSvlVariables}
261    *       (e.g. <js>"$L{my.localized.variable}"</js>).
262    * </ul>
263    */
264   boolean uniqueItems() default false;
265
266   /**
267    * <mk>default</mk> field of the {@doc SwaggerItemsObject}.
268    *
269    * <ul class='notes'>
270    *    <li>
271    *       The format is a plain-text string.
272    *    <li>
273    *       Supports {@doc DefaultRestSvlVariables}
274    *       (e.g. <js>"$L{my.localized.variable}"</js>).
275    * </ul>
276    */
277   String[] _default() default {};
278
279   /**
280    * <mk>enum</mk> field of the {@doc SwaggerItemsObject}.
281    *
282    * <ul class='notes'>
283    *    <li>
284    *       The format is a plain-text string.
285    *    <li>
286    *       Supports {@doc DefaultRestSvlVariables}
287    *       (e.g. <js>"$L{my.localized.variable}"</js>).
288    * </ul>
289    */
290   String[] _enum() default {};
291
292   /**
293    * <mk>$ref</mk> field of the {@doc SwaggerItemsObject}.
294    *
295    * <ul class='notes'>
296    *    <li>
297    *       The format is a plain-text string.
298    *    <li>
299    *       Supports {@doc DefaultRestSvlVariables}
300    *       (e.g. <js>"$L{my.localized.variable}"</js>).
301    * </ul>
302    */
303   String $ref() default "";
304
305   /**
306    * <mk>items</mk> field of the {@doc SwaggerItemsObject}.
307    *
308    * <p>
309    * Describes the type of items in the array.
310    */
311   SubItems items() default @SubItems;
312
313   /**
314    * Free-form value for the {@doc SwaggerItemsObject}.
315    *
316    * <p>
317    * This is a {@doc SimpleJson} object that makes up the swagger information for this field.
318    *
319    * <p>
320    * The following are completely equivalent ways of defining the swagger description of an Items object:
321    * <p class='bcode w800'>
322    *    <jc>// Normal</jc>
323    *    <ja>@Query</ja>(
324    *       name=<js>"status"</js>,
325    *       type=<js>"array"</js>,
326    *       items=<ja>@Items</ja>(
327    *          type=<js>"string"</js>,
328    *          _enum=<js>"AVAILABLE,PENDING,SOLD"</js>,
329    *          _default=<js>"AVAILABLE"</js>
330    *       )
331    *    )
332    * </p>
333    * <p class='bcode w800'>
334    *    <jc>// Free-form</jc>
335    *    <ja>@Query</ja>(
336    *       name=<js>"status"</js>,
337    *       type=<js>"array"</js>,
338    *       items=<ja>@Items</ja>({
339    *          <js>"type: 'string'"</js>,
340    *          <js>"enum: ['AVAILABLE','PENDING','SOLD'],"</js>,
341    *          <js>"default: 'AVAILABLE'"</js>
342    *       })
343    *    )
344    * </p>
345    * <p class='bcode w800'>
346    *    <jc>// Free-form as part of parent</jc>
347    *    <ja>@Query</ja>(
348    *       name=<js>"status"</js>,
349    *       api={
350    *          <js>"type:'array',"</js>,
351    *          <js>"items: {"</js>,
352    *             <js>"type: 'string',"</js>,
353    *             <js>"enum: ['AVAILABLE','PENDING','SOLD'],"</js>,
354    *             <js>"default: 'AVAILABLE'"</js>,
355    *          <js>"}"</js>)
356    *       }
357    *    )
358    * </p>
359    * <p class='bcode w800'>
360    *    <jc>// Free-form with variables</jc>
361    *    <ja>@Query</ja>(
362    *       name=<js>"status"</js>,
363    *       type=<js>"array"</js>,
364    *       items=<ja>@Items</ja>(<js>"$L{statusItemsSwagger}"</js>)
365    *    )
366    * </p>
367    * <p class='bcode w800'>
368    *    <mc>// Contents of MyResource.properties</mc>
369    *    <mk>statusItemsSwagger</mk> = <mv>{ type: "string", enum: ["AVAILABLE","PENDING","SOLD"], default: "AVAILABLE" }</mv>
370    * </p>
371    *
372    * <p>
373    *    The reasons why you may want to use this field include:
374    * <ul>
375    *    <li>You want to pull in the entire Swagger JSON definition for this field from an external source such as a properties file.
376    *    <li>You want to add extra fields to the Swagger documentation that are not officially part of the Swagger specification.
377    * </ul>
378    *
379    * <ul class='notes'>
380    *    <li>
381    *       Note that the only swagger field you can't specify using this value is <js>"name"</js> whose value needs to be known during servlet initialization.
382    *    <li>
383    *       The format is a {@doc SimpleJson} object.
384    *    <li>
385    *       The leading/trailing <c>{ }</c> characters are optional.
386    *       <br>The following two example are considered equivalent:
387    *       <p class='bcode w800'>
388    *    <ja>@Items</ja>(api=<js>"{type: 'string'}"</js>)
389    *       </p>
390    *       <p class='bcode w800'>
391    *    <ja>@Items</ja>(api=<js>"type: 'string'"</js>)
392    *       </p>
393    *    <li>
394    *       Multiple lines are concatenated with newlines so that you can format the value to be readable.
395    *    <li>
396    *       Supports {@doc DefaultRestSvlVariables}
397    *       (e.g. <js>"$L{my.localized.variable}"</js>).
398    *    <li>
399    *       Values defined in this field supersede values pulled from the Swagger JSON file and are superseded by individual values defined on this annotation.
400    * </ul>
401    */
402   String[] value() default {};
403}