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