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