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.json; 018 019import static org.apache.juneau.collections.JsonMap.*; 020 021import java.lang.annotation.*; 022import java.nio.charset.*; 023import java.util.*; 024import java.util.concurrent.*; 025 026import org.apache.juneau.*; 027import org.apache.juneau.annotation.*; 028import org.apache.juneau.collections.*; 029import org.apache.juneau.internal.*; 030import org.apache.juneau.jsonschema.*; 031import org.apache.juneau.utils.*; 032 033/** 034 * Serializes POJO metadata to HTTP responses as JSON-Schema. 035 * 036 * <h5 class='topic'>Media types</h5> 037 * 038 * Handles <c>Accept</c> types: <bc>application/json+schema, text/json+schema</bc> 039 * <p> 040 * Produces <c>Content-Type</c> types: <bc>application/json</bc> 041 * 042 * <h5 class='topic'>Description</h5> 043 * 044 * Produces the JSON-schema for the JSON produced by the {@link JsonSerializer} class with the same properties. 045 * 046 * <h5 class='section'>Notes:</h5><ul> 047 * <li class='note'>This class is thread safe and reusable. 048 * </ul> 049 * 050 * <h5 class='section'>See Also:</h5><ul> 051 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JsonBasics">JSON Basics</a> 052 053 * </ul> 054 */ 055public class JsonSchemaSerializer extends JsonSerializer implements JsonSchemaMetaProvider { 056 057 //------------------------------------------------------------------------------------------------------------------- 058 // Static 059 //------------------------------------------------------------------------------------------------------------------- 060 061 /** Default serializer, all default settings.*/ 062 public static final JsonSchemaSerializer DEFAULT = new JsonSchemaSerializer(create()); 063 064 /** Default serializer, all default settings.*/ 065 public static final JsonSchemaSerializer DEFAULT_READABLE = new Readable(create()); 066 067 /** Default serializer, single quotes, simple mode. */ 068 public static final JsonSchemaSerializer DEFAULT_SIMPLE = new Simple(create()); 069 070 /** Default serializer, single quotes, simple mode, with whitespace. */ 071 public static final JsonSchemaSerializer DEFAULT_SIMPLE_READABLE = new SimpleReadable(create()); 072 073 /** 074 * Creates a new builder for this object. 075 * 076 * @return A new builder. 077 */ 078 public static Builder create() { 079 return new Builder(); 080 } 081 082 //------------------------------------------------------------------------------------------------------------------- 083 // Static subclasses 084 //------------------------------------------------------------------------------------------------------------------- 085 086 /** Default serializer, with whitespace. */ 087 public static class Readable extends JsonSchemaSerializer { 088 089 /** 090 * Constructor. 091 * 092 * @param builder The builder for this object. 093 */ 094 public Readable(Builder builder) { 095 super(builder.useWhitespace()); 096 } 097 } 098 099 /** Default serializer, single quotes, simple mode. */ 100 public static class Simple extends JsonSchemaSerializer { 101 102 /** 103 * Constructor. 104 * 105 * @param builder The builder for this object. 106 */ 107 public Simple(Builder builder) { 108 super(builder.simpleAttrs().quoteChar('\'')); 109 } 110 } 111 112 /** Default serializer, single quotes, simple mode, with whitespace. */ 113 public static class SimpleReadable extends JsonSchemaSerializer { 114 115 /** 116 * Constructor. 117 * 118 * @param builder The builder for this object. 119 */ 120 public SimpleReadable(Builder builder) { 121 super(builder.simpleAttrs().quoteChar('\'').useWhitespace()); 122 } 123 } 124 125 //------------------------------------------------------------------------------------------------------------------- 126 // Builder 127 //------------------------------------------------------------------------------------------------------------------- 128 129 /** 130 * Builder class. 131 */ 132 public static class Builder extends JsonSerializer.Builder { 133 134 private static final Cache<HashKey,JsonSchemaSerializer> CACHE = Cache.of(HashKey.class, JsonSchemaSerializer.class).build(); 135 136 JsonSchemaGenerator.Builder generatorBuilder; 137 138 /** 139 * Constructor, default settings. 140 */ 141 protected Builder() { 142 produces("application/json"); 143 accept("application/json+schema,text/json+schema"); 144 generatorBuilder = JsonSchemaGenerator.create().beanContext(beanContext()); 145 } 146 147 /** 148 * Copy constructor. 149 * 150 * @param copyFrom The bean to copy from. 151 */ 152 protected Builder(JsonSchemaSerializer copyFrom) { 153 super(copyFrom); 154 generatorBuilder = copyFrom.generator.copy().beanContext(beanContext()); 155 } 156 157 /** 158 * Copy constructor. 159 * 160 * @param copyFrom The builder to copy from. 161 */ 162 protected Builder(Builder copyFrom) { 163 super(copyFrom); 164 generatorBuilder = copyFrom.generatorBuilder.copy().beanContext(beanContext()); 165 } 166 167 @Override /* Context.Builder */ 168 public Builder copy() { 169 return new Builder(this); 170 } 171 172 @Override /* Context.Builder */ 173 public JsonSchemaSerializer build() { 174 return cache(CACHE).build(JsonSchemaSerializer.class); 175 } 176 177 @Override /* Context.Builder */ 178 public HashKey hashKey() { 179 return HashKey.of( 180 super.hashKey(), 181 generatorBuilder.hashKey() 182 ); 183 } 184 185 //----------------------------------------------------------------------------------------------------------------- 186 // Properties 187 //----------------------------------------------------------------------------------------------------------------- 188 189 /** 190 * <i><l>JsonSchemaSerializer</l> configuration property: </i> Add descriptions. 191 * 192 * <p> 193 * Identifies which categories of types that descriptions should be automatically added to generated schemas. 194 * <p> 195 * The description is the result of calling {@link ClassMeta#getFullName()}. 196 * 197 * <h5 class='section'>See Also:</h5><ul> 198 * <li class='jm'>{@link org.apache.juneau.jsonschema.JsonSchemaGenerator.Builder#addDescriptionsTo(TypeCategory...)} 199 * </ul> 200 * 201 * @param values 202 * The values to add to this setting. 203 * <br>The default is an empty string. 204 * @return This object. 205 */ 206 public Builder addDescriptionsTo(TypeCategory...values) { 207 generatorBuilder.addDescriptionsTo(values); 208 return this; 209 } 210 211 /** 212 * <i><l>JsonSchemaSerializer</l> configuration property: </i> Add examples. 213 * 214 * <p> 215 * Identifies which categories of types that examples should be automatically added to generated schemas. 216 * <p> 217 * The examples come from calling {@link ClassMeta#getExample(BeanSession,JsonParserSession)} which in turn gets examples 218 * from the following: 219 * <ul class='javatree'> 220 * <li class='ja'>{@link Example} 221 * <li class='ja'>{@link Marshalled#example() Marshalled(example)} 222 * </ul> 223 * 224 * <h5 class='section'>See Also:</h5><ul> 225 * <li class='jm'>{@link org.apache.juneau.jsonschema.JsonSchemaGenerator.Builder#addExamplesTo(TypeCategory...)} 226 * </ul> 227 * 228 * @param values 229 * The values to add to this setting. 230 * <br>The default is an empty string. 231 * @return This object. 232 */ 233 public Builder addExamplesTo(TypeCategory...values) { 234 generatorBuilder.addExamplesTo(values); 235 return this; 236 } 237 238 /** 239 * <i><l>JsonSchemaSerializer</l> configuration property: </i> Allow nested descriptions. 240 * 241 * <p> 242 * Identifies whether nested descriptions are allowed in schema definitions. 243 * 244 * <h5 class='section'>See Also:</h5><ul> 245 * <li class='jm'>{@link org.apache.juneau.jsonschema.JsonSchemaGenerator.Builder#allowNestedDescriptions()} 246 * </ul> 247 * 248 * @return This object. 249 */ 250 public Builder allowNestedDescriptions() { 251 generatorBuilder.allowNestedDescriptions(); 252 return this; 253 } 254 255 /** 256 * <i><l>JsonSchemaSerializer</l> configuration property: </i> Allow nested examples. 257 * 258 * <p> 259 * Identifies whether nested examples are allowed in schema definitions. 260 * 261 * <h5 class='section'>See Also:</h5><ul> 262 * <li class='jm'>{@link org.apache.juneau.jsonschema.JsonSchemaGenerator.Builder#allowNestedExamples()} 263 * </ul> 264 * 265 * @return This object. 266 */ 267 public Builder allowNestedExamples() { 268 generatorBuilder.allowNestedExamples(); 269 return this; 270 } 271 272 /** 273 * <i><l>JsonSchemaSerializer</l> configuration property: </i> Schema definition mapper. 274 * 275 * <p> 276 * Interface to use for converting Bean classes to definition IDs and URIs. 277 * <p> 278 * Used primarily for defining common definition sections for beans in Swagger JSON. 279 * <p> 280 * This setting is ignored if {@link org.apache.juneau.jsonschema.JsonSchemaGenerator.Builder#useBeanDefs()} is not enabled. 281 * 282 * <h5 class='section'>See Also:</h5><ul> 283 * <li class='jm'>{@link org.apache.juneau.jsonschema.JsonSchemaGenerator.Builder#beanDefMapper(Class)} 284 * </ul> 285 * 286 * @param value 287 * The new value for this property. 288 * <br>The default is {@link org.apache.juneau.jsonschema.BasicBeanDefMapper}. 289 * @return This object. 290 */ 291 public Builder beanDefMapper(Class<? extends BeanDefMapper> value) { 292 generatorBuilder.beanDefMapper(value); 293 return this; 294 } 295 296 /** 297 * <i><l>JsonSchemaSerializer</l> configuration property: </i> Use bean definitions. 298 * 299 * <p> 300 * When enabled, schemas on beans will be serialized as the following: 301 * <p class='bjson'> 302 * { 303 * type: <js>'object'</js>, 304 * <js>'$ref'</js>: <js>'#/definitions/TypeId'</js> 305 * } 306 * </p> 307 * 308 * @return This object. 309 */ 310 public Builder useBeanDefs() { 311 generatorBuilder.useBeanDefs(); 312 return this; 313 } 314 @Override /* Overridden from Builder */ 315 public Builder annotations(Annotation...values) { 316 super.annotations(values); 317 return this; 318 } 319 320 @Override /* Overridden from Builder */ 321 public Builder apply(AnnotationWorkList work) { 322 super.apply(work); 323 return this; 324 } 325 326 @Override /* Overridden from Builder */ 327 public Builder applyAnnotations(Object...from) { 328 super.applyAnnotations(from); 329 return this; 330 } 331 332 @Override /* Overridden from Builder */ 333 public Builder applyAnnotations(Class<?>...from) { 334 super.applyAnnotations(from); 335 return this; 336 } 337 338 @Override /* Overridden from Builder */ 339 public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) { 340 super.cache(value); 341 return this; 342 } 343 344 @Override /* Overridden from Builder */ 345 public Builder debug() { 346 super.debug(); 347 return this; 348 } 349 350 @Override /* Overridden from Builder */ 351 public Builder debug(boolean value) { 352 super.debug(value); 353 return this; 354 } 355 356 @Override /* Overridden from Builder */ 357 public Builder impl(Context value) { 358 super.impl(value); 359 return this; 360 } 361 362 @Override /* Overridden from Builder */ 363 public Builder type(Class<? extends org.apache.juneau.Context> value) { 364 super.type(value); 365 return this; 366 } 367 368 @Override /* Overridden from Builder */ 369 public Builder beanClassVisibility(Visibility value) { 370 super.beanClassVisibility(value); 371 return this; 372 } 373 374 @Override /* Overridden from Builder */ 375 public Builder beanConstructorVisibility(Visibility value) { 376 super.beanConstructorVisibility(value); 377 return this; 378 } 379 380 @Override /* Overridden from Builder */ 381 public Builder beanContext(BeanContext value) { 382 super.beanContext(value); 383 return this; 384 } 385 386 @Override /* Overridden from Builder */ 387 public Builder beanContext(BeanContext.Builder value) { 388 super.beanContext(value); 389 return this; 390 } 391 392 @Override /* Overridden from Builder */ 393 public Builder beanDictionary(java.lang.Class<?>...values) { 394 super.beanDictionary(values); 395 return this; 396 } 397 398 @Override /* Overridden from Builder */ 399 public Builder beanFieldVisibility(Visibility value) { 400 super.beanFieldVisibility(value); 401 return this; 402 } 403 404 @Override /* Overridden from Builder */ 405 public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) { 406 super.beanInterceptor(on, value); 407 return this; 408 } 409 410 @Override /* Overridden from Builder */ 411 public Builder beanMapPutReturnsOldValue() { 412 super.beanMapPutReturnsOldValue(); 413 return this; 414 } 415 416 @Override /* Overridden from Builder */ 417 public Builder beanMethodVisibility(Visibility value) { 418 super.beanMethodVisibility(value); 419 return this; 420 } 421 422 @Override /* Overridden from Builder */ 423 public Builder beanProperties(Map<String,Object> values) { 424 super.beanProperties(values); 425 return this; 426 } 427 428 @Override /* Overridden from Builder */ 429 public Builder beanProperties(Class<?> beanClass, String properties) { 430 super.beanProperties(beanClass, properties); 431 return this; 432 } 433 434 @Override /* Overridden from Builder */ 435 public Builder beanProperties(String beanClassName, String properties) { 436 super.beanProperties(beanClassName, properties); 437 return this; 438 } 439 440 @Override /* Overridden from Builder */ 441 public Builder beanPropertiesExcludes(Map<String,Object> values) { 442 super.beanPropertiesExcludes(values); 443 return this; 444 } 445 446 @Override /* Overridden from Builder */ 447 public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) { 448 super.beanPropertiesExcludes(beanClass, properties); 449 return this; 450 } 451 452 @Override /* Overridden from Builder */ 453 public Builder beanPropertiesExcludes(String beanClassName, String properties) { 454 super.beanPropertiesExcludes(beanClassName, properties); 455 return this; 456 } 457 458 @Override /* Overridden from Builder */ 459 public Builder beanPropertiesReadOnly(Map<String,Object> values) { 460 super.beanPropertiesReadOnly(values); 461 return this; 462 } 463 464 @Override /* Overridden from Builder */ 465 public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) { 466 super.beanPropertiesReadOnly(beanClass, properties); 467 return this; 468 } 469 470 @Override /* Overridden from Builder */ 471 public Builder beanPropertiesReadOnly(String beanClassName, String properties) { 472 super.beanPropertiesReadOnly(beanClassName, properties); 473 return this; 474 } 475 476 @Override /* Overridden from Builder */ 477 public Builder beanPropertiesWriteOnly(Map<String,Object> values) { 478 super.beanPropertiesWriteOnly(values); 479 return this; 480 } 481 482 @Override /* Overridden from Builder */ 483 public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) { 484 super.beanPropertiesWriteOnly(beanClass, properties); 485 return this; 486 } 487 488 @Override /* Overridden from Builder */ 489 public Builder beanPropertiesWriteOnly(String beanClassName, String properties) { 490 super.beanPropertiesWriteOnly(beanClassName, properties); 491 return this; 492 } 493 494 @Override /* Overridden from Builder */ 495 public Builder beansRequireDefaultConstructor() { 496 super.beansRequireDefaultConstructor(); 497 return this; 498 } 499 500 @Override /* Overridden from Builder */ 501 public Builder beansRequireSerializable() { 502 super.beansRequireSerializable(); 503 return this; 504 } 505 506 @Override /* Overridden from Builder */ 507 public Builder beansRequireSettersForGetters() { 508 super.beansRequireSettersForGetters(); 509 return this; 510 } 511 512 @Override /* Overridden from Builder */ 513 public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) { 514 super.dictionaryOn(on, values); 515 return this; 516 } 517 518 @Override /* Overridden from Builder */ 519 public Builder disableBeansRequireSomeProperties() { 520 super.disableBeansRequireSomeProperties(); 521 return this; 522 } 523 524 @Override /* Overridden from Builder */ 525 public Builder disableIgnoreMissingSetters() { 526 super.disableIgnoreMissingSetters(); 527 return this; 528 } 529 530 @Override /* Overridden from Builder */ 531 public Builder disableIgnoreTransientFields() { 532 super.disableIgnoreTransientFields(); 533 return this; 534 } 535 536 @Override /* Overridden from Builder */ 537 public Builder disableIgnoreUnknownNullBeanProperties() { 538 super.disableIgnoreUnknownNullBeanProperties(); 539 return this; 540 } 541 542 @Override /* Overridden from Builder */ 543 public Builder disableInterfaceProxies() { 544 super.disableInterfaceProxies(); 545 return this; 546 } 547 548 @Override /* Overridden from Builder */ 549 public <T> Builder example(Class<T> pojoClass, T o) { 550 super.example(pojoClass, o); 551 return this; 552 } 553 554 @Override /* Overridden from Builder */ 555 public <T> Builder example(Class<T> pojoClass, String json) { 556 super.example(pojoClass, json); 557 return this; 558 } 559 560 @Override /* Overridden from Builder */ 561 public Builder findFluentSetters() { 562 super.findFluentSetters(); 563 return this; 564 } 565 566 @Override /* Overridden from Builder */ 567 public Builder findFluentSetters(Class<?> on) { 568 super.findFluentSetters(on); 569 return this; 570 } 571 572 @Override /* Overridden from Builder */ 573 public Builder ignoreInvocationExceptionsOnGetters() { 574 super.ignoreInvocationExceptionsOnGetters(); 575 return this; 576 } 577 578 @Override /* Overridden from Builder */ 579 public Builder ignoreInvocationExceptionsOnSetters() { 580 super.ignoreInvocationExceptionsOnSetters(); 581 return this; 582 } 583 584 @Override /* Overridden from Builder */ 585 public Builder ignoreUnknownBeanProperties() { 586 super.ignoreUnknownBeanProperties(); 587 return this; 588 } 589 590 @Override /* Overridden from Builder */ 591 public Builder ignoreUnknownEnumValues() { 592 super.ignoreUnknownEnumValues(); 593 return this; 594 } 595 596 @Override /* Overridden from Builder */ 597 public Builder implClass(Class<?> interfaceClass, Class<?> implClass) { 598 super.implClass(interfaceClass, implClass); 599 return this; 600 } 601 602 @Override /* Overridden from Builder */ 603 public Builder implClasses(Map<Class<?>,Class<?>> values) { 604 super.implClasses(values); 605 return this; 606 } 607 608 @Override /* Overridden from Builder */ 609 public Builder interfaceClass(Class<?> on, Class<?> value) { 610 super.interfaceClass(on, value); 611 return this; 612 } 613 614 @Override /* Overridden from Builder */ 615 public Builder interfaces(java.lang.Class<?>...value) { 616 super.interfaces(value); 617 return this; 618 } 619 620 @Override /* Overridden from Builder */ 621 public Builder locale(Locale value) { 622 super.locale(value); 623 return this; 624 } 625 626 @Override /* Overridden from Builder */ 627 public Builder mediaType(MediaType value) { 628 super.mediaType(value); 629 return this; 630 } 631 632 @Override /* Overridden from Builder */ 633 public Builder notBeanClasses(java.lang.Class<?>...values) { 634 super.notBeanClasses(values); 635 return this; 636 } 637 638 @Override /* Overridden from Builder */ 639 public Builder notBeanPackages(String...values) { 640 super.notBeanPackages(values); 641 return this; 642 } 643 644 @Override /* Overridden from Builder */ 645 public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) { 646 super.propertyNamer(value); 647 return this; 648 } 649 650 @Override /* Overridden from Builder */ 651 public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) { 652 super.propertyNamer(on, value); 653 return this; 654 } 655 656 @Override /* Overridden from Builder */ 657 public Builder sortProperties() { 658 super.sortProperties(); 659 return this; 660 } 661 662 @Override /* Overridden from Builder */ 663 public Builder sortProperties(java.lang.Class<?>...on) { 664 super.sortProperties(on); 665 return this; 666 } 667 668 @Override /* Overridden from Builder */ 669 public Builder stopClass(Class<?> on, Class<?> value) { 670 super.stopClass(on, value); 671 return this; 672 } 673 674 @Override /* Overridden from Builder */ 675 public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) { 676 super.swap(normalClass, swappedClass, swapFunction); 677 return this; 678 } 679 680 @Override /* Overridden from Builder */ 681 public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) { 682 super.swap(normalClass, swappedClass, swapFunction, unswapFunction); 683 return this; 684 } 685 686 @Override /* Overridden from Builder */ 687 public Builder swaps(Object...values) { 688 super.swaps(values); 689 return this; 690 } 691 692 @Override /* Overridden from Builder */ 693 public Builder swaps(Class<?>...values) { 694 super.swaps(values); 695 return this; 696 } 697 698 @Override /* Overridden from Builder */ 699 public Builder timeZone(TimeZone value) { 700 super.timeZone(value); 701 return this; 702 } 703 704 @Override /* Overridden from Builder */ 705 public Builder typeName(Class<?> on, String value) { 706 super.typeName(on, value); 707 return this; 708 } 709 710 @Override /* Overridden from Builder */ 711 public Builder typePropertyName(String value) { 712 super.typePropertyName(value); 713 return this; 714 } 715 716 @Override /* Overridden from Builder */ 717 public Builder typePropertyName(Class<?> on, String value) { 718 super.typePropertyName(on, value); 719 return this; 720 } 721 722 @Override /* Overridden from Builder */ 723 public Builder useEnumNames() { 724 super.useEnumNames(); 725 return this; 726 } 727 728 @Override /* Overridden from Builder */ 729 public Builder useJavaBeanIntrospector() { 730 super.useJavaBeanIntrospector(); 731 return this; 732 } 733 734 @Override /* Overridden from Builder */ 735 public Builder detectRecursions() { 736 super.detectRecursions(); 737 return this; 738 } 739 740 @Override /* Overridden from Builder */ 741 public Builder detectRecursions(boolean value) { 742 super.detectRecursions(value); 743 return this; 744 } 745 746 @Override /* Overridden from Builder */ 747 public Builder ignoreRecursions() { 748 super.ignoreRecursions(); 749 return this; 750 } 751 752 @Override /* Overridden from Builder */ 753 public Builder ignoreRecursions(boolean value) { 754 super.ignoreRecursions(value); 755 return this; 756 } 757 758 @Override /* Overridden from Builder */ 759 public Builder initialDepth(int value) { 760 super.initialDepth(value); 761 return this; 762 } 763 764 @Override /* Overridden from Builder */ 765 public Builder maxDepth(int value) { 766 super.maxDepth(value); 767 return this; 768 } 769 770 @Override /* Overridden from Builder */ 771 public Builder accept(String value) { 772 super.accept(value); 773 return this; 774 } 775 776 @Override /* Overridden from Builder */ 777 public Builder addBeanTypes() { 778 super.addBeanTypes(); 779 return this; 780 } 781 782 @Override /* Overridden from Builder */ 783 public Builder addBeanTypes(boolean value) { 784 super.addBeanTypes(value); 785 return this; 786 } 787 788 @Override /* Overridden from Builder */ 789 public Builder addRootType() { 790 super.addRootType(); 791 return this; 792 } 793 794 @Override /* Overridden from Builder */ 795 public Builder addRootType(boolean value) { 796 super.addRootType(value); 797 return this; 798 } 799 800 @Override /* Overridden from Builder */ 801 public Builder keepNullProperties() { 802 super.keepNullProperties(); 803 return this; 804 } 805 806 @Override /* Overridden from Builder */ 807 public Builder keepNullProperties(boolean value) { 808 super.keepNullProperties(value); 809 return this; 810 } 811 812 @Override /* Overridden from Builder */ 813 public Builder listener(Class<? extends org.apache.juneau.serializer.SerializerListener> value) { 814 super.listener(value); 815 return this; 816 } 817 818 @Override /* Overridden from Builder */ 819 public Builder produces(String value) { 820 super.produces(value); 821 return this; 822 } 823 824 @Override /* Overridden from Builder */ 825 public Builder sortCollections() { 826 super.sortCollections(); 827 return this; 828 } 829 830 @Override /* Overridden from Builder */ 831 public Builder sortCollections(boolean value) { 832 super.sortCollections(value); 833 return this; 834 } 835 836 @Override /* Overridden from Builder */ 837 public Builder sortMaps() { 838 super.sortMaps(); 839 return this; 840 } 841 842 @Override /* Overridden from Builder */ 843 public Builder sortMaps(boolean value) { 844 super.sortMaps(value); 845 return this; 846 } 847 848 @Override /* Overridden from Builder */ 849 public Builder trimEmptyCollections() { 850 super.trimEmptyCollections(); 851 return this; 852 } 853 854 @Override /* Overridden from Builder */ 855 public Builder trimEmptyCollections(boolean value) { 856 super.trimEmptyCollections(value); 857 return this; 858 } 859 860 @Override /* Overridden from Builder */ 861 public Builder trimEmptyMaps() { 862 super.trimEmptyMaps(); 863 return this; 864 } 865 866 @Override /* Overridden from Builder */ 867 public Builder trimEmptyMaps(boolean value) { 868 super.trimEmptyMaps(value); 869 return this; 870 } 871 872 @Override /* Overridden from Builder */ 873 public Builder trimStrings() { 874 super.trimStrings(); 875 return this; 876 } 877 878 @Override /* Overridden from Builder */ 879 public Builder trimStrings(boolean value) { 880 super.trimStrings(value); 881 return this; 882 } 883 884 @Override /* Overridden from Builder */ 885 public Builder uriContext(UriContext value) { 886 super.uriContext(value); 887 return this; 888 } 889 890 @Override /* Overridden from Builder */ 891 public Builder uriRelativity(UriRelativity value) { 892 super.uriRelativity(value); 893 return this; 894 } 895 896 @Override /* Overridden from Builder */ 897 public Builder uriResolution(UriResolution value) { 898 super.uriResolution(value); 899 return this; 900 } 901 902 @Override /* Overridden from Builder */ 903 public Builder fileCharset(Charset value) { 904 super.fileCharset(value); 905 return this; 906 } 907 908 @Override /* Overridden from Builder */ 909 public Builder maxIndent(int value) { 910 super.maxIndent(value); 911 return this; 912 } 913 914 @Override /* Overridden from Builder */ 915 public Builder quoteChar(char value) { 916 super.quoteChar(value); 917 return this; 918 } 919 920 @Override /* Overridden from Builder */ 921 public Builder quoteCharOverride(char value) { 922 super.quoteCharOverride(value); 923 return this; 924 } 925 926 @Override /* Overridden from Builder */ 927 public Builder sq() { 928 super.sq(); 929 return this; 930 } 931 932 @Override /* Overridden from Builder */ 933 public Builder streamCharset(Charset value) { 934 super.streamCharset(value); 935 return this; 936 } 937 938 @Override /* Overridden from Builder */ 939 public Builder useWhitespace() { 940 super.useWhitespace(); 941 return this; 942 } 943 944 @Override /* Overridden from Builder */ 945 public Builder useWhitespace(boolean value) { 946 super.useWhitespace(value); 947 return this; 948 } 949 950 @Override /* Overridden from Builder */ 951 public Builder ws() { 952 super.ws(); 953 return this; 954 } 955 956 @Override /* Overridden from Builder */ 957 public Builder addBeanTypesJson() { 958 super.addBeanTypesJson(); 959 return this; 960 } 961 962 @Override /* Overridden from Builder */ 963 public Builder addBeanTypesJson(boolean value) { 964 super.addBeanTypesJson(value); 965 return this; 966 } 967 968 @Override /* Overridden from Builder */ 969 public Builder escapeSolidus() { 970 super.escapeSolidus(); 971 return this; 972 } 973 974 @Override /* Overridden from Builder */ 975 public Builder escapeSolidus(boolean value) { 976 super.escapeSolidus(value); 977 return this; 978 } 979 980 @Override /* Overridden from Builder */ 981 public Builder simpleAttrs() { 982 super.simpleAttrs(); 983 return this; 984 } 985 986 @Override /* Overridden from Builder */ 987 public Builder simpleAttrs(boolean value) { 988 super.simpleAttrs(value); 989 return this; 990 } 991 992 @Override /* Overridden from Builder */ 993 public Builder json5() { 994 super.json5(); 995 return this; 996 } 997 } 998 999 //------------------------------------------------------------------------------------------------------------------- 1000 // Instance 1001 //------------------------------------------------------------------------------------------------------------------- 1002 1003 final JsonSchemaGenerator generator; 1004 1005 private final Map<ClassMeta<?>,JsonSchemaClassMeta> jsonSchemaClassMetas = new ConcurrentHashMap<>(); 1006 private final Map<BeanPropertyMeta,JsonSchemaBeanPropertyMeta> jsonSchemaBeanPropertyMetas = new ConcurrentHashMap<>(); 1007 1008 /** 1009 * Constructor. 1010 * 1011 * @param builder The builder for this object. 1012 */ 1013 public JsonSchemaSerializer(Builder builder) { 1014 super(builder.detectRecursions().ignoreRecursions()); 1015 1016 generator = builder.generatorBuilder.build(); 1017 } 1018 1019 @Override /* Context */ 1020 public Builder copy() { 1021 return new Builder(this); 1022 } 1023 1024 @Override /* Context */ 1025 public JsonSchemaSerializerSession.Builder createSession() { 1026 return JsonSchemaSerializerSession.create(this); 1027 } 1028 1029 @Override /* Context */ 1030 public JsonSchemaSerializerSession getSession() { 1031 return createSession().build(); 1032 } 1033 1034 JsonSchemaGenerator getGenerator() { 1035 return generator; 1036 } 1037 1038 //----------------------------------------------------------------------------------------------------------------- 1039 // Extended metadata 1040 //----------------------------------------------------------------------------------------------------------------- 1041 1042 @Override /* JsonSchemaMetaProvider */ 1043 public JsonSchemaClassMeta getJsonSchemaClassMeta(ClassMeta<?> cm) { 1044 JsonSchemaClassMeta m = jsonSchemaClassMetas.get(cm); 1045 if (m == null) { 1046 m = new JsonSchemaClassMeta(cm, this); 1047 jsonSchemaClassMetas.put(cm, m); 1048 } 1049 return m; 1050 } 1051 1052 @Override /* JsonSchemaMetaProvider */ 1053 public JsonSchemaBeanPropertyMeta getJsonSchemaBeanPropertyMeta(BeanPropertyMeta bpm) { 1054 JsonSchemaBeanPropertyMeta m = jsonSchemaBeanPropertyMetas.get(bpm); 1055 if (m == null) { 1056 m = new JsonSchemaBeanPropertyMeta(bpm.getDelegateFor(), this); 1057 jsonSchemaBeanPropertyMetas.put(bpm, m); 1058 } 1059 return m; 1060 } 1061 1062 //----------------------------------------------------------------------------------------------------------------- 1063 // Other methods 1064 //----------------------------------------------------------------------------------------------------------------- 1065 1066 @Override /* Context */ 1067 protected JsonMap properties() { 1068 return filteredMap("generator", generator); 1069 } 1070}