1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.serializer;
18
19 import static org.apache.juneau.commons.utils.AssertionUtils.*;
20 import static org.apache.juneau.commons.utils.IoUtils.*;
21 import static org.apache.juneau.commons.utils.ThrowableUtils.*;
22 import static org.apache.juneau.commons.utils.Utils.*;
23
24 import java.lang.annotation.*;
25 import java.nio.charset.*;
26 import java.util.*;
27
28 import org.apache.juneau.*;
29 import org.apache.juneau.commons.collections.*;
30 import org.apache.juneau.commons.function.*;
31 import org.apache.juneau.commons.reflect.*;
32 import org.apache.juneau.json.*;
33
34
35
36
37
38
39
40
41
42
43
44
45 public class WriterSerializer extends Serializer {
46
47
48
49 public static class Builder extends Serializer.Builder {
50
51 private boolean useWhitespace;
52 private Character quoteChar;
53 private Character quoteCharOverride;
54 private Charset fileCharset;
55 private Charset streamCharset;
56 private int maxIndent;
57
58
59
60
61 protected Builder() {
62 fileCharset = Charset.defaultCharset();
63 streamCharset = UTF8;
64 maxIndent = env("WriterSerializer.maxIndent", 100);
65 quoteChar = env("WriterSerializer.quoteChar").map(x -> (x.length() > 0 ? x.charAt(0) : null)).orElse(null);
66 quoteCharOverride = env("WriterSerializer.quoteCharOverride").map(x -> (x.length() > 0 ? x.charAt(0) : null)).orElse(null);
67 useWhitespace = env("WriterSerializer.useWhitespace", false);
68 }
69
70
71
72
73
74
75
76 protected Builder(Builder copyFrom) {
77 super(assertArgNotNull("copyFrom", copyFrom));
78 fileCharset = copyFrom.fileCharset;
79 streamCharset = copyFrom.streamCharset;
80 maxIndent = copyFrom.maxIndent;
81 quoteChar = copyFrom.quoteChar;
82 quoteCharOverride = copyFrom.quoteCharOverride;
83 useWhitespace = copyFrom.useWhitespace;
84 }
85
86
87
88
89
90
91
92 protected Builder(WriterSerializer copyFrom) {
93 super(assertArgNotNull("copyFrom", copyFrom));
94 fileCharset = copyFrom.getFileCharset();
95 streamCharset = copyFrom.getStreamCharset();
96 maxIndent = copyFrom.maxIndent;
97 quoteChar = copyFrom.quoteChar;
98 quoteCharOverride = copyFrom.quoteCharOverride;
99 useWhitespace = copyFrom.useWhitespace;
100 }
101
102 @Override
103 public Builder accept(String value) {
104 super.accept(value);
105 return this;
106 }
107
108 @Override
109 public Builder addBeanTypes() {
110 super.addBeanTypes();
111 return this;
112 }
113
114 @Override
115 public Builder addBeanTypes(boolean value) {
116 super.addBeanTypes(value);
117 return this;
118 }
119
120 @Override
121 public Builder addRootType() {
122 super.addRootType();
123 return this;
124 }
125
126 @Override
127 public Builder addRootType(boolean value) {
128 super.addRootType(value);
129 return this;
130 }
131
132 @Override
133 public Builder annotations(Annotation...values) {
134 super.annotations(values);
135 return this;
136 }
137
138 @Override
139 public Builder apply(AnnotationWorkList work) {
140 super.apply(work);
141 return this;
142 }
143
144 @Override
145 public Builder applyAnnotations(Class<?>...from) {
146 super.applyAnnotations(from);
147 return this;
148 }
149
150 @Override
151 public Builder applyAnnotations(Object...from) {
152 super.applyAnnotations(from);
153 return this;
154 }
155
156 @Override
157 public Builder beanClassVisibility(Visibility value) {
158 super.beanClassVisibility(value);
159 return this;
160 }
161
162 @Override
163 public Builder beanConstructorVisibility(Visibility value) {
164 super.beanConstructorVisibility(value);
165 return this;
166 }
167
168 @Override
169 public Builder beanContext(BeanContext value) {
170 super.beanContext(value);
171 return this;
172 }
173
174 @Override
175 public Builder beanContext(BeanContext.Builder value) {
176 super.beanContext(value);
177 return this;
178 }
179
180 @Override
181 public Builder beanDictionary(java.lang.Class<?>...values) {
182 super.beanDictionary(values);
183 return this;
184 }
185
186 @Override
187 public Builder beanFieldVisibility(Visibility value) {
188 super.beanFieldVisibility(value);
189 return this;
190 }
191
192 @Override
193 public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) {
194 super.beanInterceptor(on, value);
195 return this;
196 }
197
198 @Override
199 public Builder beanMapPutReturnsOldValue() {
200 super.beanMapPutReturnsOldValue();
201 return this;
202 }
203
204 @Override
205 public Builder beanMethodVisibility(Visibility value) {
206 super.beanMethodVisibility(value);
207 return this;
208 }
209
210 @Override
211 public Builder beanProperties(Class<?> beanClass, String properties) {
212 super.beanProperties(beanClass, properties);
213 return this;
214 }
215
216 @Override
217 public Builder beanProperties(Map<String,Object> values) {
218 super.beanProperties(values);
219 return this;
220 }
221
222 @Override
223 public Builder beanProperties(String beanClassName, String properties) {
224 super.beanProperties(beanClassName, properties);
225 return this;
226 }
227
228 @Override
229 public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) {
230 super.beanPropertiesExcludes(beanClass, properties);
231 return this;
232 }
233
234 @Override
235 public Builder beanPropertiesExcludes(Map<String,Object> values) {
236 super.beanPropertiesExcludes(values);
237 return this;
238 }
239
240 @Override
241 public Builder beanPropertiesExcludes(String beanClassName, String properties) {
242 super.beanPropertiesExcludes(beanClassName, properties);
243 return this;
244 }
245
246 @Override
247 public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) {
248 super.beanPropertiesReadOnly(beanClass, properties);
249 return this;
250 }
251
252 @Override
253 public Builder beanPropertiesReadOnly(Map<String,Object> values) {
254 super.beanPropertiesReadOnly(values);
255 return this;
256 }
257
258 @Override
259 public Builder beanPropertiesReadOnly(String beanClassName, String properties) {
260 super.beanPropertiesReadOnly(beanClassName, properties);
261 return this;
262 }
263
264 @Override
265 public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) {
266 super.beanPropertiesWriteOnly(beanClass, properties);
267 return this;
268 }
269
270 @Override
271 public Builder beanPropertiesWriteOnly(Map<String,Object> values) {
272 super.beanPropertiesWriteOnly(values);
273 return this;
274 }
275
276 @Override
277 public Builder beanPropertiesWriteOnly(String beanClassName, String properties) {
278 super.beanPropertiesWriteOnly(beanClassName, properties);
279 return this;
280 }
281
282 @Override
283 public Builder beansRequireDefaultConstructor() {
284 super.beansRequireDefaultConstructor();
285 return this;
286 }
287
288 @Override
289 public Builder beansRequireSerializable() {
290 super.beansRequireSerializable();
291 return this;
292 }
293
294 @Override
295 public Builder beansRequireSettersForGetters() {
296 super.beansRequireSettersForGetters();
297 return this;
298 }
299
300 @Override
301 public WriterSerializer build() {
302 return build(WriterSerializer.class);
303 }
304
305 @Override
306 public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) {
307 super.cache(value);
308 return this;
309 }
310
311 @Override
312 public Builder copy() {
313 return new Builder(this);
314 }
315
316 @Override
317 public Builder debug() {
318 super.debug();
319 return this;
320 }
321
322 @Override
323 public Builder debug(boolean value) {
324 super.debug(value);
325 return this;
326 }
327
328 @Override
329 public Builder detectRecursions() {
330 super.detectRecursions();
331 return this;
332 }
333
334 @Override
335 public Builder detectRecursions(boolean value) {
336 super.detectRecursions(value);
337 return this;
338 }
339
340 @Override
341 public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) {
342 super.dictionaryOn(on, values);
343 return this;
344 }
345
346 @Override
347 public Builder disableBeansRequireSomeProperties() {
348 super.disableBeansRequireSomeProperties();
349 return this;
350 }
351
352 @Override
353 public Builder disableIgnoreMissingSetters() {
354 super.disableIgnoreMissingSetters();
355 return this;
356 }
357
358 @Override
359 public Builder disableIgnoreTransientFields() {
360 super.disableIgnoreTransientFields();
361 return this;
362 }
363
364 @Override
365 public Builder disableIgnoreUnknownNullBeanProperties() {
366 super.disableIgnoreUnknownNullBeanProperties();
367 return this;
368 }
369
370 @Override
371 public Builder disableInterfaceProxies() {
372 super.disableInterfaceProxies();
373 return this;
374 }
375
376 @Override
377 public <T> Builder example(Class<T> pojoClass, String json) {
378 super.example(pojoClass, json);
379 return this;
380 }
381
382 @Override
383 public <T> Builder example(Class<T> pojoClass, T o) {
384 super.example(pojoClass, o);
385 return this;
386 }
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415 public Builder fileCharset(Charset value) {
416 fileCharset = value;
417 return this;
418 }
419
420 @Override
421 public Builder findFluentSetters() {
422 super.findFluentSetters();
423 return this;
424 }
425
426 @Override
427 public Builder findFluentSetters(Class<?> on) {
428 super.findFluentSetters(on);
429 return this;
430 }
431
432 @Override
433 public HashKey hashKey() {
434
435 return HashKey.of(
436 super.hashKey(),
437 fileCharset,
438 streamCharset,
439 maxIndent,
440 quoteChar,
441 quoteCharOverride,
442 useWhitespace
443 );
444
445 }
446
447 @Override
448 public Builder ignoreInvocationExceptionsOnGetters() {
449 super.ignoreInvocationExceptionsOnGetters();
450 return this;
451 }
452
453 @Override
454 public Builder ignoreInvocationExceptionsOnSetters() {
455 super.ignoreInvocationExceptionsOnSetters();
456 return this;
457 }
458
459 @Override
460 public Builder ignoreRecursions() {
461 super.ignoreRecursions();
462 return this;
463 }
464
465 @Override
466 public Builder ignoreRecursions(boolean value) {
467 super.ignoreRecursions(value);
468 return this;
469 }
470
471 @Override
472 public Builder ignoreUnknownBeanProperties() {
473 super.ignoreUnknownBeanProperties();
474 return this;
475 }
476
477 @Override
478 public Builder ignoreUnknownEnumValues() {
479 super.ignoreUnknownEnumValues();
480 return this;
481 }
482
483 @Override
484 public Builder impl(Context value) {
485 super.impl(value);
486 return this;
487 }
488
489 @Override
490 public Builder implClass(Class<?> interfaceClass, Class<?> implClass) {
491 super.implClass(interfaceClass, implClass);
492 return this;
493 }
494
495 @Override
496 public Builder implClasses(Map<Class<?>,Class<?>> values) {
497 super.implClasses(values);
498 return this;
499 }
500
501 @Override
502 public Builder initialDepth(int value) {
503 super.initialDepth(value);
504 return this;
505 }
506
507 @Override
508 public Builder interfaceClass(Class<?> on, Class<?> value) {
509 super.interfaceClass(on, value);
510 return this;
511 }
512
513 @Override
514 public Builder interfaces(java.lang.Class<?>...value) {
515 super.interfaces(value);
516 return this;
517 }
518
519 @Override
520 public Builder keepNullProperties() {
521 super.keepNullProperties();
522 return this;
523 }
524
525 @Override
526 public Builder keepNullProperties(boolean value) {
527 super.keepNullProperties(value);
528 return this;
529 }
530
531 @Override
532 public Builder listener(Class<? extends org.apache.juneau.serializer.SerializerListener> value) {
533 super.listener(value);
534 return this;
535 }
536
537 @Override
538 public Builder locale(Locale value) {
539 super.locale(value);
540 return this;
541 }
542
543 @Override
544 public Builder maxDepth(int value) {
545 super.maxDepth(value);
546 return this;
547 }
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574 public Builder maxIndent(int value) {
575 maxIndent = value;
576 return this;
577 }
578
579 @Override
580 public Builder mediaType(MediaType value) {
581 super.mediaType(value);
582 return this;
583 }
584
585 @Override
586 public Builder notBeanClasses(java.lang.Class<?>...values) {
587 super.notBeanClasses(values);
588 return this;
589 }
590
591 @Override
592 public Builder notBeanPackages(String...values) {
593 super.notBeanPackages(values);
594 return this;
595 }
596
597 @Override
598 public Builder produces(String value) {
599 super.produces(value);
600 return this;
601 }
602
603 @Override
604 public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) {
605 super.propertyNamer(on, value);
606 return this;
607 }
608
609 @Override
610 public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) {
611 super.propertyNamer(value);
612 return this;
613 }
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647 public Builder quoteChar(char value) {
648 quoteChar = value;
649 return this;
650 }
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667 public Builder quoteCharOverride(char value) {
668 quoteCharOverride = value;
669 return this;
670 }
671
672 @Override
673 public Builder sortCollections() {
674 super.sortCollections();
675 return this;
676 }
677
678 @Override
679 public Builder sortCollections(boolean value) {
680 super.sortCollections(value);
681 return this;
682 }
683
684 @Override
685 public Builder sortMaps() {
686 super.sortMaps();
687 return this;
688 }
689
690 @Override
691 public Builder sortMaps(boolean value) {
692 super.sortMaps(value);
693 return this;
694 }
695
696 @Override
697 public Builder sortProperties() {
698 super.sortProperties();
699 return this;
700 }
701
702 @Override
703 public Builder sortProperties(java.lang.Class<?>...on) {
704 super.sortProperties(on);
705 return this;
706 }
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737 public Builder sq() {
738 return quoteChar('\'');
739 }
740
741 @Override
742 public Builder stopClass(Class<?> on, Class<?> value) {
743 super.stopClass(on, value);
744 return this;
745 }
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774 public Builder streamCharset(Charset value) {
775 streamCharset = value;
776 return this;
777 }
778
779 @Override
780 public <T,S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) {
781 super.swap(normalClass, swappedClass, swapFunction);
782 return this;
783 }
784
785 @Override
786 public <T,S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) {
787 super.swap(normalClass, swappedClass, swapFunction, unswapFunction);
788 return this;
789 }
790
791 @Override
792 public Builder swaps(Class<?>...values) {
793 super.swaps(values);
794 return this;
795 }
796
797 @Override
798 public Builder swaps(Object...values) {
799 super.swaps(values);
800 return this;
801 }
802
803 @Override
804 public Builder timeZone(TimeZone value) {
805 super.timeZone(value);
806 return this;
807 }
808
809 @Override
810 public Builder trimEmptyCollections() {
811 super.trimEmptyCollections();
812 return this;
813 }
814
815 @Override
816 public Builder trimEmptyCollections(boolean value) {
817 super.trimEmptyCollections(value);
818 return this;
819 }
820
821 @Override
822 public Builder trimEmptyMaps() {
823 super.trimEmptyMaps();
824 return this;
825 }
826
827 @Override
828 public Builder trimEmptyMaps(boolean value) {
829 super.trimEmptyMaps(value);
830 return this;
831 }
832
833 @Override
834 public Builder trimStrings() {
835 super.trimStrings();
836 return this;
837 }
838
839 @Override
840 public Builder trimStrings(boolean value) {
841 super.trimStrings(value);
842 return this;
843 }
844
845 @Override
846 public Builder type(Class<? extends org.apache.juneau.Context> value) {
847 super.type(value);
848 return this;
849 }
850
851 @Override
852 public Builder typeName(Class<?> on, String value) {
853 super.typeName(on, value);
854 return this;
855 }
856
857 @Override
858 public Builder typePropertyName(Class<?> on, String value) {
859 super.typePropertyName(on, value);
860 return this;
861 }
862
863 @Override
864 public Builder typePropertyName(String value) {
865 super.typePropertyName(value);
866 return this;
867 }
868
869 @Override
870 public Builder uriContext(UriContext value) {
871 super.uriContext(value);
872 return this;
873 }
874
875 @Override
876 public Builder uriRelativity(UriRelativity value) {
877 super.uriRelativity(value);
878 return this;
879 }
880
881 @Override
882 public Builder uriResolution(UriResolution value) {
883 super.uriResolution(value);
884 return this;
885 }
886
887 @Override
888 public Builder useEnumNames() {
889 super.useEnumNames();
890 return this;
891 }
892
893 @Override
894 public Builder useJavaBeanIntrospector() {
895 super.useJavaBeanIntrospector();
896 return this;
897 }
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924 public Builder useWhitespace() {
925 return useWhitespace(true);
926 }
927
928
929
930
931
932
933
934 public Builder useWhitespace(boolean value) {
935 useWhitespace = value;
936 return this;
937 }
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964 public Serializer.Builder ws() {
965 return useWhitespace();
966 }
967 }
968
969
970
971
972
973
974 public static Builder create() {
975 return new Builder();
976 }
977
978 protected final boolean useWhitespace;
979 protected final Character quoteChar;
980 protected final Character quoteCharOverride;
981 private final Charset fileCharset;
982 private final Charset streamCharset;
983 protected final int maxIndent;
984
985 private final char quoteCharValue;
986
987
988
989
990
991
992
993 protected WriterSerializer(Builder builder) {
994 super(builder);
995
996 fileCharset = builder.fileCharset;
997 maxIndent = builder.maxIndent;
998 quoteChar = builder.quoteChar;
999 quoteCharOverride = builder.quoteCharOverride;
1000 streamCharset = builder.streamCharset;
1001 useWhitespace = builder.useWhitespace;
1002
1003 quoteCharValue = nn(quoteCharOverride) ? quoteCharOverride : nn(quoteChar) ? quoteChar : '"';
1004 }
1005
1006 @Override
1007 public Builder copy() {
1008 return new Builder(this);
1009 }
1010
1011 @Override
1012 public WriterSerializerSession.Builder createSession() {
1013 return WriterSerializerSession.create(this);
1014 }
1015
1016 @Override
1017 public WriterSerializerSession getSession() { return createSession().build(); }
1018
1019 @Override
1020 public final boolean isWriterSerializer() { return true; }
1021
1022
1023
1024
1025
1026
1027
1028 public final WriterSerializer println(Object o) {
1029 System.out.println(toString(o));
1030 return this;
1031 }
1032
1033
1034
1035
1036
1037
1038
1039
1040 @Override
1041 public final String serialize(Object o) throws SerializeException {
1042 return getSession().serialize(o);
1043 }
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054 public final String toString(Object o) {
1055 try {
1056 return serialize(o);
1057 } catch (Exception e) {
1058 throw toRex(e);
1059 }
1060 }
1061
1062
1063
1064
1065
1066
1067
1068
1069 protected final Charset getFileCharset() { return fileCharset; }
1070
1071
1072
1073
1074
1075
1076
1077
1078 protected final int getMaxIndent() { return maxIndent; }
1079
1080
1081
1082
1083
1084
1085
1086
1087 protected char getQuoteChar() { return quoteCharValue; }
1088
1089
1090
1091
1092
1093
1094
1095
1096 protected final Charset getStreamCharset() { return streamCharset; }
1097
1098
1099
1100
1101
1102
1103
1104
1105 protected final boolean isUseWhitespace() { return useWhitespace; }
1106
1107 @Override
1108 protected FluentMap<String,Object> properties() {
1109 return super.properties()
1110 .a("fileCharset", fileCharset)
1111 .a("maxIndent", maxIndent)
1112 .a("quoteChar", quoteChar)
1113 .a("streamCharset", streamCharset)
1114 .a("useWhitespace", useWhitespace);
1115 }
1116
1117
1118
1119
1120
1121
1122
1123
1124 protected Character quoteChar() {
1125 return nn(quoteCharOverride) ? quoteCharOverride : quoteChar;
1126 }
1127 }