001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.serializer;
014
015import static org.apache.juneau.collections.JsonMap.*;
016import static org.apache.juneau.common.internal.ThrowableUtils.*;
017
018import java.lang.annotation.*;
019import java.lang.reflect.*;
020import java.nio.charset.*;
021import java.util.*;
022
023import org.apache.juneau.*;
024import org.apache.juneau.collections.*;
025import org.apache.juneau.common.internal.*;
026import org.apache.juneau.internal.*;
027import org.apache.juneau.json.*;
028import org.apache.juneau.utils.*;
029
030/**
031 * Subclass of {@link Serializer} for character-based serializers.
032 *
033 * <h5 class='section'>Notes:</h5><ul>
034 *    <li class='note'>This class is thread safe and reusable.
035 * </ul>
036 *
037 * <h5 class='section'>See Also:</h5><ul>
038 *    <li class='link'><a class="doclink" href="../../../../index.html#jm.SerializersAndParsers">Serializers and Parsers</a>
039 * </ul>
040 */
041public class WriterSerializer extends Serializer {
042
043   //-------------------------------------------------------------------------------------------------------------------
044   // Static
045   //-------------------------------------------------------------------------------------------------------------------
046
047   /**
048    * Creates a new builder for this object.
049    *
050    * @return A new builder.
051    */
052   public static Builder create() {
053      return new Builder();
054   }
055
056   //-------------------------------------------------------------------------------------------------------------------
057   // Builder
058   //-------------------------------------------------------------------------------------------------------------------
059
060   /**
061    * Builder class.
062    */
063   @FluentSetters
064   public static class Builder extends Serializer.Builder {
065
066      boolean useWhitespace;
067      Charset fileCharset, streamCharset;
068      int maxIndent;
069      Character quoteChar, quoteCharOverride;
070
071      /**
072       * Constructor, default settings.
073       */
074      protected Builder() {
075         super();
076         fileCharset = Charset.defaultCharset();
077         streamCharset = IOUtils.UTF8;
078         maxIndent = env("WriterSerializer.maxIndent", 100);
079         quoteChar = env("WriterSerializer.quoteChar", (Character)null);
080         quoteCharOverride = env("WriterSerializer.quoteCharOverride", (Character)null);
081         useWhitespace = env("WriterSerializer.useWhitespace", false);
082      }
083
084      /**
085       * Copy constructor.
086       *
087       * @param copyFrom The bean to copy from.
088       */
089      protected Builder(WriterSerializer copyFrom) {
090         super(copyFrom);
091         fileCharset = copyFrom.fileCharset;
092         streamCharset = copyFrom.streamCharset;
093         maxIndent = copyFrom.maxIndent;
094         quoteChar = copyFrom.quoteChar;
095         quoteCharOverride = copyFrom.quoteCharOverride;
096         useWhitespace = copyFrom.useWhitespace;
097      }
098
099      /**
100       * Copy constructor.
101       *
102       * @param copyFrom The builder to copy from.
103       */
104      protected Builder(Builder copyFrom) {
105         super(copyFrom);
106         fileCharset = copyFrom.fileCharset;
107         streamCharset = copyFrom.streamCharset;
108         maxIndent = copyFrom.maxIndent;
109         quoteChar = copyFrom.quoteChar;
110         quoteCharOverride = copyFrom.quoteCharOverride;
111         useWhitespace = copyFrom.useWhitespace;
112      }
113
114      @Override /* Context.Builder */
115      public Builder copy() {
116         return new Builder(this);
117      }
118
119      @Override /* Context.Builder */
120      public WriterSerializer build() {
121         return build(WriterSerializer.class);
122      }
123
124      @Override /* Context.Builder */
125      public HashKey hashKey() {
126         return HashKey.of(
127            super.hashKey(),
128            fileCharset,
129            streamCharset,
130            maxIndent,
131            quoteChar,
132            quoteCharOverride,
133            useWhitespace
134         );
135      }
136
137      //-----------------------------------------------------------------------------------------------------------------
138      // Properties
139      //-----------------------------------------------------------------------------------------------------------------
140
141      /**
142       * File charset.
143       *
144       * <p>
145       * The character set to use for writing <c>Files</c> to the file system.
146       *
147       * <p>
148       * Used when passing in files to {@link Serializer#serialize(Object, Object)}.
149       *
150       * <h5 class='section'>Example:</h5>
151       * <p class='bjava'>
152       *    <jc>// Create a serializer that writes UTF-8 files.</jc>
153       *    WriterSerializer <jv>serializer</jv> = JsonSerializer
154       *       .<jsm>create</jsm>()
155       *       .fileCharset(Charset.<jsm>forName</jsm>(<js>"UTF-8"</js>))
156       *       .build();
157       *
158       *    <jc>// Use it to read a UTF-8 encoded file.</jc>
159       *    <jv>serializer</jv>.serialize(<jk>new</jk> File(<js>"MyBean.txt"</js>), <jv>myBean</jv>);
160       * </p>
161       *
162       * @param value
163       *    The new value for this property.
164       *    <br>The default is the system JVM setting.
165       * @return This object.
166       */
167      @FluentSetter
168      public Builder fileCharset(Charset value) {
169         fileCharset = value;
170         return this;
171      }
172
173      /**
174       * Maximum indentation.
175       *
176       * <p>
177       * Specifies the maximum indentation level in the serialized document.
178       *
179       * <h5 class='section'>Notes:</h5><ul>
180       *    <li class='note'>This setting does not apply to the RDF serializers.
181       * </ul>
182       *
183       * <h5 class='section'>Example:</h5>
184       * <p class='bjava'>
185       *    <jc>// Create a serializer that indents a maximum of 20 tabs.</jc>
186       *    WriterSerializer <jv>serializer</jv> = JsonSerializer
187       *       .<jsm>create</jsm>()
188       *       .ws()  <jc>// Enable whitespace</jc>
189       *       .maxIndent(20)
190       *       .build();
191       * </p>
192       *
193       * @param value
194       *    The new value for this property.
195       *    <br>The default is <c>100</c>.
196       * @return This object.
197       */
198      @FluentSetter
199      public Builder maxIndent(int value) {
200         maxIndent = value;
201         return this;
202      }
203
204      /**
205       *  Quote character.
206       *
207       * <p>
208       * Specifies the character to use for quoting attributes and values.
209       *
210       * <h5 class='section'>Notes:</h5><ul>
211       *    <li class='note'>This setting does not apply to the RDF serializers.
212       * </ul>
213       *
214       * <h5 class='section'>Example:</h5>
215       * <p class='bjava'>
216       *    <jc>// Create a serializer that uses single quotes.</jc>
217       *    WriterSerializer <jv>serializer</jv> = JsonSerializer
218       *       .<jsm>create</jsm>()
219       *       .quoteChar(<js>'\''</js>)
220       *       .build();
221       *
222       *    <jc>// A bean with a single property</jc>
223       *    <jk>public class</jk> MyBean {
224       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
225       *    }
226       *
227       *    <jc>// Produces {'foo':'bar'}</jc>
228       *    String <jv>json</jv> = <jv>serializer</jv>.toString(<jk>new</jk> MyBean());
229       * </p>
230       *
231       * @param value
232       *    The new value for this property.
233       *    <br>The default is <js>'"'</js>.
234       * @return This object.
235       */
236      @FluentSetter
237      public Builder quoteChar(char value) {
238         quoteChar = value;
239         return this;
240      }
241
242      /**
243       * Quote character override.
244       *
245       * <p>
246       * Similar to {@link #quoteChar(char)} but takes precedence over that setting.
247       *
248       * <p>
249       * Allows you to override the quote character even if it's set by a subclass such as {@link Json5Serializer}.
250       *
251       *
252       * @param value
253       *    The new value for this property.
254       *    <br>The default is <jk>null</jk>.
255       * @return This object.
256       */
257      @FluentSetter
258      public Builder quoteCharOverride(char value) {
259         quoteCharOverride = value;
260         return this;
261      }
262
263      /**
264       *  Quote character.
265       *
266       * <p>
267       * Specifies to use single quotes for quoting attributes and values.
268       *
269       * <h5 class='section'>Notes:</h5><ul>
270       *    <li class='note'>This setting does not apply to the RDF serializers.
271       * </ul>
272       *
273       * <h5 class='section'>Example:</h5>
274       * <p class='bjava'>
275       *    <jc>// Create a serializer that uses single quotes.</jc>
276       *    WriterSerializer <jv>serializer</jv> = JsonSerializer
277       *       .<jsm>create</jsm>()
278       *       .sq()
279       *       .build();
280       *
281       *    <jc>// A bean with a single property</jc>
282       *    <jk>public class</jk> MyBean {
283       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
284       *    }
285       *
286       *    <jc>// Produces {'foo':'bar'}</jc>
287       *    String <jv>json</jv> = <jv>serializer</jv>.toString(<jk>new</jk> MyBean());
288       * </p>
289       *
290       * @return This object.
291       */
292      @FluentSetter
293      public Builder sq() {
294         return quoteChar('\'');
295      }
296
297      /**
298       * Output stream charset.
299       *
300       * <p>
301       * The character set to use when writing to <c>OutputStreams</c>.
302       *
303       * <p>
304       * Used when passing in output streams and byte arrays to {@link WriterSerializer#serialize(Object, Object)}.
305       *
306       * <h5 class='section'>Example:</h5>
307       * <p class='bjava'>
308       *    <jc>// Create a serializer that writes UTF-8 files.</jc>
309       *    WriterSerializer <jv>serializer</jv> = JsonSerializer
310       *       .<jsm>create</jsm>()
311       *       .streamCharset(Charset.<jsm>forName</jsm>(<js>"UTF-8"</js>))
312       *       .build();
313       *
314       *    <jc>// Use it to write to a UTF-8 encoded output stream.</jc>
315       *    <jv>serializer</jv>.serializer(<jk>new</jk> FileOutputStreamStream(<js>"MyBean.txt"</js>), <jv>myBean</jv>);
316       * </p>
317       *
318       * @param value
319       *    The new value for this property.
320       *    <br>The default is the system JVM setting.
321       * @return This object.
322       */
323      @FluentSetter
324      public Builder streamCharset(Charset value) {
325         streamCharset = value;
326         return this;
327      }
328
329      /**
330       *  Use whitespace.
331       *
332       * <p>
333       * When enabled, whitespace is added to the output to improve readability.
334       *
335       * <h5 class='section'>Example:</h5>
336       * <p class='bjava'>
337       *    <jc>// Create a serializer with whitespace enabled.</jc>
338       *    WriterSerializer <jv>serializer</jv> = JsonSerializer
339       *       .<jsm>create</jsm>()
340       *       .useWhitespace()
341       *       .build();
342       *
343       *    <jc>// A bean with a single property</jc>
344       *    <jk>public class</jk> MyBean {
345       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
346       *    }
347       *
348       *    <jc>// Produces "\{\n\t"foo": "bar"\n\}\n"</jc>
349       *    String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean());
350       * </p>
351       *
352       * @return This object.
353       */
354      @FluentSetter
355      public Builder useWhitespace() {
356         return useWhitespace(true);
357      }
358
359      /**
360       * Same as {@link #useWhitespace()} but allows you to explicitly specify the value.
361       *
362       * @param value The value for this setting.
363       * @return This object.
364       */
365      @FluentSetter
366      public Builder useWhitespace(boolean value) {
367         useWhitespace = value;
368         return this;
369      }
370
371      /**
372       *  Use whitespace.
373       *
374       * <p>
375       * When enabled, whitespace is added to the output to improve readability.
376       *
377       * <h5 class='section'>Example:</h5>
378       * <p class='bjava'>
379       *    <jc>// Create a serializer with whitespace enabled.</jc>
380       *    WriterSerializer <jv>serializer</jv> = JsonSerializer
381       *       .<jsm>create</jsm>()
382       *       .ws()
383       *       .build();
384       *
385       *    <jc>// A bean with a single property</jc>
386       *    <jk>public class</jk> MyBean {
387       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
388       *    }
389       *
390       *    <jc>// Produces "\{\n\t"foo": "bar"\n\}\n"</jc>
391       *    String <jv>json</jv> = <jv>serializer</jv>.serialize(<jk>new</jk> MyBean());
392       * </p>
393       *
394       * @return This object.
395       */
396      @FluentSetter
397      public Serializer.Builder ws() {
398         return useWhitespace();
399      }
400
401      // <FluentSetters>
402
403      @Override /* GENERATED - org.apache.juneau.Context.Builder */
404      public Builder annotations(Annotation...values) {
405         super.annotations(values);
406         return this;
407      }
408
409      @Override /* GENERATED - org.apache.juneau.Context.Builder */
410      public Builder apply(AnnotationWorkList work) {
411         super.apply(work);
412         return this;
413      }
414
415      @Override /* GENERATED - org.apache.juneau.Context.Builder */
416      public Builder applyAnnotations(java.lang.Class<?>...fromClasses) {
417         super.applyAnnotations(fromClasses);
418         return this;
419      }
420
421      @Override /* GENERATED - org.apache.juneau.Context.Builder */
422      public Builder applyAnnotations(Method...fromMethods) {
423         super.applyAnnotations(fromMethods);
424         return this;
425      }
426
427      @Override /* GENERATED - org.apache.juneau.Context.Builder */
428      public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) {
429         super.cache(value);
430         return this;
431      }
432
433      @Override /* GENERATED - org.apache.juneau.Context.Builder */
434      public Builder debug() {
435         super.debug();
436         return this;
437      }
438
439      @Override /* GENERATED - org.apache.juneau.Context.Builder */
440      public Builder debug(boolean value) {
441         super.debug(value);
442         return this;
443      }
444
445      @Override /* GENERATED - org.apache.juneau.Context.Builder */
446      public Builder impl(Context value) {
447         super.impl(value);
448         return this;
449      }
450
451      @Override /* GENERATED - org.apache.juneau.Context.Builder */
452      public Builder type(Class<? extends org.apache.juneau.Context> value) {
453         super.type(value);
454         return this;
455      }
456
457      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
458      public Builder beanClassVisibility(Visibility value) {
459         super.beanClassVisibility(value);
460         return this;
461      }
462
463      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
464      public Builder beanConstructorVisibility(Visibility value) {
465         super.beanConstructorVisibility(value);
466         return this;
467      }
468
469      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
470      public Builder beanContext(BeanContext value) {
471         super.beanContext(value);
472         return this;
473      }
474
475      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
476      public Builder beanContext(BeanContext.Builder value) {
477         super.beanContext(value);
478         return this;
479      }
480
481      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
482      public Builder beanDictionary(java.lang.Class<?>...values) {
483         super.beanDictionary(values);
484         return this;
485      }
486
487      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
488      public Builder beanFieldVisibility(Visibility value) {
489         super.beanFieldVisibility(value);
490         return this;
491      }
492
493      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
494      public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) {
495         super.beanInterceptor(on, value);
496         return this;
497      }
498
499      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
500      public Builder beanMapPutReturnsOldValue() {
501         super.beanMapPutReturnsOldValue();
502         return this;
503      }
504
505      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
506      public Builder beanMethodVisibility(Visibility value) {
507         super.beanMethodVisibility(value);
508         return this;
509      }
510
511      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
512      public Builder beanProperties(Map<String,Object> values) {
513         super.beanProperties(values);
514         return this;
515      }
516
517      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
518      public Builder beanProperties(Class<?> beanClass, String properties) {
519         super.beanProperties(beanClass, properties);
520         return this;
521      }
522
523      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
524      public Builder beanProperties(String beanClassName, String properties) {
525         super.beanProperties(beanClassName, properties);
526         return this;
527      }
528
529      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
530      public Builder beanPropertiesExcludes(Map<String,Object> values) {
531         super.beanPropertiesExcludes(values);
532         return this;
533      }
534
535      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
536      public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) {
537         super.beanPropertiesExcludes(beanClass, properties);
538         return this;
539      }
540
541      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
542      public Builder beanPropertiesExcludes(String beanClassName, String properties) {
543         super.beanPropertiesExcludes(beanClassName, properties);
544         return this;
545      }
546
547      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
548      public Builder beanPropertiesReadOnly(Map<String,Object> values) {
549         super.beanPropertiesReadOnly(values);
550         return this;
551      }
552
553      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
554      public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) {
555         super.beanPropertiesReadOnly(beanClass, properties);
556         return this;
557      }
558
559      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
560      public Builder beanPropertiesReadOnly(String beanClassName, String properties) {
561         super.beanPropertiesReadOnly(beanClassName, properties);
562         return this;
563      }
564
565      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
566      public Builder beanPropertiesWriteOnly(Map<String,Object> values) {
567         super.beanPropertiesWriteOnly(values);
568         return this;
569      }
570
571      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
572      public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) {
573         super.beanPropertiesWriteOnly(beanClass, properties);
574         return this;
575      }
576
577      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
578      public Builder beanPropertiesWriteOnly(String beanClassName, String properties) {
579         super.beanPropertiesWriteOnly(beanClassName, properties);
580         return this;
581      }
582
583      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
584      public Builder beansRequireDefaultConstructor() {
585         super.beansRequireDefaultConstructor();
586         return this;
587      }
588
589      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
590      public Builder beansRequireSerializable() {
591         super.beansRequireSerializable();
592         return this;
593      }
594
595      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
596      public Builder beansRequireSettersForGetters() {
597         super.beansRequireSettersForGetters();
598         return this;
599      }
600
601      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
602      public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) {
603         super.dictionaryOn(on, values);
604         return this;
605      }
606
607      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
608      public Builder disableBeansRequireSomeProperties() {
609         super.disableBeansRequireSomeProperties();
610         return this;
611      }
612
613      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
614      public Builder disableIgnoreMissingSetters() {
615         super.disableIgnoreMissingSetters();
616         return this;
617      }
618
619      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
620      public Builder disableIgnoreTransientFields() {
621         super.disableIgnoreTransientFields();
622         return this;
623      }
624
625      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
626      public Builder disableIgnoreUnknownNullBeanProperties() {
627         super.disableIgnoreUnknownNullBeanProperties();
628         return this;
629      }
630
631      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
632      public Builder disableInterfaceProxies() {
633         super.disableInterfaceProxies();
634         return this;
635      }
636
637      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
638      public <T> Builder example(Class<T> pojoClass, T o) {
639         super.example(pojoClass, o);
640         return this;
641      }
642
643      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
644      public <T> Builder example(Class<T> pojoClass, String json) {
645         super.example(pojoClass, json);
646         return this;
647      }
648
649      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
650      public Builder findFluentSetters() {
651         super.findFluentSetters();
652         return this;
653      }
654
655      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
656      public Builder findFluentSetters(Class<?> on) {
657         super.findFluentSetters(on);
658         return this;
659      }
660
661      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
662      public Builder ignoreInvocationExceptionsOnGetters() {
663         super.ignoreInvocationExceptionsOnGetters();
664         return this;
665      }
666
667      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
668      public Builder ignoreInvocationExceptionsOnSetters() {
669         super.ignoreInvocationExceptionsOnSetters();
670         return this;
671      }
672
673      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
674      public Builder ignoreUnknownBeanProperties() {
675         super.ignoreUnknownBeanProperties();
676         return this;
677      }
678
679      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
680      public Builder ignoreUnknownEnumValues() {
681         super.ignoreUnknownEnumValues();
682         return this;
683      }
684
685      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
686      public Builder implClass(Class<?> interfaceClass, Class<?> implClass) {
687         super.implClass(interfaceClass, implClass);
688         return this;
689      }
690
691      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
692      public Builder implClasses(Map<Class<?>,Class<?>> values) {
693         super.implClasses(values);
694         return this;
695      }
696
697      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
698      public Builder interfaceClass(Class<?> on, Class<?> value) {
699         super.interfaceClass(on, value);
700         return this;
701      }
702
703      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
704      public Builder interfaces(java.lang.Class<?>...value) {
705         super.interfaces(value);
706         return this;
707      }
708
709      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
710      public Builder locale(Locale value) {
711         super.locale(value);
712         return this;
713      }
714
715      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
716      public Builder mediaType(MediaType value) {
717         super.mediaType(value);
718         return this;
719      }
720
721      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
722      public Builder notBeanClasses(java.lang.Class<?>...values) {
723         super.notBeanClasses(values);
724         return this;
725      }
726
727      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
728      public Builder notBeanPackages(String...values) {
729         super.notBeanPackages(values);
730         return this;
731      }
732
733      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
734      public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) {
735         super.propertyNamer(value);
736         return this;
737      }
738
739      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
740      public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) {
741         super.propertyNamer(on, value);
742         return this;
743      }
744
745      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
746      public Builder sortProperties() {
747         super.sortProperties();
748         return this;
749      }
750
751      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
752      public Builder sortProperties(java.lang.Class<?>...on) {
753         super.sortProperties(on);
754         return this;
755      }
756
757      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
758      public Builder stopClass(Class<?> on, Class<?> value) {
759         super.stopClass(on, value);
760         return this;
761      }
762
763      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
764      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) {
765         super.swap(normalClass, swappedClass, swapFunction);
766         return this;
767      }
768
769      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
770      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) {
771         super.swap(normalClass, swappedClass, swapFunction, unswapFunction);
772         return this;
773      }
774
775      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
776      public Builder swaps(java.lang.Class<?>...values) {
777         super.swaps(values);
778         return this;
779      }
780
781      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
782      public Builder timeZone(TimeZone value) {
783         super.timeZone(value);
784         return this;
785      }
786
787      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
788      public Builder typeName(Class<?> on, String value) {
789         super.typeName(on, value);
790         return this;
791      }
792
793      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
794      public Builder typePropertyName(String value) {
795         super.typePropertyName(value);
796         return this;
797      }
798
799      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
800      public Builder typePropertyName(Class<?> on, String value) {
801         super.typePropertyName(on, value);
802         return this;
803      }
804
805      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
806      public Builder useEnumNames() {
807         super.useEnumNames();
808         return this;
809      }
810
811      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
812      public Builder useJavaBeanIntrospector() {
813         super.useJavaBeanIntrospector();
814         return this;
815      }
816
817      @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */
818      public Builder detectRecursions() {
819         super.detectRecursions();
820         return this;
821      }
822
823      @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */
824      public Builder detectRecursions(boolean value) {
825         super.detectRecursions(value);
826         return this;
827      }
828
829      @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */
830      public Builder ignoreRecursions() {
831         super.ignoreRecursions();
832         return this;
833      }
834
835      @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */
836      public Builder ignoreRecursions(boolean value) {
837         super.ignoreRecursions(value);
838         return this;
839      }
840
841      @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */
842      public Builder initialDepth(int value) {
843         super.initialDepth(value);
844         return this;
845      }
846
847      @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */
848      public Builder maxDepth(int value) {
849         super.maxDepth(value);
850         return this;
851      }
852
853      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
854      public Builder accept(String value) {
855         super.accept(value);
856         return this;
857      }
858
859      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
860      public Builder addBeanTypes() {
861         super.addBeanTypes();
862         return this;
863      }
864
865      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
866      public Builder addBeanTypes(boolean value) {
867         super.addBeanTypes(value);
868         return this;
869      }
870
871      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
872      public Builder addRootType() {
873         super.addRootType();
874         return this;
875      }
876
877      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
878      public Builder addRootType(boolean value) {
879         super.addRootType(value);
880         return this;
881      }
882
883      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
884      public Builder keepNullProperties() {
885         super.keepNullProperties();
886         return this;
887      }
888
889      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
890      public Builder keepNullProperties(boolean value) {
891         super.keepNullProperties(value);
892         return this;
893      }
894
895      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
896      public Builder listener(Class<? extends org.apache.juneau.serializer.SerializerListener> value) {
897         super.listener(value);
898         return this;
899      }
900
901      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
902      public Builder produces(String value) {
903         super.produces(value);
904         return this;
905      }
906
907      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
908      public Builder sortCollections() {
909         super.sortCollections();
910         return this;
911      }
912
913      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
914      public Builder sortCollections(boolean value) {
915         super.sortCollections(value);
916         return this;
917      }
918
919      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
920      public Builder sortMaps() {
921         super.sortMaps();
922         return this;
923      }
924
925      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
926      public Builder sortMaps(boolean value) {
927         super.sortMaps(value);
928         return this;
929      }
930
931      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
932      public Builder trimEmptyCollections() {
933         super.trimEmptyCollections();
934         return this;
935      }
936
937      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
938      public Builder trimEmptyCollections(boolean value) {
939         super.trimEmptyCollections(value);
940         return this;
941      }
942
943      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
944      public Builder trimEmptyMaps() {
945         super.trimEmptyMaps();
946         return this;
947      }
948
949      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
950      public Builder trimEmptyMaps(boolean value) {
951         super.trimEmptyMaps(value);
952         return this;
953      }
954
955      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
956      public Builder trimStrings() {
957         super.trimStrings();
958         return this;
959      }
960
961      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
962      public Builder trimStrings(boolean value) {
963         super.trimStrings(value);
964         return this;
965      }
966
967      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
968      public Builder uriContext(UriContext value) {
969         super.uriContext(value);
970         return this;
971      }
972
973      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
974      public Builder uriRelativity(UriRelativity value) {
975         super.uriRelativity(value);
976         return this;
977      }
978
979      @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */
980      public Builder uriResolution(UriResolution value) {
981         super.uriResolution(value);
982         return this;
983      }
984
985      // </FluentSetters>
986   }
987
988   //-------------------------------------------------------------------------------------------------------------------
989   // Instance
990   //-------------------------------------------------------------------------------------------------------------------
991
992   final Charset fileCharset, streamCharset;
993   final int maxIndent;
994   final Character quoteChar, quoteCharOverride;
995   final boolean useWhitespace;
996
997   private final char quoteCharValue;
998
999   /**
1000    * Constructor.
1001    *
1002    * @param builder
1003    *    The builder for this object.
1004    */
1005   protected WriterSerializer(Builder builder) {
1006      super(builder);
1007
1008      maxIndent = builder.maxIndent;
1009      quoteChar = builder.quoteChar;
1010      quoteCharOverride = builder.quoteCharOverride;
1011      streamCharset = builder.streamCharset;
1012      fileCharset = builder.fileCharset;
1013      useWhitespace = builder.useWhitespace;
1014
1015      quoteCharValue = quoteCharOverride != null ? quoteCharOverride : quoteChar != null ? quoteChar : '"';
1016   }
1017
1018   @Override /* Context */
1019   public Builder copy() {
1020      return new Builder(this);
1021   }
1022
1023   @Override /* Context */
1024   public WriterSerializerSession.Builder createSession() {
1025      return WriterSerializerSession.create(this);
1026   }
1027
1028   @Override /* Context */
1029   public WriterSerializerSession getSession() {
1030      return createSession().build();
1031   }
1032
1033   @Override /* Serializer */
1034   public final boolean isWriterSerializer() {
1035      return true;
1036   }
1037
1038   /**
1039    * Convenience method for serializing an object to a <c>String</c>.
1040    *
1041    * @param o The object to serialize.
1042    * @return The output serialized to a string.
1043    * @throws SerializeException If a problem occurred trying to convert the output.
1044    */
1045   @Override /* Serializer */
1046   public final String serialize(Object o) throws SerializeException {
1047      return getSession().serialize(o);
1048   }
1049
1050   /**
1051    * Identical to {@link #serialize(Object)} except throws a {@link RuntimeException} instead of a {@link SerializeException}.
1052    *
1053    * <p>
1054    * This is typically good enough for debugging purposes.
1055    *
1056    * @param o The object to serialize.
1057    * @return The serialized object.
1058    */
1059   public final String toString(Object o) {
1060      try {
1061         return serialize(o);
1062      } catch (Exception e) {
1063         throw asRuntimeException(e);
1064      }
1065   }
1066
1067   /**
1068    * Convenience method for serializing an object and sending it to STDOUT.
1069    *
1070    * @param o The object to serialize.
1071    * @return This object.
1072    */
1073   public final WriterSerializer println(Object o) {
1074      System.out.println(toString(o));  // NOT DEBUG
1075      return this;
1076   }
1077
1078   //-----------------------------------------------------------------------------------------------------------------
1079   // Properties
1080   //-----------------------------------------------------------------------------------------------------------------
1081
1082   /**
1083    * File charset.
1084    *
1085    * @see Builder#fileCharset(Charset)
1086    * @return
1087    *    The character set to use when writing to <c>Files</c> on the file system.
1088    */
1089   protected final Charset getFileCharset() {
1090      return fileCharset;
1091   }
1092
1093   /**
1094    * Maximum indentation.
1095    *
1096    * @see Builder#maxIndent(int)
1097    * @return
1098    *    The maximum indentation level in the serialized document.
1099    */
1100   protected final int getMaxIndent() {
1101      return maxIndent;
1102   }
1103
1104   /**
1105    * Quote character.
1106    *
1107    * @see Builder#quoteChar(char)
1108    * @return
1109    *    The character used for quoting attributes and values.
1110    */
1111   protected char getQuoteChar() {
1112      return quoteCharValue;
1113   }
1114
1115   /**
1116    * Quote character.
1117    *
1118    * @see Builder#quoteChar(char)
1119    * @return
1120    *    The character used for quoting attributes and values.
1121    */
1122   protected Character quoteChar() {
1123      return quoteCharOverride != null ? quoteCharOverride : quoteChar;
1124   }
1125
1126   /**
1127    * Output stream charset.
1128    *
1129    * @see Builder#streamCharset(Charset)
1130    * @return
1131    *    The character set to use when writing to <c>OutputStreams</c> and byte arrays.
1132    */
1133   protected final Charset getStreamCharset() {
1134      return streamCharset;
1135   }
1136
1137   /**
1138    * Trim strings.
1139    *
1140    * @see Builder#useWhitespace()
1141    * @return
1142    *    When enabled, whitespace is added to the output to improve readability.
1143    */
1144   protected final boolean isUseWhitespace() {
1145      return useWhitespace;
1146   }
1147
1148   //-----------------------------------------------------------------------------------------------------------------
1149   // Other methods
1150   //-----------------------------------------------------------------------------------------------------------------
1151
1152   @Override /* Context */
1153   protected JsonMap properties() {
1154      return filteredMap("fileCharset", fileCharset, "maxIndent", maxIndent, "quoteChar", quoteChar, "streamCharset", streamCharset, "useWhitespace", useWhitespace);
1155   }
1156}