Merge pull request #380 from rfoltyns/feature/filtering_parser_match_count
#208 FilteringParserDelegate match count support
diff --git a/src/main/java/com/fasterxml/jackson/core/filter/FilteringParserDelegate.java b/src/main/java/com/fasterxml/jackson/core/filter/FilteringParserDelegate.java
index c355446..4459e7f 100644
--- a/src/main/java/com/fasterxml/jackson/core/filter/FilteringParserDelegate.java
+++ b/src/main/java/com/fasterxml/jackson/core/filter/FilteringParserDelegate.java
@@ -414,7 +414,7 @@
}
_itemFilter = f;
if (f == TokenFilter.INCLUDE_ALL) {
- if (_includePath) {
+ if (_verifyAllowedMatches() && _includePath) {
return (_currToken = t);
}
}
@@ -437,7 +437,9 @@
f = _headContext.checkValue(f);
if ((f == TokenFilter.INCLUDE_ALL)
|| ((f != null) && f.includeValue(delegate))) {
- return (_currToken = t);
+ if (_verifyAllowedMatches()) {
+ return (_currToken = t);
+ }
}
}
// Otherwise not included (leaves must be explicitly included)
@@ -572,7 +574,7 @@
}
_itemFilter = f;
if (f == TokenFilter.INCLUDE_ALL) {
- if (_includePath) {
+ if (_verifyAllowedMatches() && _includePath) {
return (_currToken = t);
}
// if (_includeImmediateParent) { ...
@@ -597,7 +599,9 @@
f = _headContext.checkValue(f);
if ((f == TokenFilter.INCLUDE_ALL)
|| ((f != null) && f.includeValue(delegate))) {
- return (_currToken = t);
+ if (_verifyAllowedMatches()) {
+ return (_currToken = t);
+ }
}
}
// Otherwise not included (leaves must be explicitly included)
@@ -714,7 +718,7 @@
continue main_loop;
}
_itemFilter = f;
- if (f == TokenFilter.INCLUDE_ALL) {
+ if (f == TokenFilter.INCLUDE_ALL && _verifyAllowedMatches()) {
return _nextBuffered(buffRoot);
}
}
@@ -729,7 +733,9 @@
f = _headContext.checkValue(f);
if ((f == TokenFilter.INCLUDE_ALL)
|| ((f != null) && f.includeValue(delegate))) {
- return _nextBuffered(buffRoot);
+ if (_verifyAllowedMatches()) {
+ return _nextBuffered(buffRoot);
+ }
}
}
// Otherwise not included (leaves must be explicitly included)
@@ -767,7 +773,15 @@
}
}
}
-
+
+ private final boolean _verifyAllowedMatches() throws IOException {
+ if (_matchCount == 0 || _allowMultipleMatches) {
+ ++_matchCount;
+ return true;
+ }
+ return false;
+ }
+
@Override
public JsonToken nextValue() throws IOException {
// Re-implemented same as ParserMinimalBase:
diff --git a/src/test/java/com/fasterxml/jackson/core/filter/BasicGeneratorFilteringTest.java b/src/test/java/com/fasterxml/jackson/core/filter/BasicGeneratorFilteringTest.java
index 759167e..a99e814 100644
--- a/src/test/java/com/fasterxml/jackson/core/filter/BasicGeneratorFilteringTest.java
+++ b/src/test/java/com/fasterxml/jackson/core/filter/BasicGeneratorFilteringTest.java
@@ -190,6 +190,7 @@
gen.close();
assertEquals(aposToQuotes("{'ob':{'value':['x']}}"), w.toString());
+ assertEquals(1, gen.getMatchCount());
}
public void testSingleMatchFilteringWithPathRawBinary() throws Exception
@@ -240,47 +241,51 @@
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();
- JsonGenerator gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
+ 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();
-
- JsonGenerator gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
+
+ 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();
-
- JsonGenerator gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
+
+ 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();
- JsonGenerator gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
+ 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}";
@@ -293,24 +298,26 @@
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();
- JsonGenerator gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
+ 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();
- JsonGenerator gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
+ FilteringGeneratorDelegate gen = new FilteringGeneratorDelegate(JSON_F.createGenerator(w),
TokenFilter.INCLUDE_ALL,
true, true);
diff --git a/src/test/java/com/fasterxml/jackson/core/filter/BasicParserFilteringTest.java b/src/test/java/com/fasterxml/jackson/core/filter/BasicParserFilteringTest.java
index 987d89c..290fb04 100644
--- a/src/test/java/com/fasterxml/jackson/core/filter/BasicParserFilteringTest.java
+++ b/src/test/java/com/fasterxml/jackson/core/filter/BasicParserFilteringTest.java
@@ -81,52 +81,118 @@
public void testSingleMatchFilteringWithoutPath() throws Exception
{
JsonParser p0 = JSON_F.createParser(SIMPLE);
- JsonParser p = new FilteringParserDelegate(p0,
+ FilteringParserDelegate p = new FilteringParserDelegate(p0,
new NameMatchFilter("value"),
false, // includePath
false // multipleMatches
);
String result = readAndWrite(JSON_F, p);
assertEquals(aposToQuotes("3"), result);
+ assertEquals(1, p.getMatchCount());
+ }
+
+ public void testSingleMatchFilteringWithPath() throws Exception
+ {
+ String jsonString = aposToQuotes("{'a':123,'array':[1,2],'ob':{'value0':2,'value':3,'value2':4},'b':true}");
+ JsonParser p0 = JSON_F.createParser(jsonString);
+ FilteringParserDelegate p = new FilteringParserDelegate(p0,
+ new NameMatchFilter("a"),
+ true, // includePath
+ false // multipleMatches
+ );
+ String result = readAndWrite(JSON_F, p);
+ assertEquals(aposToQuotes("{'a':123}"), result);
+ assertEquals(1, p.getMatchCount());
}
@SuppressWarnings("resource")
- public void testNotAllowMultipleMatches() throws Exception
+ public void testNotAllowMultipleMatchesWithoutPath1() throws Exception
{
- String jsonString = aposToQuotes("{'a':123,'array':[1,2],'ob':{'value0':2,'value':3,'value2':4},'value':4,'b':true}");
+ String jsonString = aposToQuotes("{'a':123,'array':[1,2],'ob':{'value0':2,'value':3,'value2':4,'value':{'value0':2}},'b':true}");
JsonParser p0 = JSON_F.createParser(jsonString);
- JsonParser p = new FilteringParserDelegate(p0,
+ FilteringParserDelegate p = new FilteringParserDelegate(p0,
new NameMatchFilter("value"),
false, // includePath
false // multipleMatches -false
);
String result = readAndWrite(JSON_F, p);
assertEquals(aposToQuotes("3"), result);
+ assertEquals(1, p.getMatchCount());
}
-
+
@SuppressWarnings("resource")
- public void testAllowMultipleMatches() throws Exception
+ public void testNotAllowMultipleMatchesWithoutPath2() throws Exception
{
- String jsonString = aposToQuotes("{'a':123,'array':[1,2],'ob':{'value0':2,'value':3,'value2':4},'value':4,'b':true}");
+ String jsonString = aposToQuotes("{'a':123,'array':[1,2],'array':[3,4],'ob':{'value0':2,'value':3,'value2':4,'value':{'value0':2}},'value':\"val\",'b':true}");
JsonParser p0 = JSON_F.createParser(jsonString);
- JsonParser p = new FilteringParserDelegate(p0,
+ FilteringParserDelegate p = new FilteringParserDelegate(p0,
+ new IndexMatchFilter(1),
+ false, // includePath
+ false // multipleMatches -false
+ );
+ String result = readAndWrite(JSON_F, p);
+ assertEquals(aposToQuotes("2"), result);
+ assertEquals(1, p.getMatchCount());
+ }
+
+ @SuppressWarnings("resource")
+ public void testAllowMultipleMatchesWithoutPath() throws Exception
+ {
+ String jsonString = aposToQuotes("{'a':123,'array':[1,2],'ob':{'value0':2,'value':3,'value2':4,'value':{'value0':2}},'value':\"val\",'b':true}");
+ JsonParser p0 = JSON_F.createParser(jsonString);
+ FilteringParserDelegate p = new FilteringParserDelegate(p0,
new NameMatchFilter("value"),
false, // includePath
true // multipleMatches - true
);
String result = readAndWrite(JSON_F, p);
- assertEquals(aposToQuotes("3 4"), result);
+ assertEquals(aposToQuotes("3 {\"value0\":2} \"val\""), result);
+ assertEquals(3, p.getMatchCount());
+ }
+
+
+ @SuppressWarnings("resource")
+ public void testAllowMultipleMatchesWithPath1() throws Exception
+ {
+ String jsonString = aposToQuotes("{'a':123,'array':[1,2],'ob':{'value0':2,'value':3,'value2':4,'value':{'value0':2}},'value':\"val\",'b':true}");
+ JsonParser p0 = JSON_F.createParser(jsonString);
+ FilteringParserDelegate p = new FilteringParserDelegate(p0,
+ new NameMatchFilter("value"),
+ true, // includePath
+ true // multipleMatches - true
+ );
+ String result = readAndWrite(JSON_F, p);
+ assertEquals(aposToQuotes("{\"ob\":{\"value\":3,\"value\":{\"value0\":2}},\"value\":\"val\"}"), result);
+ assertEquals(3, p.getMatchCount());
+ }
+
+
+ @SuppressWarnings("resource")
+ public void testAllowMultipleMatchesWithPath2() throws Exception
+ {
+ String jsonString = aposToQuotes("{'a':123,'array':[1,2],'ob':{'value0':2,'value':3,'array':[3,4],'value':{'value0':2}},'value':\"val\",'b':true}");
+ JsonParser p0 = JSON_F.createParser(jsonString);
+ FilteringParserDelegate p = new FilteringParserDelegate(p0,
+ new IndexMatchFilter(1),
+ true, // includePath
+ true // multipleMatches - true
+ );
+ String result = readAndWrite(JSON_F, p);
+ assertEquals(aposToQuotes("{\"array\":[2],\"ob\":{\"array\":[4]}}"), result);
+ assertEquals(2, p.getMatchCount());
}
@SuppressWarnings("resource")
public void testMultipleMatchFilteringWithPath1() throws Exception
{
JsonParser p0 = JSON_F.createParser(SIMPLE);
- JsonParser p = new FilteringParserDelegate(p0,
+ FilteringParserDelegate p = new FilteringParserDelegate(p0,
new NameMatchFilter("value0", "value2"),
true, /* includePath */ true /* multipleMatches */ );
String result = readAndWrite(JSON_F, p);
assertEquals(aposToQuotes("{'ob':{'value0':2,'value2':4}}"), result);
+ assertEquals(2, p.getMatchCount());
+
}
@SuppressWarnings("resource")
@@ -134,51 +200,57 @@
{
String INPUT = aposToQuotes("{'a':123,'ob':{'value0':2,'value':3,'value2':4},'b':true}");
JsonParser p0 = JSON_F.createParser(INPUT);
- JsonParser p = new FilteringParserDelegate(p0,
+ FilteringParserDelegate p = new FilteringParserDelegate(p0,
new NameMatchFilter("b", "value"),
true, true);
String result = readAndWrite(JSON_F, p);
assertEquals(aposToQuotes("{'ob':{'value':3},'b':true}"), result);
+ assertEquals(2, p.getMatchCount());
}
@SuppressWarnings("resource")
public void testMultipleMatchFilteringWithPath3() throws Exception
{
- final String JSON = aposToQuotes("{'root':{'a0':true,'a':{'value':3},'b':{'value':4}},'b0':false}");
+ final String JSON = aposToQuotes("{'root':{'a0':true,'a':{'value':3},'b':{'value':\"foo\"}},'b0':false}");
JsonParser p0 = JSON_F.createParser(JSON);
- JsonParser p = new FilteringParserDelegate(p0,
+ FilteringParserDelegate p = new FilteringParserDelegate(p0,
new NameMatchFilter("value"),
true, true);
String result = readAndWrite(JSON_F, p);
- assertEquals(aposToQuotes("{'root':{'a':{'value':3},'b':{'value':4}}}"), result);
+ assertEquals(aposToQuotes("{'root':{'a':{'value':3},'b':{'value':\"foo\"}}}"), result);
+ assertEquals(2, p.getMatchCount());
}
@SuppressWarnings("resource")
public void testIndexMatchWithPath1() throws Exception
{
- JsonParser p = new FilteringParserDelegate(JSON_F.createParser(SIMPLE),
+ FilteringParserDelegate p = new FilteringParserDelegate(JSON_F.createParser(SIMPLE),
new IndexMatchFilter(1), true, true);
String result = readAndWrite(JSON_F, p);
assertEquals(aposToQuotes("{'array':[2]}"), result);
+ assertEquals(1, p.getMatchCount());
p = new FilteringParserDelegate(JSON_F.createParser(SIMPLE),
new IndexMatchFilter(0), true, true);
result = readAndWrite(JSON_F, p);
assertEquals(aposToQuotes("{'array':[1]}"), result);
+ assertEquals(1, p.getMatchCount());
}
@SuppressWarnings("resource")
public void testIndexMatchWithPath2() throws Exception
{
- JsonParser p = new FilteringParserDelegate(JSON_F.createParser(SIMPLE),
+ FilteringParserDelegate p = new FilteringParserDelegate(JSON_F.createParser(SIMPLE),
new IndexMatchFilter(0, 1), true, true);
assertEquals(aposToQuotes("{'array':[1,2]}"), readAndWrite(JSON_F, p));
+ assertEquals(2, p.getMatchCount());
String JSON = aposToQuotes("{'a':123,'array':[1,2,3,4,5],'b':[1,2,3]}");
p = new FilteringParserDelegate(JSON_F.createParser(JSON),
new IndexMatchFilter(1, 3), true, true);
assertEquals(aposToQuotes("{'array':[2,4],'b':[2]}"), readAndWrite(JSON_F, p));
+ assertEquals(3, p.getMatchCount());
}
@SuppressWarnings("resource")