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.commons.utils.CollectionUtils.*; 022import static org.apache.juneau.jsonschema.SchemaUtils.*; 023 024import java.lang.annotation.*; 025import java.lang.reflect.*; 026import java.util.*; 027import java.util.function.*; 028 029import org.apache.juneau.*; 030import org.apache.juneau.collections.*; 031import org.apache.juneau.commons.annotation.*; 032import org.apache.juneau.commons.reflect.*; 033import org.apache.juneau.commons.utils.*; 034import org.apache.juneau.parser.*; 035import org.apache.juneau.svl.*; 036 037/** 038 * Utility classes and methods for the {@link Schema @Schema} annotation. 039 * 040 */ 041public class SchemaAnnotation { 042 /** 043 * Applies targeted {@link Schema} annotations to a {@link org.apache.juneau.Context.Builder}. 044 */ 045 public static class Apply extends AnnotationApplier<Schema,Context.Builder> { 046 047 /** 048 * Constructor. 049 * 050 * @param vr The resolver for resolving values in annotations. 051 */ 052 public Apply(VarResolverSession vr) { 053 super(Schema.class, Context.Builder.class, vr); 054 } 055 056 @Override 057 public void apply(AnnotationInfo<Schema> ai, Context.Builder b) { 058 Schema a = ai.inner(); 059 if (isEmptyArray(a.on()) && isEmptyArray(a.onClass())) 060 return; 061 b.annotations(a); 062 } 063 } 064 065 /** 066 * A collection of {@link Schema @Schema annotations}. 067 */ 068 @Documented 069 @Target({ METHOD, TYPE }) 070 @Retention(RUNTIME) 071 @Inherited 072 public static @interface Array { 073 074 /** 075 * The child annotations. 076 * 077 * @return The annotation value. 078 */ 079 Schema[] value(); 080 } 081 082 /** 083 * Builder class. 084 * 085 * <h5 class='section'>See Also:</h5><ul> 086 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#annotations(Annotation...)} 087 * </ul> 088 */ 089 public static class Builder extends AppliedAnnotationObject.BuilderTMF { 090 091 private boolean aev, allowEmptyValue, emax, emin, exclusiveMaximum, exclusiveMinimum, ignore, r, readOnly, required, ro, sie, skipIfEmpty, ui, uniqueItems; 092 private ExternalDocs externalDocs = ExternalDocsAnnotation.DEFAULT; 093 private Items items = ItemsAnnotation.DEFAULT; 094 private 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; 095 private String $ref = "", cf = "", collectionFormat = "", discriminator = "", f = "", format = "", max = "", maximum = "", min = "", minimum = "", mo = "", multipleOf = "", p = "", 096 pattern = "", t = "", title = "", type = ""; 097 private String[] default_ = {}, enum_ = {}, additionalProperties = {}, allOf = {}, d = {}, description = {}, df = {}, e = {}, properties = {}, xml = {}; 098 private boolean deprecatedProperty; 099 private String $id = "", contentMediaType = "", contentEncoding = "", exclusiveMaximumValue = "", exclusiveMinimumValue = ""; 100 private String[] const_ = {}, examples = {}, $comment = {}, prefixItems = {}, unevaluatedItems = {}, unevaluatedProperties = {}, dependentSchemas = {}, dependentRequired = {}, if_ = {}, 101 then_ = {}, else_ = {}, $defs = {}; 102 103 /** 104 * Constructor. 105 */ 106 protected Builder() { 107 super(Schema.class); 108 } 109 110 /** 111 * Sets the {@link Schema#const_} property on this annotation. 112 * 113 * @param value The new value for this property. 114 * @return This object. 115 */ 116 public Builder const_(String...value) { 117 const_ = value; 118 return this; 119 } 120 121 /** 122 * Sets the {@link Schema#default_} property on this annotation. 123 * 124 * @param value The new value for this property. 125 * @return This object. 126 */ 127 public Builder default_(String...value) { 128 default_ = value; 129 return this; 130 } 131 132 /** 133 * Sets the {@link Schema#else_} property on this annotation. 134 * 135 * @param value The new value for this property. 136 * @return This object. 137 */ 138 public Builder else_(String...value) { 139 else_ = value; 140 return this; 141 } 142 143 /** 144 * Sets the {@link Schema#enum_} property on this annotation. 145 * 146 * @param value The new value for this property. 147 * @return This object. 148 */ 149 public Builder enum_(String...value) { 150 enum_ = value; 151 return this; 152 } 153 154 /** 155 * Sets the {@link Schema#if_} property on this annotation. 156 * 157 * @param value The new value for this property. 158 * @return This object. 159 */ 160 public Builder if_(String...value) { 161 if_ = value; 162 return this; 163 } 164 165 /** 166 * Sets the {@link Schema#then_} property on this annotation. 167 * 168 * @param value The new value for this property. 169 * @return This object. 170 */ 171 public Builder then_(String...value) { 172 then_ = value; 173 return this; 174 } 175 176 /** 177 * Sets the {@link Schema#$comment} property on this annotation. 178 * 179 * @param value The new value for this property. 180 * @return This object. 181 */ 182 public Builder $comment(String...value) { 183 this.$comment = value; 184 return this; 185 } 186 187 /** 188 * Sets the {@link Schema#$defs} property on this annotation. 189 * 190 * @param value The new value for this property. 191 * @return This object. 192 */ 193 public Builder $defs(String...value) { 194 this.$defs = value; 195 return this; 196 } 197 198 /** 199 * Sets the {@link Schema#$id} property on this annotation. 200 * 201 * @param value The new value for this property. 202 * @return This object. 203 */ 204 public Builder $id(String value) { 205 this.$id = value; 206 return this; 207 } 208 209 /** 210 * Sets the {@link Schema#$ref} property on this annotation. 211 * 212 * @param value The new value for this property. 213 * @return This object. 214 */ 215 public Builder $ref(String value) { 216 this.$ref = value; 217 return this; 218 } 219 220 /** 221 * Sets the {@link Schema#additionalProperties} property on this annotation. 222 * 223 * @param value The new value for this property. 224 * @return This object. 225 */ 226 public Builder additionalProperties(String...value) { 227 additionalProperties = value; 228 return this; 229 } 230 231 /** 232 * Sets the {@link Schema#aev} property on this annotation. 233 * 234 * @param value The new value for this property. 235 * @return This object. 236 */ 237 public Builder aev(boolean value) { 238 aev = value; 239 return this; 240 } 241 242 /** 243 * Sets the {@link Schema#allOf} property on this annotation. 244 * 245 * @param value The new value for this property. 246 * @return This object. 247 */ 248 public Builder allOf(String...value) { 249 allOf = value; 250 return this; 251 } 252 253 /** 254 * Sets the {@link Schema#allowEmptyValue} property on this annotation. 255 * 256 * @param value The new value for this property. 257 * @return This object. 258 */ 259 public Builder allowEmptyValue(boolean value) { 260 allowEmptyValue = value; 261 return this; 262 } 263 264 /** 265 * Instantiates a new {@link Schema @Schema} object initialized with this builder. 266 * 267 * @return A new {@link Schema @Schema} object. 268 */ 269 public Schema build() { 270 return new Object(this); 271 } 272 273 /** 274 * Sets the description property on this annotation. 275 * 276 * @param value The new value for this property. 277 * @return This object. 278 */ 279 public Builder description(String...value) { 280 description = value; 281 return this; 282 } 283 284 /** 285 * Sets the {@link Schema#cf} property on this annotation. 286 * 287 * @param value The new value for this property. 288 * @return This object. 289 */ 290 public Builder cf(String value) { 291 cf = value; 292 return this; 293 } 294 295 /** 296 * Sets the {@link Schema#collectionFormat} property on this annotation. 297 * 298 * @param value The new value for this property. 299 * @return This object. 300 */ 301 public Builder collectionFormat(String value) { 302 collectionFormat = value; 303 return this; 304 } 305 306 /** 307 * Sets the {@link Schema#contentEncoding} property on this annotation. 308 * 309 * @param value The new value for this property. 310 * @return This object. 311 */ 312 public Builder contentEncoding(String value) { 313 contentEncoding = value; 314 return this; 315 } 316 317 /** 318 * Sets the {@link Schema#contentMediaType} property on this annotation. 319 * 320 * @param value The new value for this property. 321 * @return This object. 322 */ 323 public Builder contentMediaType(String value) { 324 contentMediaType = value; 325 return this; 326 } 327 328 /** 329 * Sets the {@link Schema#d} property on this annotation. 330 * 331 * @param value The new value for this property. 332 * @return This object. 333 */ 334 public Builder d(String...value) { 335 d = value; 336 return this; 337 } 338 339 /** 340 * Sets the {@link Schema#dependentRequired} property on this annotation. 341 * 342 * @param value The new value for this property. 343 * @return This object. 344 */ 345 public Builder dependentRequired(String...value) { 346 dependentRequired = value; 347 return this; 348 } 349 350 /** 351 * Sets the {@link Schema#dependentSchemas} property on this annotation. 352 * 353 * @param value The new value for this property. 354 * @return This object. 355 */ 356 public Builder dependentSchemas(String...value) { 357 dependentSchemas = value; 358 return this; 359 } 360 361 /** 362 * Sets the {@link Schema#deprecatedProperty} property on this annotation. 363 * 364 * @param value The new value for this property. 365 * @return This object. 366 */ 367 public Builder deprecatedProperty(boolean value) { 368 deprecatedProperty = value; 369 return this; 370 } 371 372 /** 373 * Sets the {@link Schema#df} property on this annotation. 374 * 375 * @param value The new value for this property. 376 * @return This object. 377 */ 378 public Builder df(String...value) { 379 df = value; 380 return this; 381 } 382 383 /** 384 * Sets the {@link Schema#discriminator} property on this annotation. 385 * 386 * @param value The new value for this property. 387 * @return This object. 388 */ 389 public Builder discriminator(String value) { 390 discriminator = value; 391 return this; 392 } 393 394 /** 395 * Sets the {@link Schema#e} property on this annotation. 396 * 397 * @param value The new value for this property. 398 * @return This object. 399 */ 400 public Builder e(String...value) { 401 e = value; 402 return this; 403 } 404 405 /** 406 * Sets the {@link Schema#emax} property on this annotation. 407 * 408 * @param value The new value for this property. 409 * @return This object. 410 */ 411 public Builder emax(boolean value) { 412 emax = value; 413 return this; 414 } 415 416 /** 417 * Sets the {@link Schema#emin} property on this annotation. 418 * 419 * @param value The new value for this property. 420 * @return This object. 421 */ 422 public Builder emin(boolean value) { 423 emin = value; 424 return this; 425 } 426 427 /** 428 * Sets the {@link Schema#examples} property on this annotation. 429 * 430 * @param value The new value for this property. 431 * @return This object. 432 */ 433 public Builder examples(String...value) { 434 examples = value; 435 return this; 436 } 437 438 /** 439 * Sets the {@link Schema#exclusiveMaximum} property on this annotation. 440 * 441 * @param value The new value for this property. 442 * @return This object. 443 */ 444 public Builder exclusiveMaximum(boolean value) { 445 exclusiveMaximum = value; 446 return this; 447 } 448 449 /** 450 * Sets the {@link Schema#exclusiveMaximumValue} property on this annotation. 451 * 452 * @param value The new value for this property. 453 * @return This object. 454 */ 455 public Builder exclusiveMaximumValue(String value) { 456 exclusiveMaximumValue = value; 457 return this; 458 } 459 460 /** 461 * Sets the {@link Schema#exclusiveMinimum} property on this annotation. 462 * 463 * @param value The new value for this property. 464 * @return This object. 465 */ 466 public Builder exclusiveMinimum(boolean value) { 467 exclusiveMinimum = value; 468 return this; 469 } 470 471 /** 472 * Sets the {@link Schema#exclusiveMinimumValue} property on this annotation. 473 * 474 * @param value The new value for this property. 475 * @return This object. 476 */ 477 public Builder exclusiveMinimumValue(String value) { 478 exclusiveMinimumValue = value; 479 return this; 480 } 481 482 /** 483 * Sets the {@link Schema#externalDocs} property on this annotation. 484 * 485 * @param value The new value for this property. 486 * @return This object. 487 */ 488 public Builder externalDocs(ExternalDocs value) { 489 externalDocs = value; 490 return this; 491 } 492 493 /** 494 * Sets the {@link Schema#f} property on this annotation. 495 * 496 * @param value The new value for this property. 497 * @return This object. 498 */ 499 public Builder f(String value) { 500 f = value; 501 return this; 502 } 503 504 /** 505 * Sets the {@link Schema#format} property on this annotation. 506 * 507 * @param value The new value for this property. 508 * @return This object. 509 */ 510 public Builder format(String value) { 511 format = value; 512 return this; 513 } 514 515 /** 516 * Sets the {@link Schema#ignore} property on this annotation. 517 * 518 * @param value The new value for this property. 519 * @return This object. 520 */ 521 public Builder ignore(boolean value) { 522 ignore = value; 523 return this; 524 } 525 526 /** 527 * Sets the {@link Schema#items} property on this annotation. 528 * 529 * @param value The new value for this property. 530 * @return This object. 531 */ 532 public Builder items(Items value) { 533 items = value; 534 return this; 535 } 536 537 /** 538 * Sets the {@link Schema#max} property on this annotation. 539 * 540 * @param value The new value for this property. 541 * @return This object. 542 */ 543 public Builder max(String value) { 544 max = value; 545 return this; 546 } 547 548 /** 549 * Sets the {@link Schema#maxi} property on this annotation. 550 * 551 * @param value The new value for this property. 552 * @return This object. 553 */ 554 public Builder maxi(long value) { 555 maxi = value; 556 return this; 557 } 558 559 /** 560 * Sets the {@link Schema#maximum} property on this annotation. 561 * 562 * @param value The new value for this property. 563 * @return This object. 564 */ 565 public Builder maximum(String value) { 566 maximum = value; 567 return this; 568 } 569 570 /** 571 * Sets the {@link Schema#maxItems} property on this annotation. 572 * 573 * @param value The new value for this property. 574 * @return This object. 575 */ 576 public Builder maxItems(long value) { 577 maxItems = value; 578 return this; 579 } 580 581 /** 582 * Sets the {@link Schema#maxl} property on this annotation. 583 * 584 * @param value The new value for this property. 585 * @return This object. 586 */ 587 public Builder maxl(long value) { 588 maxl = value; 589 return this; 590 } 591 592 /** 593 * Sets the {@link Schema#maxLength} property on this annotation. 594 * 595 * @param value The new value for this property. 596 * @return This object. 597 */ 598 public Builder maxLength(long value) { 599 maxLength = value; 600 return this; 601 } 602 603 /** 604 * Sets the {@link Schema#maxp} property on this annotation. 605 * 606 * @param value The new value for this property. 607 * @return This object. 608 */ 609 public Builder maxp(long value) { 610 maxp = value; 611 return this; 612 } 613 614 /** 615 * Sets the {@link Schema#maxProperties} property on this annotation. 616 * 617 * @param value The new value for this property. 618 * @return This object. 619 */ 620 public Builder maxProperties(long value) { 621 maxProperties = value; 622 return this; 623 } 624 625 /** 626 * Sets the {@link Schema#min} property on this annotation. 627 * 628 * @param value The new value for this property. 629 * @return This object. 630 */ 631 public Builder min(String value) { 632 min = value; 633 return this; 634 } 635 636 /** 637 * Sets the {@link Schema#mini} property on this annotation. 638 * 639 * @param value The new value for this property. 640 * @return This object. 641 */ 642 public Builder mini(long value) { 643 mini = value; 644 return this; 645 } 646 647 /** 648 * Sets the {@link Schema#minimum} property on this annotation. 649 * 650 * @param value The new value for this property. 651 * @return This object. 652 */ 653 public Builder minimum(String value) { 654 minimum = value; 655 return this; 656 } 657 658 /** 659 * Sets the {@link Schema#minItems} property on this annotation. 660 * 661 * @param value The new value for this property. 662 * @return This object. 663 */ 664 public Builder minItems(long value) { 665 minItems = value; 666 return this; 667 } 668 669 /** 670 * Sets the {@link Schema#minl} property on this annotation. 671 * 672 * @param value The new value for this property. 673 * @return This object. 674 */ 675 public Builder minl(long value) { 676 minl = value; 677 return this; 678 } 679 680 /** 681 * Sets the {@link Schema#minLength} property on this annotation. 682 * 683 * @param value The new value for this property. 684 * @return This object. 685 */ 686 public Builder minLength(long value) { 687 minLength = value; 688 return this; 689 } 690 691 /** 692 * Sets the {@link Schema#minp} property on this annotation. 693 * 694 * @param value The new value for this property. 695 * @return This object. 696 */ 697 public Builder minp(long value) { 698 minp = value; 699 return this; 700 } 701 702 /** 703 * Sets the {@link Schema#minProperties} property on this annotation. 704 * 705 * @param value The new value for this property. 706 * @return This object. 707 */ 708 public Builder minProperties(long value) { 709 minProperties = value; 710 return this; 711 } 712 713 /** 714 * Sets the {@link Schema#mo} property on this annotation. 715 * 716 * @param value The new value for this property. 717 * @return This object. 718 */ 719 public Builder mo(String value) { 720 mo = value; 721 return this; 722 } 723 724 /** 725 * Sets the {@link Schema#multipleOf} property on this annotation. 726 * 727 * @param value The new value for this property. 728 * @return This object. 729 */ 730 public Builder multipleOf(String value) { 731 multipleOf = value; 732 return this; 733 } 734 735 // ----------------------------------------------------------------------------------------------------------------- 736 // JSON Schema Draft 2020-12 property setters 737 // ----------------------------------------------------------------------------------------------------------------- 738 739 /** 740 * Sets the {@link Schema#p} property on this annotation. 741 * 742 * @param value The new value for this property. 743 * @return This object. 744 */ 745 public Builder p(String value) { 746 p = value; 747 return this; 748 } 749 750 /** 751 * Sets the {@link Schema#pattern} property on this annotation. 752 * 753 * @param value The new value for this property. 754 * @return This object. 755 */ 756 public Builder pattern(String value) { 757 pattern = value; 758 return this; 759 } 760 761 /** 762 * Sets the {@link Schema#prefixItems} property on this annotation. 763 * 764 * @param value The new value for this property. 765 * @return This object. 766 */ 767 public Builder prefixItems(String...value) { 768 prefixItems = value; 769 return this; 770 } 771 772 /** 773 * Sets the {@link Schema#properties} property on this annotation. 774 * 775 * @param value The new value for this property. 776 * @return This object. 777 */ 778 public Builder properties(String...value) { 779 properties = value; 780 return this; 781 } 782 783 /** 784 * Sets the {@link Schema#r} property on this annotation. 785 * 786 * @param value The new value for this property. 787 * @return This object. 788 */ 789 public Builder r(boolean value) { 790 r = value; 791 return this; 792 } 793 794 /** 795 * Sets the {@link Schema#readOnly} property on this annotation. 796 * 797 * @param value The new value for this property. 798 * @return This object. 799 */ 800 public Builder readOnly(boolean value) { 801 readOnly = value; 802 return this; 803 } 804 805 /** 806 * Sets the {@link Schema#required} property on this annotation. 807 * 808 * @param value The new value for this property. 809 * @return This object. 810 */ 811 public Builder required(boolean value) { 812 required = value; 813 return this; 814 } 815 816 /** 817 * Sets the {@link Schema#ro} property on this annotation. 818 * 819 * @param value The new value for this property. 820 * @return This object. 821 */ 822 public Builder ro(boolean value) { 823 ro = value; 824 return this; 825 } 826 827 /** 828 * Sets the {@link Schema#sie} property on this annotation. 829 * 830 * @param value The new value for this property. 831 * @return This object. 832 */ 833 public Builder sie(boolean value) { 834 sie = value; 835 return this; 836 } 837 838 /** 839 * Sets the {@link Schema#skipIfEmpty} property on this annotation. 840 * 841 * @param value The new value for this property. 842 * @return This object. 843 */ 844 public Builder skipIfEmpty(boolean value) { 845 skipIfEmpty = value; 846 return this; 847 } 848 849 /** 850 * Sets the {@link Schema#t} property on this annotation. 851 * 852 * @param value The new value for this property. 853 * @return This object. 854 */ 855 public Builder t(String value) { 856 t = value; 857 return this; 858 } 859 860 /** 861 * Sets the {@link Schema#title} property on this annotation. 862 * 863 * @param value The new value for this property. 864 * @return This object. 865 */ 866 public Builder title(String value) { 867 title = value; 868 return this; 869 } 870 871 /** 872 * Sets the {@link Schema#type} property on this annotation. 873 * 874 * @param value The new value for this property. 875 * @return This object. 876 */ 877 public Builder type(String value) { 878 type = value; 879 return this; 880 } 881 882 /** 883 * Sets the {@link Schema#ui} property on this annotation. 884 * 885 * @param value The new value for this property. 886 * @return This object. 887 */ 888 public Builder ui(boolean value) { 889 ui = value; 890 return this; 891 } 892 893 /** 894 * Sets the {@link Schema#unevaluatedItems} property on this annotation. 895 * 896 * @param value The new value for this property. 897 * @return This object. 898 */ 899 public Builder unevaluatedItems(String...value) { 900 unevaluatedItems = value; 901 return this; 902 } 903 904 /** 905 * Sets the {@link Schema#unevaluatedProperties} property on this annotation. 906 * 907 * @param value The new value for this property. 908 * @return This object. 909 */ 910 public Builder unevaluatedProperties(String...value) { 911 unevaluatedProperties = value; 912 return this; 913 } 914 915 /** 916 * Sets the {@link Schema#uniqueItems} property on this annotation. 917 * 918 * @param value The new value for this property. 919 * @return This object. 920 */ 921 public Builder uniqueItems(boolean value) { 922 uniqueItems = value; 923 return this; 924 } 925 926 /** 927 * Sets the {@link Schema#xml} property on this annotation. 928 * 929 * @param value The new value for this property. 930 * @return This object. 931 */ 932 public Builder xml(String...value) { 933 xml = value; 934 return this; 935 } 936 937 @Override /* Overridden from AppliedAnnotationObject.Builder */ 938 public Builder on(String...value) { 939 super.on(value); 940 return this; 941 } 942 943 @Override /* Overridden from AppliedAnnotationObject.BuilderT */ 944 public Builder on(Class<?>...value) { 945 super.on(value); 946 return this; 947 } 948 949 @Override /* Overridden from AppliedOnClassAnnotationObject.Builder */ 950 public Builder onClass(Class<?>...value) { 951 super.onClass(value); 952 return this; 953 } 954 955 @Override /* Overridden from AppliedAnnotationObject.BuilderM */ 956 public Builder on(Method...value) { 957 super.on(value); 958 return this; 959 } 960 961 @Override /* Overridden from AppliedAnnotationObject.BuilderMF */ 962 public Builder on(Field...value) { 963 super.on(value); 964 return this; 965 } 966 967 @Override /* Overridden from AppliedAnnotationObject.BuilderT */ 968 public Builder on(ClassInfo...value) { 969 super.on(value); 970 return this; 971 } 972 973 @Override /* Overridden from AppliedAnnotationObject.BuilderT */ 974 public Builder onClass(ClassInfo...value) { 975 super.onClass(value); 976 return this; 977 } 978 979 @Override /* Overridden from AppliedAnnotationObject.BuilderTMF */ 980 public Builder on(FieldInfo...value) { 981 super.on(value); 982 return this; 983 } 984 985 @Override /* Overridden from AppliedAnnotationObject.BuilderTMF */ 986 public Builder on(MethodInfo...value) { 987 super.on(value); 988 return this; 989 } 990 991 } 992 993 private static class Object extends AppliedOnClassAnnotationObject implements Schema { 994 995 private final String[] description; 996 private final boolean aev, allowEmptyValue, exclusiveMaximum, emax, exclusiveMinimum, emin, uniqueItems, ui, required, r, readOnly, ro, sie, skipIfEmpty, ignore; 997 private final ExternalDocs externalDocs; 998 private final Items items; 999 private final long maxLength, maxl, minLength, minl, maxItems, maxi, minItems, mini, maxProperties, maxp, minProperties, minp; 1000 private final String $ref, format, f, title, multipleOf, mo, maximum, max, minimum, min, pattern, p, type, t, collectionFormat, cf, discriminator; 1001 private final String[] d, default_, df, enum_, e, allOf, properties, additionalProperties, xml; 1002 // JSON Schema Draft 2020-12 fields 1003 private final boolean deprecatedProperty; 1004 private final String $id, contentMediaType, contentEncoding, exclusiveMaximumValue, exclusiveMinimumValue; 1005 private final String[] const_, examples, $comment, prefixItems, unevaluatedItems, unevaluatedProperties, dependentSchemas, dependentRequired, if_, then_, else_, $defs; 1006 1007 Object(SchemaAnnotation.Builder b) { 1008 super(b); 1009 description = copyOf(b.description); 1010 $ref = b.$ref; 1011 default_ = copyOf(b.default_); 1012 enum_ = copyOf(b.enum_); 1013 additionalProperties = copyOf(b.additionalProperties); 1014 allOf = copyOf(b.allOf); 1015 aev = b.aev; 1016 allowEmptyValue = b.allowEmptyValue; 1017 cf = b.cf; 1018 collectionFormat = b.collectionFormat; 1019 d = copyOf(b.d); 1020 df = copyOf(b.df); 1021 discriminator = b.discriminator; 1022 e = copyOf(b.e); 1023 emax = b.emax; 1024 emin = b.emin; 1025 exclusiveMaximum = b.exclusiveMaximum; 1026 exclusiveMinimum = b.exclusiveMinimum; 1027 externalDocs = b.externalDocs; 1028 f = b.f; 1029 format = b.format; 1030 ignore = b.ignore; 1031 items = b.items; 1032 max = b.max; 1033 maxi = b.maxi; 1034 maximum = b.maximum; 1035 maxItems = b.maxItems; 1036 maxl = b.maxl; 1037 maxLength = b.maxLength; 1038 maxp = b.maxp; 1039 maxProperties = b.maxProperties; 1040 min = b.min; 1041 mini = b.mini; 1042 minimum = b.minimum; 1043 minItems = b.minItems; 1044 minl = b.minl; 1045 minLength = b.minLength; 1046 minp = b.minp; 1047 minProperties = b.minProperties; 1048 mo = b.mo; 1049 multipleOf = b.multipleOf; 1050 p = b.p; 1051 pattern = b.pattern; 1052 properties = copyOf(b.properties); 1053 r = b.r; 1054 readOnly = b.readOnly; 1055 required = b.required; 1056 ro = b.ro; 1057 sie = b.sie; 1058 skipIfEmpty = b.skipIfEmpty; 1059 t = b.t; 1060 title = b.title; 1061 type = b.type; 1062 ui = b.ui; 1063 uniqueItems = b.uniqueItems; 1064 xml = copyOf(b.xml); 1065 deprecatedProperty = b.deprecatedProperty; 1066 $id = b.$id; 1067 contentMediaType = b.contentMediaType; 1068 contentEncoding = b.contentEncoding; 1069 exclusiveMaximumValue = b.exclusiveMaximumValue; 1070 exclusiveMinimumValue = b.exclusiveMinimumValue; 1071 const_ = copyOf(b.const_); 1072 examples = copyOf(b.examples); 1073 $comment = copyOf(b.$comment); 1074 prefixItems = copyOf(b.prefixItems); 1075 unevaluatedItems = copyOf(b.unevaluatedItems); 1076 unevaluatedProperties = copyOf(b.unevaluatedProperties); 1077 dependentSchemas = copyOf(b.dependentSchemas); 1078 dependentRequired = copyOf(b.dependentRequired); 1079 if_ = copyOf(b.if_); 1080 then_ = copyOf(b.then_); 1081 else_ = copyOf(b.else_); 1082 $defs = copyOf(b.$defs); 1083 } 1084 1085 @Override /* Overridden from Schema */ 1086 public String[] const_() { 1087 return const_; 1088 } 1089 1090 @Override /* Overridden from Schema */ 1091 public String[] default_() { 1092 return default_; 1093 } 1094 1095 @Override /* Overridden from Schema */ 1096 public String[] else_() { 1097 return else_; 1098 } 1099 1100 @Override /* Overridden from Schema */ 1101 public String[] enum_() { 1102 return enum_; 1103 } 1104 1105 @Override /* Overridden from Schema */ 1106 public String[] if_() { 1107 return if_; 1108 } 1109 1110 @Override /* Overridden from Schema */ 1111 public String[] then_() { 1112 return then_; 1113 } 1114 1115 @Override /* Overridden from Schema */ 1116 public String[] $comment() { 1117 return $comment; 1118 } 1119 1120 @Override /* Overridden from Schema */ 1121 public String[] $defs() { 1122 return $defs; 1123 } 1124 1125 @Override /* Overridden from Schema */ 1126 public String $id() { 1127 return $id; 1128 } 1129 1130 @Override /* Overridden from Schema */ 1131 public String $ref() { 1132 return $ref; 1133 } 1134 1135 @Override /* Overridden from Schema */ 1136 public String[] additionalProperties() { 1137 return additionalProperties; 1138 } 1139 1140 @Override /* Overridden from Schema */ 1141 public boolean aev() { 1142 return aev; 1143 } 1144 1145 @Override /* Overridden from Schema */ 1146 public String[] allOf() { 1147 return allOf; 1148 } 1149 1150 @Override /* Overridden from Schema */ 1151 public boolean allowEmptyValue() { 1152 return allowEmptyValue; 1153 } 1154 1155 @Override /* Overridden from Schema */ 1156 public String cf() { 1157 return cf; 1158 } 1159 1160 @Override /* Overridden from Schema */ 1161 public String collectionFormat() { 1162 return collectionFormat; 1163 } 1164 1165 @Override /* Overridden from Schema */ 1166 public String contentEncoding() { 1167 return contentEncoding; 1168 } 1169 1170 @Override /* Overridden from Schema */ 1171 public String contentMediaType() { 1172 return contentMediaType; 1173 } 1174 1175 @Override /* Overridden from Schema */ 1176 public String[] d() { 1177 return d; 1178 } 1179 1180 @Override /* Overridden from Schema */ 1181 public String[] dependentRequired() { 1182 return dependentRequired; 1183 } 1184 1185 @Override /* Overridden from Schema */ 1186 public String[] dependentSchemas() { 1187 return dependentSchemas; 1188 } 1189 1190 @Override /* Overridden from Schema */ 1191 public boolean deprecatedProperty() { 1192 return deprecatedProperty; 1193 } 1194 1195 @Override /* Overridden from Schema */ 1196 public String[] df() { 1197 return df; 1198 } 1199 1200 @Override /* Overridden from Schema */ 1201 public String discriminator() { 1202 return discriminator; 1203 } 1204 1205 @Override /* Overridden from Schema */ 1206 public String[] e() { 1207 return e; 1208 } 1209 1210 @Override /* Overridden from Schema */ 1211 public boolean emax() { 1212 return emax; 1213 } 1214 1215 @Override /* Overridden from Schema */ 1216 public boolean emin() { 1217 return emin; 1218 } 1219 1220 @Override /* Overridden from Schema */ 1221 public String[] examples() { 1222 return examples; 1223 } 1224 1225 @Override /* Overridden from Schema */ 1226 public boolean exclusiveMaximum() { 1227 return exclusiveMaximum; 1228 } 1229 1230 @Override /* Overridden from Schema */ 1231 public String exclusiveMaximumValue() { 1232 return exclusiveMaximumValue; 1233 } 1234 1235 @Override /* Overridden from Schema */ 1236 public boolean exclusiveMinimum() { 1237 return exclusiveMinimum; 1238 } 1239 1240 @Override /* Overridden from Schema */ 1241 public String exclusiveMinimumValue() { 1242 return exclusiveMinimumValue; 1243 } 1244 1245 @Override /* Overridden from Schema */ 1246 public ExternalDocs externalDocs() { 1247 return externalDocs; 1248 } 1249 1250 @Override /* Overridden from Schema */ 1251 public String f() { 1252 return f; 1253 } 1254 1255 @Override /* Overridden from Schema */ 1256 public String format() { 1257 return format; 1258 } 1259 1260 @Override /* Overridden from Schema */ 1261 public boolean ignore() { 1262 return ignore; 1263 } 1264 1265 @Override /* Overridden from Schema */ 1266 public Items items() { 1267 return items; 1268 } 1269 1270 @Override /* Overridden from Schema */ 1271 public String max() { 1272 return max; 1273 } 1274 1275 @Override /* Overridden from Schema */ 1276 public long maxi() { 1277 return maxi; 1278 } 1279 1280 @Override /* Overridden from Schema */ 1281 public String maximum() { 1282 return maximum; 1283 } 1284 1285 @Override /* Overridden from Schema */ 1286 public long maxItems() { 1287 return maxItems; 1288 } 1289 1290 @Override /* Overridden from Schema */ 1291 public long maxl() { 1292 return maxl; 1293 } 1294 1295 @Override /* Overridden from Schema */ 1296 public long maxLength() { 1297 return maxLength; 1298 } 1299 1300 @Override /* Overridden from Schema */ 1301 public long maxp() { 1302 return maxp; 1303 } 1304 1305 @Override /* Overridden from Schema */ 1306 public long maxProperties() { 1307 return maxProperties; 1308 } 1309 1310 @Override /* Overridden from Schema */ 1311 public String min() { 1312 return min; 1313 } 1314 1315 @Override /* Overridden from Schema */ 1316 public long mini() { 1317 return mini; 1318 } 1319 1320 @Override /* Overridden from Schema */ 1321 public String minimum() { 1322 return minimum; 1323 } 1324 1325 @Override /* Overridden from Schema */ 1326 public long minItems() { 1327 return minItems; 1328 } 1329 1330 @Override /* Overridden from Schema */ 1331 public long minl() { 1332 return minl; 1333 } 1334 1335 @Override /* Overridden from Schema */ 1336 public long minLength() { 1337 return minLength; 1338 } 1339 1340 @Override /* Overridden from Schema */ 1341 public long minp() { 1342 return minp; 1343 } 1344 1345 @Override /* Overridden from Schema */ 1346 public long minProperties() { 1347 return minProperties; 1348 } 1349 1350 @Override /* Overridden from Schema */ 1351 public String mo() { 1352 return mo; 1353 } 1354 1355 @Override /* Overridden from Schema */ 1356 public String multipleOf() { 1357 return multipleOf; 1358 } 1359 1360 // ----------------------------------------------------------------------------------------------------------------- 1361 // JSON Schema Draft 2020-12 property getters 1362 // ----------------------------------------------------------------------------------------------------------------- 1363 1364 @Override /* Overridden from Schema */ 1365 public String p() { 1366 return p; 1367 } 1368 1369 @Override /* Overridden from Schema */ 1370 public String pattern() { 1371 return pattern; 1372 } 1373 1374 @Override /* Overridden from Schema */ 1375 public String[] prefixItems() { 1376 return prefixItems; 1377 } 1378 1379 @Override /* Overridden from Schema */ 1380 public String[] properties() { 1381 return properties; 1382 } 1383 1384 @Override /* Overridden from Schema */ 1385 public boolean r() { 1386 return r; 1387 } 1388 1389 @Override /* Overridden from Schema */ 1390 public boolean readOnly() { 1391 return readOnly; 1392 } 1393 1394 @Override /* Overridden from Schema */ 1395 public boolean required() { 1396 return required; 1397 } 1398 1399 @Override /* Overridden from Schema */ 1400 public boolean ro() { 1401 return ro; 1402 } 1403 1404 @Override /* Overridden from Schema */ 1405 public boolean sie() { 1406 return sie; 1407 } 1408 1409 @Override /* Overridden from Schema */ 1410 public boolean skipIfEmpty() { 1411 return skipIfEmpty; 1412 } 1413 1414 @Override /* Overridden from Schema */ 1415 public String t() { 1416 return t; 1417 } 1418 1419 @Override /* Overridden from Schema */ 1420 public String title() { 1421 return title; 1422 } 1423 1424 @Override /* Overridden from Schema */ 1425 public String type() { 1426 return type; 1427 } 1428 1429 @Override /* Overridden from Schema */ 1430 public boolean ui() { 1431 return ui; 1432 } 1433 1434 @Override /* Overridden from Schema */ 1435 public String[] unevaluatedItems() { 1436 return unevaluatedItems; 1437 } 1438 1439 @Override /* Overridden from Schema */ 1440 public String[] unevaluatedProperties() { 1441 return unevaluatedProperties; 1442 } 1443 1444 @Override /* Overridden from Schema */ 1445 public boolean uniqueItems() { 1446 return uniqueItems; 1447 } 1448 1449 @Override /* Overridden from Schema */ 1450 public String[] xml() { 1451 return xml; 1452 } 1453 1454 @Override /* Overridden from annotation */ 1455 public String[] description() { 1456 return description; 1457 } 1458 } 1459 1460 /** Default value */ 1461 public static final Schema DEFAULT = create().build(); 1462 1463 /** 1464 * Converts the specified <ja>@Schema</ja> annotation into a generic map. 1465 * 1466 * @param a The annotation instance. Can be <jk>null</jk>. 1467 * @return The schema converted to a map, or and empty map if the annotation was null. 1468 * @throws ParseException Malformed input encountered. 1469 */ 1470 @SuppressWarnings("deprecation") 1471 public static JsonMap asMap(Schema a) throws ParseException { 1472 if (a == null) 1473 return JsonMap.EMPTY_MAP; 1474 var m = new JsonMap(); 1475 if (SchemaAnnotation.empty(a)) 1476 return m; 1477 Predicate<String> ne = Utils::ne; 1478 Predicate<Collection<?>> nec = Utils::ne; 1479 Predicate<Map<?,?>> nem = Utils::ne; 1480 Predicate<Boolean> nf = Utils::isTrue; 1481 Predicate<Long> nm1 = Utils::nm1; 1482 // @formatter:off 1483 return m 1484 .appendIf(nem, "additionalProperties", parseMap(a.additionalProperties())) 1485 .appendIf(ne, "allOf", joinnl(a.allOf())) 1486 .appendFirst(ne, "collectionFormat", a.collectionFormat(), a.cf()) 1487 .appendIf(ne, "default", joinnl(a.default_(), a.df())) 1488 .appendIf(ne, "discriminator", a.discriminator()) 1489 .appendIf(ne, "description", joinnl(a.description(), a.d())) 1490 .appendFirst(nec, "enum", parseSet(a.enum_()), parseSet(a.e())) 1491 // Handle exclusiveMaximum with Draft 2020-12 fallback 1492 .appendIf(ne, "exclusiveMaximum", 1493 ne.test(a.exclusiveMaximumValue()) ? a.exclusiveMaximumValue() : 1494 (a.exclusiveMaximum() || a.emax()) ? "true" : null) 1495 // Handle exclusiveMinimum with Draft 2020-12 fallback 1496 .appendIf(ne, "exclusiveMinimum", 1497 ne.test(a.exclusiveMinimumValue()) ? a.exclusiveMinimumValue() : 1498 (a.exclusiveMinimum() || a.emin()) ? "true" : null) 1499 .appendIf(nem, "externalDocs", ExternalDocsAnnotation.merge(m.getMap("externalDocs"), a.externalDocs())) 1500 .appendFirst(ne, "format", a.format(), a.f()) 1501 .appendIf(ne, "ignore", a.ignore() ? "true" : null) 1502 .appendIf(nem, "items", merge(m.getMap("items"), a.items())) 1503 .appendFirst(ne, "maximum", a.maximum(), a.max()) 1504 .appendFirst(nm1, "maxItems", a.maxItems(), a.maxi()) 1505 .appendFirst(nm1, "maxLength", a.maxLength(), a.maxl()) 1506 .appendFirst(nm1, "maxProperties", a.maxProperties(), a.maxp()) 1507 .appendFirst(ne, "minimum", a.minimum(), a.min()) 1508 .appendFirst(nm1, "minItems", a.minItems(), a.mini()) 1509 .appendFirst(nm1, "minLength", a.minLength(), a.minl()) 1510 .appendFirst(nm1, "minProperties", a.minProperties(), a.minp()) 1511 .appendFirst(ne, "multipleOf", a.multipleOf(), a.mo()) 1512 .appendFirst(ne, "pattern", a.pattern(), a.p()) 1513 .appendIf(nem, "properties", parseMap(a.properties())) 1514 .appendIf(nf, "readOnly", a.readOnly() || a.ro()) 1515 .appendIf(nf, "required", a.required() || a.r()) 1516 .appendIf(ne, "title", a.title()) 1517 .appendFirst(ne, "type", a.type(), a.t()) 1518 .appendIf(nf, "uniqueItems", a.uniqueItems() || a.ui()) 1519 .appendIf(ne, "xml", joinnl(a.xml())) 1520 .appendIf(ne, "$ref", a.$ref()) 1521 // JSON Schema Draft 2020-12 properties 1522 .appendIf(ne, "const", joinnl(a.const_())) 1523 .appendIf(nec, "examples", a.examples().length == 0 ? null : l(a.examples())) 1524 .appendIf(ne, "$comment", joinnl(a.$comment())) 1525 .appendIf(nf, "deprecated", a.deprecatedProperty()) 1526 .appendIf(ne, "contentMediaType", a.contentMediaType()) 1527 .appendIf(ne, "contentEncoding", a.contentEncoding()) 1528 .appendIf(ne, "prefixItems", joinnl(a.prefixItems())) 1529 .appendIf(ne, "unevaluatedItems", joinnl(a.unevaluatedItems())) 1530 .appendIf(ne, "unevaluatedProperties", joinnl(a.unevaluatedProperties())) 1531 .appendIf(ne, "dependentSchemas", joinnl(a.dependentSchemas())) 1532 .appendIf(ne, "dependentRequired", joinnl(a.dependentRequired())) 1533 .appendIf(ne, "if", joinnl(a.if_())) 1534 .appendIf(ne, "then", joinnl(a.then_())) 1535 .appendIf(ne, "else", joinnl(a.else_())) 1536 .appendIf(ne, "$defs", joinnl(a.$defs())) 1537 .appendIf(ne, "$id", a.$id()) 1538 ; 1539 // @formatter:on 1540 } 1541 1542 /** 1543 * Instantiates a new builder for this class. 1544 * 1545 * @return A new builder object. 1546 */ 1547 public static Builder create() { 1548 return new Builder(); 1549 } 1550 1551 /** 1552 * Instantiates a new builder for this class. 1553 * 1554 * @param on The targets this annotation applies to. 1555 * @return A new builder object. 1556 */ 1557 public static Builder create(Class<?>...on) { 1558 return create().on(on); 1559 } 1560 1561 /** 1562 * Instantiates a new builder for this class. 1563 * 1564 * @param on The targets this annotation applies to. 1565 * @return A new builder object. 1566 */ 1567 public static Builder create(String...on) { 1568 return create().on(on); 1569 } 1570 1571 /** 1572 * Returns <jk>true</jk> if the specified annotation contains all default values. 1573 * 1574 * @param a The annotation to check. 1575 * @return <jk>true</jk> if the specified annotation contains all default values. 1576 */ 1577 public static boolean empty(Schema a) { 1578 return a == null || DEFAULT.equals(a); 1579 } 1580 1581 private static JsonMap merge(JsonMap m, Items a) throws ParseException { 1582 if (ItemsAnnotation.empty(a)) 1583 return m; 1584 Predicate<String> ne = Utils::ne; 1585 Predicate<Collection<?>> nec = Utils::ne; 1586 Predicate<Map<?,?>> nem = Utils::ne; 1587 Predicate<Boolean> nf = Utils::isTrue; 1588 Predicate<Long> nm1 = Utils::nm1; 1589 return m.appendFirst(ne, "collectionFormat", a.collectionFormat(), a.cf()).appendIf(ne, "default", joinnl(a.default_(), a.df())).appendFirst(nec, "enum", parseSet(a.enum_()), parseSet(a.e())) 1590 .appendFirst(ne, "format", a.format(), a.f()).appendIf(nf, "exclusiveMaximum", a.exclusiveMaximum() || a.emax()).appendIf(nf, "exclusiveMinimum", a.exclusiveMinimum() || a.emin()) 1591 .appendIf(nem, "items", SubItemsAnnotation.merge(m.getMap("items"), a.items())).appendFirst(ne, "maximum", a.maximum(), a.max()).appendFirst(nm1, "maxItems", a.maxItems(), a.maxi()) 1592 .appendFirst(nm1, "maxLength", a.maxLength(), a.maxl()).appendFirst(ne, "minimum", a.minimum(), a.min()).appendFirst(nm1, "minItems", a.minItems(), a.mini()) 1593 .appendFirst(nm1, "minLength", a.minLength(), a.minl()).appendFirst(ne, "multipleOf", a.multipleOf(), a.mo()).appendFirst(ne, "pattern", a.pattern(), a.p()) 1594 .appendIf(nf, "uniqueItems", a.uniqueItems() || a.ui()).appendFirst(ne, "type", a.type(), a.t()).appendIf(ne, "$ref", a.$ref()); 1595 } 1596}