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