blob: a99e814f2d478aecbe08f1f250e94258a7871531 [file] [log] [blame]
package com.fasterxml.jackson.core.filter;
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.io.SerializedString;
/**
* Low-level tests for explicit, hand-written tests for generator-side
* filtering.
*/
@SuppressWarnings("resource")
public class BasicGeneratorFilteringTest extends BaseTest
{
static class NameMatchFilter extends TokenFilter
{
private final Set<String> _names;
public NameMatchFilter(String... names) {
_names = new HashSet<String>(Arrays.asList(names));
}
@Override
public TokenFilter includeElement(int index) {
return this;
}
@Override
public TokenFilter includeProperty(String name) {
if (_names.contains(name)) {
return TokenFilter.INCLUDE_ALL;
}
return this;
}
@Override
protected boolean _includeScalar() { return false; }
}
static class IndexMatchFilter extends TokenFilter
{
private final BitSet _indices;
public IndexMatchFilter(int... ixs) {
_indices = new BitSet();
for (int ix : ixs) {
_indices.set(ix);
}
}
@Override
public TokenFilter includeProperty(String name) {
return this;
}
@Override
public TokenFilter includeElement(int index) {
if (_indices.get(index)) {
return TokenFilter.INCLUDE_ALL;
}
return null;
}
@Override
protected boolean _includeScalar() { return false; }
}
/*
/**********************************************************
/* Test methods
/**********************************************************
*/
private final JsonFactory JSON_F = new JsonFactory();
public void testNonFiltering() throws Exception
{
// First, verify non-filtering
StringWriter w = new StringWriter();
JsonGenerator gen = JSON_F.createGenerator(w);
final String JSON = "{'a':123,'array':[1,2],'ob':{'value0':2,'value':3,'value2':4},'b':true}";
writeJsonDoc(JSON_F, JSON, gen);
assertEquals(aposToQuotes(
"{'a':123,'array':[1,2],'ob':{'value0':2,'value':3,'value2':4},'b':true}"),
w.toString());
}
public void testSingleMatchFilteringWithoutPath() throws Exception
{
StringWriter w = new StringWriter();
JsonGenerator gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
new NameMatchFilter("value"),
false, // includePath
false // multipleMatches
);
final String JSON = "{'a':123,'array':[1,2],'ob':{'value0':2,'value':3,'value2':4},'b':true}";
writeJsonDoc(JSON_F, JSON, gen);
// 21-Apr-2015, tatu: note that there were plans to actually
// allow "immediate parent inclusion" for matches on property
// names. This behavior was NOT included in release however, so:
// assertEquals(aposToQuotes("{'value':3}"), w.toString());
assertEquals(aposToQuotes("3"), w.toString());
}
public void testSingleMatchFilteringWithPath() throws Exception
{
StringWriter w = new StringWriter();
JsonGenerator origGen = JSON_F.createGenerator(w);
NameMatchFilter filter = new NameMatchFilter("value");
FilteringGeneratorDelegate gen = new FilteringGeneratorDelegate(origGen,
filter,
true, // includePath
false // multipleMatches
);
// Hmmh. Should we get access to eventual target?
assertSame(w, gen.getOutputTarget());
assertNotNull(gen.getFilterContext());
assertSame(filter, gen.getFilter());
final String JSON = "{'a':123,'array':[1,2],'ob':{'value0':2,'value':3,'value2':4},'b':true}";
writeJsonDoc(JSON_F, JSON, gen);
assertEquals(aposToQuotes("{'ob':{'value':3}}"), w.toString());
assertEquals(1, gen.getMatchCount());
}
public void testSingleMatchFilteringWithPathSkippedArray() throws Exception
{
StringWriter w = new StringWriter();
JsonGenerator origGen = JSON_F.createGenerator(w);
NameMatchFilter filter = new NameMatchFilter("value");
FilteringGeneratorDelegate gen = new FilteringGeneratorDelegate(origGen,
filter,
true, // includePath
false // multipleMatches
);
// Hmmh. Should we get access to eventual target?
assertSame(w, gen.getOutputTarget());
assertNotNull(gen.getFilterContext());
assertSame(filter, gen.getFilter());
final String JSON = "{'array':[1,[2,3]],'ob':[{'value':'bar'}],'b':{'foo':[1,'foo']}}";
writeJsonDoc(JSON_F, JSON, gen);
assertEquals(aposToQuotes("{'ob':[{'value':'bar'}]}"), w.toString());
assertEquals(1, gen.getMatchCount());
}
// Alternative take, using slightly different calls for FIELD_NAME, START_ARRAY
public void testSingleMatchFilteringWithPathAlternate1() throws Exception
{
StringWriter w = new StringWriter();
FilteringGeneratorDelegate gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
new NameMatchFilter("value"),
true, // includePath
false // multipleMatches
);
//final String JSON = "{'a':123,'array':[1,2],'ob':{'value0':2,'value':[3],'value2':'foo'},'b':true}";
gen.writeStartObject();
gen.writeFieldName(new SerializedString("a"));
gen.writeNumber(123);
gen.writeFieldName("array");
gen.writeStartArray(2);
gen.writeNumber("1");
gen.writeNumber((short) 2);
gen.writeEndArray();
gen.writeFieldName(new SerializedString("ob"));
gen.writeStartObject();
gen.writeNumberField("value0", 2);
gen.writeFieldName(new SerializedString("value"));
gen.writeStartArray(1);
gen.writeString(new SerializedString("x")); // just to vary generation method
gen.writeEndArray();
gen.writeStringField("value2", "foo");
gen.writeEndObject();
gen.writeBooleanField("b", true);
gen.writeEndObject();
gen.close();
assertEquals(aposToQuotes("{'ob':{'value':['x']}}"), w.toString());
assertEquals(1, gen.getMatchCount());
}
public void testSingleMatchFilteringWithPathRawBinary() throws Exception
{
StringWriter w = new StringWriter();
FilteringGeneratorDelegate gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
new NameMatchFilter("array"),
true, // includePath
false // multipleMatches
);
//final String JSON = "{'header':['ENCODED',raw],'array':['base64stuff',1,2,3,4,5,6.25,7.5],'extra':[1,2,3,4,5,6.25,7.5]}";
gen.writeStartObject();
gen.writeFieldName("header");
gen.writeStartArray();
gen.writeBinary(new byte[] { 1 });
gen.writeRawValue(new SerializedString("1"));
gen.writeRawValue("2");
gen.writeEndArray();
gen.writeFieldName("array");
gen.writeStartArray();
gen.writeBinary(new byte[] { 1 });
gen.writeNumber((short) 1);
gen.writeNumber((int) 2);
gen.writeNumber((long) 3);
gen.writeNumber(BigInteger.valueOf(4));
gen.writeRaw(" ");
gen.writeNumber(new BigDecimal("5.0"));
gen.writeRaw(new SerializedString(" /*x*/"));
gen.writeNumber(6.25f);
gen.writeNumber(7.5);
gen.writeEndArray();
gen.writeArrayFieldStart("extra");
gen.writeNumber((short) 1);
gen.writeNumber((int) 2);
gen.writeNumber((long) 3);
gen.writeNumber(BigInteger.valueOf(4));
gen.writeNumber(new BigDecimal("5.0"));
gen.writeNumber(6.25f);
gen.writeNumber(7.5);
gen.writeEndArray();
gen.writeEndObject();
gen.close();
assertEquals(aposToQuotes("{'array':['AQ==',1,2,3,4 ,5.0 /*x*/,6.25,7.5]}"), w.toString());
assertEquals(1, gen.getMatchCount());
}
public void testMultipleMatchFilteringWithPath1() throws Exception
{
StringWriter w = new StringWriter();
FilteringGeneratorDelegate gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
new NameMatchFilter("value0", "value2"),
true, /* includePath */ true /* multipleMatches */ );
final String JSON = "{'a':123,'array':[1,2],'ob':{'value0':2,'value':3,'value2':4},'b':true}";
writeJsonDoc(JSON_F, JSON, gen);
assertEquals(aposToQuotes("{'ob':{'value0':2,'value2':4}}"), w.toString());
assertEquals(2, gen.getMatchCount());
}
public void testMultipleMatchFilteringWithPath2() throws Exception
{
StringWriter w = new StringWriter();
FilteringGeneratorDelegate gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
new NameMatchFilter("array", "b", "value"),
true, true);
final String JSON = "{'a':123,'array':[1,2],'ob':{'value0':2,'value':3,'value2':4},'b':true}";
writeJsonDoc(JSON_F, JSON, gen);
assertEquals(aposToQuotes("{'array':[1,2],'ob':{'value':3},'b':true}"), w.toString());
assertEquals(3, gen.getMatchCount());
}
public void testMultipleMatchFilteringWithPath3() throws Exception
{
StringWriter w = new StringWriter();
FilteringGeneratorDelegate gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
new NameMatchFilter("value"),
true, true);
final String JSON = "{'root':{'a0':true,'a':{'value':3},'b':{'value':4}},'b0':false}";
writeJsonDoc(JSON_F, JSON, gen);
assertEquals(aposToQuotes("{'root':{'a':{'value':3},'b':{'value':4}}}"), w.toString());
assertEquals(2, gen.getMatchCount());
}
public void testIndexMatchWithPath1() throws Exception
{
StringWriter w = new StringWriter();
FilteringGeneratorDelegate gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
new IndexMatchFilter(1),
true, true);
final String JSON = "{'a':123,'array':[1,2],'ob':{'value0':2,'value':3,'value2':4},'b':true}";
writeJsonDoc(JSON_F, JSON, gen);
assertEquals(aposToQuotes("{'array':[2]}"), w.toString());
w = new StringWriter();
gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
new IndexMatchFilter(0),
true, true);
writeJsonDoc(JSON_F, JSON, gen);
assertEquals(aposToQuotes("{'array':[1]}"), w.toString());
assertEquals(1, gen.getMatchCount());
}
public void testIndexMatchWithPath2() throws Exception
{
StringWriter w = new StringWriter();
FilteringGeneratorDelegate gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
new IndexMatchFilter(0,1),
true, true);
final String JSON = "{'a':123,'array':[1,2],'ob':{'value0':2,'value':3,'value2':4},'b':true}";
writeJsonDoc(JSON_F, JSON, gen);
assertEquals(aposToQuotes("{'array':[1,2]}"), w.toString());
assertEquals(2, gen.getMatchCount());
}
public void testWriteStartObjectWithObject() throws Exception
{
StringWriter w = new StringWriter();
FilteringGeneratorDelegate gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
TokenFilter.INCLUDE_ALL,
true, true);
String value = "val";
gen.writeStartObject(new Object());
gen.writeFieldName("field1");
{
gen.writeStartObject(value);
gen.writeEndObject();
}
gen.writeFieldName("field2");
gen.writeString("val2");
gen.writeEndObject();
gen.close();
assertEquals(aposToQuotes("{'field1':{},'field2':'val2'}"), w.toString());
}
}