TestDecorators.java
package com.fasterxml.jackson.core.json;
import java.io.*;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.io.IOContext;
import com.fasterxml.jackson.core.io.InputDecorator;
import com.fasterxml.jackson.core.io.OutputDecorator;
import com.fasterxml.jackson.core.util.JsonGeneratorDecorator;
import com.fasterxml.jackson.core.util.JsonGeneratorDelegate;
import static org.junit.jupiter.api.Assertions.*;
/**
* Unit tests to verify that input and output decorators work as
* expected
*
* @since 1.8
*/
@SuppressWarnings("serial")
class TestDecorators extends com.fasterxml.jackson.core.JUnit5TestBase
{
/*
/**********************************************************
/* Helper classes
/**********************************************************
*/
static class SimpleInputDecorator extends InputDecorator
{
@Override
public InputStream decorate(IOContext ctxt, InputStream in)
throws IOException
{
return new ByteArrayInputStream("123".getBytes("UTF-8"));
}
@Override
public InputStream decorate(IOContext ctxt, byte[] src, int offset, int length)
throws IOException
{
return new ByteArrayInputStream("456".getBytes("UTF-8"));
}
@Override
public Reader decorate(IOContext ctxt, Reader src) {
return new StringReader("789");
}
}
static class SimpleOutputDecorator extends OutputDecorator
{
@Override
public OutputStream decorate(IOContext ctxt, OutputStream out) throws IOException
{
out.write("123".getBytes("UTF-8"));
out.flush();
return new ByteArrayOutputStream();
}
@Override
public Writer decorate(IOContext ctxt, Writer w) throws IOException
{
w.write("567");
w.flush();
return new StringWriter();
}
}
static class SimpleGeneratorDecorator implements JsonGeneratorDecorator
{
@Override
public JsonGenerator decorate(JsonFactory factory, JsonGenerator generator) {
return new TextHider(generator);
}
static class TextHider extends JsonGeneratorDelegate {
public TextHider(JsonGenerator g) {
super(g);
}
@Override
public void writeString(String text) throws IOException {
delegate.writeString("***");
}
}
}
/*
/**********************************************************
/* Unit tests: input/output decoration
/**********************************************************
*/
@Test
void inputDecoration() throws IOException
{
JsonFactory f = JsonFactory.builder()
.inputDecorator(new SimpleInputDecorator())
.build();
JsonParser p;
// first test with Reader
p = f.createParser(new StringReader("{ }"));
// should be overridden;
assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(789, p.getIntValue());
p.close();
// similarly with InputStream
p = f.createParser(new ByteArrayInputStream("[ ]".getBytes("UTF-8")));
// should be overridden;
assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(123, p.getIntValue());
p.close();
// and with raw bytes
final byte[] bytes = "[ ]".getBytes("UTF-8");
p = f.createParser(bytes);
// should be overridden;
assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(456, p.getIntValue());
p.close();
// also diff method has diff code path so try both:
p = f.createParser(bytes, 0, bytes.length);
assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(456, p.getIntValue());
p.close();
// and also char[]
final char[] chars = " [ ]".toCharArray();
p = f.createParser(chars, 0, chars.length);
assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(789, p.getIntValue());
p.close();
}
@Test
void outputDecoration() throws IOException
{
JsonFactory f = JsonFactory.builder()
.outputDecorator(new SimpleOutputDecorator())
.build();
JsonGenerator g;
StringWriter sw = new StringWriter();
g = f.createGenerator(sw);
g.close();
assertEquals("567", sw.toString());
ByteArrayOutputStream out = new ByteArrayOutputStream();
g = f.createGenerator(out, JsonEncoding.UTF8);
g.close();
assertEquals("123", out.toString("UTF-8"));
}
@SuppressWarnings("deprecation")
@Test
void deprecatedMethods() throws IOException
{
JsonFactory f = new JsonFactory();
assertNull(f.getInputDecorator());
assertNull(f.getOutputDecorator());
final SimpleInputDecorator inDec = new SimpleInputDecorator();
final SimpleOutputDecorator outDec = new SimpleOutputDecorator();
f.setInputDecorator(inDec);
assertSame(inDec, f.getInputDecorator());
f.setOutputDecorator(outDec);
assertSame(outDec, f.getOutputDecorator());
}
/*
/**********************************************************
/* Unit tests: input/output decoration
/**********************************************************
*/
@Test
void generatorDecoration() throws Exception
{
JsonFactory f = JsonFactory.builder()
.addDecorator(new SimpleGeneratorDecorator())
.build();
final String EXP = a2q("{'password':'***'}");
// First, test with newly constructed factory
StringWriter sw = new StringWriter();
try (JsonGenerator g = f.createGenerator(sw)) {
_generateForDecorator(g);
}
assertEquals(EXP, sw.toString());
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
try (JsonGenerator g = f.createGenerator(bytes)) {
_generateForDecorator(g);
}
assertEquals(EXP, utf8String(bytes));
// Second do the same to a copy
JsonFactory f2 = f.copy();
sw = new StringWriter();
try (JsonGenerator g = f2.createGenerator(sw)) {
_generateForDecorator(g);
}
assertEquals(EXP, sw.toString());
// And re-built instance
JsonFactory f3 = f2.rebuild().build();
sw = new StringWriter();
try (JsonGenerator g = f3.createGenerator(sw)) {
_generateForDecorator(g);
}
assertEquals(EXP, sw.toString());
}
private void _generateForDecorator(JsonGenerator g) throws Exception
{
g.writeStartObject();
g.writeStringField("password", "s3cr37x!!");
g.writeEndObject();
}
}