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