package com.fasterxml.jackson.databind;
import java.io.IOException;
import java.io.StringReader;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.io.CharacterEscapes;
import com.fasterxml.jackson.core.io.SerializedString;
import com.fasterxml.jackson.databind.ObjectMapper;
public class MapperViaParserTest extends BaseMapTest
{
final static int TWO_BYTE_ESCAPED = 0x111;
final static int THREE_BYTE_ESCAPED = 0x1111;
final static SerializedString TWO_BYTE_ESCAPED_STRING = new SerializedString("&111;");
final static SerializedString THREE_BYTE_ESCAPED_STRING = new SerializedString("&1111;");
final static class Pojo
{
int _x;
public void setX(int x) { _x = x; }
}
/*
/********************************************************
/* Helper types
/********************************************************
*/
/**
* Trivial simple custom escape definition set.
*/
static class MyEscapes extends CharacterEscapes
{
private static final long serialVersionUID = 1L;
private final int[] _asciiEscapes;
public MyEscapes() {
_asciiEscapes = standardAsciiEscapesForJSON();
_asciiEscapes['a'] = 'A'; // to basically give us "\A"
_asciiEscapes['b'] = CharacterEscapes.ESCAPE_STANDARD; // too force "\u0062"
_asciiEscapes['d'] = CharacterEscapes.ESCAPE_CUSTOM;
}
@Override
public int[] getEscapeCodesForAscii() {
return _asciiEscapes;
}
@Override
public SerializableString getEscapeSequence(int ch)
{
if (ch == 'd') {
return new SerializedString("[D]");
}
if (ch == TWO_BYTE_ESCAPED) {
return TWO_BYTE_ESCAPED_STRING;
}
if (ch == THREE_BYTE_ESCAPED) {
return THREE_BYTE_ESCAPED_STRING;
}
return null;
}
}
/*
/********************************************************
/* Unit tests
/********************************************************
*/
public void testPojoReading() throws IOException
{
JsonFactory jf = new MappingJsonFactory();
final String JSON = "{ \"x\" : 9 }";
JsonParser jp = jf.createParser(new StringReader(JSON));
// let's try first by advancing:
assertToken(JsonToken.START_OBJECT, jp.nextToken());
Pojo p = jp.readValueAs(Pojo.class);
assertEquals(9, p._x);
jp.close();
// and without
jp = jf.createParser(new StringReader(JSON));
p = jp.readValueAs(Pojo.class);
assertEquals(9, p._x);
jp.close();
}
/**
* Test similar to above, but instead reads a sequence of values
*/
public void testIncrementalPojoReading()
throws IOException
{
JsonFactory jf = new MappingJsonFactory();
final String JSON = "[ 1, true, null, \"abc\" ]";
JsonParser jp = jf.createParser(new StringReader(JSON));
// let's advance past array start to prevent full binding
assertToken(JsonToken.START_ARRAY, jp.nextToken());
assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
assertEquals(Integer.valueOf(1), jp.readValueAs(Integer.class));
assertEquals(Boolean.TRUE, jp.readValueAs(Boolean.class));
/* note: null can be returned both when there is no more
* data in current scope, AND when Json null literal is
* bound!
*/
assertNull(jp.readValueAs(Object.class));
// but we can verify that it was Json null by:
assertEquals(JsonToken.VALUE_NULL, jp.getLastClearedToken());
assertEquals("abc", jp.readValueAs(String.class));
// this null is for actually hitting the END_ARRAY
assertNull(jp.readValueAs(Object.class));
assertEquals(JsonToken.END_ARRAY, jp.getLastClearedToken());
// afrer which there should be nothing to advance to:
assertNull(jp.nextToken());
jp.close();
}
@SuppressWarnings("resource")
public void testPojoReadingFailing()
throws IOException
{
// regular factory can't do it, without a call to setCodec()
JsonFactory jf = new JsonFactory();
try {
final String JSON = "{ \"x\" : 9 }";
JsonParser jp = jf.createParser(new StringReader(JSON));
Pojo p = jp.readValueAs(Pojo.class);
fail("Expected an exception: got "+p);
} catch (IllegalStateException e) {
verifyException(e, "No ObjectCodec defined");
}
}
// for [JACKSON-672]
public void testEscapingUsingMapper() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);
mapper.writeValueAsString(String.valueOf((char) 257));
}
}