blob: 67700eac352ae0bd45adf9599beb9f2f9d7509a4 [file] [log] [blame]
package org.codehaus.jackson.impl;
import java.io.*;
import org.codehaus.jackson.*;
import org.codehaus.jackson.io.CharacterEscapes;
import org.codehaus.jackson.io.SerializedString;
import org.codehaus.jackson.map.ObjectMapper;
public class TestCustomEscaping extends main.BaseTest
{
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;");
/*
/********************************************************
/* Helper types
/********************************************************
*/
/**
* Trivial simple custom escape definition set.
*/
static class MyEscapes extends CharacterEscapes
{
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
/********************************************************
*/
/**
* Test to ensure that it is possible to force escaping
* of non-ASCII characters.
* Related to [JACKSON-102]
*/
public void testAboveAsciiEscapeWithReader() throws Exception
{
_testEscapeAboveAscii(false); // reader
}
public void testAboveAsciiEscapeWithUTF8Stream() throws Exception
{
_testEscapeAboveAscii(true); // stream (utf-8)
}
// // // Tests for [JACKSON-106]
public void testEscapeCustomWithReader() throws Exception
{
_testEscapeCustom(false); // reader
}
public void testEscapeCustomWithUTF8Stream() throws Exception
{
_testEscapeCustom(true); // stream (utf-8)
}
// for [JACKSON-672]
public void testEscapingViaMapper() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);
assertEquals(quote("\\u0101"), mapper.writeValueAsString(String.valueOf((char) 257)));
}
/*
/********************************************************
/* Secondary test methods
/********************************************************
*/
private void _testEscapeAboveAscii(boolean useStream) throws Exception
{
JsonFactory f = new JsonFactory();
final String VALUE = "chars: [\u00A0]/[\u1234]";
final String KEY = "fun:\u0088:\u3456";
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
JsonGenerator jgen;
// First: output normally; should not add escaping
if (useStream) {
jgen = f.createJsonGenerator(bytes, JsonEncoding.UTF8);
} else {
jgen = f.createJsonGenerator(new OutputStreamWriter(bytes, "UTF-8"));
}
jgen.writeStartArray();
jgen.writeString(VALUE);
jgen.writeEndArray();
jgen.close();
String json = bytes.toString("UTF-8");
assertEquals("["+quote(VALUE)+"]", json);
// And then with forced ASCII; first, values
bytes = new ByteArrayOutputStream();
if (useStream) {
jgen = f.createJsonGenerator(bytes, JsonEncoding.UTF8);
} else {
jgen = f.createJsonGenerator(new OutputStreamWriter(bytes, "UTF-8"));
}
jgen.enable(JsonGenerator.Feature.ESCAPE_NON_ASCII);
jgen.writeStartArray();
jgen.writeString(VALUE);
jgen.writeEndArray();
jgen.close();
json = bytes.toString("UTF-8");
assertEquals("["+quote("chars: [\\u00A0]/[\\u1234]")+"]", json);
// and then keys
bytes = new ByteArrayOutputStream();
if (useStream) {
jgen = f.createJsonGenerator(bytes, JsonEncoding.UTF8);
} else {
jgen = f.createJsonGenerator(new OutputStreamWriter(bytes, "UTF-8"));
}
jgen.enable(JsonGenerator.Feature.ESCAPE_NON_ASCII);
jgen.writeStartObject();
jgen.writeFieldName(KEY);
jgen.writeBoolean(true);
jgen.writeEndObject();
jgen.close();
json = bytes.toString("UTF-8");
assertEquals("{"+quote("fun:\\u0088:\\u3456")+":true}", json);
}
private void _testEscapeCustom(boolean useStream) throws Exception
{
JsonFactory f = new JsonFactory().setCharacterEscapes(new MyEscapes());
final String STR_IN = "[abcd/"+((char) TWO_BYTE_ESCAPED)+"/"+((char) THREE_BYTE_ESCAPED)+"]";
final String STR_OUT = "[\\A\\u0062c[D]/"+TWO_BYTE_ESCAPED_STRING+"/"+THREE_BYTE_ESCAPED_STRING+"]";
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
JsonGenerator jgen;
// First: output normally; should not add escaping
if (useStream) {
jgen = f.createJsonGenerator(bytes, JsonEncoding.UTF8);
} else {
jgen = f.createJsonGenerator(new OutputStreamWriter(bytes, "UTF-8"));
}
jgen.writeStartObject();
jgen.writeStringField(STR_IN, STR_IN);
jgen.writeEndObject();
jgen.close();
String json = bytes.toString("UTF-8");
assertEquals("{"+quote(STR_OUT)+":"+quote(STR_OUT)+"}", json);
}
}