• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind;
2 
3 import java.io.ByteArrayOutputStream;
4 import java.io.Closeable;
5 import java.io.IOException;
6 import java.io.StringWriter;
7 import java.util.*;
8 
9 import com.fasterxml.jackson.annotation.JsonTypeInfo;
10 import com.fasterxml.jackson.annotation.JsonTypeName;
11 
12 import com.fasterxml.jackson.core.*;
13 import com.fasterxml.jackson.core.io.SerializedString;
14 import com.fasterxml.jackson.core.json.JsonWriteFeature;
15 import com.fasterxml.jackson.databind.node.ObjectNode;
16 
17 /**
18  * Unit tests for checking features added to {@link ObjectWriter}, such
19  * as adding of explicit pretty printer.
20  */
21 public class ObjectWriterTest
22     extends BaseMapTest
23 {
24     static class CloseableValue implements Closeable
25     {
26         public int x;
27 
28         public boolean closed;
29 
30         @Override
close()31         public void close() throws IOException {
32             closed = true;
33         }
34     }
35 
36     final ObjectMapper MAPPER = new ObjectMapper();
37 
38     @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
39     static class PolyBase {
40     }
41 
42     @JsonTypeName("A")
43     static class ImplA extends PolyBase {
44         public int value;
45 
ImplA(int v)46         public ImplA(int v) { value = v; }
47     }
48 
49     @JsonTypeName("B")
50     static class ImplB extends PolyBase {
51         public int b;
52 
ImplB(int v)53         public ImplB(int v) { b = v; }
54     }
55 
56     /*
57     /**********************************************************
58     /* Test methods, normal operation
59     /**********************************************************
60      */
61 
testPrettyPrinter()62     public void testPrettyPrinter() throws Exception
63     {
64         ObjectWriter writer = MAPPER.writer();
65         HashMap<String, Integer> data = new HashMap<String,Integer>();
66         data.put("a", 1);
67 
68         // default: no indentation
69         assertEquals("{\"a\":1}", writer.writeValueAsString(data));
70 
71         // and then with standard
72         writer = writer.withDefaultPrettyPrinter();
73 
74         // pretty printer uses system-specific line feeds, so we do that as well.
75         String lf = System.getProperty("line.separator");
76         assertEquals("{" + lf + "  \"a\" : 1" + lf + "}", writer.writeValueAsString(data));
77 
78         // and finally, again without indentation
79         writer = writer.with((PrettyPrinter) null);
80         assertEquals("{\"a\":1}", writer.writeValueAsString(data));
81     }
82 
testPrefetch()83     public void testPrefetch() throws Exception
84     {
85         ObjectWriter writer = MAPPER.writer();
86         assertFalse(writer.hasPrefetchedSerializer());
87         writer = writer.forType(String.class);
88         assertTrue(writer.hasPrefetchedSerializer());
89     }
90 
testObjectWriterFeatures()91     public void testObjectWriterFeatures() throws Exception
92     {
93         ObjectWriter writer = MAPPER.writer()
94                 .without(JsonWriteFeature.QUOTE_FIELD_NAMES);
95         Map<String,Integer> map = new HashMap<String,Integer>();
96         map.put("a", 1);
97         assertEquals("{a:1}", writer.writeValueAsString(map));
98         // but can also reconfigure
99         assertEquals("{\"a\":1}", writer.with(JsonWriteFeature.QUOTE_FIELD_NAMES)
100                 .writeValueAsString(map));
101     }
102 
testObjectWriterWithNode()103     public void testObjectWriterWithNode() throws Exception
104     {
105         ObjectNode stuff = MAPPER.createObjectNode();
106         stuff.put("a", 5);
107         ObjectWriter writer = MAPPER.writerFor(JsonNode.class);
108         String json = writer.writeValueAsString(stuff);
109         assertEquals("{\"a\":5}", json);
110     }
111 
testPolymorphicWithTyping()112     public void testPolymorphicWithTyping() throws Exception
113     {
114         ObjectWriter writer = MAPPER.writerFor(PolyBase.class);
115         String json;
116 
117         json = writer.writeValueAsString(new ImplA(3));
118         assertEquals(aposToQuotes("{'type':'A','value':3}"), json);
119         json = writer.writeValueAsString(new ImplB(-5));
120         assertEquals(aposToQuotes("{'type':'B','b':-5}"), json);
121     }
122 
testCanSerialize()123     public void testCanSerialize() throws Exception
124     {
125         assertTrue(MAPPER.writer().canSerialize(String.class));
126         assertTrue(MAPPER.writer().canSerialize(String.class, null));
127     }
128 
testNoPrefetch()129     public void testNoPrefetch() throws Exception
130     {
131         ObjectWriter w = MAPPER.writer()
132                 .without(SerializationFeature.EAGER_SERIALIZER_FETCH);
133         ByteArrayOutputStream out = new ByteArrayOutputStream();
134         w.writeValue(out, Integer.valueOf(3));
135         out.close();
136         assertEquals("3", out.toString("UTF-8"));
137     }
138 
testWithCloseCloseable()139     public void testWithCloseCloseable() throws Exception
140     {
141         ObjectWriter w = MAPPER.writer()
142                 .with(SerializationFeature.CLOSE_CLOSEABLE);
143         assertTrue(w.isEnabled(SerializationFeature.CLOSE_CLOSEABLE));
144         CloseableValue input = new CloseableValue();
145         assertFalse(input.closed);
146         byte[] json = w.writeValueAsBytes(input);
147         assertNotNull(json);
148         assertTrue(input.closed);
149         input.close();
150 
151         // and via explicitly passed generator
152         JsonGenerator g = MAPPER.createGenerator(new StringWriter());
153         input = new CloseableValue();
154         assertFalse(input.closed);
155         w.writeValue(g, input);
156         assertTrue(input.closed);
157         g.close();
158         input.close();
159     }
160 
testViewSettings()161     public void testViewSettings() throws Exception
162     {
163         ObjectWriter w = MAPPER.writer();
164         ObjectWriter newW = w.withView(String.class);
165         assertNotSame(w, newW);
166         assertSame(newW, newW.withView(String.class));
167 
168         newW = w.with(Locale.CANADA);
169         assertNotSame(w, newW);
170         assertSame(newW, newW.with(Locale.CANADA));
171     }
172 
testMiscSettings()173     public void testMiscSettings() throws Exception
174     {
175         ObjectWriter w = MAPPER.writer();
176         assertSame(MAPPER.getFactory(), w.getFactory());
177         assertFalse(w.hasPrefetchedSerializer());
178         assertNotNull(w.getTypeFactory());
179 
180         JsonFactory f = new JsonFactory();
181         w = w.with(f);
182         assertSame(f, w.getFactory());
183         ObjectWriter newW = w.with(Base64Variants.MODIFIED_FOR_URL);
184         assertNotSame(w, newW);
185         assertSame(newW, newW.with(Base64Variants.MODIFIED_FOR_URL));
186 
187         w = w.withAttributes(Collections.emptyMap());
188         w = w.withAttribute("a", "b");
189         assertEquals("b", w.getAttributes().getAttribute("a"));
190         w = w.withoutAttribute("a");
191         assertNull(w.getAttributes().getAttribute("a"));
192 
193         FormatSchema schema = new BogusSchema();
194         try {
195             newW = w.with(schema);
196             fail("Should not pass");
197         } catch (IllegalArgumentException e) {
198             verifyException(e, "Cannot use FormatSchema");
199         }
200     }
201 
testRootValueSettings()202     public void testRootValueSettings() throws Exception
203     {
204         ObjectWriter w = MAPPER.writer();
205 
206         // First, root name:
207         ObjectWriter newW = w.withRootName("foo");
208         assertNotSame(w, newW);
209         assertSame(newW, newW.withRootName(PropertyName.construct("foo")));
210         w = newW;
211         newW = w.withRootName((String) null);
212         assertNotSame(w, newW);
213         assertSame(newW, newW.withRootName((PropertyName) null));
214 
215         // Then root value separator
216 
217         w = w.withRootValueSeparator(new SerializedString(","));
218         assertSame(w, w.withRootValueSeparator(new SerializedString(",")));
219         assertSame(w, w.withRootValueSeparator(","));
220 
221          newW = w.withRootValueSeparator("/");
222         assertNotSame(w, newW);
223         assertSame(newW, newW.withRootValueSeparator("/"));
224 
225         newW = w.withRootValueSeparator((String) null);
226         assertNotSame(w, newW);
227 
228         newW = w.withRootValueSeparator((SerializableString) null);
229         assertNotSame(w, newW);
230     }
231 
testFeatureSettings()232     public void testFeatureSettings() throws Exception
233     {
234         ObjectWriter w = MAPPER.writer();
235         assertFalse(w.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES));
236         assertFalse(w.isEnabled(JsonGenerator.Feature.STRICT_DUPLICATE_DETECTION));
237         assertFalse(w.isEnabled(StreamWriteFeature.STRICT_DUPLICATE_DETECTION));
238 
239         ObjectWriter newW = w.with(SerializationFeature.FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS,
240                 SerializationFeature.INDENT_OUTPUT);
241         assertNotSame(w, newW);
242         assertTrue(newW.isEnabled(SerializationFeature.FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS));
243         assertTrue(newW.isEnabled(SerializationFeature.INDENT_OUTPUT));
244         assertSame(newW, newW.with(SerializationFeature.INDENT_OUTPUT));
245         assertSame(newW, newW.withFeatures(SerializationFeature.INDENT_OUTPUT));
246 
247         newW = w.withFeatures(SerializationFeature.FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS,
248                 SerializationFeature.INDENT_OUTPUT);
249         assertNotSame(w, newW);
250 
251         newW = w.without(SerializationFeature.FAIL_ON_EMPTY_BEANS,
252                 SerializationFeature.EAGER_SERIALIZER_FETCH);
253         assertNotSame(w, newW);
254         assertFalse(newW.isEnabled(SerializationFeature.FAIL_ON_EMPTY_BEANS));
255         assertFalse(newW.isEnabled(SerializationFeature.EAGER_SERIALIZER_FETCH));
256         assertSame(newW, newW.without(SerializationFeature.FAIL_ON_EMPTY_BEANS));
257         assertSame(newW, newW.withoutFeatures(SerializationFeature.FAIL_ON_EMPTY_BEANS));
258 
259         assertNotSame(w, w.withoutFeatures(SerializationFeature.FAIL_ON_EMPTY_BEANS,
260                 SerializationFeature.EAGER_SERIALIZER_FETCH));
261     }
262 
testGeneratorFeatures()263     public void testGeneratorFeatures() throws Exception
264     {
265         ObjectWriter w = MAPPER.writer();
266         assertNotSame(w, w.with(JsonWriteFeature.ESCAPE_NON_ASCII));
267         assertNotSame(w, w.withFeatures(JsonWriteFeature.ESCAPE_NON_ASCII));
268 
269         assertTrue(w.isEnabled(JsonGenerator.Feature.AUTO_CLOSE_TARGET));
270         assertNotSame(w, w.without(JsonGenerator.Feature.AUTO_CLOSE_TARGET));
271         assertNotSame(w, w.withoutFeatures(JsonGenerator.Feature.AUTO_CLOSE_TARGET));
272 
273         assertFalse(w.isEnabled(StreamWriteFeature.STRICT_DUPLICATE_DETECTION));
274         assertNotSame(w, w.with(StreamWriteFeature.STRICT_DUPLICATE_DETECTION));
275     }
276 
277     /*
278     /**********************************************************
279     /* Test methods, failures
280     /**********************************************************
281      */
282 
testArgumentChecking()283     public void testArgumentChecking() throws Exception
284     {
285         final ObjectWriter w = MAPPER.writer();
286         try {
287             w.acceptJsonFormatVisitor((JavaType) null, null);
288             fail("Should not pass");
289         } catch (IllegalArgumentException e) {
290             verifyException(e, "argument \"type\" is null");
291         }
292     }
293 
testSchema()294     public void testSchema() throws Exception
295     {
296         try {
297             MAPPER.writerFor(String.class)
298                 .with(new BogusSchema())
299                 .writeValueAsBytes("foo");
300             fail("Should not pass");
301         } catch (IllegalArgumentException e) {
302             verifyException(e, "Cannot use FormatSchema");
303         }
304     }
305 }
306