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.annotation;
014
015import static java.lang.annotation.ElementType.*;
016import static java.lang.annotation.RetentionPolicy.*;
017import static org.apache.juneau.internal.ArrayUtils.*;
018import static org.apache.juneau.jsonschema.SchemaUtils.*;
019
020import java.lang.annotation.*;
021import java.lang.reflect.*;
022import java.util.*;
023import java.util.function.*;
024
025import org.apache.juneau.*;
026import org.apache.juneau.collections.*;
027import org.apache.juneau.common.internal.*;
028import org.apache.juneau.internal.*;
029import org.apache.juneau.parser.*;
030import org.apache.juneau.reflect.*;
031import org.apache.juneau.svl.*;
032
033/**
034 * Utility classes and methods for the {@link Schema @Schema} annotation.
035 *
036 * <h5 class='section'>See Also:</h5><ul>
037 * </ul>
038 */
039public class SchemaAnnotation {
040
041   //-----------------------------------------------------------------------------------------------------------------
042   // Static
043   //-----------------------------------------------------------------------------------------------------------------
044
045   /** Default value */
046   public static final Schema DEFAULT = create().build();
047
048   /**
049    * Instantiates a new builder for this class.
050    *
051    * @return A new builder object.
052    */
053   public static Builder create() {
054      return new Builder();
055   }
056
057   /**
058    * Instantiates a new builder for this class.
059    *
060    * @param on The targets this annotation applies to.
061    * @return A new builder object.
062    */
063   public static Builder create(Class<?>...on) {
064      return create().on(on);
065   }
066
067   /**
068    * Instantiates a new builder for this class.
069    *
070    * @param on The targets this annotation applies to.
071    * @return A new builder object.
072    */
073   public static Builder create(String...on) {
074      return create().on(on);
075   }
076
077   /**
078    * Returns <jk>true</jk> if the specified annotation contains all default values.
079    *
080    * @param a The annotation to check.
081    * @return <jk>true</jk> if the specified annotation contains all default values.
082    */
083   public static boolean empty(Schema a) {
084      return a == null || DEFAULT.equals(a);
085   }
086
087   /**
088    * Converts the specified <ja>@Schema</ja> annotation into a generic map.
089    *
090    * @param a The annotation instance.  Can be <jk>null</jk>.
091    * @return The schema converted to a map, or and empty map if the annotation was null.
092    * @throws ParseException Malformed input encountered.
093    */
094   public static JsonMap asMap(Schema a) throws ParseException {
095      if (a == null)
096         return JsonMap.EMPTY_MAP;
097      JsonMap m = new JsonMap();
098      if (SchemaAnnotation.empty(a))
099         return m;
100      Predicate<String> ne = StringUtils::isNotEmpty;
101      Predicate<Collection<?>> nec = CollectionUtils::isNotEmpty;
102      Predicate<Map<?,?>> nem = CollectionUtils::isNotEmpty;
103      Predicate<Boolean> nf = ObjectUtils::isTrue;
104      Predicate<Long> nm1 = ObjectUtils::isNotMinusOne;
105      return m
106         .appendIf(nem, "additionalProperties", parseMap(a.additionalProperties()))
107         .appendIf(ne, "allOf", joinnl(a.allOf()))
108         .appendFirst(ne, "collectionFormat", a.collectionFormat(), a.cf())
109         .appendIf(ne, "default", joinnl(a._default(), a.df()))
110         .appendIf(ne, "discriminator", a.discriminator())
111         .appendIf(ne, "description", joinnl(a.description(), a.d()))
112         .appendFirst(nec, "enum", parseSet(a._enum()), parseSet(a.e()))
113         .appendIf(nf, "exclusiveMaximum", a.exclusiveMaximum() || a.emax())
114         .appendIf(nf, "exclusiveMinimum", a.exclusiveMinimum() || a.emin())
115         .appendIf(nem, "externalDocs", ExternalDocsAnnotation.merge(m.getMap("externalDocs"), a.externalDocs()))
116         .appendFirst(ne, "format", a.format(), a.f())
117         .appendIf(ne, "ignore", a.ignore() ? "true" : null)
118         .appendIf(nem, "items", merge(m.getMap("items"), a.items()))
119         .appendFirst(ne, "maximum", a.maximum(), a.max())
120         .appendFirst(nm1, "maxItems", a.maxItems(), a.maxi())
121         .appendFirst(nm1, "maxLength", a.maxLength(), a.maxl())
122         .appendFirst(nm1, "maxProperties", a.maxProperties(), a.maxp())
123         .appendFirst(ne, "minimum", a.minimum(), a.min())
124         .appendFirst(nm1, "minItems", a.minItems(), a.mini())
125         .appendFirst(nm1, "minLength", a.minLength(), a.minl())
126         .appendFirst(nm1, "minProperties", a.minProperties(), a.minp())
127         .appendFirst(ne, "multipleOf", a.multipleOf(), a.mo())
128         .appendFirst(ne, "pattern", a.pattern(), a.p())
129         .appendIf(nem, "properties", parseMap(a.properties()))
130         .appendIf(nf, "readOnly", a.readOnly() || a.ro())
131         .appendIf(nf, "required", a.required() || a.r())
132         .appendIf(ne, "title", a.title())
133         .appendFirst(ne, "type", a.type(), a.t())
134         .appendIf(nf, "uniqueItems", a.uniqueItems() || a.ui())
135         .appendIf(ne, "xml", joinnl(a.xml()))
136         .appendIf(ne, "$ref", a.$ref())
137      ;
138   }
139
140   private static JsonMap merge(JsonMap m, Items a) throws ParseException {
141      if (ItemsAnnotation.empty(a))
142         return m;
143      Predicate<String> ne = StringUtils::isNotEmpty;
144      Predicate<Collection<?>> nec = CollectionUtils::isNotEmpty;
145      Predicate<Map<?,?>> nem = CollectionUtils::isNotEmpty;
146      Predicate<Boolean> nf = ObjectUtils::isTrue;
147      Predicate<Long> nm1 = ObjectUtils::isNotMinusOne;
148      return m
149         .appendFirst(ne, "collectionFormat", a.collectionFormat(), a.cf())
150         .appendIf(ne, "default", joinnl(a._default(), a.df()))
151         .appendFirst(nec, "enum", parseSet(a._enum()), parseSet(a.e()))
152         .appendFirst(ne, "format", a.format(), a.f())
153         .appendIf(nf, "exclusiveMaximum", a.exclusiveMaximum() || a.emax())
154         .appendIf(nf, "exclusiveMinimum", a.exclusiveMinimum() || a.emin())
155         .appendIf(nem, "items", SubItemsAnnotation.merge(m.getMap("items"), a.items()))
156         .appendFirst(ne, "maximum", a.maximum(), a.max())
157         .appendFirst(nm1, "maxItems", a.maxItems(), a.maxi())
158         .appendFirst(nm1, "maxLength", a.maxLength(), a.maxl())
159         .appendFirst(ne, "minimum", a.minimum(), a.min())
160         .appendFirst(nm1, "minItems", a.minItems(), a.mini())
161         .appendFirst(nm1, "minLength", a.minLength(), a.minl())
162         .appendFirst(ne, "multipleOf", a.multipleOf(), a.mo())
163         .appendFirst(ne, "pattern", a.pattern(), a.p())
164         .appendIf(nf, "uniqueItems", a.uniqueItems() || a.ui())
165         .appendFirst(ne, "type", a.type(), a.t())
166         .appendIf(ne, "$ref", a.$ref())
167      ;
168   }
169
170   //-----------------------------------------------------------------------------------------------------------------
171   // Builder
172   //-----------------------------------------------------------------------------------------------------------------
173
174   /**
175    * Builder class.
176    *
177    * <h5 class='section'>See Also:</h5><ul>
178    *    <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#annotations(Annotation...)}
179    * </ul>
180    */
181   public static class Builder extends TargetedAnnotationTMFBuilder {
182
183      boolean aev, allowEmptyValue, emax, emin, exclusiveMaximum, exclusiveMinimum, ignore, r, readOnly, required, ro, sie, skipIfEmpty, ui, uniqueItems;
184      ExternalDocs externalDocs=ExternalDocsAnnotation.DEFAULT;
185      Items items=ItemsAnnotation.DEFAULT;
186      long maxi=-1, maxItems=-1, maxl=-1, maxLength=-1, maxp=-1, maxProperties=-1, mini=-1, minItems=-1, minl=-1, minLength=-1, minp=-1, minProperties=-1;
187      String $ref="", cf="", collectionFormat="", discriminator="", f="", format="", max="", maximum="", min="", minimum="", mo="", multipleOf="", p="", pattern="", t="", title="", type="";
188      String[] _default={}, _enum={}, additionalProperties={}, allOf={}, d={}, description={}, df={}, e={}, properties={}, value={}, xml={};
189
190      /**
191       * Constructor.
192       */
193      protected Builder() {
194         super(Schema.class);
195      }
196
197      /**
198       * Instantiates a new {@link Schema @Schema} object initialized with this builder.
199       *
200       * @return A new {@link Schema @Schema} object.
201       */
202      public Schema build() {
203         return new Impl(this);
204      }
205
206      /**
207       * Sets the {@link Schema#_default} property on this annotation.
208       *
209       * @param value The new value for this property.
210       * @return This object.
211       */
212      public Builder _default(String...value) {
213         this._default = value;
214         return this;
215      }
216
217      /**
218       * Sets the {@link Schema#_enum} property on this annotation.
219       *
220       * @param value The new value for this property.
221       * @return This object.
222       */
223      public Builder _enum(String...value) {
224         this._enum = value;
225         return this;
226      }
227
228      /**
229       * Sets the {@link Schema#$ref} property on this annotation.
230       *
231       * @param value The new value for this property.
232       * @return This object.
233       */
234      public Builder $ref(String value) {
235         this.$ref = value;
236         return this;
237      }
238
239      /**
240       * Sets the {@link Schema#additionalProperties} property on this annotation.
241       *
242       * @param value The new value for this property.
243       * @return This object.
244       */
245      public Builder additionalProperties(String...value) {
246         this.additionalProperties = value;
247         return this;
248      }
249
250      /**
251       * Sets the {@link Schema#allOf} property on this annotation.
252       *
253       * @param value The new value for this property.
254       * @return This object.
255       */
256      public Builder allOf(String...value) {
257         this.allOf = value;
258         return this;
259      }
260
261      /**
262       * Sets the {@link Schema#aev} property on this annotation.
263       *
264       * @param value The new value for this property.
265       * @return This object.
266       */
267      public Builder aev(boolean value) {
268         this.aev = value;
269         return this;
270      }
271
272      /**
273       * Sets the {@link Schema#allowEmptyValue} property on this annotation.
274       *
275       * @param value The new value for this property.
276       * @return This object.
277       */
278      public Builder allowEmptyValue(boolean value) {
279         this.allowEmptyValue = value;
280         return this;
281      }
282
283      /**
284       * Sets the {@link Schema#cf} property on this annotation.
285       *
286       * @param value The new value for this property.
287       * @return This object.
288       */
289      public Builder cf(String value) {
290         this.cf = value;
291         return this;
292      }
293
294      /**
295       * Sets the {@link Schema#collectionFormat} property on this annotation.
296       *
297       * @param value The new value for this property.
298       * @return This object.
299       */
300      public Builder collectionFormat(String value) {
301         this.collectionFormat = value;
302         return this;
303      }
304
305      /**
306       * Sets the {@link Schema#d} property on this annotation.
307       *
308       * @param value The new value for this property.
309       * @return This object.
310       */
311      public Builder d(String...value) {
312         this.d = value;
313         return this;
314      }
315
316      /**
317       * Sets the {@link Schema#description} property on this annotation.
318       *
319       * @param value The new value for this property.
320       * @return This object.
321       */
322      public Builder description(String...value) {
323         this.description = value;
324         return this;
325      }
326
327      /**
328       * Sets the {@link Schema#df} property on this annotation.
329       *
330       * @param value The new value for this property.
331       * @return This object.
332       */
333      public Builder df(String...value) {
334         this.df = value;
335         return this;
336      }
337
338      /**
339       * Sets the {@link Schema#discriminator} property on this annotation.
340       *
341       * @param value The new value for this property.
342       * @return This object.
343       */
344      public Builder discriminator(String value) {
345         this.discriminator = value;
346         return this;
347      }
348
349      /**
350       * Sets the {@link Schema#e} property on this annotation.
351       *
352       * @param value The new value for this property.
353       * @return This object.
354       */
355      public Builder e(String...value) {
356         this.e = value;
357         return this;
358      }
359
360      /**
361       * Sets the {@link Schema#emax} property on this annotation.
362       *
363       * @param value The new value for this property.
364       * @return This object.
365       */
366      public Builder emax(boolean value) {
367         this.emax = value;
368         return this;
369      }
370
371      /**
372       * Sets the {@link Schema#emin} property on this annotation.
373       *
374       * @param value The new value for this property.
375       * @return This object.
376       */
377      public Builder emin(boolean value) {
378         this.emin = value;
379         return this;
380      }
381
382      /**
383       * Sets the {@link Schema#exclusiveMaximum} property on this annotation.
384       *
385       * @param value The new value for this property.
386       * @return This object.
387       */
388      public Builder exclusiveMaximum(boolean value) {
389         this.exclusiveMaximum = value;
390         return this;
391      }
392
393      /**
394       * Sets the {@link Schema#exclusiveMinimum} property on this annotation.
395       *
396       * @param value The new value for this property.
397       * @return This object.
398       */
399      public Builder exclusiveMinimum(boolean value) {
400         this.exclusiveMinimum = value;
401         return this;
402      }
403
404      /**
405       * Sets the {@link Schema#externalDocs} property on this annotation.
406       *
407       * @param value The new value for this property.
408       * @return This object.
409       */
410      public Builder externalDocs(ExternalDocs value) {
411         this.externalDocs = value;
412         return this;
413      }
414
415      /**
416       * Sets the {@link Schema#f} property on this annotation.
417       *
418       * @param value The new value for this property.
419       * @return This object.
420       */
421      public Builder f(String value) {
422         this.f = value;
423         return this;
424      }
425
426      /**
427       * Sets the {@link Schema#format} property on this annotation.
428       *
429       * @param value The new value for this property.
430       * @return This object.
431       */
432      public Builder format(String value) {
433         this.format = value;
434         return this;
435      }
436
437      /**
438       * Sets the {@link Schema#ignore} property on this annotation.
439       *
440       * @param value The new value for this property.
441       * @return This object.
442       */
443      public Builder ignore(boolean value) {
444         this.ignore = value;
445         return this;
446      }
447
448      /**
449       * Sets the {@link Schema#items} property on this annotation.
450       *
451       * @param value The new value for this property.
452       * @return This object.
453       */
454      public Builder items(Items value) {
455         this.items = value;
456         return this;
457      }
458
459      /**
460       * Sets the {@link Schema#max} property on this annotation.
461       *
462       * @param value The new value for this property.
463       * @return This object.
464       */
465      public Builder max(String value) {
466         this.max = value;
467         return this;
468      }
469
470      /**
471       * Sets the {@link Schema#maxi} property on this annotation.
472       *
473       * @param value The new value for this property.
474       * @return This object.
475       */
476      public Builder maxi(long value) {
477         this.maxi = value;
478         return this;
479      }
480
481      /**
482       * Sets the {@link Schema#maximum} property on this annotation.
483       *
484       * @param value The new value for this property.
485       * @return This object.
486       */
487      public Builder maximum(String value) {
488         this.maximum = value;
489         return this;
490      }
491
492      /**
493       * Sets the {@link Schema#maxItems} property on this annotation.
494       *
495       * @param value The new value for this property.
496       * @return This object.
497       */
498      public Builder maxItems(long value) {
499         this.maxItems = value;
500         return this;
501      }
502
503      /**
504       * Sets the {@link Schema#maxl} property on this annotation.
505       *
506       * @param value The new value for this property.
507       * @return This object.
508       */
509      public Builder maxl(long value) {
510         this.maxl = value;
511         return this;
512      }
513
514      /**
515       * Sets the {@link Schema#maxLength} property on this annotation.
516       *
517       * @param value The new value for this property.
518       * @return This object.
519       */
520      public Builder maxLength(long value) {
521         this.maxLength = value;
522         return this;
523      }
524
525      /**
526       * Sets the {@link Schema#maxp} property on this annotation.
527       *
528       * @param value The new value for this property.
529       * @return This object.
530       */
531      public Builder maxp(long value) {
532         this.maxp = value;
533         return this;
534      }
535
536      /**
537       * Sets the {@link Schema#maxProperties} property on this annotation.
538       *
539       * @param value The new value for this property.
540       * @return This object.
541       */
542      public Builder maxProperties(long value) {
543         this.maxProperties = value;
544         return this;
545      }
546
547      /**
548       * Sets the {@link Schema#min} property on this annotation.
549       *
550       * @param value The new value for this property.
551       * @return This object.
552       */
553      public Builder min(String value) {
554         this.min = value;
555         return this;
556      }
557
558      /**
559       * Sets the {@link Schema#mini} property on this annotation.
560       *
561       * @param value The new value for this property.
562       * @return This object.
563       */
564      public Builder mini(long value) {
565         this.mini = value;
566         return this;
567      }
568
569      /**
570       * Sets the {@link Schema#minimum} property on this annotation.
571       *
572       * @param value The new value for this property.
573       * @return This object.
574       */
575      public Builder minimum(String value) {
576         this.minimum = value;
577         return this;
578      }
579
580      /**
581       * Sets the {@link Schema#minItems} property on this annotation.
582       *
583       * @param value The new value for this property.
584       * @return This object.
585       */
586      public Builder minItems(long value) {
587         this.minItems = value;
588         return this;
589      }
590
591      /**
592       * Sets the {@link Schema#minl} property on this annotation.
593       *
594       * @param value The new value for this property.
595       * @return This object.
596       */
597      public Builder minl(long value) {
598         this.minl = value;
599         return this;
600      }
601
602      /**
603       * Sets the {@link Schema#minLength} property on this annotation.
604       *
605       * @param value The new value for this property.
606       * @return This object.
607       */
608      public Builder minLength(long value) {
609         this.minLength = value;
610         return this;
611      }
612
613      /**
614       * Sets the {@link Schema#minp} property on this annotation.
615       *
616       * @param value The new value for this property.
617       * @return This object.
618       */
619      public Builder minp(long value) {
620         this.minp = value;
621         return this;
622      }
623
624      /**
625       * Sets the {@link Schema#minProperties} property on this annotation.
626       *
627       * @param value The new value for this property.
628       * @return This object.
629       */
630      public Builder minProperties(long value) {
631         this.minProperties = value;
632         return this;
633      }
634
635      /**
636       * Sets the {@link Schema#mo} property on this annotation.
637       *
638       * @param value The new value for this property.
639       * @return This object.
640       */
641      public Builder mo(String value) {
642         this.mo = value;
643         return this;
644      }
645
646      /**
647       * Sets the {@link Schema#multipleOf} property on this annotation.
648       *
649       * @param value The new value for this property.
650       * @return This object.
651       */
652      public Builder multipleOf(String value) {
653         this.multipleOf = value;
654         return this;
655      }
656
657      /**
658       * Sets the {@link Schema#p} property on this annotation.
659       *
660       * @param value The new value for this property.
661       * @return This object.
662       */
663      public Builder p(String value) {
664         this.p = value;
665         return this;
666      }
667
668      /**
669       * Sets the {@link Schema#pattern} property on this annotation.
670       *
671       * @param value The new value for this property.
672       * @return This object.
673       */
674      public Builder pattern(String value) {
675         this.pattern = value;
676         return this;
677      }
678
679      /**
680       * Sets the {@link Schema#properties} property on this annotation.
681       *
682       * @param value The new value for this property.
683       * @return This object.
684       */
685      public Builder properties(String...value) {
686         this.properties = value;
687         return this;
688      }
689
690      /**
691       * Sets the {@link Schema#r} property on this annotation.
692       *
693       * @param value The new value for this property.
694       * @return This object.
695       */
696      public Builder r(boolean value) {
697         this.r = value;
698         return this;
699      }
700
701      /**
702       * Sets the {@link Schema#readOnly} property on this annotation.
703       *
704       * @param value The new value for this property.
705       * @return This object.
706       */
707      public Builder readOnly(boolean value) {
708         this.readOnly = value;
709         return this;
710      }
711
712      /**
713       * Sets the {@link Schema#required} property on this annotation.
714       *
715       * @param value The new value for this property.
716       * @return This object.
717       */
718      public Builder required(boolean value) {
719         this.required = value;
720         return this;
721      }
722
723      /**
724       * Sets the {@link Schema#ro} property on this annotation.
725       *
726       * @param value The new value for this property.
727       * @return This object.
728       */
729      public Builder ro(boolean value) {
730         this.ro = value;
731         return this;
732      }
733
734      /**
735       * Sets the {@link Schema#sie} property on this annotation.
736       *
737       * @param value The new value for this property.
738       * @return This object.
739       */
740      public Builder sie(boolean value) {
741         this.sie = value;
742         return this;
743      }
744
745      /**
746       * Sets the {@link Schema#skipIfEmpty} property on this annotation.
747       *
748       * @param value The new value for this property.
749       * @return This object.
750       */
751      public Builder skipIfEmpty(boolean value) {
752         this.skipIfEmpty = value;
753         return this;
754      }
755
756      /**
757       * Sets the {@link Schema#t} property on this annotation.
758       *
759       * @param value The new value for this property.
760       * @return This object.
761       */
762      public Builder t(String value) {
763         this.t = value;
764         return this;
765      }
766
767      /**
768       * Sets the {@link Schema#title} property on this annotation.
769       *
770       * @param value The new value for this property.
771       * @return This object.
772       */
773      public Builder title(String value) {
774         this.title = value;
775         return this;
776      }
777
778      /**
779       * Sets the {@link Schema#type} property on this annotation.
780       *
781       * @param value The new value for this property.
782       * @return This object.
783       */
784      public Builder type(String value) {
785         this.type = value;
786         return this;
787      }
788
789      /**
790       * Sets the {@link Schema#ui} property on this annotation.
791       *
792       * @param value The new value for this property.
793       * @return This object.
794       */
795      public Builder ui(boolean value) {
796         this.ui = value;
797         return this;
798      }
799
800      /**
801       * Sets the {@link Schema#uniqueItems} property on this annotation.
802       *
803       * @param value The new value for this property.
804       * @return This object.
805       */
806      public Builder uniqueItems(boolean value) {
807         this.uniqueItems = value;
808         return this;
809      }
810
811      /**
812       * Sets the {@link Schema#xml} property on this annotation.
813       *
814       * @param value The new value for this property.
815       * @return This object.
816       */
817      public Builder xml(String...value) {
818         this.xml = value;
819         return this;
820      }
821
822      // <FluentSetters>
823
824      @Override /* GENERATED - TargetedAnnotationBuilder */
825      public Builder on(String...values) {
826         super.on(values);
827         return this;
828      }
829
830      @Override /* GENERATED - TargetedAnnotationTBuilder */
831      public Builder on(java.lang.Class<?>...value) {
832         super.on(value);
833         return this;
834      }
835
836      @Override /* GENERATED - TargetedAnnotationTBuilder */
837      public Builder onClass(java.lang.Class<?>...value) {
838         super.onClass(value);
839         return this;
840      }
841
842      @Override /* GENERATED - TargetedAnnotationTMFBuilder */
843      public Builder on(Field...value) {
844         super.on(value);
845         return this;
846      }
847
848      @Override /* GENERATED - TargetedAnnotationTMFBuilder */
849      public Builder on(Method...value) {
850         super.on(value);
851         return this;
852      }
853
854      // </FluentSetters>
855   }
856
857   //-----------------------------------------------------------------------------------------------------------------
858   // Implementation
859   //-----------------------------------------------------------------------------------------------------------------
860
861   private static class Impl extends TargetedAnnotationTImpl implements Schema {
862
863      private final boolean aev, allowEmptyValue, exclusiveMaximum, emax, exclusiveMinimum, emin, uniqueItems, ui, required, r, readOnly, ro, sie, skipIfEmpty, ignore;
864      private final ExternalDocs externalDocs;
865      private final Items items;
866      private final long maxLength, maxl, minLength, minl, maxItems, maxi, minItems, mini, maxProperties, maxp, minProperties, minp;
867      private final String $ref, format, f, title, multipleOf, mo, maximum, max, minimum, min, pattern, p, type, t, collectionFormat, cf, discriminator;
868      private final String[] description, d, _default, df, _enum, e, allOf, properties, additionalProperties, xml;
869
870      Impl(Builder b) {
871         super(b);
872         this.$ref = b.$ref;
873         this._default = copyOf(b._default);
874         this._enum = copyOf(b._enum);
875         this.additionalProperties = copyOf(b.additionalProperties);
876         this.allOf = copyOf(b.allOf);
877         this.aev = b.aev;
878         this.allowEmptyValue = b.allowEmptyValue;
879         this.cf = b.cf;
880         this.collectionFormat = b.collectionFormat;
881         this.d = copyOf(b.d);
882         this.description = copyOf(b.description);
883         this.df = copyOf(b.df);
884         this.discriminator = b.discriminator;
885         this.e = copyOf(b.e);
886         this.emax = b.emax;
887         this.emin = b.emin;
888         this.exclusiveMaximum = b.exclusiveMaximum;
889         this.exclusiveMinimum = b.exclusiveMinimum;
890         this.externalDocs = b.externalDocs;
891         this.f = b.f;
892         this.format = b.format;
893         this.ignore = b.ignore;
894         this.items = b.items;
895         this.max = b.max;
896         this.maxi = b.maxi;
897         this.maximum = b.maximum;
898         this.maxItems = b.maxItems;
899         this.maxl = b.maxl;
900         this.maxLength = b.maxLength;
901         this.maxp = b.maxp;
902         this.maxProperties = b.maxProperties;
903         this.min = b.min;
904         this.mini = b.mini;
905         this.minimum = b.minimum;
906         this.minItems = b.minItems;
907         this.minl = b.minl;
908         this.minLength = b.minLength;
909         this.minp = b.minp;
910         this.minProperties = b.minProperties;
911         this.mo = b.mo;
912         this.multipleOf = b.multipleOf;
913         this.p = b.p;
914         this.pattern = b.pattern;
915         this.properties = copyOf(b.properties);
916         this.r = b.r;
917         this.readOnly = b.readOnly;
918         this.required = b.required;
919         this.ro = b.ro;
920         this.sie = b.sie;
921         this.skipIfEmpty = b.skipIfEmpty;
922         this.t = b.t;
923         this.title = b.title;
924         this.type = b.type;
925         this.ui = b.ui;
926         this.uniqueItems = b.uniqueItems;
927         this.xml = copyOf(b.xml);
928         postConstruct();
929      }
930
931      @Override /* Schema */
932      public String[] _default() {
933         return _default;
934      }
935
936      @Override /* Schema */
937      public String[] _enum() {
938         return _enum;
939      }
940
941      @Override /* Schema */
942      public String $ref() {
943         return $ref;
944      }
945
946      @Override /* Schema */
947      public String[] additionalProperties() {
948         return additionalProperties;
949      }
950
951      @Override /* Schema */
952      public String[] allOf() {
953         return allOf;
954      }
955
956      @Override /* Schema */
957      public boolean aev() {
958         return aev;
959      }
960
961      @Override /* Schema */
962      public boolean allowEmptyValue() {
963         return allowEmptyValue;
964      }
965
966      @Override /* Schema */
967      public String cf() {
968         return cf;
969      }
970
971      @Override /* Schema */
972      public String collectionFormat() {
973         return collectionFormat;
974      }
975
976      @Override /* Schema */
977      public String[] d() {
978         return d;
979      }
980
981      @Override /* Schema */
982      public String[] description() {
983         return description;
984      }
985
986      @Override /* Schema */
987      public String[] df() {
988         return df;
989      }
990
991      @Override /* Schema */
992      public String discriminator() {
993         return discriminator;
994      }
995
996      @Override /* Schema */
997      public String[] e() {
998         return e;
999      }
1000
1001      @Override /* Schema */
1002      public boolean emax() {
1003         return emax;
1004      }
1005
1006      @Override /* Schema */
1007      public boolean emin() {
1008         return emin;
1009      }
1010
1011      @Override /* Schema */
1012      public boolean exclusiveMaximum() {
1013         return exclusiveMaximum;
1014      }
1015
1016      @Override /* Schema */
1017      public boolean exclusiveMinimum() {
1018         return exclusiveMinimum;
1019      }
1020
1021      @Override /* Schema */
1022      public ExternalDocs externalDocs() {
1023         return externalDocs;
1024      }
1025
1026      @Override /* Schema */
1027      public String f() {
1028         return f;
1029      }
1030
1031      @Override /* Schema */
1032      public String format() {
1033         return format;
1034      }
1035
1036      @Override /* Schema */
1037      public boolean ignore() {
1038         return ignore;
1039      }
1040
1041      @Override /* Schema */
1042      public Items items() {
1043         return items;
1044      }
1045
1046      @Override /* Schema */
1047      public String max() {
1048         return max;
1049      }
1050
1051      @Override /* Schema */
1052      public long maxi() {
1053         return maxi;
1054      }
1055
1056      @Override /* Schema */
1057      public String maximum() {
1058         return maximum;
1059      }
1060
1061      @Override /* Schema */
1062      public long maxItems() {
1063         return maxItems;
1064      }
1065
1066      @Override /* Schema */
1067      public long maxl() {
1068         return maxl;
1069      }
1070
1071      @Override /* Schema */
1072      public long maxLength() {
1073         return maxLength;
1074      }
1075
1076      @Override /* Schema */
1077      public long maxp() {
1078         return maxp;
1079      }
1080
1081      @Override /* Schema */
1082      public long maxProperties() {
1083         return maxProperties;
1084      }
1085
1086      @Override /* Schema */
1087      public String min() {
1088         return min;
1089      }
1090
1091      @Override /* Schema */
1092      public long mini() {
1093         return mini;
1094      }
1095
1096      @Override /* Schema */
1097      public String minimum() {
1098         return minimum;
1099      }
1100
1101      @Override /* Schema */
1102      public long minItems() {
1103         return minItems;
1104      }
1105
1106      @Override /* Schema */
1107      public long minl() {
1108         return minl;
1109      }
1110
1111      @Override /* Schema */
1112      public long minLength() {
1113         return minLength;
1114      }
1115
1116      @Override /* Schema */
1117      public long minp() {
1118         return minp;
1119      }
1120
1121      @Override /* Schema */
1122      public long minProperties() {
1123         return minProperties;
1124      }
1125
1126      @Override /* Schema */
1127      public String mo() {
1128         return mo;
1129      }
1130
1131      @Override /* Schema */
1132      public String multipleOf() {
1133         return multipleOf;
1134      }
1135
1136      @Override /* Schema */
1137      public String p() {
1138         return p;
1139      }
1140
1141      @Override /* Schema */
1142      public String pattern() {
1143         return pattern;
1144      }
1145
1146      @Override /* Schema */
1147      public String[] properties() {
1148         return properties;
1149      }
1150
1151      @Override /* Schema */
1152      public boolean r() {
1153         return r;
1154      }
1155
1156      @Override /* Schema */
1157      public boolean readOnly() {
1158         return readOnly;
1159      }
1160
1161      @Override /* Schema */
1162      public boolean required() {
1163         return required;
1164      }
1165
1166      @Override /* Schema */
1167      public boolean ro() {
1168         return ro;
1169      }
1170
1171      @Override /* Schema */
1172      public boolean sie() {
1173         return sie;
1174      }
1175
1176      @Override /* Schema */
1177      public boolean skipIfEmpty() {
1178         return skipIfEmpty;
1179      }
1180
1181      @Override /* Schema */
1182      public String t() {
1183         return t;
1184      }
1185
1186      @Override /* Schema */
1187      public String title() {
1188         return title;
1189      }
1190
1191      @Override /* Schema */
1192      public String type() {
1193         return type;
1194      }
1195
1196      @Override /* Schema */
1197      public boolean ui() {
1198         return ui;
1199      }
1200
1201      @Override /* Schema */
1202      public boolean uniqueItems() {
1203         return uniqueItems;
1204      }
1205
1206      @Override /* Schema */
1207      public String[] xml() {
1208         return xml;
1209      }
1210   }
1211
1212   //-----------------------------------------------------------------------------------------------------------------
1213   // Appliers
1214   //-----------------------------------------------------------------------------------------------------------------
1215
1216   /**
1217    * Applies targeted {@link Schema} annotations to a {@link org.apache.juneau.Context.Builder}.
1218    */
1219   public static class Apply extends AnnotationApplier<Schema,Context.Builder> {
1220
1221      /**
1222       * Constructor.
1223       *
1224       * @param vr The resolver for resolving values in annotations.
1225       */
1226      public Apply(VarResolverSession vr) {
1227         super(Schema.class, Context.Builder.class, vr);
1228      }
1229
1230      @Override
1231      public void apply(AnnotationInfo<Schema> ai, Context.Builder b) {
1232         Schema a = ai.inner();
1233         if (isEmptyArray(a.on(), a.onClass()))
1234            return;
1235         b.annotations(a);
1236      }
1237   }
1238
1239   //-----------------------------------------------------------------------------------------------------------------
1240   // Other
1241   //-----------------------------------------------------------------------------------------------------------------
1242
1243   /**
1244    * A collection of {@link Schema @Schema annotations}.
1245    */
1246   @Documented
1247   @Target({METHOD,TYPE})
1248   @Retention(RUNTIME)
1249   @Inherited
1250   public static @interface Array {
1251
1252      /**
1253       * The child annotations.
1254       *
1255       * @return The annotation value.
1256       */
1257      Schema[] value();
1258   }
1259}