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