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