diff --git a/src/main/java/tools/jackson/core/filter/JsonPointerBasedFilter.java b/src/main/java/tools/jackson/core/filter/JsonPointerBasedFilter.java
index e96367bc57..fa3cef54f1 100644
--- a/src/main/java/tools/jackson/core/filter/JsonPointerBasedFilter.java
+++ b/src/main/java/tools/jackson/core/filter/JsonPointerBasedFilter.java
@@ -13,25 +13,47 @@
public class JsonPointerBasedFilter extends TokenFilter
{
protected final JsonPointer _pathToMatch;
+ /**
+ * if true include all array elements by ignoring the array index match and advancing the JsonPointer to the next level
+ */
+ protected final boolean _includeAllElements;
public JsonPointerBasedFilter(String ptrExpr) {
- this(JsonPointer.compile(ptrExpr));
+ this(JsonPointer.compile(ptrExpr), false);
}
public JsonPointerBasedFilter(JsonPointer match) {
+ this(match, false);
+ }
+
+ /**
+ * @param ptrExpr to extract.
+ * @param includeAllElements if true array indexes in ptrExpr are ignored and all elements will be matched. default: false
+ */
+ public JsonPointerBasedFilter(String ptrExpr, boolean includeAllElements) {
+ this(JsonPointer.compile(ptrExpr), includeAllElements);
+ }
+
+ public JsonPointerBasedFilter(JsonPointer match, boolean includeAllElements) {
_pathToMatch = match;
+ _includeAllElements = includeAllElements;
}
@Override
public TokenFilter includeElement(int index) {
- JsonPointer next = _pathToMatch.matchElement(index);
+ JsonPointer next;
+ if (_includeAllElements && ! _pathToMatch.mayMatchElement()) {
+ next = _pathToMatch.tail();
+ } else {
+ next = _pathToMatch.matchElement(index);
+ }
if (next == null) {
return null;
}
if (next.matches()) {
return TokenFilter.INCLUDE_ALL;
}
- return new JsonPointerBasedFilter(next);
+ return new JsonPointerBasedFilter(next, _includeAllElements);
}
@Override
@@ -43,7 +65,7 @@ public TokenFilter includeProperty(String name) {
if (next.matches()) {
return TokenFilter.INCLUDE_ALL;
}
- return new JsonPointerBasedFilter(next);
+ return new JsonPointerBasedFilter(next, _includeAllElements);
}
@Override
diff --git a/src/test/java/tools/jackson/core/filter/GeneratorFiltering890Test.java b/src/test/java/tools/jackson/core/filter/GeneratorFiltering890Test.java
index 7ff2b48f90..23c6216167 100644
--- a/src/test/java/tools/jackson/core/filter/GeneratorFiltering890Test.java
+++ b/src/test/java/tools/jackson/core/filter/GeneratorFiltering890Test.java
@@ -23,7 +23,7 @@ private OrTokenFilter(final List extends TokenFilter> delegates) {
}
static OrTokenFilter create(final Set jsonPointers) {
- return new OrTokenFilter(jsonPointers.stream().map(JsonPointerBasedFilter::new).collect(Collectors.toList()));
+ return new OrTokenFilter(jsonPointers.stream().map(p -> new JsonPointerBasedFilter(p, true)).collect(Collectors.toList()));
}
@Override
@@ -110,6 +110,28 @@ public void testIssue809_twoProperties() throws Exception
assertEquals("[{\"id\":1,\"stuff\":[{\"name\":\"first\"}]}]", json);
}
+ public void testIssue809_fullArray() throws Exception
+ {
+ // GIVEN
+ final Set jsonPointers = Stream.of("//id", "//stuff//name").collect(Collectors.toSet());
+
+ // WHEN
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ JsonGenerator g = new FilteringGeneratorDelegate(createGenerator(outputStream), OrTokenFilter.create(jsonPointers), Inclusion.INCLUDE_ALL_AND_PATH, true);
+
+ g.writeStartArray();
+ writeOuterObject(g, 1, "first", "a", "second", "b");
+ writeOuterObject(g, 2, "third", "c", "fourth", "d");
+ g.writeEndArray();
+ g.flush();
+ g.close();
+ outputStream.close();
+
+ // THEN
+ String json = outputStream.toString("US-ASCII");
+ assertEquals("[{\"id\":1,\"stuff\":[{\"name\":\"first\"},{\"name\":\"second\"}]},{\"id\":2,\"stuff\":[{\"name\":\"third\"},{\"name\":\"fourth\"}]}]", json);
+ }
+
private static void writeOuterObject(final JsonGenerator g, final int id, final String name1, final String type1, final String name2, final String type2) throws IOException
{
g.writeStartObject();