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; 018 019import static org.apache.juneau.collections.JsonMap.*; 020 021import java.beans.*; 022import java.io.*; 023import java.lang.annotation.*; 024import java.lang.reflect.*; 025import java.util.*; 026import java.util.function.*; 027 028import org.apache.juneau.annotation.*; 029import org.apache.juneau.collections.*; 030import org.apache.juneau.internal.*; 031import org.apache.juneau.swap.*; 032import org.apache.juneau.utils.*; 033 034/** 035 * Context class for classes that use {@link BeanContext} objects. 036 * 037 * <p> 038 * This abstraction exists to allow different kinds of subclasses (e.g. JsonSerilalizer, XmlParser...) to share bean context objects since 039 * bean context objects are heavyweight objects that cache metadata about encountered beans. 040 * 041 * <h5 class='section'>Notes:</h5><ul> 042 * <li class='note'>This class is thread safe and reusable. 043 * </ul> 044 */ 045public abstract class BeanContextable extends Context { 046 047 //----------------------------------------------------------------------------------------------------------------- 048 // Builder 049 //----------------------------------------------------------------------------------------------------------------- 050 051 /** 052 * Builder class. 053 */ 054 public abstract static class Builder extends Context.Builder { 055 056 BeanContext.Builder bcBuilder; 057 BeanContext bc; 058 059 /** 060 * Constructor. 061 * 062 * All default settings. 063 */ 064 protected Builder() { 065 this.bcBuilder = BeanContext.create(); 066 registerBuilders(bcBuilder); 067 } 068 069 /** 070 * Copy constructor. 071 * 072 * @param copyFrom The bean to copy from. 073 */ 074 protected Builder(BeanContextable copyFrom) { 075 super(copyFrom); 076 this.bcBuilder = copyFrom.getBeanContext().copy(); 077 registerBuilders(bcBuilder); 078 } 079 080 /** 081 * Copy constructor. 082 * 083 * @param copyFrom The builder to copy from. 084 */ 085 protected Builder(Builder copyFrom) { 086 super(copyFrom); 087 this.bcBuilder = copyFrom.bcBuilder.copy(); 088 this.bc = copyFrom.bc; 089 registerBuilders(bcBuilder); 090 } 091 092 @Override /* Context.Builder */ 093 public abstract Builder copy(); 094 095 @Override /* Context.Builder */ 096 public HashKey hashKey() { 097 return HashKey.of( 098 super.hashKey(), 099 bcBuilder.hashKey(), 100 bc == null ? 0 : bc.hashKey 101 ); 102 } 103 104 /** 105 * Returns the inner bean context builder. 106 * 107 * @return The inner bean context builder. 108 */ 109 public BeanContext.Builder beanContext() { 110 return bcBuilder; 111 } 112 113 /** 114 * Applies an operation to the inner bean context builder. 115 * 116 * @param operation The operation to apply. 117 * @return This object. 118 */ 119 public final Builder beanContext(Consumer<BeanContext.Builder> operation) { 120 operation.accept(beanContext()); 121 return this; 122 } 123 124 //----------------------------------------------------------------------------------------------------------------- 125 // Properties 126 //----------------------------------------------------------------------------------------------------------------- 127 128 /** 129 * Overrides the bean context builder. 130 * 131 * <p> 132 * Used when sharing bean context builders across multiple context objects. 133 * For example, {@link org.apache.juneau.jsonschema.JsonSchemaGenerator.Builder} uses this to apply common bean settings with the JSON 134 * serializer and parser. 135 * 136 * @param value The new value for this setting. 137 * @return This object. 138 */ 139 public Builder beanContext(BeanContext.Builder value) { 140 this.bcBuilder = value; 141 return this; 142 } 143 144 /** 145 * Specifies an already-instantiated bean context to use. 146 * 147 * <p> 148 * Provides an optimization for cases where serializers and parsers can use an existing 149 * bean context without having to go through <c><jv>beanContext</jv>.copy().build()</c>. 150 * An example is {@link BeanContext#getBeanToStringSerializer()}. 151 * 152 * @param value The bean context to use. 153 * @return This object. 154 */ 155 public Builder beanContext(BeanContext value) { 156 this.bc = value; 157 return this; 158 } 159 160 /** 161 * Minimum bean class visibility. 162 * 163 * <p> 164 * Classes are not considered beans unless they meet the minimum visibility requirements. 165 * For example, if the visibility is <jsf>PUBLIC</jsf> and the bean class is <jk>protected</jk>, then the class 166 * will not be interpreted as a bean class and be serialized as a string. 167 * Use this setting to reduce the visibility requirement. 168 * 169 * <h5 class='section'>Example:</h5> 170 * <p class='bjava'> 171 * <jc>// A bean with a protected class and one field.</jc> 172 * <jk>protected class</jk> MyBean { 173 * <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>; 174 * } 175 * 176 * <jc>// Create a serializer that's capable of serializing the class.</jc> 177 * WriterSerializer <jv>serializer</jv> = JsonSerializer 178 * .<jsm>create</jsm>() 179 * .beanClassVisibility(<jsf>PROTECTED</jsf>) 180 * .build(); 181 * 182 * <jc>// Produces: {"foo","bar"}</jc> 183 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 184 * </p> 185 * 186 * <h5 class='section'>Notes:</h5> 187 * <ul> 188 * <li class='note'>The {@link Bean @Bean} annotation can be used on a non-public bean class to override this setting. 189 * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a public bean class to ignore it as a bean. 190 * </ul> 191 * 192 * <h5 class='section'>See Also:</h5> 193 * <ul> 194 * <li class='ja'>{@link BeanConfig#beanClassVisibility()} 195 * </ul> 196 * 197 * @param value 198 * The new value for this setting. 199 * <br>The default is {@link Visibility#PUBLIC}. 200 * @return This object. 201 */ 202 public Builder beanClassVisibility(Visibility value) { 203 bcBuilder.beanClassVisibility(value); 204 return this; 205 } 206 207 /** 208 * Minimum bean constructor visibility. 209 * 210 * <p> 211 * Only look for constructors with the specified minimum visibility. 212 * 213 * <p> 214 * This setting affects the logic for finding no-arg constructors for bean. Normally, only <jk>public</jk> no-arg 215 * constructors are used. Use this setting if you want to reduce the visibility requirement. 216 * 217 * <h5 class='section'>Example:</h5> 218 * <p class='bjava'> 219 * <jc>// A bean with a protected constructor and one field.</jc> 220 * <jk>public class</jk> MyBean { 221 * <jk>public</jk> String <jf>foo</jf>; 222 * 223 * <jk>protected</jk> MyBean() {} 224 * } 225 * 226 * <jc>// Create a parser capable of calling the protected constructor.</jc> 227 * ReaderParser <jv>parser</jv> = ReaderParser 228 * .<jsm>create</jsm>() 229 * .beanConstructorVisibility(<jsf>PROTECTED</jsf>) 230 * .build(); 231 * 232 * <jc>// Use it.</jc> 233 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"{foo:'bar'}"</js>, MyBean.<jk>class</jk>); 234 * </p> 235 * 236 * <h5 class='section'>Notes:</h5><ul> 237 * <li class='note'>The {@link Beanc @Beanc} annotation can also be used to expose a non-public constructor. 238 * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a public bean constructor to ignore it. 239 * </ul> 240 * 241 * <h5 class='section'>See Also:</h5><ul> 242 * <li class='ja'>{@link BeanConfig#beanConstructorVisibility()} 243 * </ul> 244 * 245 * @param value 246 * The new value for this setting. 247 * <br>The default is {@link Visibility#PUBLIC}. 248 * @return This object. 249 */ 250 public Builder beanConstructorVisibility(Visibility value) { 251 bcBuilder.beanConstructorVisibility(value); 252 return this; 253 } 254 255 /** 256 * Minimum bean field visibility. 257 * 258 * <p> 259 * Only look for bean fields with the specified minimum visibility. 260 * 261 * <p> 262 * This affects which fields on a bean class are considered bean properties. Normally only <jk>public</jk> fields are considered. 263 * Use this setting if you want to reduce the visibility requirement. 264 * 265 * <h5 class='section'>Example:</h5> 266 * <p class='bjava'> 267 * <jc>// A bean with a protected field.</jc> 268 * <jk>public class</jk> MyBean { 269 * <jk>protected</jk> String <jf>foo</jf> = <js>"bar"</js>; 270 * } 271 * 272 * <jc>// Create a serializer that recognizes the protected field.</jc> 273 * WriterSerializer <jv>serializer</jv> = JsonSerializer 274 * .<jsm>create</jsm>() 275 * .beanFieldVisibility(<jsf>PROTECTED</jsf>) 276 * .build(); 277 * 278 * <jc>// Produces: {"foo":"bar"}</jc> 279 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 280 * </p> 281 * 282 * <p> 283 * Bean fields can be ignored as properties entirely by setting the value to {@link Visibility#NONE} 284 * 285 * <p class='bjava'> 286 * <jc>// Disable using fields as properties entirely.</jc> 287 * WriterSerializer <jv>serializer</jv> = JsonSerializer 288 * .<jsm>create</jsm>() 289 * .beanFieldVisibility(<jsf>NONE</jsf>) 290 * .build(); 291 * </p> 292 * 293 * <h5 class='section'>Notes:</h5><ul> 294 * <li class='note'>The {@link Beanp @Beanp} annotation can also be used to expose a non-public field. 295 * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a public bean field to ignore it as a bean property. 296 * </ul> 297 * 298 * <h5 class='section'>See Also:</h5><ul> 299 * <li class='ja'>{@link BeanConfig#beanFieldVisibility()} 300 * </ul> 301 * 302 * @param value 303 * The new value for this setting. 304 * <br>The default is {@link Visibility#PUBLIC}. 305 * @return This object. 306 */ 307 public Builder beanFieldVisibility(Visibility value) { 308 bcBuilder.beanFieldVisibility(value); 309 return this; 310 } 311 312 /** 313 * Bean interceptor. 314 * 315 * <p> 316 * Bean interceptors can be used to intercept calls to getters and setters and alter their values in transit. 317 * 318 * <h5 class='section'>Example:</h5> 319 * <p class='bjava'> 320 * <jc>// Interceptor that strips out sensitive information.</jc> 321 * <jk>public class</jk> AddressInterceptor <jk>extends</jk> BeanInterceptor<Address> { 322 * 323 * <jk>public</jk> Object readProperty(Address <jv>bean</jv>, String <jv>name</jv>, Object <jv>value</jv>) { 324 * <jk>if</jk> (<js>"taxInfo"</js>.equals(<jv>name</jv>)) 325 * <jk>return</jk> <js>"redacted"</js>; 326 * <jk>return</jk> <jv>value</jv>; 327 * } 328 * 329 * <jk>public</jk> Object writeProperty(Address <jv>bean</jv>, String <jv>name</jv>, Object <jv>value</jv>) { 330 * <jk>if</jk> (<js>"taxInfo"</js>.equals(<jv>name</jv>) && <js>"redacted"</js>.equals(<jv>value</jv>)) 331 * <jk>return</jk> TaxInfoUtils.<jsm>lookup</jsm>(<jv>bean</jv>.getStreet(), <jv>bean</jv>.getCity(), <jv>bean</jv>.getState()); 332 * <jk>return</jk> <jv>value</jv>; 333 * } 334 * } 335 * 336 * <jc>// Our bean class.</jc> 337 * <jk>public class</jk> Address { 338 * <jk>public</jk> String getTaxInfo() {...} 339 * <jk>public void</jk> setTaxInfo(String <jv>value</jv>) {...} 340 * } 341 * 342 * <jc>// Register filter on serializer or parser.</jc> 343 * WriterSerializer <jv>serializer</jv> = JsonSerializer 344 * .<jsm>create</jsm>() 345 * .beanInterceptor(Address.<jk>class</jk>, AddressInterceptor.<jk>class</jk>) 346 * .build(); 347 * 348 * <jc>// Produces: {"taxInfo":"redacted"}</jc> 349 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> Address()); 350 * </p> 351 * 352 * <h5 class='section'>See Also:</h5><ul> 353 * <li class='jc'>{@link BeanInterceptor} 354 * <li class='ja'>{@link Bean#interceptor() Bean(interceptor)} 355 * </ul> 356 * 357 * @param on The bean that the filter applies to. 358 * @param value 359 * The new value for this setting. 360 * @return This object. 361 */ 362 public Builder beanInterceptor(Class<?> on, Class<? extends BeanInterceptor<?>> value) { 363 bcBuilder.beanInterceptor(on, value); 364 return this; 365 } 366 367 /** 368 * BeanMap.put() returns old property value. 369 * 370 * <p> 371 * When enabled, then the {@link BeanMap#put(String,Object) BeanMap.put()} method will return old property 372 * values. Otherwise, it returns <jk>null</jk>. 373 * 374 * <p> 375 * Disabled by default because it introduces a slight performance penalty during serialization. 376 * 377 * <h5 class='section'>Example:</h5> 378 * <p class='bjava'> 379 * <jc>// Create a context that creates BeanMaps with normal put() behavior.</jc> 380 * BeanContext <jv>context</jv> = BeanContext 381 * .<jsm>create</jsm>() 382 * .beanMapPutReturnsOldValue() 383 * .build(); 384 * 385 * BeanMap<MyBean> <jv>beanMap</jv> = <jv>context</jv>.createSession().toBeanMap(<jk>new</jk> MyBean()); 386 * <jv>beanMap</jv>.put(<js>"foo"</js>, <js>"bar"</js>); 387 * Object <jv>oldValue</jv> = <jv>beanMap</jv>.put(<js>"foo"</js>, <js>"baz"</js>); <jc>// oldValue == "bar"</jc> 388 * </p> 389 * 390 * <h5 class='section'>See Also:</h5><ul> 391 * <li class='ja'>{@link BeanConfig#beanMapPutReturnsOldValue()} 392 * <li class='jm'>{@link BeanContext.Builder#beanMapPutReturnsOldValue()} 393 * </ul> 394 * 395 * @return This object. 396 */ 397 public Builder beanMapPutReturnsOldValue() { 398 bcBuilder.beanMapPutReturnsOldValue(); 399 return this; 400 } 401 402 /** 403 * Minimum bean method visibility. 404 * 405 * <p> 406 * Only look for bean methods with the specified minimum visibility. 407 * 408 * <p> 409 * This affects which methods are detected as getters and setters on a bean class. Normally only <jk>public</jk> getters and setters are considered. 410 * Use this setting if you want to reduce the visibility requirement. 411 * 412 * <h5 class='section'>Example:</h5> 413 * <p class='bjava'> 414 * <jc>// A bean with a protected getter.</jc> 415 * <jk>public class</jk> MyBean { 416 * <jk>public</jk> String getFoo() { <jk>return</jk> <js>"foo"</js>; } 417 * <jk>protected</jk> String getBar() { <jk>return</jk> <js>"bar"</js>; } 418 * } 419 * 420 * <jc>// Create a serializer that looks for protected getters and setters.</jc> 421 * WriterSerializer <jv>serializer</jv> = JsonSerializer 422 * .<jsm>create</jsm>() 423 * .beanMethodVisibility(<jsf>PROTECTED</jsf>) 424 * .build(); 425 * 426 * <jc>// Produces: {"foo":"foo","bar":"bar"}</jc> 427 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 428 * </p> 429 * 430 * <h5 class='section'>Notes:</h5><ul> 431 * <li class='note'>The {@link Beanp @Beanp} annotation can also be used to expose a non-public method. 432 * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a public bean getter/setter to ignore it as a bean property. 433 * </ul> 434 * 435 * <h5 class='section'>See Also:</h5><ul> 436 * <li class='ja'>{@link BeanConfig#beanMethodVisibility()} 437 * </ul> 438 * 439 * @param value 440 * The new value for this setting. 441 * <br>The default is {@link Visibility#PUBLIC} 442 * @return This object. 443 */ 444 public Builder beanMethodVisibility(Visibility value) { 445 bcBuilder.beanMethodVisibility(value); 446 return this; 447 } 448 449 /** 450 * Beans require no-arg constructors. 451 * 452 * <p> 453 * When enabled, a Java class must implement a default no-arg constructor to be considered a bean. 454 * Otherwise, the bean will be serialized as a string using the {@link Object#toString()} method. 455 * 456 * <h5 class='section'>Example:</h5> 457 * <p class='bjava'> 458 * <jc>// A bean without a no-arg constructor.</jc> 459 * <jk>public class</jk> MyBean { 460 * 461 * <jc>// A property method.</jc> 462 * <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>; 463 * 464 * <jc>// A no-arg constructor</jc> 465 * <jk>public</jk> MyBean(String <jv>foo</jv>) { 466 * <jk>this</jk>.<jf>foo</jf> = <jv>foo</jv>; 467 * } 468 * 469 * <ja>@Override</ja> 470 * <jk>public</jk> String toString() { 471 * <jk>return</jk> <js>"bar"</js>; 472 * } 473 * } 474 * 475 * <jc>// Create a serializer that ignores beans without default constructors.</jc> 476 * WriterSerializer <jv>serializer</jv> = JsonSerializer 477 * .<jsm>create</jsm>() 478 * .beansRequireDefaultConstructor() 479 * .build(); 480 * 481 * <jc>// Produces: "bar"</jc> 482 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 483 * </p> 484 * 485 * <h5 class='section'>Notes:</h5><ul> 486 * <li class='note'>The {@link Bean @Bean} annotation can be used on a bean class to override this setting. 487 * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a class to ignore it as a bean. 488 * </ul> 489 * 490 * <h5 class='section'>See Also:</h5><ul> 491 * <li class='ja'>{@link BeanConfig#beansRequireDefaultConstructor()} 492 * <li class='jm'>{@link BeanContext.Builder#beansRequireDefaultConstructor()} 493 * </ul> 494 * 495 * @return This object. 496 */ 497 public Builder beansRequireDefaultConstructor() { 498 bcBuilder.beansRequireDefaultConstructor(); 499 return this; 500 } 501 502 /** 503 * Beans require Serializable interface. 504 * 505 * <p> 506 * When enabled, a Java class must implement the {@link Serializable} interface to be considered a bean. 507 * Otherwise, the bean will be serialized as a string using the {@link Object#toString()} method. 508 * 509 * <h5 class='section'>Example:</h5> 510 * <p class='bjava'> 511 * <jc>// A bean without a Serializable interface.</jc> 512 * <jk>public class</jk> MyBean { 513 * 514 * <jc>// A property method.</jc> 515 * <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>; 516 * 517 * <ja>@Override</ja> 518 * <jk>public</jk> String toString() { 519 * <jk>return</jk> <js>"bar"</js>; 520 * } 521 * } 522 * 523 * <jc>// Create a serializer that ignores beans not implementing Serializable.</jc> 524 * WriterSerializer <jv>serializer</jv> = JsonSerializer 525 * .<jsm>create</jsm>() 526 * .beansRequireSerializable() 527 * .build(); 528 * 529 * <jc>// Produces: "bar"</jc> 530 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 531 * </p> 532 * 533 * <h5 class='section'>Notes:</h5><ul> 534 * <li class='note'>The {@link Bean @Bean} annotation can be used on a bean class to override this setting. 535 * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a class to ignore it as a bean. 536 * </ul> 537 * 538 * <h5 class='section'>See Also:</h5><ul> 539 * <li class='ja'>{@link BeanConfig#beansRequireSerializable()} 540 * <li class='jm'>{@link BeanContext.Builder#beansRequireSerializable()} 541 * </ul> 542 * 543 * @return This object. 544 */ 545 public Builder beansRequireSerializable() { 546 bcBuilder.beansRequireSerializable(); 547 return this; 548 } 549 550 /** 551 * Beans require setters for getters. 552 * 553 * <p> 554 * When enabled, ignore read-only properties (properties with getters but not setters). 555 * 556 * <h5 class='section'>Example:</h5> 557 * <p class='bjava'> 558 * <jc>// A bean without a Serializable interface.</jc> 559 * <jk>public class</jk> MyBean { 560 * 561 * <jc>// A read/write property.</jc> 562 * <jk>public</jk> String getFoo() { <jk>return</jk> <js>"foo"</js>; } 563 * <jk>public void</jk> setFoo(String <jv>foo</jv>) { ... } 564 * 565 * <jc>// A read-only property.</jc> 566 * <jk>public</jk> String getBar() { <jk>return</jk> <js>"bar"</js>; } 567 * } 568 * 569 * <jc>// Create a serializer that ignores bean properties without setters.</jc> 570 * WriterSerializer <jv>serializer</jv> = JsonSerializer 571 * .<jsm>create</jsm>() 572 * .beansRequireSettersForGetters() 573 * .build(); 574 * 575 * <jc>// Produces: {"foo":"foo"}</jc> 576 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 577 * </p> 578 * 579 * <h5 class='section'>Notes:</h5><ul> 580 * <li class='note'>The {@link Beanp @Beanp} annotation can be used on the getter to override this setting. 581 * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on getters to ignore them as bean properties. 582 * </ul> 583 * 584 * <h5 class='section'>See Also:</h5><ul> 585 * <li class='ja'>{@link BeanConfig#beansRequireSettersForGetters()} 586 * <li class='jm'>{@link BeanContext.Builder#beansRequireSettersForGetters()} 587 * </ul> 588 * 589 * @return This object. 590 */ 591 public Builder beansRequireSettersForGetters() { 592 bcBuilder.beansRequireSettersForGetters(); 593 return this; 594 } 595 596 /** 597 * Beans don't require at least one property. 598 * 599 * <p> 600 * When enabled, then a Java class doesn't need to contain at least 1 property to be considered a bean. 601 * Otherwise, the bean will be serialized as a string using the {@link Object#toString()} method. 602 * 603 * <p> 604 * The {@link Bean @Bean} annotation can be used on a class to override this setting when <jk>true</jk>. 605 * 606 * <h5 class='section'>Example:</h5> 607 * <p class='bjava'> 608 * <jc>// A bean with no properties.</jc> 609 * <jk>public class</jk> MyBean { 610 * } 611 * 612 * <jc>// Create a serializer that serializes beans even if they have zero properties.</jc> 613 * WriterSerializer <jv>serializer</jv> = JsonSerializer 614 * .<jsm>create</jsm>() 615 * .disableBeansRequireSomeProperties() 616 * .build(); 617 * 618 * <jc>// Produces: {}</jc> 619 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 620 * </p> 621 * 622 * <h5 class='section'>Notes:</h5><ul> 623 * <li class='note'>The {@link Bean @Bean} annotation can be used on the class to force it to be recognized as a bean class 624 * even if it has no properties. 625 * </ul> 626 * 627 * <h5 class='section'>See Also:</h5><ul> 628 * <li class='ja'>{@link BeanConfig#disableBeansRequireSomeProperties()} 629 * <li class='jm'>{@link BeanContext.Builder#disableBeansRequireSomeProperties()} 630 * </ul> 631 * 632 * @return This object. 633 */ 634 public Builder disableBeansRequireSomeProperties() { 635 bcBuilder.disableBeansRequireSomeProperties(); 636 return this; 637 } 638 639 /** 640 * Bean property includes. 641 * 642 * <p> 643 * Specifies the set and order of names of properties associated with the bean class. 644 * 645 * <p> 646 * For example, <c>beanProperties(MyBean.<jk>class</jk>, <js>"foo,bar"</js>)</c> means only serialize the <c>foo</c> and 647 * <c>bar</c> properties on the specified bean. Likewise, parsing will ignore any bean properties not specified 648 * and either throw an exception or silently ignore them depending on whether {@link #ignoreUnknownBeanProperties()} 649 * has been called. 650 * 651 * <p> 652 * This value is entirely optional if you simply want to expose all the getters and public fields on 653 * a class as bean properties. However, it's useful if you want certain getters to be ignored or you want the properties to be 654 * serialized in a particular order. Note that on IBM JREs, the property order is the same as the order in the source code, 655 * whereas on Oracle JREs, the order is entirely random. 656 * 657 * <p> 658 * Setting applies to specified class and all subclasses. 659 * 660 * <h5 class='section'>Example:</h5> 661 * <p class='bjava'> 662 * <jc>// A bean with 3 properties.</jc> 663 * <jk>public class</jk> MyBean { 664 * <jk>public</jk> String 665 * <jf>foo</jf> = <js>"foo"</js>, 666 * <jf>bar</jf> = <js>"bar"</js>, 667 * <jf>baz</jf> = <js>"baz"</js>; 668 * } 669 * 670 * <jc>// Create a serializer that includes only the 'foo' and 'bar' properties on the MyBean class.</jc> 671 * WriterSerializer <jv>serializer</jv> = JsonSerializer 672 * .<jsm>create</jsm>() 673 * .beanProperties(MyBean.<jk>class</jk>, <js>"foo,bar"</js>) 674 * .build(); 675 * 676 * <jc>// Produces: {"foo":"foo","bar":"bar"}</jc> 677 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 678 * </p> 679 * 680 * <p> 681 * This method is functionally equivalent to the following code: 682 * <p class='bjava'> 683 * <jv>builder</jv>.annotations(BeanAnnotation.<jsm>create</jsm>(<jv>beanClass</jv>).properties(<jv>properties</jv>).build()); 684 * </p> 685 * 686 * <h5 class='section'>See Also:</h5><ul> 687 * <li class='jm'>{@link Bean#properties()}/{@link Bean#p()} - On an annotation on the bean class itself. 688 * </ul> 689 * 690 * @param beanClass The bean class. 691 * @param properties Comma-delimited list of property names. 692 * @return This object. 693 */ 694 public Builder beanProperties(Class<?> beanClass, String properties) { 695 bcBuilder.beanProperties(beanClass, properties); 696 return this; 697 } 698 699 /** 700 * Bean property includes. 701 * 702 * <p> 703 * Specifies the set and order of names of properties associated with bean classes. 704 * 705 * <p> 706 * For example, <c>beanProperties(AMap.<jsm>of</jsm>(<js>"MyBean"</js>, <js>"foo,bar"</js>))</c> means only serialize the <c>foo</c> and 707 * <c>bar</c> properties on the specified bean. Likewise, parsing will ignore any bean properties not specified 708 * and either throw an exception or silently ignore them depending on whether {@link #ignoreUnknownBeanProperties()} 709 * has been called. 710 * 711 * <p> 712 * This value is entirely optional if you simply want to expose all the getters and public fields on 713 * a class as bean properties. However, it's useful if you want certain getters to be ignored or you want the properties to be 714 * serialized in a particular order. Note that on IBM JREs, the property order is the same as the order in the source code, 715 * whereas on Oracle JREs, the order is entirely random. 716 * 717 * <p> 718 * Setting applies to specified class and all subclasses. 719 * 720 * <h5 class='section'>Example:</h5> 721 * <p class='bjava'> 722 * <jc>// A bean with 3 properties.</jc> 723 * <jk>public class</jk> MyBean { 724 * <jk>public</jk> String 725 * <jf>foo</jf> = <js>"foo"</js>, 726 * <jf>bar</jf> = <js>"bar"</js>, 727 * <jf>baz</jf> = <js>"baz"</js>; 728 * } 729 * 730 * <jc>// Create a serializer that includes only the 'foo' and 'bar' properties on the MyBean class.</jc> 731 * WriterSerializer <jv>serializer</jv> = JsonSerializer 732 * .<jsm>create</jsm>() 733 * .beanProperties(AMap.<jsm>of</jsm>(<js>"MyBean"</js>, <js>"foo,bar"</js>)) 734 * .build(); 735 * 736 * <jc>// Produces: {"foo":"foo","bar":"bar"}</jc> 737 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 738 * </p> 739 * 740 * <p> 741 * This method is functionally equivalent to the following code for each entry: 742 * <p class='bjava'> 743 * <jv>builder</jv>.annotations(BeanAnnotation.<jsm>create</jsm>(<jv>key</jv>).properties(<jv>value</jv>.toString()).build()); 744 * </p> 745 * 746 * <h5 class='section'>See Also:</h5><ul> 747 * <li class='jma'>{@link Bean#properties()} / {@link Bean#p()}- On an annotation on the bean class itself. 748 * </ul> 749 * 750 * @param values 751 * The values to add to this builder. 752 * <br>Keys are bean class names which can be a simple name, fully-qualified name, or <js>"*"</js> for all beans. 753 * <br>Values are comma-delimited lists of property names. Non-String objects are first converted to Strings. 754 * @return This object. 755 */ 756 public Builder beanProperties(Map<String,Object> values) { 757 bcBuilder.beanProperties(values); 758 return this; 759 } 760 761 /** 762 * Bean property includes. 763 * 764 * <p> 765 * Specifies the set and order of names of properties associated with the bean class. 766 * 767 * <p> 768 * For example, <c>beanProperties(<js>"MyBean"</js>, <js>"foo,bar"</js>)</c> means only serialize the <c>foo</c> and 769 * <c>bar</c> properties on the specified bean. Likewise, parsing will ignore any bean properties not specified 770 * and either throw an exception or silently ignore them depending on whether {@link #ignoreUnknownBeanProperties()} 771 * has been called. 772 * 773 * <p> 774 * This value is entirely optional if you simply want to expose all the getters and public fields on 775 * a class as bean properties. However, it's useful if you want certain getters to be ignored or you want the properties to be 776 * serialized in a particular order. Note that on IBM JREs, the property order is the same as the order in the source code, 777 * whereas on Oracle JREs, the order is entirely random. 778 * 779 * <p> 780 * Setting applies to specified class and all subclasses. 781 * 782 * <h5 class='section'>Example:</h5> 783 * <p class='bjava'> 784 * <jc>// A bean with 3 properties.</jc> 785 * <jk>public class</jk> MyBean { 786 * <jk>public</jk> String 787 * <jf>foo</jf> = <js>"foo"</js>, 788 * <jf>bar</jf> = <js>"bar"</js>, 789 * <jf>baz</jf> = <js>"baz"</js>; 790 * } 791 * 792 * <jc>// Create a serializer that includes only the 'foo' and 'bar' properties on the MyBean class.</jc> 793 * WriterSerializer <jv>serializer</jv> = JsonSerializer 794 * .<jsm>create</jsm>() 795 * .beanProperties(<js>"MyBean"</js>, <js>"foo,bar"</js>) 796 * .build(); 797 * 798 * <jc>// Produces: {"foo":"foo","bar":"bar"}</jc> 799 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 800 * </p> 801 * 802 * <p> 803 * This method is functionally equivalent to the following code: 804 * <p class='bjava'> 805 * <jv>builder</jv>.annotations(BeanAnnotation.<jsm>create</jsm>(<jv>beanClassName</jv>).properties(<jv>properties</jv>).build()); 806 * </p> 807 * 808 * <h5 class='section'>See Also:</h5><ul> 809 * <li class='jma'>{@link Bean#properties()} / {@link Bean#p()} - On an annotation on the bean class itself. 810 * </ul> 811 * 812 * @param beanClassName 813 * The bean class name. 814 * <br>Can be a simple name, fully-qualified name, or <js>"*"</js> for all beans. 815 * @param properties Comma-delimited list of property names. 816 * @return This object. 817 */ 818 public Builder beanProperties(String beanClassName, String properties) { 819 bcBuilder.beanProperties(beanClassName, properties); 820 return this; 821 } 822 823 /** 824 * Bean property excludes. 825 * 826 * <p> 827 * Specifies to exclude the specified list of properties for the specified bean class. 828 * 829 * <p> 830 * Same as {@link #beanProperties(Class, String)} except you specify a list of bean property names that you want to exclude from 831 * serialization. 832 * 833 * <p> 834 * Setting applies to specified class and all subclasses. 835 * 836 * <h5 class='section'>Example:</h5> 837 * <p class='bjava'> 838 * <jc>// A bean with 3 properties.</jc> 839 * <jk>public class</jk> MyBean { 840 * <jk>public</jk> String 841 * <jf>foo</jf> = <js>"foo"</js>, 842 * <jf>bar</jf> = <js>"bar"</js>, 843 * <jf>baz</jf> = <js>"baz"</js>; 844 * } 845 * 846 * <jc>// Create a serializer that excludes the "bar" and "baz" properties on the MyBean class.</jc> 847 * WriterSerializer <jv>serializer</jv> = JsonSerializer 848 * .<jsm>create</jsm>() 849 * .beanPropertiesExcludes(MyBean.<jk>class</jk>, <js>"bar,baz"</js>) 850 * .build(); 851 * 852 * <jc>// Produces: {"foo":"foo"}</jc> 853 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 854 * </p> 855 * 856 * <p> 857 * This method is functionally equivalent to the following code: 858 * <p class='bjava'> 859 * <jv>builder</jv>.annotations(BeanAnnotation.<jsm>create</jsm>(<jv>beanClass</jv>).excludeProperties(<jv>properties</jv>).build()); 860 * </p> 861 * 862 * <h5 class='section'>See Also:</h5><ul> 863 * <li class='jma'>{@link Bean#excludeProperties()} / {@link Bean#xp()} 864 * </ul> 865 * 866 * @param beanClass The bean class. 867 * @param properties Comma-delimited list of property names. 868 * @return This object. 869 */ 870 public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) { 871 bcBuilder.beanPropertiesExcludes(beanClass, properties); 872 return this; 873 } 874 875 /** 876 * Bean property excludes. 877 * 878 * <p> 879 * Specifies to exclude the specified list of properties for the specified bean classes. 880 * 881 * <p> 882 * Same as {@link #beanProperties(Map)} except you specify a list of bean property names that you want to exclude from 883 * serialization. 884 * 885 * <p> 886 * Setting applies to specified class and all subclasses. 887 * 888 * <h5 class='section'>Example:</h5> 889 * <p class='bjava'> 890 * <jc>// A bean with 3 properties.</jc> 891 * <jk>public class</jk> MyBean { 892 * <jk>public</jk> String 893 * <jf>foo</jf> = <js>"foo"</js>, 894 * <jf>bar</jf> = <js>"bar"</js>, 895 * <jf>baz</jf> = <js>"baz"</js>; 896 * } 897 * 898 * <jc>// Create a serializer that excludes the "bar" and "baz" properties on the MyBean class.</jc> 899 * WriterSerializer <jv>serializer</jv> = JsonSerializer 900 * .<jsm>create</jsm>() 901 * .beanPropertiesExcludes(AMap.of(<js>"MyBean"</js>, <js>"bar,baz"</js>)) 902 * .build(); 903 * 904 * <jc>// Produces: {"foo":"foo"}</jc> 905 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 906 * </p> 907 * 908 * <p> 909 * This method is functionally equivalent to the following code for each entry: 910 * <p class='bjava'> 911 * <jv>builder</jv>.annotations(BeanAnnotation.<jsm>create</jsm>(<jv>key</jv>).excludeProperties(<jv>value</jv>.toString()).build()); 912 * </p> 913 * 914 * <h5 class='section'>See Also:</h5><ul> 915 * <li class='jma'>{@link Bean#excludeProperties()} / {@link Bean#xp()} 916 * </ul> 917 * 918 * @param values 919 * The values to add to this builder. 920 * <br>Keys are bean class names which can be a simple name, fully-qualified name, or <js>"*"</js> for all beans. 921 * <br>Values are comma-delimited lists of property names. Non-String objects are first converted to Strings. 922 * @return This object. 923 */ 924 public Builder beanPropertiesExcludes(Map<String,Object> values) { 925 bcBuilder.beanPropertiesExcludes(values); 926 return this; 927 } 928 929 /** 930 * Bean property excludes. 931 * 932 * <p> 933 * Specifies to exclude the specified list of properties for the specified bean class. 934 * 935 * <p> 936 * Same as {@link #beanPropertiesExcludes(String, String)} except you specify a list of bean property names that you want to exclude from 937 * serialization. 938 * 939 * <p> 940 * Setting applies to specified class and all subclasses. 941 * 942 * <h5 class='section'>Example:</h5> 943 * <p class='bjava'> 944 * <jc>// A bean with 3 properties.</jc> 945 * <jk>public class</jk> MyBean { 946 * <jk>public</jk> String 947 * <jf>foo</jf> = <js>"foo"</js>, 948 * <jf>bar</jf> = <js>"bar"</js>, 949 * <jf>baz</jf> = <js>"baz"</js>; 950 * } 951 * 952 * <jc>// Create a serializer that excludes the "bar" and "baz" properties on the MyBean class.</jc> 953 * WriterSerializer <jv>serializer</jv> = JsonSerializer 954 * .<jsm>create</jsm>() 955 * .beanPropertiesExcludes(<js>"MyBean"</js>, <js>"bar,baz"</js>) 956 * .build(); 957 * 958 * <jc>// Produces: {"foo":"foo"}</jc> 959 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 960 * </p> 961 * 962 * <p> 963 * This method is functionally equivalent to the following code: 964 * <p class='bjava'> 965 * <jv>builder</jv>.annotations(BeanAnnotation.<jsm>create</jsm>(<jv>beanClassName</jv>).excludeProperties(<jv>properties</jv>).build()); 966 * </p> 967 * 968 * <h5 class='section'>See Also:</h5><ul> 969 * <li class='jma'>{@link Bean#excludeProperties()} / {@link Bean#xp()} 970 * </ul> 971 * 972 * @param beanClassName 973 * The bean class name. 974 * <br>Can be a simple name, fully-qualified name, or <js>"*"</js> for all bean classes. 975 * @param properties Comma-delimited list of property names. 976 * @return This object. 977 */ 978 public Builder beanPropertiesExcludes(String beanClassName, String properties) { 979 bcBuilder.beanPropertiesExcludes(beanClassName, properties); 980 return this; 981 } 982 983 /** 984 * Read-only bean properties. 985 * 986 * <p> 987 * Specifies one or more properties on a bean that are read-only despite having valid getters. 988 * Serializers will serialize such properties as usual, but parsers will silently ignore them. 989 * Note that this is different from the {@link #beanProperties(Class,String) beanProperties}/{@link #beanPropertiesExcludes(Class,String) beanPropertiesExcludes} settings which include or exclude properties 990 * for both serializers and parsers. 991 * 992 * <h5 class='section'>Example:</h5> 993 * <p class='bjava'> 994 * <jc>// A bean with 3 properties.</jc> 995 * <jk>public class</jk> MyBean { 996 * <jk>public</jk> String <jf>foo</jf>, <jf>bar</jf>, <jf>baz</jf>; 997 * } 998 * 999 * <jc>// Create a serializer with read-only property settings.</jc> 1000 * WriterSerializer <jv>serializer</jv> = JsonSerializer 1001 * .<jsm>create</jsm>() 1002 * .beanPropertiesReadOnly(MyBean.<jk>class</jk>, <js>"bar,baz"</js>) 1003 * .build(); 1004 * 1005 * <jc>// All 3 properties will be serialized.</jc> 1006 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 1007 * 1008 * <jc>// Create a parser with read-only property settings.</jc> 1009 * ReaderParser <jv>parser</jv> = JsonParser 1010 * .<jsm>create</jsm>() 1011 * .beanPropertiesReadOnly(MyBean.<jk>class</jk>, <js>"bar,baz"</js>) 1012 * .ignoreUnknownBeanProperties() 1013 * .build(); 1014 * 1015 * <jc>// Parser ignores bar and baz properties.</jc> 1016 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"{foo:'foo',bar:'bar',baz:'baz'}"</js>, MyBean.<jk>class</jk>); 1017 * </p> 1018 * 1019 * <p> 1020 * This method is functionally equivalent to the following code: 1021 * <p class='bjava'> 1022 * <jv>builder</jv>.annotations(BeanAnnotation.<jsm>create</jsm>(<jv>beanClass</jv>).readOnlyProperties(<jv>properties</jv>).build()); 1023 * </p> 1024 * 1025 * <h5 class='section'>See Also:</h5><ul> 1026 * <li class='jma'>{@link Bean#readOnlyProperties()} / {@link Bean#ro()} 1027 * </ul> 1028 * 1029 * @param beanClass The bean class. 1030 * @param properties Comma-delimited list of property names. 1031 * @return This object. 1032 */ 1033 public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) { 1034 bcBuilder.beanPropertiesReadOnly(beanClass, properties); 1035 return this; 1036 } 1037 1038 /** 1039 * Read-only bean properties. 1040 * 1041 * <p> 1042 * Specifies one or more properties on beans that are read-only despite having valid getters. 1043 * Serializers will serialize such properties as usual, but parsers will silently ignore them. 1044 * Note that this is different from the {@link #beanProperties(Class,String) beanProperties}/{@link #beanPropertiesExcludes(Class,String) beanPropertiesExcludes} settings which include or exclude properties 1045 * for both serializers and parsers. 1046 * 1047 * <h5 class='section'>Example:</h5> 1048 * <p class='bjava'> 1049 * <jc>// A bean with 3 properties.</jc> 1050 * <jk>public class</jk> MyBean { 1051 * <jk>public</jk> String <jf>foo</jf>, <jf>bar</jf>, <jf>baz</jf>; 1052 * } 1053 * 1054 * <jc>// Create a serializer with read-only property settings.</jc> 1055 * WriterSerializer <jv>serializer</jv> = JsonSerializer 1056 * .<jsm>create</jsm>() 1057 * .beanPropertiesReadOnly(AMap.<jsm>of</jsm>(<js>"MyBean"</js>, <js>"bar,baz"</js>)) 1058 * .build(); 1059 * 1060 * <jc>// All 3 properties will be serialized.</jc> 1061 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 1062 * 1063 * <jc>// Create a parser with read-only property settings.</jc> 1064 * ReaderParser <jv>parser</jv> = JsonParser 1065 * .<jsm>create</jsm>() 1066 * .beanPropertiesReadOnly(AMap.<jsm>of</jsm>(<js>"MyBean"</js>, <js>"bar,baz"</js>)) 1067 * .ignoreUnknownBeanProperties() 1068 * .build(); 1069 * 1070 * <jc>// Parser ignores bar and baz properties.</jc> 1071 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"{foo:'foo',bar:'bar',baz:'baz'}"</js>, MyBean.<jk>class</jk>); 1072 * </p> 1073 * 1074 * <p> 1075 * This method is functionally equivalent to the following code for each entry: 1076 * <p class='bjava'> 1077 * <jv>builder</jv>.annotations(BeanAnnotation.<jsm>create</jsm>(<jv>key</jv>).readOnlyProperties(<jv>value</jv>.toString()).build()); 1078 * </p> 1079 * 1080 * <h5 class='section'>See Also:</h5><ul> 1081 * <li class='jma'>{@link Bean#readOnlyProperties()} / {@link Bean#ro()} 1082 * </ul> 1083 * 1084 * @param values 1085 * The values to add to this builder. 1086 * <br>Keys are bean class names which can be a simple name, fully-qualified name, or <js>"*"</js> for all beans. 1087 * <br>Values are comma-delimited lists of property names. Non-String objects are first converted to Strings. 1088 * @return This object. 1089 */ 1090 public Builder beanPropertiesReadOnly(Map<String,Object> values) { 1091 bcBuilder.beanPropertiesReadOnly(values); 1092 return this; 1093 } 1094 1095 /** 1096 * Read-only bean properties. 1097 * 1098 * <p> 1099 * Specifies one or more properties on a bean that are read-only despite having valid getters. 1100 * Serializers will serialize such properties as usual, but parsers will silently ignore them. 1101 * Note that this is different from the {@link #beanProperties(Class,String) beanProperties}/{@link #beanPropertiesExcludes(Class,String) beanPropertiesExcludes} settings which include or exclude properties 1102 * for both serializers and parsers. 1103 * 1104 * <h5 class='section'>Example:</h5> 1105 * <p class='bjava'> 1106 * <jc>// A bean with 3 properties.</jc> 1107 * <jk>public class</jk> MyBean { 1108 * <jk>public</jk> String <jf>foo</jf>, <jf>bar</jf>, <jf>baz</jf>; 1109 * } 1110 * 1111 * <jc>// Create a serializer with read-only property settings.</jc> 1112 * WriterSerializer <jv>serializer</jv> = JsonSerializer 1113 * .<jsm>create</jsm>() 1114 * .beanPropertiesReadOnly(<js>"MyBean"</js>, <js>"bar,baz"</js>) 1115 * .build(); 1116 * 1117 * <jc>// All 3 properties will be serialized.</jc> 1118 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 1119 * 1120 * <jc>// Create a parser with read-only property settings.</jc> 1121 * ReaderParser <jv>parser</jv> = JsonParser 1122 * .<jsm>create</jsm>() 1123 * .beanPropertiesReadOnly(<js>"MyBean"</js>, <js>"bar,baz"</js>) 1124 * .ignoreUnknownBeanProperties() 1125 * .build(); 1126 * 1127 * <jc>// Parser ignores bar and baz properties.</jc> 1128 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"{foo:'foo',bar:'bar',baz:'baz'}"</js>, MyBean.<jk>class</jk>); 1129 * </p> 1130 * 1131 * <p> 1132 * This method is functionally equivalent to the following code: 1133 * <p class='bjava'> 1134 * <jv>builder</jv>.annotations(BeanAnnotation.<jsm>create</jsm>(<jv>beanClassName</jv>).readOnlyProperties(<jv>properties</jv>).build()); 1135 * </p> 1136 * 1137 * <h5 class='section'>See Also:</h5><ul> 1138 * <li class='jma'>{@link Bean#readOnlyProperties()} / {@link Bean#ro()} 1139 * </ul> 1140 * 1141 * @param beanClassName 1142 * The bean class name. 1143 * <br>Can be a simple name, fully-qualified name, or <js>"*"</js> for all bean classes. 1144 * @param properties Comma-delimited list of property names. 1145 * @return This object. 1146 */ 1147 public Builder beanPropertiesReadOnly(String beanClassName, String properties) { 1148 bcBuilder.beanPropertiesReadOnly(beanClassName, properties); 1149 return this; 1150 } 1151 1152 /** 1153 * Write-only bean properties. 1154 * 1155 * <p> 1156 * Specifies one or more properties on a bean that are write-only despite having valid setters. 1157 * Parsers will parse such properties as usual, but serializers will silently ignore them. 1158 * Note that this is different from the {@link #beanProperties(Class,String) beanProperties}/{@link #beanPropertiesExcludes(Class,String) beanPropertiesExcludes} settings which include or exclude properties 1159 * for both serializers and parsers. 1160 * 1161 * <h5 class='section'>Example:</h5> 1162 * <p class='bjava'> 1163 * <jc>// A bean with 3 properties.</jc> 1164 * <jk>public class</jk> MyBean { 1165 * <jk>public</jk> String <jf>foo</jf>, <jf>bar</jf>, <jf>baz</jf>; 1166 * } 1167 * 1168 * <jc>// Create a serializer with write-only property settings.</jc> 1169 * WriterSerializer <jv>serializer</jv> = JsonSerializer 1170 * .<jsm>create</jsm>() 1171 * .beanPropertiesWriteOnly(MyBean.<jk>class</jk>, <js>"bar,baz"</js>) 1172 * .build(); 1173 * 1174 * <jc>// Only foo will be serialized.</jc> 1175 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 1176 * 1177 * <jc>// Create a parser with write-only property settings.</jc> 1178 * ReaderParser <jv>parser</jv> = JsonParser 1179 * .<jsm>create</jsm>() 1180 * .beanPropertiesWriteOnly(MyBean.<jk>class</jk>, <js>"bar,baz"</js>) 1181 * .build(); 1182 * 1183 * <jc>// Parser parses all 3 properties.</jc> 1184 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"{foo:'foo',bar:'bar',baz:'baz'}"</js>, MyBean.<jk>class</jk>); 1185 * </p> 1186 * 1187 * <p> 1188 * This method is functionally equivalent to the following code: 1189 * <p class='bjava'> 1190 * <jv>builder</jv>.annotations(BeanAnnotation.<jsm>create</jsm>(<jv>beanClass</jv>).writeOnlyProperties(<jv>properties</jv>).build()); 1191 * </p> 1192 * 1193 * <h5 class='section'>See Also:</h5><ul> 1194 * <li class='jma'>{@link Bean#writeOnlyProperties()} / {@link Bean#wo()} 1195 * </ul> 1196 * 1197 * @param beanClass The bean class. 1198 * @param properties Comma-delimited list of property names. 1199 * @return This object. 1200 */ 1201 public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) { 1202 bcBuilder.beanPropertiesWriteOnly(beanClass, properties); 1203 return this; 1204 } 1205 1206 /** 1207 * Write-only bean properties. 1208 * 1209 * <p> 1210 * Specifies one or more properties on a bean that are write-only despite having valid setters. 1211 * Parsers will parse such properties as usual, but serializers will silently ignore them. 1212 * Note that this is different from the {@link #beanProperties(Class,String) beanProperties}/{@link #beanPropertiesExcludes(Class,String) beanPropertiesExcludes} settings which include or exclude properties 1213 * for both serializers and parsers. 1214 * 1215 * <h5 class='section'>Example:</h5> 1216 * <p class='bjava'> 1217 * <jc>// A bean with 3 properties.</jc> 1218 * <jk>public class</jk> MyBean { 1219 * <jk>public</jk> String <jf>foo</jf>, <jf>bar</jf>, <jf>baz</jf>; 1220 * } 1221 * 1222 * <jc>// Create a serializer with write-only property settings.</jc> 1223 * WriterSerializer <jv>serializer</jv> = JsonSerializer 1224 * .<jsm>create</jsm>() 1225 * .beanPropertiesWriteOnly(AMap.<jsm>of</jsm>(<js>"MyBean"</js>, <js>"bar,baz"</js>)) 1226 * .build(); 1227 * 1228 * <jc>// Only foo will be serialized.</jc> 1229 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 1230 * 1231 * <jc>// Create a parser with write-only property settings.</jc> 1232 * ReaderParser <jv>parser</jv> = JsonParser 1233 * .<jsm>create</jsm>() 1234 * .beanPropertiesWriteOnly(AMap.<jsm>of</jsm>(<js>"MyBean"</js>, <js>"bar,baz"</js>)) 1235 * .build(); 1236 * 1237 * <jc>// Parser parses all 3 properties.</jc> 1238 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"{foo:'foo',bar:'bar',baz:'baz'}"</js>, MyBean.<jk>class</jk>); 1239 * </p> 1240 * 1241 * <p> 1242 * This method is functionally equivalent to the following code for each entry: 1243 * <p class='bjava'> 1244 * <jv>builder</jv>.annotations(BeanAnnotation.<jsm>create</jsm>(<jv>key</jv>).writeOnlyProperties(<jv>value</jv>.toString()).build()); 1245 * </p> 1246 * 1247 * <h5 class='section'>See Also:</h5><ul> 1248 * <li class='jma'>{@link Bean#writeOnlyProperties()} / {@link Bean#wo()} 1249 * </ul> 1250 * 1251 * @param values 1252 * The values to add to this builder. 1253 * <br>Keys are bean class names which can be a simple name, fully-qualified name, or <js>"*"</js> for all beans. 1254 * <br>Values are comma-delimited lists of property names. Non-String objects are first converted to Strings. 1255 * @return This object. 1256 */ 1257 public Builder beanPropertiesWriteOnly(Map<String,Object> values) { 1258 bcBuilder.beanPropertiesWriteOnly(values); 1259 return this; 1260 } 1261 1262 /** 1263 * Write-only bean properties. 1264 * 1265 * <p> 1266 * Specifies one or more properties on a bean that are write-only despite having valid setters. 1267 * Parsers will parse such properties as usual, but serializers will silently ignore them. 1268 * Note that this is different from the {@link #beanProperties(Class,String) beanProperties}/{@link #beanPropertiesExcludes(Class,String) beanPropertiesExcludes} settings which include or exclude properties 1269 * for both serializers and parsers. 1270 * 1271 * <h5 class='section'>Example:</h5> 1272 * <p class='bjava'> 1273 * <jc>// A bean with 3 properties.</jc> 1274 * <jk>public class</jk> MyBean { 1275 * <jk>public</jk> String <jf>foo</jf>, <jf>bar</jf>, <jf>baz</jf>; 1276 * } 1277 * 1278 * <jc>// Create a serializer with write-only property settings.</jc> 1279 * WriterSerializer <jv>serializer</jv> = JsonSerializer 1280 * .<jsm>create</jsm>() 1281 * .beanPropertiesWriteOnly(<js>"MyBean"</js>, <js>"bar,baz"</js>) 1282 * .build(); 1283 * 1284 * <jc>// Only foo will be serialized.</jc> 1285 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 1286 * 1287 * <jc>// Create a parser with write-only property settings.</jc> 1288 * ReaderParser <jv>parser</jv> = JsonParser 1289 * .<jsm>create</jsm>() 1290 * .beanPropertiesWriteOnly(<js>"MyBean"</js>, <js>"bar,baz"</js>) 1291 * .build(); 1292 * 1293 * <jc>// Parser parses all 3 properties.</jc> 1294 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"{foo:'foo',bar:'bar',baz:'baz'}"</js>, MyBean.<jk>class</jk>); 1295 * </p> 1296 * 1297 * <p> 1298 * This method is functionally equivalent to the following code: 1299 * <p class='bjava'> 1300 * <jv>builder</jv>.annotations(BeanAnnotation.<jsm>create</jsm>(<jv>beanClassName</jv>).writeOnlyProperties(<jv>properties</jv>).build()); 1301 * </p> 1302 * 1303 * <h5 class='section'>See Also:</h5><ul> 1304 * <li class='jma'>{@link Bean#writeOnlyProperties()} / {@link Bean#wo()} 1305 * </ul> 1306 * 1307 * @param beanClassName 1308 * The bean class name. 1309 * <br>Can be a simple name, fully-qualified name, or <js>"*"</js> for all bean classes. 1310 * @param properties Comma-delimited list of property names. 1311 * @return This object. 1312 */ 1313 public Builder beanPropertiesWriteOnly(String beanClassName, String properties) { 1314 bcBuilder.beanPropertiesWriteOnly(beanClassName, properties); 1315 return this; 1316 } 1317 1318 /** 1319 * Bean dictionary. 1320 * 1321 * <p> 1322 * The list of classes that make up the bean dictionary in this bean context. 1323 * 1324 * <p> 1325 * Values are prepended to the list so that later calls can override classes of earlier calls. 1326 * 1327 * <p> 1328 * A dictionary is a name/class mapping used to find class types during parsing when they cannot be inferred 1329 * through reflection. The names are defined through the {@link Bean#typeName() @Bean(typeName)} annotation defined 1330 * on the bean class. For example, if a class <c>Foo</c> has a type-name of <js>"myfoo"</js>, then it would end up 1331 * serialized as <js>"{_type:'myfoo',...}"</js> in JSON 1332 * or <js>"<myfoo>...</myfoo>"</js> in XML. 1333 * 1334 * <p> 1335 * This setting tells the parsers which classes to look for when resolving <js>"_type"</js> attributes. 1336 * 1337 * <p> 1338 * Values can consist of any of the following types: 1339 * <ul> 1340 * <li>Any bean class that specifies a value for {@link Bean#typeName() @Bean(typeName)}. 1341 * <li>Any subclass of {@link BeanDictionaryList} containing a collection of bean classes with type name annotations. 1342 * <li>Any subclass of {@link BeanDictionaryMap} containing a mapping of type names to classes without type name annotations. 1343 * <li>Any array or collection of the objects above. 1344 * </ul> 1345 * 1346 * <h5 class='section'>Example:</h5> 1347 * <p class='bjava'> 1348 * <jc>// POJOs with @Bean(name) annotations.</jc> 1349 * <ja>@Bean</ja>(typeName=<js>"foo"</js>) 1350 * <jk>public class</jk> Foo {...} 1351 * <ja>@Bean</ja>(typeName=<js>"bar"</js>) 1352 * <jk>public class</jk> Bar {...} 1353 * 1354 * <jc>// Create a parser and tell it which classes to try to resolve.</jc> 1355 * ReaderParser <jv>parser</jv> = JsonParser 1356 * .<jsm>create</jsm>() 1357 * .dictionary(Foo.<jk>class</jk>, Bar.<jk>class</jk>) 1358 * .addBeanTypes() 1359 * .build(); 1360 * 1361 * <jc>// A bean with a field with an indeterminate type.</jc> 1362 * <jk>public class</jk> MyBean { 1363 * <jk>public</jk> Object <jf>mySimpleField</jf>; 1364 * } 1365 * 1366 * <jc>// Parse bean.</jc> 1367 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"{mySimpleField:{_type:'foo',...}}"</js>, MyBean.<jk>class</jk>); 1368 * </p> 1369 * 1370 * <p> 1371 * Another option is to use the {@link Bean#dictionary()} annotation on the POJO class itself: 1372 * 1373 * <p class='bjava'> 1374 * <jc>// Instead of by parser, define a bean dictionary on a class through an annotation.</jc> 1375 * <jc>// This applies to all properties on this class and all subclasses.</jc> 1376 * <ja>@Bean</ja>(dictionary={Foo.<jk>class</jk>,Bar.<jk>class</jk>}) 1377 * <jk>public class</jk> MyBean { 1378 * <jk>public</jk> Object <jf>mySimpleField</jf>; <jc>// May contain Foo or Bar object.</jc> 1379 * <jk>public</jk> Map<String,Object> <jf>myMapField</jf>; <jc>// May contain Foo or Bar objects.</jc> 1380 * } 1381 * </p> 1382 * 1383 * <p> 1384 * A typical usage is to allow for HTML documents to be parsed back into HTML beans: 1385 * <p class='bjava'> 1386 * <jc>// Use the predefined HTML5 bean dictionary which is a BeanDictionaryList.</jc> 1387 * ReaderParser <jv>parser</jv> = HtmlParser 1388 * .<jsm>create</jsm>() 1389 * .dictionary(HtmlBeanDictionary.<jk>class</jk>) 1390 * .build(); 1391 * 1392 * <jc>// Parse an HTML body into HTML beans.</jc> 1393 * Body <jv>body</jv> = <jv>parser</jv>.parse(<js>"<body><ul><li>foo</li><li>bar</li></ul>"</js>, Body.<jk>class</jk>); 1394 * </p> 1395 * 1396 * <h5 class='section'>See Also:</h5><ul> 1397 * <li class='ja'>{@link Bean#dictionary()} 1398 * <li class='ja'>{@link Beanp#dictionary()} 1399 * <li class='ja'>{@link BeanConfig#dictionary()} 1400 * <li class='ja'>{@link BeanConfig#dictionary_replace()} 1401 * </ul> 1402 * 1403 * @param values 1404 * The values to add to this setting. 1405 * @return This object. 1406 */ 1407 public Builder beanDictionary(Class<?>...values) { 1408 bcBuilder.beanDictionary(values); 1409 return this; 1410 } 1411 1412 /** 1413 * Bean dictionary. 1414 * 1415 * <p> 1416 * This is identical to {@link #beanDictionary(Class...)}, but specifies a dictionary within the context of 1417 * a single class as opposed to globally. 1418 * 1419 * <h5 class='section'>Example:</h5> 1420 * <p class='bjava'> 1421 * <jc>// POJOs with @Bean(name) annotations.</jc> 1422 * <ja>@Bean</ja>(typeName=<js>"foo"</js>) 1423 * <jk>public class</jk> Foo {...} 1424 * <ja>@Bean</ja>(typeName=<js>"bar"</js>) 1425 * <jk>public class</jk> Bar {...} 1426 * 1427 * <jc>// A bean with a field with an indeterminate type.</jc> 1428 * <jk>public class</jk> MyBean { 1429 * <jk>public</jk> Object <jf>mySimpleField</jf>; 1430 * } 1431 * 1432 * <jc>// Create a parser and tell it which classes to try to resolve.</jc> 1433 * ReaderParser <jv>parser</jv> = JsonParser 1434 * .<jsm>create</jsm>() 1435 * .dictionaryOn(MyBean.<jk>class</jk>, Foo.<jk>class</jk>, Bar.<jk>class</jk>) 1436 * .build(); 1437 * 1438 * <jc>// Parse bean.</jc> 1439 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"{mySimpleField:{_type:'foo',...}}"</js>, MyBean.<jk>class</jk>); 1440 * </p> 1441 * 1442 * <p> 1443 * This is functionally equivalent to the {@link Bean#dictionary()} annotation. 1444 * 1445 * <h5 class='section'>See Also:</h5><ul> 1446 * <li class='ja'>{@link Bean#dictionary()} 1447 * <li class='jm'>{@link BeanContext.Builder#beanDictionary(Class...)} 1448 * </ul> 1449 * 1450 * @param on The class that the dictionary values apply to. 1451 * @param values 1452 * The new values for this setting. 1453 * @return This object. 1454 */ 1455 public Builder dictionaryOn(Class<?> on, Class<?>...values) { 1456 bcBuilder.dictionaryOn(on, values); 1457 return this; 1458 } 1459 1460 /** 1461 * POJO example. 1462 * 1463 * <p> 1464 * Specifies an example of the specified class. 1465 * 1466 * <p> 1467 * Examples are used in cases such as POJO examples in Swagger documents. 1468 * 1469 * <h5 class='section'>Example:</h5> 1470 * <p class='bjava'> 1471 * <jc>// Create a serializer that excludes the 'foo' and 'bar' properties on the MyBean class.</jc> 1472 * WriterSerializer <jv>serializer</jv> = JsonSerializer 1473 * .<jsm>create</jsm>() 1474 * .example(MyBean.<jk>class</jk>, <jk>new</jk> MyBean().setFoo(<js>"foo"</js>).setBar(123)) 1475 * .build(); 1476 * </p> 1477 * 1478 * <p> 1479 * This is a shorthand method for the following code: 1480 * <p class='bjava'> 1481 * <jv>builder</jv>.annotations(MarshalledAnnotation.<jsm>create</jsm>(<jv>pojoClass</jv>).example(Json5.<jsf>DEFAULT</jsf>.toString(<jv>object</jv>)).build()) 1482 * </p> 1483 * 1484 * <h5 class='section'>Notes:</h5><ul> 1485 * <li class='note'>Using this method assumes the serialized form of the object is the same as that produced 1486 * by the default serializer. This may not be true based on settings or swaps on the constructed serializer. 1487 * </ul> 1488 * 1489 * <p> 1490 * POJO examples can also be defined on classes via the following: 1491 * <ul class='spaced-list'> 1492 * <li>The {@link Marshalled#example()} annotation on the class itself. 1493 * <li>A static field annotated with {@link Example @Example}. 1494 * <li>A static method annotated with {@link Example @Example} with zero arguments or one {@link BeanSession} argument. 1495 * <li>A static method with name <c>example</c> with no arguments or one {@link BeanSession} argument. 1496 * </ul> 1497 * 1498 * @param <T> The POJO class. 1499 * @param pojoClass The POJO class. 1500 * @param o 1501 * An instance of the POJO class used for examples. 1502 * @return This object. 1503 */ 1504 public <T> Builder example(Class<T> pojoClass, T o) { 1505 bcBuilder.example(pojoClass, o); 1506 return this; 1507 } 1508 1509 /** 1510 * POJO example. 1511 * 1512 * <p> 1513 * Specifies an example in JSON of the specified class. 1514 * 1515 * <p> 1516 * Examples are used in cases such as POJO examples in Swagger documents. 1517 * 1518 * <p> 1519 * Setting applies to specified class and all subclasses. 1520 * 1521 * <h5 class='section'>Example:</h5> 1522 * <p class='bjava'> 1523 * <jc>// Create a serializer that excludes the 'foo' and 'bar' properties on the MyBean class.</jc> 1524 * WriterSerializer <jv>serializer</jv> = JsonSerializer 1525 * .<jsm>create</jsm>() 1526 * .example(MyBean.<jk>class</jk>, <js>"{foo:'bar'}"</js>) 1527 * .build(); 1528 * </p> 1529 * 1530 * <p> 1531 * This is a shorthand method for the following code: 1532 * <p class='bjava'> 1533 * <jv>builder</jv>.annotations(MarshalledAnnotation.<jsm>create</jsm>(<jv>pojoClass</jv>).example(<jv>json</jv>).build()) 1534 * </p> 1535 * 1536 * <p> 1537 * POJO examples can also be defined on classes via the following: 1538 * <ul class='spaced-list'> 1539 * <li>A static field annotated with {@link Example @Example}. 1540 * <li>A static method annotated with {@link Example @Example} with zero arguments or one {@link BeanSession} argument. 1541 * <li>A static method with name <c>example</c> with no arguments or one {@link BeanSession} argument. 1542 * </ul> 1543 * 1544 * <h5 class='section'>See Also:</h5><ul> 1545 * <li class='ja'>{@link Marshalled#example()} 1546 * </ul> 1547 * 1548 * @param <T> The POJO class type. 1549 * @param pojoClass The POJO class. 1550 * @param json The JSON 5 representation of the example. 1551 * @return This object. 1552 */ 1553 public <T> Builder example(Class<T> pojoClass, String json) { 1554 bcBuilder.example(pojoClass, json); 1555 return this; 1556 } 1557 1558 /** 1559 * Find fluent setters. 1560 * 1561 * <p> 1562 * When enabled, fluent setters are detected on beans during parsing. 1563 * 1564 * <p> 1565 * Fluent setters must have the following attributes: 1566 * <ul> 1567 * <li>Public. 1568 * <li>Not static. 1569 * <li>Take in one parameter. 1570 * <li>Return the bean itself. 1571 * </ul> 1572 * 1573 * <h5 class='section'>Example:</h5> 1574 * <p class='bjava'> 1575 * <jc>// A bean with a fluent setter.</jc> 1576 * <jk>public class</jk> MyBean { 1577 * <jk>public</jk> MyBean foo(String <jv>value</jv>) {...} 1578 * } 1579 * 1580 * <jc>// Create a parser that finds fluent setters.</jc> 1581 * ReaderParser <jv>parser</jv> = JsonParser 1582 * .<jsm>create</jsm>() 1583 * .findFluentSetters() 1584 * .build(); 1585 * 1586 * <jc>// Parse into bean using fluent setter.</jc> 1587 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"{foo:'bar'}"</js>, MyBean.<jk>class</jk>); 1588 * </p> 1589 * 1590 * <h5 class='section'>Notes:</h5><ul> 1591 * <li class='note'>The {@link Beanp @Beanp} annotation can also be used on methods to individually identify them as fluent setters. 1592 * <li class='note'>The {@link Bean#findFluentSetters() @Bean.fluentSetters()} annotation can also be used on classes to specify to look for fluent setters. 1593 * </ul> 1594 * 1595 * <h5 class='section'>See Also:</h5><ul> 1596 * <li class='ja'>{@link Bean#findFluentSetters()} 1597 * <li class='ja'>{@link BeanConfig#findFluentSetters()} 1598 * <li class='jm'>{@link BeanContext.Builder#findFluentSetters()} 1599 * </ul> 1600 * 1601 * @return This object. 1602 */ 1603 public Builder findFluentSetters() { 1604 bcBuilder.findFluentSetters(); 1605 return this; 1606 } 1607 1608 /** 1609 * Find fluent setters. 1610 * 1611 * <p> 1612 * Identical to {@link #findFluentSetters()} but enables it on a specific class only. 1613 * 1614 * <h5 class='section'>Example:</h5> 1615 * <p class='bjava'> 1616 * <jc>// A bean with a fluent setter.</jc> 1617 * <jk>public class</jk> MyBean { 1618 * <jk>public</jk> MyBean foo(String <jv>value</jv>) {...} 1619 * } 1620 * 1621 * <jc>// Create a parser that finds fluent setters.</jc> 1622 * ReaderParser <jv>parser</jv> = JsonParser 1623 * .<jsm>create</jsm>() 1624 * .findFluentSetters(MyBean.<jk>class</jk>) 1625 * .build(); 1626 * 1627 * <jc>// Parse into bean using fluent setter.</jc> 1628 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"{foo:'bar'}"</js>, MyBean.<jk>class</jk>); 1629 * </p> 1630 * 1631 * <h5 class='section'>Notes:</h5><ul> 1632 * <li class='note'>This method is functionally equivalent to using the {@link Bean#findFluentSetters()} annotation. 1633 * </ul> 1634 * 1635 * <h5 class='section'>See Also:</h5><ul> 1636 * <li class='ja'>{@link Bean#findFluentSetters()} 1637 * <li class='jm'>{@link BeanContext.Builder#findFluentSetters()} 1638 * </ul> 1639 * 1640 * @param on The class that this applies to. 1641 * @return This object. 1642 */ 1643 public Builder findFluentSetters(Class<?> on) { 1644 bcBuilder.findFluentSetters(on); 1645 return this; 1646 } 1647 1648 /** 1649 * Ignore invocation errors on getters. 1650 * 1651 * <p> 1652 * When enabled, errors thrown when calling bean getter methods will silently be ignored. 1653 * Otherwise, a {@code BeanRuntimeException} is thrown. 1654 * 1655 * <h5 class='section'>Example:</h5> 1656 * <p class='bjava'> 1657 * <jc>// A bean with a property that throws an exception.</jc> 1658 * <jk>public class</jk> MyBean { 1659 * <jk>public</jk> String getFoo() { 1660 * <jk>throw new</jk> RuntimeException(<js>"foo"</js>); 1661 * } 1662 * } 1663 * 1664 * <jc>// Create a serializer that ignores bean getter exceptions.</jc> 1665 * WriterSerializer <jv>serializer</jv> = JsonSerializer 1666 * .<jsm>create</jsm>() 1667 * .ingoreInvocationExceptionsOnGetters() 1668 * .build(); 1669 * 1670 * <jc>// Exception is ignored.</jc> 1671 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 1672 * </p> 1673 * 1674 * <h5 class='section'>See Also:</h5><ul> 1675 * <li class='ja'>{@link BeanConfig#ignoreInvocationExceptionsOnGetters()} 1676 * <li class='jm'>{@link BeanContext.Builder#ignoreInvocationExceptionsOnGetters()} 1677 * </ul> 1678 * 1679 * @return This object. 1680 */ 1681 public Builder ignoreInvocationExceptionsOnGetters() { 1682 bcBuilder.ignoreInvocationExceptionsOnGetters(); 1683 return this; 1684 } 1685 1686 /** 1687 * Ignore invocation errors on setters. 1688 * 1689 * <p> 1690 * When enabled, errors thrown when calling bean setter methods will silently be ignored. 1691 * Otherwise, a {@code BeanRuntimeException} is thrown. 1692 * 1693 * <h5 class='section'>Example:</h5> 1694 * <p class='bjava'> 1695 * <jc>// A bean with a property that throws an exception.</jc> 1696 * <jk>public class</jk> MyBean { 1697 * <jk>public void</jk> setFoo(String <jv>foo</jv>) { 1698 * <jk>throw new</jk> RuntimeException(<js>"foo"</js>); 1699 * } 1700 * } 1701 * 1702 * <jc>// Create a parser that ignores bean setter exceptions.</jc> 1703 * ReaderParser <jv>parser</jv> = JsonParser 1704 * .<jsm>create</jsm>() 1705 * .ignoreInvocationExceptionsOnSetters() 1706 * .build(); 1707 * 1708 * <jc>// Exception is ignored.</jc> 1709 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"{foo:'bar'}"</js>, MyBean.<jk>class</jk>); 1710 * </p> 1711 * 1712 * <h5 class='section'>See Also:</h5><ul> 1713 * <li class='ja'>{@link BeanConfig#ignoreInvocationExceptionsOnSetters()} 1714 * <li class='jm'>{@link BeanContext.Builder#ignoreInvocationExceptionsOnSetters()} 1715 * </ul> 1716 * 1717 * @return This object. 1718 */ 1719 public Builder ignoreInvocationExceptionsOnSetters() { 1720 bcBuilder.ignoreInvocationExceptionsOnSetters(); 1721 return this; 1722 } 1723 1724 /** 1725 * Don't silently ignore missing setters. 1726 * 1727 * <p> 1728 * When enabled, trying to set a value on a bean property without a setter will throw a {@link BeanRuntimeException}. 1729 * Otherwise, it will be silently ignored. 1730 * 1731 * <h5 class='section'>Example:</h5> 1732 * <p class='bjava'> 1733 * <jc>// A bean with a property with a getter but not a setter.</jc> 1734 * <jk>public class</jk> MyBean { 1735 * <jk>public void</jk> getFoo() { 1736 * <jk>return</jk> <js>"foo"</js>; 1737 * } 1738 * } 1739 * 1740 * <jc>// Create a parser that throws an exception if a setter is not found but a getter is.</jc> 1741 * ReaderParser <jv>parser</jv> = JsonParser 1742 * .<jsm>create</jsm>() 1743 * .disableIgnoreMissingSetters() 1744 * .build(); 1745 * 1746 * <jc>// Throws a ParseException.</jc> 1747 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"{foo:'bar'}"</js>, MyBean.<jk>class</jk>); 1748 * </p> 1749 * 1750 * <h5 class='section'>Notes:</h5><ul> 1751 * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on getters and fields to ignore them. 1752 * </ul> 1753 * 1754 * <h5 class='section'>See Also:</h5><ul> 1755 * <li class='ja'>{@link BeanConfig#disableIgnoreMissingSetters()} 1756 * <li class='jm'>{@link BeanContext.Builder#disableIgnoreMissingSetters()} 1757 * </ul> 1758 * 1759 * @return This object. 1760 */ 1761 public Builder disableIgnoreMissingSetters() { 1762 bcBuilder.disableIgnoreMissingSetters(); 1763 return this; 1764 } 1765 1766 /** 1767 * Don't ignore transient fields. 1768 * 1769 * <p> 1770 * When enabled, methods and fields marked as <jk>transient</jk> will not be ignored as bean properties. 1771 * 1772 * <h5 class='section'>Example:</h5> 1773 * <p class='bjava'> 1774 * <jc>// A bean with a transient field.</jc> 1775 * <jk>public class</jk> MyBean { 1776 * <jk>public transient</jk> String <jf>foo</jf> = <js>"foo"</js>; 1777 * } 1778 * 1779 * <jc>// Create a serializer that doesn't ignore transient fields.</jc> 1780 * WriterSerializer <jv>serializer</jv> = JsonSerializer 1781 * .<jsm>create</jsm>() 1782 * .disableIgnoreTransientFields() 1783 * .build(); 1784 * 1785 * <jc>// Produces: {"foo":"foo"}</jc> 1786 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 1787 * </p> 1788 * 1789 * <h5 class='section'>Notes:</h5><ul> 1790 * <li class='note'>The {@link Beanp @Beanp} annotation can also be used on transient fields to keep them from being ignored. 1791 * </ul> 1792 * 1793 * <h5 class='section'>See Also:</h5><ul> 1794 * <li class='ja'>{@link BeanConfig#disableIgnoreTransientFields()} 1795 * <li class='jm'>{@link BeanContext.Builder#disableIgnoreTransientFields()} 1796 * </ul> 1797 * 1798 * @return This object. 1799 */ 1800 public Builder disableIgnoreTransientFields() { 1801 bcBuilder.disableIgnoreTransientFields(); 1802 return this; 1803 } 1804 1805 /** 1806 * Ignore unknown properties. 1807 * 1808 * <p> 1809 * When enabled, trying to set a value on a non-existent bean property will silently be ignored. 1810 * Otherwise, a {@code BeanRuntimeException} is thrown. 1811 * 1812 * <h5 class='section'>Example:</h5> 1813 * <p class='bjava'> 1814 * <jc>// A bean with a single property.</jc> 1815 * <jk>public class</jk> MyBean { 1816 * <jk>public</jk> String <jf>foo</jf>; 1817 * } 1818 * 1819 * <jc>// Create a parser that ignores missing bean properties.</jc> 1820 * ReaderParser <jv>parser</jv> = JsonParser 1821 * .<jsm>create</jsm>() 1822 * .ignoreUnknownBeanProperties() 1823 * .build(); 1824 * 1825 * <jc>// Doesn't throw an exception on unknown 'bar' property.</jc> 1826 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"{foo:'foo',bar:'bar'}"</js>, MyBean.<jk>class</jk>); 1827 * </p> 1828 * 1829 * <h5 class='section'>See Also:</h5><ul> 1830 * <li class='ja'>{@link BeanConfig#ignoreUnknownBeanProperties()} 1831 * <li class='jm'>{@link BeanContext.Builder#ignoreUnknownBeanProperties()} 1832 * </ul> 1833 * 1834 * @return This object. 1835 */ 1836 public Builder ignoreUnknownBeanProperties() { 1837 bcBuilder.ignoreUnknownBeanProperties(); 1838 return this; 1839 } 1840 1841 /** 1842 * Ignore unknown enum values. 1843 * 1844 * <p> 1845 * When enabled, unknown enum values are set to <jk>null</jk> instead of throwing a parse exception. 1846 * 1847 * <h5 class='section'>See Also:</h5><ul> 1848 * <li class='ja'>{@link BeanConfig#ignoreUnknownEnumValues()} 1849 * <li class='jm'>{@link BeanContext.Builder#ignoreUnknownEnumValues()} 1850 * </ul> 1851 * 1852 * @return This object. 1853 */ 1854 public Builder ignoreUnknownEnumValues() { 1855 bcBuilder.ignoreUnknownEnumValues(); 1856 return this; 1857 } 1858 1859 /** 1860 * Don't ignore unknown properties with null values. 1861 * 1862 * <p> 1863 * When enabled, trying to set a <jk>null</jk> value on a non-existent bean property will throw a {@link BeanRuntimeException}. 1864 * Otherwise it will be silently ignored. 1865 * 1866 * <h5 class='section'>Example:</h5> 1867 * <p class='bjava'> 1868 * <jc>// A bean with a single property.</jc> 1869 * <jk>public class</jk> MyBean { 1870 * <jk>public</jk> String <jf>foo</jf>; 1871 * } 1872 * 1873 * <jc>// Create a parser that throws an exception on an unknown property even if the value being set is null.</jc> 1874 * ReaderParser <jv>parser</jv> = JsonParser 1875 * .<jsm>create</jsm>() 1876 * .disableIgnoreUnknownNullBeanProperties() 1877 * .build(); 1878 * 1879 * <jc>// Throws a BeanRuntimeException wrapped in a ParseException on the unknown 'bar' property.</jc> 1880 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"{foo:'foo',bar:null}"</js>, MyBean.<jk>class</jk>); 1881 * </p> 1882 * 1883 * <h5 class='section'>See Also:</h5><ul> 1884 * <li class='ja'>{@link BeanConfig#disableIgnoreUnknownNullBeanProperties()} 1885 * <li class='jm'>{@link BeanContext.Builder#disableIgnoreUnknownNullBeanProperties()} 1886 * </ul> 1887 * 1888 * @return This object. 1889 */ 1890 public Builder disableIgnoreUnknownNullBeanProperties() { 1891 bcBuilder.disableIgnoreUnknownNullBeanProperties(); 1892 return this; 1893 } 1894 1895 /** 1896 * Implementation classes. 1897 * 1898 * <p> 1899 * For interfaces and abstract classes this method can be used to specify an implementation class for the 1900 * interface/abstract class so that instances of the implementation class are used when instantiated (e.g. during a 1901 * parse). 1902 * 1903 * <h5 class='section'>Example:</h5> 1904 * <p class='bjava'> 1905 * <jc>// A bean interface.</jc> 1906 * <jk>public interface</jk> MyBean { 1907 * ... 1908 * } 1909 * 1910 * <jc>// A bean implementation.</jc> 1911 * <jk>public class</jk> MyBeanImpl <jk>implements</jk> MyBean { 1912 * ... 1913 * } 1914 1915 * <jc>// Create a parser that instantiates MyBeanImpls when parsing MyBeans.</jc> 1916 * ReaderParser <jv>parser</jv> = JsonParser 1917 * .<jsm>create</jsm>() 1918 * .implClass(MyBean.<jk>class</jk>, MyBeanImpl.<jk>class</jk>) 1919 * .build(); 1920 * 1921 * <jc>// Instantiates a MyBeanImpl,</jc> 1922 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"..."</js>, MyBean.<jk>class</jk>); 1923 * </p> 1924 * 1925 * @param interfaceClass The interface class. 1926 * @param implClass The implementation class. 1927 * @return This object. 1928 */ 1929 public Builder implClass(Class<?> interfaceClass, Class<?> implClass) { 1930 bcBuilder.implClass(interfaceClass, implClass); 1931 return this; 1932 } 1933 1934 /** 1935 * Implementation classes. 1936 * 1937 * <p> 1938 * For interfaces and abstract classes this method can be used to specify an implementation class for the 1939 * interface/abstract class so that instances of the implementation class are used when instantiated (e.g. during a 1940 * parse). 1941 * 1942 * <h5 class='section'>Example:</h5> 1943 * <p class='bjava'> 1944 * <jc>// A bean with a single property.</jc> 1945 * <jk>public interface</jk> MyBean { 1946 * ... 1947 * } 1948 * 1949 * <jc>// A bean with a single property.</jc> 1950 * <jk>public class</jk> MyBeanImpl <jk>implements</jk> MyBean { 1951 * ... 1952 * } 1953 1954 * <jc>// Create a parser that instantiates MyBeanImpls when parsing MyBeans.</jc> 1955 * ReaderParser <jv>parser</jv> = JsonParser 1956 * .<jsm>create</jsm>() 1957 * .implClasses(AMap.<jsm>of</jsm>(MyBean.<jk>class</jk>, MyBeanImpl.<jk>class</jk>)) 1958 * .build(); 1959 * 1960 * <jc>// Instantiates a MyBeanImpl,</jc> 1961 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"..."</js>, MyBean.<jk>class</jk>); 1962 * </p> 1963 * 1964 * @param values 1965 * The new value for this setting. 1966 * @return This object. 1967 */ 1968 public Builder implClasses(Map<Class<?>,Class<?>> values) { 1969 bcBuilder.implClasses(values); 1970 return this; 1971 } 1972 1973 /** 1974 * Identifies a class to be used as the interface class for the specified class and all subclasses. 1975 * 1976 * <p> 1977 * When specified, only the list of properties defined on the interface class will be used during serialization. 1978 * Additional properties on subclasses will be ignored. 1979 * 1980 * <p class='bjava'> 1981 * <jc>// Parent class or interface</jc> 1982 * <jk>public abstract class</jk> A { 1983 * <jk>public</jk> String <jf>foo</jf> = <js>"foo"</js>; 1984 * } 1985 * 1986 * <jc>// Sub class</jc> 1987 * <jk>public class</jk> A1 <jk>extends</jk> A { 1988 * <jk>public</jk> String <jf>bar</jf> = <js>"bar"</js>; 1989 * } 1990 * 1991 * <jc>// Create a serializer and define our interface class mapping.</jc> 1992 * WriterSerializer <jv>serializer</jv> = JsonSerializer 1993 * .<jsm>create</jsm>() 1994 * .interfaceClass(A1.<jk>class</jk>, A.<jk>class</jk>) 1995 * .build(); 1996 * 1997 * <jc>// Produces "{"foo":"foo"}"</jc> 1998 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> A1()); 1999 * </p> 2000 * 2001 * <p> 2002 * This annotation can be used on the parent class so that it filters to all child classes, or can be set 2003 * individually on the child classes. 2004 * 2005 * <h5 class='section'>Notes:</h5><ul> 2006 * <li class='note'>The {@link Bean#interfaceClass() @Bean(interfaceClass)} annotation is the equivalent annotation-based solution. 2007 * </ul> 2008 * 2009 * @param on The class that the interface class applies to. 2010 * @param value 2011 * The new value for this setting. 2012 * @return This object. 2013 */ 2014 public Builder interfaceClass(Class<?> on, Class<?> value) { 2015 bcBuilder.interfaceClass(on, value); 2016 return this; 2017 } 2018 2019 /** 2020 * Identifies a set of interfaces. 2021 * 2022 * <p> 2023 * When specified, only the list of properties defined on the interface class will be used during serialization 2024 * of implementation classes. Additional properties on subclasses will be ignored. 2025 * 2026 * <p class='bjava'> 2027 * <jc>// Parent class or interface</jc> 2028 * <jk>public abstract class</jk> A { 2029 * <jk>public</jk> String <jf>foo</jf> = <js>"foo"</js>; 2030 * } 2031 * 2032 * <jc>// Sub class</jc> 2033 * <jk>public class</jk> A1 <jk>extends</jk> A { 2034 * <jk>public</jk> String <jf>bar</jf> = <js>"bar"</js>; 2035 * } 2036 * 2037 * <jc>// Create a serializer and define our interface class mapping.</jc> 2038 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2039 * .<jsm>create</jsm>() 2040 * .interfaces(A.<jk>class</jk>) 2041 * .build(); 2042 * 2043 * <jc>// Produces "{"foo":"foo"}"</jc> 2044 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> A1()); 2045 * </p> 2046 * 2047 * <p> 2048 * This annotation can be used on the parent class so that it filters to all child classes, or can be set 2049 * individually on the child classes. 2050 * 2051 * <h5 class='section'>Notes:</h5><ul> 2052 * <li class='note'>The {@link Bean#interfaceClass() @Bean(interfaceClass)} annotation is the equivalent annotation-based solution. 2053 * </ul> 2054 * 2055 * @param value 2056 * The new value for this setting. 2057 * @return This object. 2058 */ 2059 public Builder interfaces(Class<?>...value) { 2060 bcBuilder.interfaces(value); 2061 return this; 2062 } 2063 2064 /** 2065 * <i><l>Context</l> configuration property: </i> Locale. 2066 * 2067 * <p> 2068 * Specifies the default locale for serializer and parser sessions when not specified via {@link BeanSession.Builder#locale(Locale)}. 2069 * Typically used for POJO swaps that need to deal with locales such as swaps that convert <l>Date</l> and <l>Calendar</l> 2070 * objects to strings by accessing it via the session passed into the {@link ObjectSwap#swap(BeanSession, Object)} and 2071 * {@link ObjectSwap#unswap(BeanSession, Object, ClassMeta, String)} methods. 2072 * 2073 * <h5 class='section'>Example:</h5> 2074 * <p class='bjava'> 2075 * <jc>// Define a POJO swap that skips serializing beans if we're in the UK.</jc> 2076 * <jk>public class</jk> MyBeanSwap <jk>extends</jk> StringSwap<MyBean> { 2077 * <ja>@Override</ja> 2078 * <jk>public</jk> String swap(BeanSession <jv>session</jv>, MyBean <jv>bean</jv>) <jk>throws</jk> Exception { 2079 * <jk>if</jk> (<jv>session</jv>.getLocale().equals(Locale.<jsf>UK</jsf>)) 2080 * <jk>return null</jk>; 2081 * <jk>return</jk> <jv>bean</jv>.toString(); 2082 * } 2083 * } 2084 * 2085 * <jc>// Create a serializer that uses the specified locale if it's not passed in through session args.</jc> 2086 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2087 * .<jsm>create</jsm>() 2088 * .locale(Locale.<jsf>UK</jsf>) 2089 * .swaps(MyBeanSwap.<jk>class</jk>) 2090 * .build(); 2091 * </p> 2092 * 2093 * <h5 class='section'>See Also:</h5><ul> 2094 * <li class='ja'>{@link BeanConfig#locale()} 2095 * <li class='jm'>{@link BeanContext.Builder#locale(Locale)} 2096 * <li class='jm'>{@link BeanSession.Builder#locale(Locale)} 2097 * </ul> 2098 * 2099 * @param value The new value for this property. 2100 * @return This object. 2101 */ 2102 public Builder locale(Locale value) { 2103 bcBuilder.locale(value); 2104 return this; 2105 } 2106 2107 /** 2108 * <i><l>Context</l> configuration property: </i> Media type. 2109 * 2110 * <p> 2111 * Specifies the default media type for serializer and parser sessions when not specified via {@link BeanSession.Builder#mediaType(MediaType)}. 2112 * Typically used for POJO swaps that need to serialize the same POJO classes differently depending on 2113 * the specific requested media type. For example, a swap could handle a request for media types <js>"application/json"</js> 2114 * and <js>"application/json+foo"</js> slightly differently even though they're both being handled by the same JSON 2115 * serializer or parser. 2116 * 2117 * <h5 class='section'>Example:</h5> 2118 * <p class='bjava'> 2119 * <jc>// Define a POJO swap that skips serializing beans if the media type is application/json.</jc> 2120 * <jk>public class</jk> MyBeanSwap <jk>extends</jk> StringSwap<MyBean> { 2121 * <ja>@Override</ja> 2122 * <jk>public</jk> String swap(BeanSession <jv>session</jv>, MyBean <jv>bean</jv>) <jk>throws</jk> Exception { 2123 * <jk>if</jk> (<jv>session</jv>.getMediaType().equals(<js>"application/json"</js>)) 2124 * <jk>return null</jk>; 2125 * <jk>return</jk> <jv>bean</jv>.toString(); 2126 * } 2127 * } 2128 * 2129 * <jc>// Create a serializer that uses the specified media type if it's not passed in through session args.</jc> 2130 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2131 * .<jsm>create</jsm>() 2132 * .mediaType(MediaType.<jsf>JSON</jsf>) 2133 * .build(); 2134 * </p> 2135 * 2136 * <h5 class='section'>See Also:</h5><ul> 2137 * <li class='ja'>{@link BeanConfig#mediaType()} 2138 * <li class='jm'>{@link BeanContext.Builder#mediaType(MediaType)} 2139 * <li class='jm'>{@link BeanSession.Builder#mediaType(MediaType)} 2140 * </ul> 2141 * 2142 * @param value The new value for this property. 2143 * @return This object. 2144 */ 2145 public Builder mediaType(MediaType value) { 2146 bcBuilder.mediaType(value); 2147 return this; 2148 } 2149 2150 /** 2151 * Bean class exclusions. 2152 * 2153 * <p> 2154 * List of classes that should not be treated as beans even if they appear to be bean-like. 2155 * Not-bean classes are converted to <c>Strings</c> during serialization. 2156 * 2157 * <p> 2158 * Values can consist of any of the following types: 2159 * <ul> 2160 * <li>Classes. 2161 * <li>Arrays and collections of classes. 2162 * </ul> 2163 * 2164 * <h5 class='section'>Example:</h5> 2165 * <p class='bjava'> 2166 * <jc>// A bean with a single property.</jc> 2167 * <jk>public class</jk> MyBean { 2168 * <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>; 2169 * 2170 * <jk>public</jk> String toString() { 2171 * <jk>return</jk> <js>"baz"</js>; 2172 * } 2173 * } 2174 * 2175 * <jc>// Create a serializer that doesn't treat MyBean as a bean class.</jc> 2176 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2177 * .<jsm>create</jsm>() 2178 * .notBeanClasses(MyBean.<jk>class</jk>) 2179 * .build(); 2180 * 2181 * <jc>// Produces "baz" instead of {"foo":"bar"}</jc> 2182 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 2183 * </p> 2184 * 2185 * <h5 class='section'>Notes:</h5><ul> 2186 * <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on classes to prevent them from being recognized as beans. 2187 * </ul> 2188 * 2189 * <h5 class='section'>See Also:</h5><ul> 2190 * <li class='ja'>{@link BeanIgnore} 2191 * <li class='ja'>{@link BeanConfig#notBeanClasses()} 2192 * <li class='jf'>{@link BeanContext.Builder#notBeanClasses()} 2193 * </ul> 2194 * 2195 * @param values 2196 * The values to add to this setting. 2197 * <br>Values can consist of any of the following types: 2198 * <ul> 2199 * <li>Classes. 2200 * <li>Arrays and collections of classes. 2201 * </ul> 2202 * @return This object. 2203 */ 2204 public Builder notBeanClasses(Class<?>...values) { 2205 bcBuilder.notBeanClasses(values); 2206 return this; 2207 } 2208 2209 /** 2210 * Bean package exclusions. 2211 * 2212 * <p> 2213 * Used as a convenient way of defining the {@link BeanContext.Builder#notBeanClasses(Class...)} property for entire packages. 2214 * Any classes within these packages will be serialized to strings using {@link Object#toString()}. 2215 * 2216 * <p> 2217 * Note that you can specify suffix patterns to include all subpackages. 2218 * 2219 * <p> 2220 * Values can consist of any of the following types: 2221 * <ul> 2222 * <li>Strings. 2223 * <li>Arrays and collections of strings. 2224 * </ul> 2225 * 2226 * <h5 class='section'>Example:</h5> 2227 * <p class='bjava'> 2228 * <jc>// Create a serializer that ignores beans in the specified packages.</jc> 2229 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2230 * .<jsm>create</jsm>() 2231 * .notBeanPackages(<js>"org.apache.foo"</js>, <js>"org.apache.bar.*"</js>) 2232 * .build(); 2233 * </p> 2234 * 2235 * <h5 class='section'>See Also:</h5><ul> 2236 * <li class='jm'>{@link BeanContext.Builder#notBeanPackages(String...)} 2237 * </ul> 2238 * 2239 * @param values 2240 * The values to add to this setting. 2241 * <br>Values can consist of any of the following types: 2242 * <ul> 2243 * <li>{@link Package} objects. 2244 * <li>Strings. 2245 * <li>Arrays and collections of anything in this list. 2246 * </ul> 2247 * @return This object. 2248 */ 2249 public Builder notBeanPackages(String...values) { 2250 bcBuilder.notBeanPackages(values); 2251 return this; 2252 } 2253 2254 /** 2255 * Bean property namer 2256 * 2257 * <p> 2258 * The class to use for calculating bean property names. 2259 * 2260 * <p> 2261 * Predefined classes: 2262 * <ul> 2263 * <li>{@link BasicPropertyNamer} - Default. 2264 * <li>{@link PropertyNamerDLC} - Dashed-lower-case names. 2265 * <li>{@link PropertyNamerULC} - Dashed-upper-case names. 2266 * </ul> 2267 * 2268 * <h5 class='section'>Example:</h5> 2269 * <p class='bjava'> 2270 * <jc>// A bean with a single property.</jc> 2271 * <jk>public class</jk> MyBean { 2272 * <jk>public</jk> String <jf>fooBarBaz</jf> = <js>"fooBarBaz"</js>; 2273 * } 2274 * 2275 * <jc>// Create a serializer that uses Dashed-Lower-Case property names.</jc> 2276 * <jc>// (e.g. "foo-bar-baz" instead of "fooBarBaz")</jc> 2277 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2278 * .<jsm>create</jsm>() 2279 * .propertyNamer(PropertyNamerDLC.<jk>class</jk>) 2280 * .build(); 2281 * 2282 * <jc>// Produces: {"foo-bar-baz":"fooBarBaz"}</jc> 2283 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 2284 * </p> 2285 * 2286 * <h5 class='section'>See Also:</h5><ul> 2287 * <li class='jm'>{@link BeanContext.Builder#propertyNamer(Class)} 2288 * </ul> 2289 * 2290 * @param value 2291 * The new value for this setting. 2292 * <br>The default is {@link BasicPropertyNamer}. 2293 * @return This object. 2294 */ 2295 public Builder propertyNamer(Class<? extends PropertyNamer> value) { 2296 bcBuilder.propertyNamer(value); 2297 return this; 2298 } 2299 2300 /** 2301 * Bean property namer 2302 * 2303 * <p> 2304 * Same as {@link #propertyNamer(Class)} but allows you to specify a namer for a specific class. 2305 * 2306 * <h5 class='section'>Example:</h5> 2307 * <p class='bjava'> 2308 * <jc>// A bean with a single property.</jc> 2309 * <jk>public class</jk> MyBean { 2310 * <jk>public</jk> String <jf>fooBarBaz</jf> = <js>"fooBarBaz"</js>; 2311 * } 2312 * 2313 * <jc>// Create a serializer that uses Dashed-Lower-Case property names for the MyBean class only.</jc> 2314 * <jc>// (e.g. "foo-bar-baz" instead of "fooBarBaz")</jc> 2315 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2316 * .<jsm>create</jsm>() 2317 * .propertyNamer(MyBean.<jk>class</jk>, PropertyNamerDLC.<jk>class</jk>) 2318 * .build(); 2319 * 2320 * <jc>// Produces: {"foo-bar-baz":"fooBarBaz"}</jc> 2321 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 2322 * </p> 2323 * 2324 * <h5 class='section'>See Also:</h5><ul> 2325 * <li class='ja'>{@link Bean#propertyNamer() Bean(propertyNamer)} 2326 * <li class='jm'>{@link BeanContext.Builder#propertyNamer(Class)} 2327 * </ul> 2328 * 2329 * @param on The class that the namer applies to. 2330 * @param value 2331 * The new value for this setting. 2332 * <br>The default is {@link BasicPropertyNamer}. 2333 * @return This object. 2334 */ 2335 public Builder propertyNamer(Class<?> on, Class<? extends PropertyNamer> value) { 2336 bcBuilder.propertyNamer(on, value); 2337 return this; 2338 } 2339 2340 /** 2341 * Sort bean properties. 2342 * 2343 * <p> 2344 * When enabled, all bean properties will be serialized and access in alphabetical order. 2345 * Otherwise, the natural order of the bean properties is used which is dependent on the JVM vendor. 2346 * On IBM JVMs, the bean properties are ordered based on their ordering in the Java file. 2347 * On Oracle JVMs, the bean properties are not ordered (which follows the official JVM specs). 2348 * 2349 * <p> 2350 * this setting is disabled by default so that IBM JVM users don't have to use {@link Bean @Bean} annotations 2351 * to force bean properties to be in a particular order and can just alter the order of the fields/methods 2352 * in the Java file. 2353 * 2354 * <h5 class='section'>Example:</h5> 2355 * <p class='bjava'> 2356 * <jc>// A bean with 3 properties.</jc> 2357 * <jk>public class</jk> MyBean { 2358 * <jk>public</jk> String <jf>c</jf> = <js>"1"</js>; 2359 * <jk>public</jk> String <jf>b</jf> = <js>"2"</js>; 2360 * <jk>public</jk> String <jf>a</jf> = <js>"3"</js>; 2361 * } 2362 * 2363 * <jc>// Create a serializer that sorts bean properties.</jc> 2364 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2365 * .<jsm>create</jsm>() 2366 * .sortProperties() 2367 * .build(); 2368 * 2369 * <jc>// Produces: {"a":"3","b":"2","c":"1"}</jc> 2370 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 2371 * </p> 2372 * 2373 * <h5 class='section'>Notes:</h5><ul> 2374 * <li class='note'>The {@link Bean#sort() @Bean.sort()} annotation can also be used to sort properties on just a single class. 2375 * </ul> 2376 * 2377 * <h5 class='section'>See Also:</h5><ul> 2378 * <li class='jm'>{@link BeanContext.Builder#sortProperties()} 2379 * </ul> 2380 * 2381 * @return This object. 2382 */ 2383 public Builder sortProperties() { 2384 bcBuilder.sortProperties(); 2385 return this; 2386 } 2387 2388 /** 2389 * Sort bean properties. 2390 * 2391 * <p> 2392 * Same as {@link #sortProperties()} but allows you to specify individual bean classes instead of globally. 2393 * 2394 * <h5 class='section'>Example:</h5> 2395 * <p class='bjava'> 2396 * <jc>// A bean with 3 properties.</jc> 2397 * <jk>public class</jk> MyBean { 2398 * <jk>public</jk> String <jf>c</jf> = <js>"1"</js>; 2399 * <jk>public</jk> String <jf>b</jf> = <js>"2"</js>; 2400 * <jk>public</jk> String <jf>a</jf> = <js>"3"</js>; 2401 * } 2402 * 2403 * <jc>// Create a serializer that sorts properties on MyBean.</jc> 2404 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2405 * .<jsm>create</jsm>() 2406 * .sortProperties(MyBean.<jk>class</jk>) 2407 * .build(); 2408 * 2409 * <jc>// Produces: {"a":"3","b":"2","c":"1"}</jc> 2410 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 2411 * </p> 2412 * 2413 * <h5 class='section'>See Also:</h5><ul> 2414 * <li class='ja'>{@link Bean#sort() Bean(sort)} 2415 * <li class='jm'>{@link BeanContext.Builder#sortProperties()} 2416 * </ul> 2417 * 2418 * @param on The bean classes to sort properties on. 2419 * @return This object. 2420 */ 2421 public Builder sortProperties(Class<?>...on) { 2422 bcBuilder.sortProperties(on); 2423 return this; 2424 } 2425 2426 /** 2427 * Identifies a stop class for the annotated class. 2428 * 2429 * <p> 2430 * Identical in purpose to the stop class specified by {@link Introspector#getBeanInfo(Class, Class)}. 2431 * Any properties in the stop class or in its base classes will be ignored during analysis. 2432 * 2433 * <p> 2434 * For example, in the following class hierarchy, instances of <c>C3</c> will include property <c>p3</c>, 2435 * but not <c>p1</c> or <c>p2</c>. 2436 * 2437 * <h5 class='section'>Example:</h5> 2438 * <p class='bjava'> 2439 * <jk>public class</jk> C1 { 2440 * <jk>public int</jk> getP1(); 2441 * } 2442 * 2443 * <jk>public class</jk> C2 <jk>extends</jk> C1 { 2444 * <jk>public int</jk> getP2(); 2445 * } 2446 * 2447 * <jk>public class</jk> C3 <jk>extends</jk> C2 { 2448 * <jk>public int</jk> getP3(); 2449 * } 2450 * 2451 * <jc>// Create a serializer specifies a stop class for C3.</jc> 2452 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2453 * .<jsm>create</jsm>() 2454 * .stopClass(C3.<jk>class</jk>, C2.<jk>class</jk>) 2455 * .build(); 2456 * 2457 * <jc>// Produces: {"p3":"..."}</jc> 2458 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> C3()); 2459 * </p> 2460 * 2461 * @param on The class on which the stop class is being applied. 2462 * @param value 2463 * The new value for this setting. 2464 * @return This object. 2465 */ 2466 public Builder stopClass(Class<?> on, Class<?> value) { 2467 bcBuilder.stopClass(on, value); 2468 return this; 2469 } 2470 2471 /** 2472 * Java object swaps. 2473 * 2474 * <p> 2475 * Swaps are used to "swap out" non-serializable classes with serializable equivalents during serialization, 2476 * and "swap in" the non-serializable class during parsing. 2477 * 2478 * <p> 2479 * An example of a swap would be a <c>Calendar</c> object that gets swapped out for an ISO8601 string. 2480 * 2481 * <p> 2482 * Multiple swaps can be associated with a single class. 2483 * When multiple swaps are applicable to the same class, the media type pattern defined by 2484 * {@link ObjectSwap#forMediaTypes()} or {@link Swap#mediaTypes() @Swap(mediaTypes)} are used to come up with the best match. 2485 * 2486 * <p> 2487 * Values can consist of any of the following types: 2488 * <ul> 2489 * <li>Any subclass of {@link ObjectSwap}. 2490 * <li>Any instance of {@link ObjectSwap}. 2491 * <li>Any surrogate class. A shortcut for defining a {@link SurrogateSwap}. 2492 * <li>Any array or collection of the objects above. 2493 * </ul> 2494 * 2495 * <h5 class='section'>Example:</h5> 2496 * <p class='bjava'> 2497 * <jc>// Sample swap for converting Dates to ISO8601 strings.</jc> 2498 * <jk>public class</jk> MyDateSwap <jk>extends</jk> StringSwap<Date> { 2499 * <jc>// ISO8601 formatter.</jc> 2500 * <jk>private</jk> DateFormat <jf>format</jf> = <jk>new</jk> SimpleDateFormat(<js>"yyyy-MM-dd'T'HH:mm:ssZ"</js>); 2501 * 2502 * <ja>@Override</ja> 2503 * <jk>public</jk> String swap(BeanSession <jv>session</jv>, Date <jv>date</jv>) { 2504 * <jk>return</jk> <jf>format</jf>.format(<jv>date</jv>); 2505 * } 2506 * 2507 * <ja>@Override</ja> 2508 * <jk>public</jk> Date unswap(BeanSession <jv>session</jv>, String <jv>string</jv>, ClassMeta <jv>hint</jv>) <jk>throws</jk> Exception { 2509 * <jk>return</jk> <jf>format</jf>.parse(<jv>string</jv>); 2510 * } 2511 * } 2512 * 2513 * <jc>// Sample bean with a Date field.</jc> 2514 * <jk>public class</jk> MyBean { 2515 * <jk>public</jk> Date <jf>date</jf> = <jk>new</jk> Date(112, 2, 3, 4, 5, 6); 2516 * } 2517 * 2518 * <jc>// Create a serializer that uses our date swap.</jc> 2519 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2520 * .<jsm>create</jsm>() 2521 * .swaps(MyDateSwap.<jk>class</jk>) 2522 * .build(); 2523 * 2524 * <jc>// Produces: {"date":"2012-03-03T04:05:06-0500"}</jc> 2525 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 2526 * 2527 * <jc>// Create a serializer that uses our date swap.</jc> 2528 * ReaderParser <jv>parser</jv> = JsonParser 2529 * .<jsm>create</jsm>() 2530 * .swaps(MyDateSwap.<jk>class</jk>) 2531 * .build(); 2532 * 2533 * <jc>// Use our parser to parse a bean.</jc> 2534 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<jv>json</jv>, MyBean.<jk>class</jk>); 2535 * </p> 2536 * 2537 * <h5 class='section'>Notes:</h5><ul> 2538 * <li class='note'>The {@link Swap @Swap} annotation can also be used on classes to identify swaps for the class. 2539 * <li class='note'>The {@link Swap @Swap} annotation can also be used on bean methods and fields to identify swaps for values of those bean properties. 2540 * </ul> 2541 * 2542 * <h5 class='section'>See Also:</h5><ul> 2543 * <li class='jf'>{@link BeanContext.Builder#swaps(Class...)} 2544 * </ul> 2545 * 2546 * @param values 2547 * The values to add to this setting. 2548 * <br>Values can consist of any of the following types: 2549 * <ul> 2550 * <li>Any subclass of {@link ObjectSwap}. 2551 * <li>Any surrogate class. A shortcut for defining a {@link SurrogateSwap}. 2552 * <li>Any array/collection/stream of the objects above. 2553 * </ul> 2554 * @return This object. 2555 */ 2556 public Builder swaps(Object...values) { 2557 bcBuilder.swaps(values); 2558 return this; 2559 } 2560 2561 /** 2562 * Same as {@link #swaps(Object...)} except explicitly specifies class varargs to avoid compilation warnings. 2563 * 2564 * @param values 2565 * The values to add to this setting. 2566 * <br>Values can consist of any of the following types: 2567 * <ul> 2568 * <li>Any subclass of {@link ObjectSwap}. 2569 * <li>Any surrogate class. A shortcut for defining a {@link SurrogateSwap}. 2570 * </ul> 2571 * @return This object. 2572 */ 2573 public Builder swaps(Class<?>...values) { 2574 bcBuilder.swaps(values); 2575 return this; 2576 } 2577 2578 /** 2579 * A shortcut for defining a {@link FunctionalSwap}. 2580 * 2581 * <h5 class='section'>Example:</h5> 2582 * <p class='bjava'> 2583 * <jc>// Create a serializer that performs a custom format for Date objects.</jc> 2584 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2585 * .<jsm>create</jsm>() 2586 * .swap(Date.<jk>class</jk>, String.<jk>class</jk>, <jv>x</jv> -> <jsm>format</jsm>(<jv>x</jv>)) 2587 * .build(); 2588 * </p> 2589 * 2590 * @param <T> The object type being swapped out. 2591 * @param <S> The object type being swapped in. 2592 * @param normalClass The object type being swapped out. 2593 * @param swappedClass The object type being swapped in. 2594 * @param swapFunction The function to convert the object. 2595 * @return This object. 2596 */ 2597 public <T,S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) { 2598 bcBuilder.swap(normalClass, swappedClass, swapFunction); 2599 return this; 2600 } 2601 2602 /** 2603 * A shortcut for defining a {@link FunctionalSwap}. 2604 * 2605 * <h5 class='section'>Example:</h5> 2606 * <p class='bjava'> 2607 * <jc>// Create a serializer that performs a custom format for Date objects.</jc> 2608 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2609 * .<jsm>create</jsm>() 2610 * .swap(Date.<jk>class</jk>, String.<jk>class</jk>, <jv>x</jv> -> <jsm>format</jsm>(<jv>x</jv>), <jv>x</jv> -> <jsm>parse</jsm>(<jv>x</jv>)) 2611 * .build(); 2612 * </p> 2613 * 2614 * @param <T> The object type being swapped out. 2615 * @param <S> The object type being swapped in. 2616 * @param normalClass The object type being swapped out. 2617 * @param swappedClass The object type being swapped in. 2618 * @param swapFunction The function to convert the object during serialization. 2619 * @param unswapFunction The function to convert the object during parsing. 2620 * @return This object. 2621 */ 2622 public <T,S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) { 2623 bcBuilder.swap(normalClass, swappedClass, swapFunction, unswapFunction); 2624 return this; 2625 } 2626 2627 /** 2628 * <i><l>Context</l> configuration property: </i> TimeZone. 2629 * 2630 * <p> 2631 * Specifies the default time zone for serializer and parser sessions when not specified via {@link BeanSession.Builder#timeZone(TimeZone)}. 2632 * Typically used for POJO swaps that need to deal with timezones such as swaps that convert <l>Date</l> and <l>Calendar</l> 2633 * objects to strings by accessing it via the session passed into the {@link ObjectSwap#swap(BeanSession, Object)} and 2634 * {@link ObjectSwap#unswap(BeanSession, Object, ClassMeta, String)} methods. 2635 * 2636 * <h5 class='section'>Example:</h5> 2637 * <p class='bjava'> 2638 * <jc>// Define a POJO swap that skips serializing beans if the time zone is GMT.</jc> 2639 * <jk>public class</jk> MyBeanSwap <jk>extends</jk> StringSwap<MyBean> { 2640 * <ja>@Override</ja> 2641 * <jk>public</jk> String swap(BeanSession <jv>session</jv>, MyBean <jv>bean</jv>) <jk>throws</jk> Exception { 2642 * <jk>if</jk> (<jv>session</jv>.getTimeZone().equals(TimeZone.<jsf>GMT</jsf>)) 2643 * <jk>return null</jk>; 2644 * <jk>return</jk> <jv>bean</jv>.toString(); 2645 * } 2646 * } 2647 * 2648 * <jc>// Create a serializer that uses GMT if the timezone is not specified in the session args.</jc> 2649 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2650 * .<jsm>create</jsm>() 2651 * .timeZone(TimeZone.<jsf>GMT</jsf>) 2652 * .build(); 2653 * </p> 2654 * 2655 * <h5 class='section'>See Also:</h5><ul> 2656 * <li class='ja'>{@link BeanConfig#timeZone()} 2657 * <li class='jm'>{@link BeanContext.Builder#timeZone(TimeZone)} 2658 * <li class='jm'>{@link BeanSession.Builder#timeZone(TimeZone)} 2659 * </ul> 2660 * 2661 * @param value The new value for this property. 2662 * @return This object. 2663 */ 2664 public Builder timeZone(TimeZone value) { 2665 bcBuilder.timeZone(value); 2666 return this; 2667 } 2668 2669 /** 2670 * An identifying name for this class. 2671 * 2672 * <p> 2673 * The name is used to identify the class type during parsing when it cannot be inferred through reflection. 2674 * For example, if a bean property is of type <c>Object</c>, then the serializer will add the name to the 2675 * output so that the class can be determined during parsing. 2676 * 2677 * <p> 2678 * It is also used to specify element names in XML. 2679 * 2680 * <h5 class='section'>Example:</h5> 2681 * <p class='bjava'> 2682 * <jc>// Use _type='mybean' to identify this bean.</jc> 2683 * <jk>public class</jk> MyBean {...} 2684 * 2685 * <jc>// Create a serializer and specify the type name..</jc> 2686 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2687 * .<jsm>create</jsm>() 2688 * .typeName(MyBean.<jk>class</jk>, <js>"mybean"</js>) 2689 * .build(); 2690 * 2691 * <jc>// Produces: {"_type":"mybean",...}</jc> 2692 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 2693 * </p> 2694 * 2695 * <h5 class='section'>Notes:</h5><ul> 2696 * <li class='note'>Equivalent to the {@link Bean#typeName() Bean(typeName)} annotation. 2697 * </ul> 2698 * 2699 * <h5 class='section'>See Also:</h5><ul> 2700 * <li class='jc'>{@link Bean#typeName() Bean(typeName)} 2701 * <li class='jm'>{@link BeanContext.Builder#beanDictionary(Class...)} 2702 * </ul> 2703 * 2704 * @param on 2705 * The class the type name is being defined on. 2706 * @param value 2707 * The new value for this setting. 2708 * @return This object. 2709 */ 2710 public Builder typeName(Class<?> on, String value) { 2711 bcBuilder.typeName(on, value); 2712 return this; 2713 } 2714 2715 /** 2716 * Bean type property name. 2717 * 2718 * <p> 2719 * This specifies the name of the bean property used to store the dictionary name of a bean type so that the 2720 * parser knows the data type to reconstruct. 2721 * 2722 * <h5 class='section'>Example:</h5> 2723 * <p class='bjava'> 2724 * <jc>// POJOs with @Bean(name) annotations.</jc> 2725 * <ja>@Bean</ja>(typeName=<js>"foo"</js>) 2726 * <jk>public class</jk> Foo {...} 2727 * <ja>@Bean</ja>(typeName=<js>"bar"</js>) 2728 * <jk>public class</jk> Bar {...} 2729 * 2730 * <jc>// Create a serializer that uses 't' instead of '_type' for dictionary names.</jc> 2731 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2732 * .<jsm>create</jsm>() 2733 * .typePropertyName(<js>"t"</js>) 2734 * .dictionary(Foo.<jk>class</jk>, Bar.<jk>class</jk>) 2735 * .build(); 2736 * 2737 * <jc>// Create a serializer that uses 't' instead of '_type' for dictionary names.</jc> 2738 * ReaderParser <jv>parser</jv> = JsonParser 2739 * .<jsm>create</jsm>() 2740 * .typePropertyName(<js>"t"</js>) 2741 * .dictionary(Foo.<jk>class</jk>, Bar.<jk>class</jk>) 2742 * .build(); 2743 * 2744 * <jc>// A bean with a field with an indeterminate type.</jc> 2745 * <jk>public class</jk> MyBean { 2746 * <jk>public</jk> Object <jf>mySimpleField</jf>; 2747 * } 2748 * 2749 * <jc>// Produces "{mySimpleField:{t:'foo',...}}".</jc> 2750 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 2751 * 2752 * <jc>// Parse bean.</jc> 2753 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<jv>json</jv>, MyBean.<jk>class</jk>); 2754 * </p> 2755 * 2756 * <h5 class='section'>See Also:</h5><ul> 2757 * <li class='ja'>{@link Bean#typePropertyName()} 2758 * <li class='ja'>{@link BeanConfig#typePropertyName()} 2759 * <li class='jm'>{@link BeanContext.Builder#typePropertyName(String)} 2760 * </ul> 2761 * 2762 * @param value 2763 * The new value for this setting. 2764 * <br>The default is <js>"_type"</js>. 2765 * @return This object. 2766 */ 2767 public Builder typePropertyName(String value) { 2768 bcBuilder.typePropertyName(value); 2769 return this; 2770 } 2771 2772 /** 2773 * Bean type property name. 2774 * 2775 * <p> 2776 * Same as {@link #typePropertyName(String)} except targets a specific bean class instead of globally. 2777 * 2778 * <h5 class='section'>Example:</h5> 2779 * <p class='bjava'> 2780 * <jc>// POJOs with @Bean(name) annotations.</jc> 2781 * <ja>@Bean</ja>(typeName=<js>"foo"</js>) 2782 * <jk>public class</jk> Foo {...} 2783 * <ja>@Bean</ja>(typeName=<js>"bar"</js>) 2784 * <jk>public class</jk> Bar {...} 2785 * 2786 * <jc>// A bean with a field with an indeterminate type.</jc> 2787 * <jk>public class</jk> MyBean { 2788 * <jk>public</jk> Object <jf>mySimpleField</jf>; 2789 * } 2790 * 2791 * <jc>// Create a serializer that uses 't' instead of '_type' for dictionary names.</jc> 2792 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2793 * .<jsm>create</jsm>() 2794 * .typePropertyName(MyBean.<jk>class</jk>, <js>"t"</js>) 2795 * .dictionary(Foo.<jk>class</jk>, Bar.<jk>class</jk>) 2796 * .build(); 2797 * 2798 * <jc>// Produces "{mySimpleField:{t:'foo',...}}".</jc> 2799 * String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean()); 2800 * </p> 2801 * 2802 * <h5 class='section'>See Also:</h5><ul> 2803 * <li class='ja'>{@link Bean#typePropertyName() Bean(typePropertyName)} 2804 * <li class='jm'>{@link BeanContext.Builder#typePropertyName(String)} 2805 * </ul> 2806 * 2807 * @param on The class the type property name applies to. 2808 * @param value 2809 * The new value for this setting. 2810 * <br>The default is <js>"_type"</js>. 2811 * @return This object. 2812 */ 2813 public Builder typePropertyName(Class<?> on, String value) { 2814 bcBuilder.typePropertyName(on, value); 2815 return this; 2816 } 2817 2818 /** 2819 * Use enum names. 2820 * 2821 * <p> 2822 * When enabled, enums are always serialized by name, not using {@link Object#toString()}. 2823 * 2824 * <h5 class='section'>Example:</h5> 2825 * <p class='bjava'> 2826 * <jc>// Create a serializer with debug enabled.</jc> 2827 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2828 * .<jsm>create</jsm>() 2829 * .useEnumNames() 2830 * .build(); 2831 * 2832 * <jc>// Enum with overridden toString().</jc> 2833 * <jc>// Will be serialized as ONE/TWO/THREE even though there's a toString() method.</jc> 2834 * <jk>public enum</jk> Option { 2835 * <jsf>ONE</jsf>(1), 2836 * <jsf>TWO</jsf>(2), 2837 * <jsf>THREE</jsf>(3); 2838 * 2839 * <jk>private int</jk> <jf>value</jf>; 2840 * 2841 * Option(<jk>int</jk> <jv>value</jv>) { 2842 * <jk>this</jk>.<jf>value</jf> = <jv>value</jv>; 2843 * } 2844 * 2845 * <ja>@Override</ja> 2846 * <jk>public</jk> String toString() { 2847 * <jk>return</jk> String.<jsm>valueOf</jsm>(<jf>value</jf>); 2848 * } 2849 * } 2850 * </p> 2851 * 2852 * <h5 class='section'>See Also:</h5><ul> 2853 * <li class='jm'>{@link BeanContext.Builder#useEnumNames()} 2854 * </ul> 2855 * 2856 * @return This object. 2857 */ 2858 public Builder useEnumNames() { 2859 bcBuilder.useEnumNames(); 2860 return this; 2861 } 2862 2863 /** 2864 * Don't use interface proxies. 2865 * 2866 * <p> 2867 * When enabled, interfaces will be instantiated as proxy classes through the use of an 2868 * {@link InvocationHandler} if there is no other way of instantiating them. 2869 * Otherwise, throws a {@link BeanRuntimeException}. 2870 * 2871 * <h5 class='section'>See Also:</h5><ul> 2872 * <li class='ja'>{@link BeanConfig#disableInterfaceProxies()} 2873 * <li class='jm'>{@link BeanContext.Builder#disableInterfaceProxies()} 2874 * </ul> 2875 * 2876 * @return This object. 2877 */ 2878 public Builder disableInterfaceProxies() { 2879 bcBuilder.disableInterfaceProxies(); 2880 return this; 2881 } 2882 2883 /** 2884 * Use Java Introspector. 2885 * 2886 * <p> 2887 * Using the built-in Java bean introspector will not pick up fields or non-standard getters/setters. 2888 * <br>Most {@link Bean @Bean} annotations will be ignored. 2889 * 2890 * <h5 class='section'>Example:</h5> 2891 * <p class='bjava'> 2892 * <jc>// Create a serializer that only uses the built-in java bean introspector for finding properties.</jc> 2893 * WriterSerializer <jv>serializer</jv> = JsonSerializer 2894 * .<jsm>create</jsm>() 2895 * .useJavaBeanIntrospector() 2896 * .build(); 2897 * </p> 2898 * 2899 * <h5 class='section'>See Also:</h5><ul> 2900 * <li class='jmf'>{@link BeanContext.Builder#useJavaBeanIntrospector()} 2901 * </ul> 2902 * 2903 * @return This object. 2904 */ 2905 public Builder useJavaBeanIntrospector() { 2906 bcBuilder.useJavaBeanIntrospector(); 2907 return this; 2908 } 2909 2910 @Override /* Context.Builder */ 2911 public Builder annotations(Annotation...value) { 2912 bcBuilder.annotations(value); 2913 super.annotations(value); 2914 return this; 2915 } 2916 2917 @Override /* Context.Builder */ 2918 public Builder debug() { 2919 bcBuilder.debug(); 2920 super.debug(); 2921 return this; 2922 } 2923 @Override /* Overridden from Builder */ 2924 public Builder apply(AnnotationWorkList work) { 2925 super.apply(work); 2926 return this; 2927 } 2928 2929 @Override /* Overridden from Builder */ 2930 public Builder applyAnnotations(Object...from) { 2931 super.applyAnnotations(from); 2932 return this; 2933 } 2934 2935 @Override /* Overridden from Builder */ 2936 public Builder applyAnnotations(Class<?>...from) { 2937 super.applyAnnotations(from); 2938 return this; 2939 } 2940 2941 @Override /* Overridden from Builder */ 2942 public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) { 2943 super.cache(value); 2944 return this; 2945 } 2946 2947 @Override /* Overridden from Builder */ 2948 public Builder impl(Context value) { 2949 super.impl(value); 2950 return this; 2951 } 2952 2953 @Override /* Overridden from Builder */ 2954 public Builder type(Class<? extends org.apache.juneau.Context> value) { 2955 super.type(value); 2956 return this; 2957 } 2958 } 2959 2960 //----------------------------------------------------------------------------------------------------------------- 2961 // Instance 2962 //----------------------------------------------------------------------------------------------------------------- 2963 2964 final BeanContext beanContext; 2965 2966 /** 2967 * Constructor. 2968 * 2969 * @param b The builder for this object. 2970 */ 2971 protected BeanContextable(Builder b) { 2972 super(b); 2973 beanContext = b.bc != null ? b.bc : b.bcBuilder.build(); 2974 } 2975 2976 /** 2977 * Returns the bean context for this object. 2978 * 2979 * @return The bean context for this object. 2980 */ 2981 public BeanContext getBeanContext() { 2982 return beanContext; 2983 } 2984 2985 //----------------------------------------------------------------------------------------------------------------- 2986 // Other methods 2987 //----------------------------------------------------------------------------------------------------------------- 2988 2989 @Override /* Context */ 2990 protected JsonMap properties() { 2991 return filteredMap("beanContext", beanContext.properties()); 2992 } 2993}