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 org.apache.juneau.commons.utils.CollectionUtils.*;
020import static org.apache.juneau.jsonschema.SchemaUtils.*;
021
022import java.lang.annotation.*;
023import java.util.*;
024import java.util.function.*;
025
026import org.apache.juneau.collections.*;
027import org.apache.juneau.commons.annotation.*;
028import org.apache.juneau.commons.utils.*;
029import org.apache.juneau.parser.*;
030
031/**
032 * Utility classes and methods for the {@link SubItems @SubItems} annotation.
033 *
034 */
035public class SubItemsAnnotation {
036   /**
037    * Builder class.
038    *
039    * <h5 class='section'>See Also:</h5><ul>
040    *    <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#annotations(Annotation...)}
041    * </ul>
042    */
043   public static class Builder extends AnnotationObject.Builder {
044
045      private String[] description = {};
046      private String $ref = "", cf = "", collectionFormat = "", f = "", format = "", max = "", maximum = "", min = "", minimum = "", mo = "", multipleOf = "", p = "", pattern = "", t = "",
047         type = "";
048      private long maxItems = -1, maxLength = -1, maxi = -1, maxl = -1, minItems = -1, minLength = -1, mini = -1, minl = -1;
049      private boolean emax, emin, exclusiveMaximum, exclusiveMinimum, ui, uniqueItems;
050      private String[] default_ = {}, enum_ = {}, df = {}, e = {}, items = {};
051
052      /**
053       * Constructor.
054       */
055      protected Builder() {
056         super(SubItems.class);
057      }
058
059      /**
060       * Sets the <c>default_</c> property on this annotation.
061       *
062       * @param value The new value for this property.
063       * @return This object.
064       */
065      public Builder default_(String...value) {
066         default_ = value;
067         return this;
068      }
069
070      /**
071       * Sets the <c>enum_</c> property on this annotation.
072       *
073       * @param value The new value for this property.
074       * @return This object.
075       */
076      public Builder enum_(String...value) {
077         enum_ = value;
078         return this;
079      }
080
081      /**
082       * Sets the <c>$ref</c> property on this annotation.
083       *
084       * @param value The new value for this property.
085       * @return This object.
086       */
087      public Builder $ref(String value) {
088         this.$ref = value;
089         return this;
090      }
091
092      /**
093       * Instantiates a new {@link SubItems @SubItems} object initialized with this builder.
094       *
095       * @return A new {@link SubItems @SubItems} object.
096       */
097      public SubItems build() {
098         return new Object(this);
099      }
100
101      /**
102       * Sets the description property on this annotation.
103       *
104       * @param value The new value for this property.
105       * @return This object.
106       */
107      public Builder description(String...value) {
108         description = value;
109         return this;
110      }
111
112      /**
113       * Sets the <c>cf</c> property on this annotation.
114       *
115       * @param value The new value for this property.
116       * @return This object.
117       */
118      public Builder cf(String value) {
119         cf = value;
120         return this;
121      }
122
123      /**
124       * Sets the <c>collectionFormat</c> property on this annotation.
125       *
126       * @param value The new value for this property.
127       * @return This object.
128       */
129      public Builder collectionFormat(String value) {
130         collectionFormat = value;
131         return this;
132      }
133
134      /**
135       * Sets the <c>df</c> property on this annotation.
136       *
137       * @param value The new value for this property.
138       * @return This object.
139       */
140      public Builder df(String...value) {
141         df = value;
142         return this;
143      }
144
145      /**
146       * Sets the <c>e</c> property on this annotation.
147       *
148       * @param value The new value for this property.
149       * @return This object.
150       */
151      public Builder e(String...value) {
152         e = value;
153         return this;
154      }
155
156      /**
157       * Sets the <c>emax</c> property on this annotation.
158       *
159       * @param value The new value for this property.
160       * @return This object.
161       */
162      public Builder emax(boolean value) {
163         emax = value;
164         return this;
165      }
166
167      /**
168       * Sets the <c>emin</c> property on this annotation.
169       *
170       * @param value The new value for this property.
171       * @return This object.
172       */
173      public Builder emin(boolean value) {
174         emin = value;
175         return this;
176      }
177
178      /**
179       * Sets the <c>exclusiveMaximum</c> property on this annotation.
180       *
181       * @param value The new value for this property.
182       * @return This object.
183       */
184      public Builder exclusiveMaximum(boolean value) {
185         exclusiveMaximum = value;
186         return this;
187      }
188
189      /**
190       * Sets the <c>exclusiveMinimum</c> property on this annotation.
191       *
192       * @param value The new value for this property.
193       * @return This object.
194       */
195      public Builder exclusiveMinimum(boolean value) {
196         exclusiveMinimum = value;
197         return this;
198      }
199
200      /**
201       * Sets the <c>f</c> property on this annotation.
202       *
203       * @param value The new value for this property.
204       * @return This object.
205       */
206      public Builder f(String value) {
207         f = value;
208         return this;
209      }
210
211      /**
212       * Sets the <c>format</c> property on this annotation.
213       *
214       * @param value The new value for this property.
215       * @return This object.
216       */
217      public Builder format(String value) {
218         format = value;
219         return this;
220      }
221
222      /**
223       * Sets the <c>items</c> property on this annotation.
224       *
225       * @param value The new value for this property.
226       * @return This object.
227       */
228      public Builder items(String...value) {
229         items = value;
230         return this;
231      }
232
233      /**
234       * Sets the <c>max</c> property on this annotation.
235       *
236       * @param value The new value for this property.
237       * @return This object.
238       */
239      public Builder max(String value) {
240         max = value;
241         return this;
242      }
243
244      /**
245       * Sets the <c>maxi</c> property on this annotation.
246       *
247       * @param value The new value for this property.
248       * @return This object.
249       */
250      public Builder maxi(long value) {
251         maxi = value;
252         return this;
253      }
254
255      /**
256       * Sets the <c>maximum</c> property on this annotation.
257       *
258       * @param value The new value for this property.
259       * @return This object.
260       */
261      public Builder maximum(String value) {
262         maximum = value;
263         return this;
264      }
265
266      /**
267       * Sets the <c>maxItems</c> property on this annotation.
268       *
269       * @param value The new value for this property.
270       * @return This object.
271       */
272      public Builder maxItems(long value) {
273         maxItems = value;
274         return this;
275      }
276
277      /**
278       * Sets the <c>maxl</c> property on this annotation.
279       *
280       * @param value The new value for this property.
281       * @return This object.
282       */
283      public Builder maxl(long value) {
284         maxl = value;
285         return this;
286      }
287
288      /**
289       * Sets the <c>maxLength</c> property on this annotation.
290       *
291       * @param value The new value for this property.
292       * @return This object.
293       */
294      public Builder maxLength(long value) {
295         maxLength = value;
296         return this;
297      }
298
299      /**
300       * Sets the <c>min</c> property on this annotation.
301       *
302       * @param value The new value for this property.
303       * @return This object.
304       */
305      public Builder min(String value) {
306         min = value;
307         return this;
308      }
309
310      /**
311       * Sets the <c>mini</c> property on this annotation.
312       *
313       * @param value The new value for this property.
314       * @return This object.
315       */
316      public Builder mini(long value) {
317         mini = value;
318         return this;
319      }
320
321      /**
322       * Sets the <c>minimum</c> property on this annotation.
323       *
324       * @param value The new value for this property.
325       * @return This object.
326       */
327      public Builder minimum(String value) {
328         minimum = value;
329         return this;
330      }
331
332      /**
333       * Sets the <c>minItems</c> property on this annotation.
334       *
335       * @param value The new value for this property.
336       * @return This object.
337       */
338      public Builder minItems(long value) {
339         minItems = value;
340         return this;
341      }
342
343      /**
344       * Sets the <c>minl</c> property on this annotation.
345       *
346       * @param value The new value for this property.
347       * @return This object.
348       */
349      public Builder minl(long value) {
350         minl = value;
351         return this;
352      }
353
354      /**
355       * Sets the <c>minLength</c> property on this annotation.
356       *
357       * @param value The new value for this property.
358       * @return This object.
359       */
360      public Builder minLength(long value) {
361         minLength = value;
362         return this;
363      }
364
365      /**
366       * Sets the <c>mo</c> property on this annotation.
367       *
368       * @param value The new value for this property.
369       * @return This object.
370       */
371      public Builder mo(String value) {
372         mo = value;
373         return this;
374      }
375
376      /**
377       * Sets the <c>multipleOf</c> property on this annotation.
378       *
379       * @param value The new value for this property.
380       * @return This object.
381       */
382      public Builder multipleOf(String value) {
383         multipleOf = value;
384         return this;
385      }
386
387      /**
388       * Sets the <c>p</c> property on this annotation.
389       *
390       * @param value The new value for this property.
391       * @return This object.
392       */
393      public Builder p(String value) {
394         p = value;
395         return this;
396      }
397
398      /**
399       * Sets the <c>pattern</c> property on this annotation.
400       *
401       * @param value The new value for this property.
402       * @return This object.
403       */
404      public Builder pattern(String value) {
405         pattern = value;
406         return this;
407      }
408
409      /**
410       * Sets the <c>t</c> property on this annotation.
411       *
412       * @param value The new value for this property.
413       * @return This object.
414       */
415      public Builder t(String value) {
416         t = value;
417         return this;
418      }
419
420      /**
421       * Sets the <c>type</c> property on this annotation.
422       *
423       * @param value The new value for this property.
424       * @return This object.
425       */
426      public Builder type(String value) {
427         type = value;
428         return this;
429      }
430
431      /**
432       * Sets the <c>ui</c> property on this annotation.
433       *
434       * @param value The new value for this property.
435       * @return This object.
436       */
437      public Builder ui(boolean value) {
438         ui = value;
439         return this;
440      }
441
442      /**
443       * Sets the <c>uniqueItems</c> property on this annotation.
444       *
445       * @param value The new value for this property.
446       * @return This object.
447       */
448      public Builder uniqueItems(boolean value) {
449         uniqueItems = value;
450         return this;
451      }
452
453   }
454
455   private static class Object extends AnnotationObject implements SubItems {
456
457      private final String[] description;
458      private final boolean emax, emin, exclusiveMaximum, exclusiveMinimum, ui, uniqueItems;
459      private final long maxi, maxItems, maxl, maxLength, mini, minItems, minl, minLength;
460      private final String $ref, cf, collectionFormat, f, format, max, maximum, min, minimum, mo, multipleOf, p, pattern, t, type;
461      private final String[] default_, enum_, df, e, items;
462
463      Object(SubItemsAnnotation.Builder b) {
464         super(b);
465         description = copyOf(b.description);
466         $ref = b.$ref;
467         default_ = copyOf(b.default_);
468         enum_ = copyOf(b.enum_);
469         cf = b.cf;
470         collectionFormat = b.collectionFormat;
471         df = copyOf(b.df);
472         e = copyOf(b.e);
473         emax = b.emax;
474         emin = b.emin;
475         exclusiveMaximum = b.exclusiveMaximum;
476         exclusiveMinimum = b.exclusiveMinimum;
477         f = b.f;
478         format = b.format;
479         items = copyOf(b.items);
480         max = b.max;
481         maxi = b.maxi;
482         maximum = b.maximum;
483         maxItems = b.maxItems;
484         maxl = b.maxl;
485         maxLength = b.maxLength;
486         min = b.min;
487         mini = b.mini;
488         minimum = b.minimum;
489         minItems = b.minItems;
490         minl = b.minl;
491         minLength = b.minLength;
492         mo = b.mo;
493         multipleOf = b.multipleOf;
494         p = b.p;
495         pattern = b.pattern;
496         t = b.t;
497         type = b.type;
498         ui = b.ui;
499         uniqueItems = b.uniqueItems;
500      }
501
502      @Override /* Overridden from SubItems */
503      public String[] default_() {
504         return default_;
505      }
506
507      @Override /* Overridden from SubItems */
508      public String[] enum_() {
509         return enum_;
510      }
511
512      @Override /* Overridden from SubItems */
513      public String $ref() {
514         return $ref;
515      }
516
517      @Override /* Overridden from SubItems */
518      public String cf() {
519         return cf;
520      }
521
522      @Override /* Overridden from SubItems */
523      public String collectionFormat() {
524         return collectionFormat;
525      }
526
527      @Override /* Overridden from SubItems */
528      public String[] df() {
529         return df;
530      }
531
532      @Override /* Overridden from SubItems */
533      public String[] e() {
534         return e;
535      }
536
537      @Override /* Overridden from SubItems */
538      public boolean emax() {
539         return emax;
540      }
541
542      @Override /* Overridden from SubItems */
543      public boolean emin() {
544         return emin;
545      }
546
547      @Override /* Overridden from SubItems */
548      public boolean exclusiveMaximum() {
549         return exclusiveMaximum;
550      }
551
552      @Override /* Overridden from SubItems */
553      public boolean exclusiveMinimum() {
554         return exclusiveMinimum;
555      }
556
557      @Override /* Overridden from SubItems */
558      public String f() {
559         return f;
560      }
561
562      @Override /* Overridden from SubItems */
563      public String format() {
564         return format;
565      }
566
567      @Override /* Overridden from SubItems */
568      public String[] items() {
569         return items;
570      }
571
572      @Override /* Overridden from SubItems */
573      public String max() {
574         return max;
575      }
576
577      @Override /* Overridden from SubItems */
578      public long maxi() {
579         return maxi;
580      }
581
582      @Override /* Overridden from SubItems */
583      public String maximum() {
584         return maximum;
585      }
586
587      @Override /* Overridden from SubItems */
588      public long maxItems() {
589         return maxItems;
590      }
591
592      @Override /* Overridden from SubItems */
593      public long maxl() {
594         return maxl;
595      }
596
597      @Override /* Overridden from SubItems */
598      public long maxLength() {
599         return maxLength;
600      }
601
602      @Override /* Overridden from SubItems */
603      public String min() {
604         return min;
605      }
606
607      @Override /* Overridden from SubItems */
608      public long mini() {
609         return mini;
610      }
611
612      @Override /* Overridden from SubItems */
613      public String minimum() {
614         return minimum;
615      }
616
617      @Override /* Overridden from SubItems */
618      public long minItems() {
619         return minItems;
620      }
621
622      @Override /* Overridden from SubItems */
623      public long minl() {
624         return minl;
625      }
626
627      @Override /* Overridden from SubItems */
628      public long minLength() {
629         return minLength;
630      }
631
632      @Override /* Overridden from SubItems */
633      public String mo() {
634         return mo;
635      }
636
637      @Override /* Overridden from SubItems */
638      public String multipleOf() {
639         return multipleOf;
640      }
641
642      @Override /* Overridden from SubItems */
643      public String p() {
644         return p;
645      }
646
647      @Override /* Overridden from SubItems */
648      public String pattern() {
649         return pattern;
650      }
651
652      @Override /* Overridden from SubItems */
653      public String t() {
654         return t;
655      }
656
657      @Override /* Overridden from SubItems */
658      public String type() {
659         return type;
660      }
661
662      @Override /* Overridden from SubItems */
663      public boolean ui() {
664         return ui;
665      }
666
667      @Override /* Overridden from SubItems */
668      public boolean uniqueItems() {
669         return uniqueItems;
670      }
671
672      @Override /* Overridden from annotation */
673      public String[] description() {
674         return description;
675      }
676   }
677
678   /** Default value */
679   public static final SubItems DEFAULT = create().build();
680
681   /**
682    * Instantiates a new builder for this class.
683    *
684    * @return A new builder object.
685    */
686   public static Builder create() {
687      return new Builder();
688   }
689
690   /**
691    * Returns <jk>true</jk> if the specified annotation contains all default values.
692    *
693    * @param a The annotation to check.
694    * @return <jk>true</jk> if the specified annotation contains all default values.
695    */
696   public static boolean empty(org.apache.juneau.annotation.SubItems a) {
697      return a == null || DEFAULT.equals(a);
698   }
699
700   /**
701    * Merges the contents of the specified annotation into the specified generic map.
702    *
703    * @param om The map to copy the contents to.
704    * @param a The annotation to apply.
705    * @return The same map with the annotation contents applied.
706    * @throws ParseException Invalid JSON found in value.
707    */
708   public static JsonMap merge(JsonMap om, SubItems a) throws ParseException {
709      if (SubItemsAnnotation.empty(a))
710         return om;
711      Predicate<String> ne = Utils::ne;
712      Predicate<Collection<?>> nec = Utils::ne;
713      Predicate<Map<?,?>> nem = Utils::ne;
714      Predicate<Boolean> nf = Utils::isTrue;
715      Predicate<Long> nm1 = Utils::nm1;
716      // @formatter:off
717      return om
718         .appendFirst(ne, "collectionFormat", a.collectionFormat(), a.cf())
719         .appendIf(ne, "default", joinnl(a.default_(), a.df()))
720         .appendFirst(nec, "enum", parseSet(a.enum_()), parseSet(a.e()))
721         .appendIf(nf, "exclusiveMaximum", a.exclusiveMaximum() || a.emax())
722         .appendIf(nf, "exclusiveMinimum", a.exclusiveMinimum() || a.emin())
723         .appendFirst(ne, "format", a.format(), a.f())
724         .appendIf(nem, "items", parseMap(a.items()))
725         .appendFirst(ne, "maximum", a.maximum(), a.max())
726         .appendFirst(nm1, "maxItems", a.maxItems(), a.maxi())
727         .appendFirst(nm1, "maxLength", a.maxLength(), a.maxl())
728         .appendFirst(ne, "minimum", a.minimum(), a.min())
729         .appendFirst(nm1, "minItems", a.minItems(), a.mini())
730         .appendFirst(nm1, "minLength", a.minLength(), a.minl())
731         .appendFirst(ne, "multipleOf", a.multipleOf(), a.mo())
732         .appendFirst(ne, "pattern", a.pattern(), a.p())
733         .appendFirst(ne, "type", a.type(), a.t())
734         .appendIf(nf, "uniqueItems", a.uniqueItems() || a.ui())
735         .appendIf(ne, "$ref", a.$ref())
736      ;
737      // @formatter:on
738   }
739}