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