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