1 package com.fasterxml.jackson.databind; 2 3 import java.io.IOException; 4 import java.io.StringReader; 5 6 import com.fasterxml.jackson.core.*; 7 import com.fasterxml.jackson.core.io.CharacterEscapes; 8 import com.fasterxml.jackson.core.io.SerializedString; 9 import com.fasterxml.jackson.core.json.JsonWriteFeature; 10 import com.fasterxml.jackson.databind.ObjectMapper; 11 import com.fasterxml.jackson.databind.json.JsonMapper; 12 13 public class MapperViaParserTest extends BaseMapTest 14 { 15 final static int TWO_BYTE_ESCAPED = 0x111; 16 final static int THREE_BYTE_ESCAPED = 0x1111; 17 18 final static SerializedString TWO_BYTE_ESCAPED_STRING = new SerializedString("&111;"); 19 final static SerializedString THREE_BYTE_ESCAPED_STRING = new SerializedString("&1111;"); 20 21 final static class Pojo 22 { 23 int _x; 24 setX(int x)25 public void setX(int x) { _x = x; } 26 } 27 28 /* 29 /******************************************************** 30 /* Helper types 31 /******************************************************** 32 */ 33 34 /** 35 * Trivial simple custom escape definition set. 36 */ 37 static class MyEscapes extends CharacterEscapes 38 { 39 private static final long serialVersionUID = 1L; 40 41 private final int[] _asciiEscapes; 42 MyEscapes()43 public MyEscapes() { 44 _asciiEscapes = standardAsciiEscapesForJSON(); 45 _asciiEscapes['a'] = 'A'; // to basically give us "\A" 46 _asciiEscapes['b'] = CharacterEscapes.ESCAPE_STANDARD; // too force "\u0062" 47 _asciiEscapes['d'] = CharacterEscapes.ESCAPE_CUSTOM; 48 } 49 50 @Override getEscapeCodesForAscii()51 public int[] getEscapeCodesForAscii() { 52 return _asciiEscapes; 53 } 54 55 @Override getEscapeSequence(int ch)56 public SerializableString getEscapeSequence(int ch) 57 { 58 if (ch == 'd') { 59 return new SerializedString("[D]"); 60 } 61 if (ch == TWO_BYTE_ESCAPED) { 62 return TWO_BYTE_ESCAPED_STRING; 63 } 64 if (ch == THREE_BYTE_ESCAPED) { 65 return THREE_BYTE_ESCAPED_STRING; 66 } 67 return null; 68 } 69 } 70 71 /* 72 /******************************************************** 73 /* Unit tests 74 /******************************************************** 75 */ 76 testPojoReading()77 public void testPojoReading() throws IOException 78 { 79 JsonFactory jf = new MappingJsonFactory(); 80 final String JSON = "{ \"x\" : 9 }"; 81 JsonParser jp = jf.createParser(new StringReader(JSON)); 82 83 // let's try first by advancing: 84 assertToken(JsonToken.START_OBJECT, jp.nextToken()); 85 Pojo p = jp.readValueAs(Pojo.class); 86 assertEquals(9, p._x); 87 jp.close(); 88 89 // and without 90 jp = jf.createParser(new StringReader(JSON)); 91 p = jp.readValueAs(Pojo.class); 92 assertEquals(9, p._x); 93 jp.close(); 94 } 95 96 /** 97 * Test similar to above, but instead reads a sequence of values 98 */ testIncrementalPojoReading()99 public void testIncrementalPojoReading() throws IOException 100 { 101 JsonFactory jf = new MappingJsonFactory(); 102 final String JSON = "[ 1, true, null, \"abc\" ]"; 103 JsonParser p = jf.createParser(new StringReader(JSON)); 104 105 // let's advance past array start to prevent full binding 106 assertToken(JsonToken.START_ARRAY, p.nextToken()); 107 108 assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); 109 assertEquals(Integer.valueOf(1), p.readValueAs(Integer.class)); 110 assertEquals(Boolean.TRUE, p.readValueAs(Boolean.class)); 111 /* note: null can be returned both when there is no more 112 * data in current scope, AND when Json null literal is 113 * bound! 114 */ 115 assertNull(p.readValueAs(Object.class)); 116 // but we can verify that it was Json null by: 117 assertEquals(JsonToken.VALUE_NULL, p.getLastClearedToken()); 118 119 assertEquals("abc", p.readValueAs(String.class)); 120 121 // this null is for actually hitting the END_ARRAY 122 assertNull(p.readValueAs(Object.class)); 123 assertEquals(JsonToken.END_ARRAY, p.getLastClearedToken()); 124 125 // afrer which there should be nothing to advance to: 126 assertNull(p.nextToken()); 127 128 p.close(); 129 } 130 131 @SuppressWarnings("resource") testPojoReadingFailing()132 public void testPojoReadingFailing() throws IOException 133 { 134 // regular factory can't do it, without a call to setCodec() 135 JsonFactory f = new JsonFactory(); 136 try { 137 final String JSON = "{ \"x\" : 9 }"; 138 JsonParser p = f.createParser(new StringReader(JSON)); 139 Pojo pojo = p.readValueAs(Pojo.class); 140 fail("Expected an exception: got "+pojo); 141 } catch (IllegalStateException e) { 142 verifyException(e, "No ObjectCodec defined"); 143 } 144 } 145 testEscapingUsingMapper()146 public void testEscapingUsingMapper() throws Exception 147 { 148 ObjectMapper mapper = JsonMapper.builder() 149 .configure(JsonWriteFeature.ESCAPE_NON_ASCII, true) 150 .build(); 151 mapper.writeValueAsString(String.valueOf((char) 257)); 152 } 153 } 154