001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau;
018
019import static org.apache.juneau.commons.utils.AssertionUtils.*;
020import static org.apache.juneau.commons.utils.Utils.*;
021
022import java.beans.*;
023import java.io.*;
024import java.lang.annotation.*;
025import java.lang.reflect.*;
026import java.util.*;
027import java.util.function.*;
028
029import org.apache.juneau.annotation.*;
030import org.apache.juneau.commons.collections.*;
031import org.apache.juneau.commons.function.*;
032import org.apache.juneau.commons.reflect.*;
033import org.apache.juneau.commons.reflect.Visibility;
034import org.apache.juneau.swap.*;
035
036/**
037 * Context class for classes that use {@link BeanContext} objects.
038 *
039 * <p>
040 * This abstraction exists to allow different kinds of subclasses (e.g. JsonSerilalizer, XmlParser...) to share bean context objects since
041 * bean context objects are heavyweight objects that cache metadata about encountered beans.
042 *
043 * <h5 class='section'>Notes:</h5><ul>
044 *    <li class='note'>This class is thread safe and reusable.
045 * </ul>
046 */
047public abstract class BeanContextable extends Context {
048
049   /**
050    * Builder class.
051    */
052   public abstract static class Builder extends Context.Builder {
053
054      private BeanContext.Builder bcBuilder;
055      private BeanContext bc;
056
057      /**
058       * Constructor.
059       *
060       * All default settings.
061       */
062      protected Builder() {
063         this.bcBuilder = BeanContext.create();
064         registerBuilders(bcBuilder);
065      }
066
067      /**
068       * Copy constructor.
069       *
070       * @param copyFrom The bean to copy from.
071       */
072      protected Builder(BeanContextable copyFrom) {
073         super(copyFrom);
074         this.bcBuilder = copyFrom.getBeanContext().copy();
075         registerBuilders(bcBuilder);
076      }
077
078      /**
079       * Copy constructor.
080       *
081       * @param copyFrom The builder to copy from.
082       */
083      protected Builder(Builder copyFrom) {
084         super(copyFrom);
085         this.bcBuilder = copyFrom.bcBuilder.copy();
086         this.bc = copyFrom.bc;
087         registerBuilders(bcBuilder);
088      }
089
090      @Override /* Overridden from Context.Builder */
091      public Builder annotations(Annotation...value) {
092         bcBuilder.annotations(value);
093         super.annotations(value);
094         return this;
095      }
096
097      @Override /* Overridden from Builder */
098      public Builder apply(AnnotationWorkList work) {
099         super.apply(work);
100         return this;
101      }
102
103      @Override /* Overridden from Builder */
104      public Builder applyAnnotations(Class<?>...from) {
105         super.applyAnnotations(from);
106         return this;
107      }
108
109      @Override /* Overridden from Builder */
110      public Builder applyAnnotations(Object...from) {
111         super.applyAnnotations(from);
112         return this;
113      }
114
115      /**
116       * Minimum bean class visibility.
117       *
118       * <p>
119       * Classes are not considered beans unless they meet the minimum visibility requirements.
120       * For example, if the visibility is <jsf>PUBLIC</jsf> and the bean class is <jk>protected</jk>, then the class
121       * will not be interpreted as a bean class and be serialized as a string.
122       * Use this setting to reduce the visibility requirement.
123       *
124       * <h5 class='section'>Example:</h5>
125       * <p class='bjava'>
126       *    <jc>// A bean with a protected class and one field.</jc>
127       *    <jk>protected class</jk> MyBean {
128       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
129       *    }
130       *
131       *    <jc>// Create a serializer that's capable of serializing the class.</jc>
132       *    WriterSerializer <jv>serializer</jv> = JsonSerializer
133       *       .<jsm>create</jsm>()
134       *       .beanClassVisibility(<jsf>PROTECTED</jsf>)
135       *       .build();
136       *
137       *    <jc>// Produces:  {"foo","bar"}</jc>
138       *    String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean());
139       * </p>
140       *
141       * <h5 class='section'>Notes:</h5>
142       * <ul>
143       *    <li class='note'>The {@link Bean @Bean} annotation can be used on a non-public bean class to override this setting.
144       *    <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a public bean class to ignore it as a bean.
145       * </ul>
146       *
147       * <h5 class='section'>See Also:</h5>
148       * <ul>
149       *    <li class='ja'>{@link BeanConfig#beanClassVisibility()}
150       * </ul>
151       *
152       * @param value
153       *    The new value for this setting.
154       *    <br>The default is {@link Visibility#PUBLIC}.
155       *    <br>Cannot be <jk>null</jk>.
156       * @return This object.
157       */
158      public Builder beanClassVisibility(Visibility value) {
159         bcBuilder.beanClassVisibility(assertArgNotNull("value", value));
160         return this;
161      }
162
163      /**
164       * Minimum bean constructor visibility.
165       *
166       * <p>
167       * Only look for constructors with the specified minimum visibility.
168       *
169       * <p>
170       * This setting affects the logic for finding no-arg constructors for bean.  Normally, only <jk>public</jk> no-arg
171       * constructors are used.  Use this setting if you want to reduce the visibility requirement.
172       *
173       * <h5 class='section'>Example:</h5>
174       * <p class='bjava'>
175       *    <jc>// A bean with a protected constructor and one field.</jc>
176       *    <jk>public class</jk> MyBean {
177       *       <jk>public</jk> String <jf>foo</jf>;
178       *
179       *       <jk>protected</jk> MyBean() {}
180       *    }
181       *
182       *    <jc>// Create a parser capable of calling the protected constructor.</jc>
183       *    ReaderParser <jv>parser</jv> = ReaderParser
184       *       .<jsm>create</jsm>()
185       *       .beanConstructorVisibility(<jsf>PROTECTED</jsf>)
186       *       .build();
187       *
188       *    <jc>// Use it.</jc>
189       *    MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<js>"{foo:'bar'}"</js>, MyBean.<jk>class</jk>);
190       * </p>
191       *
192       * <h5 class='section'>Notes:</h5><ul>
193       *    <li class='note'>The {@link Beanc @Beanc} annotation can also be used to expose a non-public constructor.
194       *    <li class='note'>The {@link BeanIgnore @BeanIgnore} annotation can also be used on a public bean constructor to ignore it.
195       * </ul>
196       *
197       * <h5 class='section'>See Also:</h5><ul>
198       *    <li class='ja'>{@link BeanConfig#beanConstructorVisibility()}
199       * </ul>
200       *
201       * @param value
202       *    The new value for this setting.
203       *    <br>The default is {@link Visibility#PUBLIC}.
204       *    <br>Cannot be <jk>null</jk>.
205       * @return This object.
206       */
207      public Builder beanConstructorVisibility(Visibility value) {
208         bcBuilder.beanConstructorVisibility(assertArgNotNull("value", value));
209         return this;
210      }
211
212      /**
213       * Returns the inner bean context builder.
214       *
215       * @return The inner bean context builder.
216       */
217      public BeanContext.Builder beanContext() {
218         return bcBuilder;
219      }
220
221      /**
222       * Specifies an already-instantiated bean context to use.
223       *
224       * <p>
225       * Provides an optimization for cases where serializers and parsers can use an existing
226       * bean context without having to go through <c><jv>beanContext</jv>.copy().build()</c>.
227       * An example is {@link BeanContext#getBeanToStringSerializer()}.
228       *
229       * @param value The bean context to use.
230       *    <br>Cannot be <jk>null</jk>.
231       * @return This object.
232       */
233      public Builder beanContext(BeanContext value) {
234         bc = assertArgNotNull("value", value);
235         return this;
236      }
237
238      /**
239       * Overrides the bean context builder.
240       *
241       * <p>
242       * Used when sharing bean context builders across multiple context objects.
243       * For example, {@link org.apache.juneau.jsonschema.JsonSchemaGenerator.Builder} uses this to apply common bean settings with the JSON
244       * serializer and parser.
245       *
246       * @param value The new value for this setting.
247       *    <br>Cannot be <jk>null</jk>.
248       * @return This object.
249       */
250      public Builder beanContext(BeanContext.Builder value) {
251         bcBuilder = assertArgNotNull("value", value);
252         return this;
253      }
254
255      /**
256       * Applies an operation to the inner bean context builder.
257       *
258       * @param operation The operation to apply.
259       *    <br>Cannot be <jk>null</jk>.
260       * @return This object.
261       */
262      public final Builder beanContext(Consumer<BeanContext.Builder> operation) {
263         assertArgNotNull("operation", operation);
264         operation.accept(beanContext());
265         return this;
266      }
267
268      /**
269       * Bean dictionary.
270       *
271       * <p>
272       * The list of classes that make up the bean dictionary in this bean context.
273       *
274       * <p>
275       * Values are prepended to the list so that later calls can override classes of earlier calls.
276       *
277       * <p>
278       * A dictionary is a name/class mapping used to find class types during parsing when they cannot be inferred
279       * through reflection.  The names are defined through the {@link Bean#typeName() @Bean(typeName)} annotation defined
280       * on the bean class.  For example, if a class <c>Foo</c> has a type-name of <js>"myfoo"</js>, then it would end up
281       * serialized as <js>"{_type:'myfoo',...}"</js> in JSON
282       * or <js>"&lt;myfoo&gt;...&lt;/myfoo&gt;"</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&lt;String,Object&gt; <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>"&lt;body&gt;&lt;ul&gt;&lt;li&gt;foo&lt;/li&gt;&lt;li&gt;bar&lt;/li&gt;&lt;/ul&gt;"</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&lt;Address&gt; {
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>) &amp;&amp; <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&lt;MyBean&gt; <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:&emsp;</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&lt;MyBean&gt; {
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:&emsp;</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&lt;MyBean&gt; {
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> -&gt; <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> -&gt; <jsm>format</jsm>(<jv>x</jv>), <jv>x</jv> -&gt; <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&lt;Date&gt; {
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:&emsp;</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&lt;MyBean&gt; {
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}