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.CollectionUtils.*;
20 import static org.junit.jupiter.api.Assertions.*;
21
22 import java.nio.charset.Charset;
23 import java.util.function.*;
24
25 import org.apache.juneau.*;
26 import org.apache.juneau.commons.reflect.*;
27 import org.apache.juneau.json.*;
28 import org.apache.juneau.msgpack.*;
29 import org.apache.juneau.serializer.annotation.*;
30 import org.apache.juneau.svl.*;
31 import org.junit.jupiter.api.*;
32
33
34
35
36 class SerializerConfigAnnotation_Test extends TestBase {
37
38 private static void check(String expected, Object o) {
39 assertEquals(expected, TO_STRING.apply(o));
40 }
41
42 private static final Function<Object,String> TO_STRING = t -> {
43 if (t == null)
44 return null;
45 if (t instanceof AA)
46 return "AA";
47 return t.toString();
48 };
49
50 static VarResolverSession sr = VarResolver.create().vars(XVar.class).build().createSession();
51
52
53
54
55
56 public static class AA extends SerializerListener {}
57
58 @SerializerConfig(
59 addBeanTypes="$X{true}",
60 addRootType="$X{true}",
61 binaryFormat="$X{HEX}",
62 detectRecursions="$X{true}",
63 ignoreRecursions="$X{true}",
64 initialDepth="$X{1}",
65 listener=AA.class,
66 maxDepth="$X{1}",
67 maxIndent="$X{1}",
68 quoteChar="$X{'}",
69 sortCollections="$X{true}",
70 sortMaps="$X{true}",
71 trimEmptyCollections="$X{true}",
72 trimEmptyMaps="$X{true}",
73 keepNullProperties="$X{false}",
74 trimStrings="$X{true}",
75 uriContext="{}",
76 uriRelativity="$X{RESOURCE}",
77 uriResolution="$X{ABSOLUTE}",
78 useWhitespace="$X{true}"
79 )
80 static class A {}
81 static ClassInfo a = ClassInfo.of(A.class);
82
83 @Test void a01_basicWriterSerializer() {
84 var al = AnnotationWorkList.of(sr, rstream(a.getAnnotations()));
85 var x = JsonSerializer.create().apply(al).build().getSession();
86 check("true", ((SerializerSession)x).isAddBeanTypes());
87 check("true", x.isAddRootType());
88 check("true", x.isDetectRecursions());
89 check("true", x.isIgnoreRecursions());
90 check("1", x.getInitialDepth());
91 check("AA", x.getListener());
92 check("1", x.getMaxDepth());
93 check("1", x.getMaxIndent());
94 check("'", x.getQuoteChar());
95 check("true", x.isSortCollections());
96 check("true", x.isSortMaps());
97 check("true", x.isTrimEmptyCollections());
98 check("true", x.isTrimEmptyMaps());
99 check("false", x.isKeepNullProperties());
100 check("true", x.isTrimStrings());
101 check("{aContextRoot=/,aPathInfo=/,aServletPath=/,rContextRoot=/,rPath=/,rResource=/}", x.getUriContext());
102 check("RESOURCE", x.getUriRelativity());
103 check("ABSOLUTE", x.getUriResolution());
104 check("true", x.isUseWhitespace());
105 }
106
107 @Test void a02_basicOutputStreamSerializer() {
108 var al = AnnotationWorkList.of(sr, rstream(a.getAnnotations()));
109 var x = MsgPackSerializer.create().apply(al).build().getSession();
110 check("true", ((SerializerSession)x).isAddBeanTypes());
111 check("true", x.isAddRootType());
112 check("HEX", x.getBinaryFormat());
113 check("true", x.isDetectRecursions());
114 check("true", x.isIgnoreRecursions());
115 check("1", x.getInitialDepth());
116 check("AA", x.getListener());
117 check("1", x.getMaxDepth());
118 check("true", x.isSortCollections());
119 check("true", x.isSortMaps());
120 check("true", x.isTrimEmptyCollections());
121 check("true", x.isTrimEmptyMaps());
122 check("false", x.isKeepNullProperties());
123 check("true", x.isTrimStrings());
124 check("{aContextRoot=/,aPathInfo=/,aServletPath=/,rContextRoot=/,rPath=/,rResource=/}", x.getUriContext());
125 check("RESOURCE", x.getUriRelativity());
126 check("ABSOLUTE", x.getUriResolution());
127 }
128
129
130
131
132
133 @SerializerConfig()
134 static class B {}
135 static ClassInfo b = ClassInfo.of(B.class);
136
137 @Test void b01_noValuesWriterSerializer() {
138 var al = AnnotationWorkList.of(sr, rstream(b.getAnnotations()));
139 var x = JsonSerializer.create().apply(al).build().getSession();
140 check("false", ((SerializerSession)x).isAddBeanTypes());
141 check("false", x.isAddRootType());
142 check(null, x.getListener());
143 check("100", x.getMaxIndent());
144 check("\"", x.getQuoteChar());
145 check("false", x.isSortCollections());
146 check("false", x.isSortMaps());
147 check("false", x.isTrimEmptyCollections());
148 check("false", x.isTrimEmptyMaps());
149 check("false", x.isKeepNullProperties());
150 check("false", x.isTrimStrings());
151 check("{aContextRoot=/,aPathInfo=/,aServletPath=/,rContextRoot=/,rPath=/,rResource=/}", x.getUriContext());
152 check("RESOURCE", x.getUriRelativity());
153 check("NONE", x.getUriResolution());
154 check("false", x.isUseWhitespace());
155 }
156
157 @Test void b02_noValuesOutputStreamSerializer() {
158 var al = AnnotationWorkList.of(sr, rstream(b.getAnnotations()));
159 var x = MsgPackSerializer.create().apply(al).build().getSession();
160 check("false", ((SerializerSession)x).isAddBeanTypes());
161 check("false", x.isAddRootType());
162 check("HEX", x.getBinaryFormat());
163 check(null, x.getListener());
164 check("false", x.isSortCollections());
165 check("false", x.isSortMaps());
166 check("false", x.isTrimEmptyCollections());
167 check("false", x.isTrimEmptyMaps());
168 check("false", x.isKeepNullProperties());
169 check("false", x.isTrimStrings());
170 check("{aContextRoot=/,aPathInfo=/,aServletPath=/,rContextRoot=/,rPath=/,rResource=/}", x.getUriContext());
171 check("RESOURCE", x.getUriRelativity());
172 check("NONE", x.getUriResolution());
173 }
174
175
176
177
178
179 static class C {}
180 static ClassInfo c = ClassInfo.of(C.class);
181
182 @Test void c01_noAnnotationWriterSerializer() {
183 var al = AnnotationWorkList.of(sr, rstream(c.getAnnotations()));
184 var x = JsonSerializer.create().apply(al).build().getSession();
185 check("false", ((SerializerSession)x).isAddBeanTypes());
186 check("false", x.isAddRootType());
187 check(null, x.getListener());
188 check("100", x.getMaxIndent());
189 check("\"", x.getQuoteChar());
190 check("false", x.isSortCollections());
191 check("false", x.isSortMaps());
192 check("false", x.isTrimEmptyCollections());
193 check("false", x.isTrimEmptyMaps());
194 check("false", x.isKeepNullProperties());
195 check("false", x.isTrimStrings());
196 check("{aContextRoot=/,aPathInfo=/,aServletPath=/,rContextRoot=/,rPath=/,rResource=/}", x.getUriContext());
197 check("RESOURCE", x.getUriRelativity());
198 check("NONE", x.getUriResolution());
199 check("false", x.isUseWhitespace());
200 }
201
202 @Test void c02_noAnnotationOutputStreamSerializer() {
203 var al = AnnotationWorkList.of(sr, rstream(c.getAnnotations()));
204 var x = MsgPackSerializer.create().apply(al).build().getSession();
205 check("false", ((SerializerSession)x).isAddBeanTypes());
206 check("false", x.isAddRootType());
207 check("HEX", x.getBinaryFormat());
208 check(null, x.getListener());
209 check("false", x.isSortCollections());
210 check("false", x.isSortMaps());
211 check("false", x.isTrimEmptyCollections());
212 check("false", x.isTrimEmptyMaps());
213 check("false", x.isKeepNullProperties());
214 check("false", x.isTrimStrings());
215 check("{aContextRoot=/,aPathInfo=/,aServletPath=/,rContextRoot=/,rPath=/,rResource=/}", x.getUriContext());
216 check("RESOURCE", x.getUriRelativity());
217 check("NONE", x.getUriResolution());
218 }
219
220
221
222
223
224 @SerializerConfig(
225 quoteChar="$X{ab}"
226 )
227 static class D {}
228 static ClassInfo d = ClassInfo.of(D.class);
229
230 @Test void d01_invalidQuoteChar_throwsException() {
231 var al = AnnotationWorkList.of(sr, rstream(d.getAnnotations()));
232 assertThrows(ConfigException.class, () -> {
233 JsonSerializer.create().apply(al).build();
234 });
235 }
236
237 @SerializerConfig(
238 fileCharset="$X{UTF-8}",
239 streamCharset="$X{ISO-8859-1}"
240 )
241 static class E {}
242 static ClassInfo e = ClassInfo.of(E.class);
243
244 @Test void d02_charsetWithNonDefaultValue() {
245 var al = AnnotationWorkList.of(sr, rstream(e.getAnnotations()));
246 var x = JsonSerializer.create().apply(al).build().getSession();
247 check("UTF-8", x.getFileCharset().name());
248 check("ISO-8859-1", x.getStreamCharset().name());
249 }
250
251 @SerializerConfig(
252 fileCharset="$X{default}",
253 streamCharset="$X{DEFAULT}"
254 )
255 static class E2 {}
256 static ClassInfo e2 = ClassInfo.of(E2.class);
257
258 @Test void d02b_charsetWithDefaultValue() {
259 var al = AnnotationWorkList.of(sr, rstream(e2.getAnnotations()));
260 var x = JsonSerializer.create().apply(al).build().getSession();
261 check(Charset.defaultCharset().name(), x.getFileCharset().name());
262 check(Charset.defaultCharset().name(), x.getStreamCharset().name());
263 }
264
265 @SerializerConfig(
266 initialDepth="$X{abc}",
267 maxDepth="$X{xyz}",
268 maxIndent="$X{invalid}"
269 )
270 static class F {}
271 static ClassInfo f = ClassInfo.of(F.class);
272
273 @Test void d03_invalidInteger_throwsException() {
274 var al = AnnotationWorkList.of(sr, rstream(f.getAnnotations()));
275 assertThrows(ConfigException.class, () -> {
276 JsonSerializer.create().apply(al).build();
277 });
278 }
279 }