TestDecorators.java
package tools.jackson.core.unittest.json;
import java.io.*;
import org.junit.jupiter.api.Test;
import tools.jackson.core.*;
import tools.jackson.core.exc.JacksonIOException;
import tools.jackson.core.io.IOContext;
import tools.jackson.core.io.InputDecorator;
import tools.jackson.core.io.OutputDecorator;
import tools.jackson.core.json.JsonFactory;
import tools.jackson.core.util.JsonGeneratorDecorator;
import tools.jackson.core.util.JsonGeneratorDelegate;
import static org.junit.jupiter.api.Assertions.*;
/**
* Unit tests to verify that input and output decorators work as
* expected
*/
@SuppressWarnings("serial")
class TestDecorators extends tools.jackson.core.unittest.JacksonCoreTestBase
{
/*
/**********************************************************
/* Helper classes
/**********************************************************
*/
static class SimpleInputDecorator extends InputDecorator
{
@Override
public InputStream decorate(IOContext ctxt, InputStream in)
throws JacksonException
{
try {
return new ByteArrayInputStream("123".getBytes("UTF-8"));
} catch (IOException e) {
throw JacksonIOException.construct(e, null);
}
}
@Override
public InputStream decorate(IOContext ctxt, byte[] src, int offset, int length)
throws JacksonException
{
try {
return new ByteArrayInputStream("456".getBytes("UTF-8"));
} catch (IOException e) {
throw JacksonIOException.construct(e, null);
}
}
@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 JacksonException
{
try {
out.write("123".getBytes("UTF-8"));
out.flush();
} catch (IOException e) {
throw JacksonIOException.construct(e, null);
}
return new ByteArrayOutputStream();
}
@Override
public Writer decorate(IOContext ctxt, Writer w) throws JacksonException
{
try {
w.write("567");
w.flush();
} catch (IOException e) {
throw JacksonIOException.construct(e, null);
}
return new StringWriter();
}
}
static class SimpleGeneratorDecorator implements JsonGeneratorDecorator
{
@Override
public JsonGenerator decorate(TokenStreamFactory factory, JsonGenerator generator) {
return new TextHider(generator);
}
static class TextHider extends JsonGeneratorDelegate {
public TextHider(JsonGenerator g) {
super(g);
}
@Override
public JsonGenerator writeString(String text) {
delegate.writeString("***");
return this;
}
}
}
/*
/**********************************************************
/* 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(ObjectReadContext.empty(), new StringReader("{ }"));
// should be overridden;
assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(789, p.getIntValue());
p.close();
// similarly with InputStream
p = f.createParser(ObjectReadContext.empty(), 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(ObjectReadContext.empty(), 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(ObjectReadContext.empty(), 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(ObjectReadContext.empty(), 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 jg;
StringWriter sw = new StringWriter();
jg = f.createGenerator(ObjectWriteContext.empty(), sw);
jg.close();
assertEquals("567", sw.toString());
ByteArrayOutputStream out = new ByteArrayOutputStream();
jg = f.createGenerator(ObjectWriteContext.empty(), out, JsonEncoding.UTF8);
jg.close();
assertEquals("123", out.toString("UTF-8"));
}
/*
/**********************************************************
/* 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(ObjectWriteContext.empty(), sw)) {
_generateForDecorator(g);
}
assertEquals(EXP, sw.toString());
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
try (JsonGenerator g = f.createGenerator(ObjectWriteContext.empty(), 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(ObjectWriteContext.empty(), sw)) {
_generateForDecorator(g);
}
assertEquals(EXP, sw.toString());
// And re-built instance
JsonFactory f3 = f2.rebuild().build();
sw = new StringWriter();
try (JsonGenerator g = f3.createGenerator(ObjectWriteContext.empty(), sw)) {
_generateForDecorator(g);
}
assertEquals(EXP, sw.toString());
}
private void _generateForDecorator(JsonGenerator g) throws Exception
{
g.writeStartObject();
g.writeStringProperty("password", "s3cr37x!!");
g.writeEndObject();
}
}