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