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