diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x
index 0b6bacab87..2b5c261794 100644
--- a/release-notes/CREDITS-2.x
+++ b/release-notes/CREDITS-2.x
@@ -352,22 +352,24 @@ Chris Rankin (chrisr3@github)
(2.15.1)
Przemyslaw Gomulka (pgomulka@github)
- * Contributed #882: Allow TokenFIlter to skip last elements in arrays
+ * Contributed #882: Allow TokenFIlter to skip last elements in arrays
(2.14.2)
Markus Spika (DemonicTutor@github)
- * Contributed #890: `FilteringGeneratorDelegate` does not create new `filterContext`
+ * Contributed #890: `FilteringGeneratorDelegate` does not create new `filterContext`
if `tokenFilter` is null
(2.14.2)
+ * Contributed #1036: Allow all array elements in `JsonPointerBasedFilter`
+ (2.16.0)
Pedro Nacht (pnacht@github)
- * Contributed #844: Add SLSA provenance via build script
+ * Contributed #844: Add SLSA provenance via build script
(2.15.0)
Jonas Konrad (yawkat@github)
- * Contributed #921: Add `JsonFactory.Feature` to disable charset detection
+ * Contributed #921: Add `JsonFactory.Feature` to disable charset detection
(2.15.0)
Carter Kozak (carterkozak@github)
- * Contributed #1015: `JsonFactory` implementations should respect `CANONICALIZE_FIELD_NAMES`
+ * Contributed #1015: `JsonFactory` implementations should respect `CANONICALIZE_FIELD_NAMES`
(2.15.1)
diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x
index a8c63d140c..4595114344 100644
--- a/release-notes/VERSION-2.x
+++ b/release-notes/VERSION-2.x
@@ -21,6 +21,8 @@ a pure JSON library.
(contributed by Carter K)
#1035: Root cause for failing test for `testMangledIntsBytes()` in `ParserErrorHandlingTest`
(reported by @harsha-99)
+#1036: Allow all array elements in `JsonPointerBasedFilter`
+ (contribited by Markus S)
2.15.2 (not yet released)
diff --git a/src/main/java/com/fasterxml/jackson/core/filter/JsonPointerBasedFilter.java b/src/main/java/com/fasterxml/jackson/core/filter/JsonPointerBasedFilter.java
index ea0b3dcd79..74df9c9ef5 100644
--- a/src/main/java/com/fasterxml/jackson/core/filter/JsonPointerBasedFilter.java
+++ b/src/main/java/com/fasterxml/jackson/core/filter/JsonPointerBasedFilter.java
@@ -14,24 +14,52 @@ 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
+ *
+ * @since 2.16
+ */
+ protected final boolean _includeAllElements;
+
public JsonPointerBasedFilter(String ptrExpr) {
- this(JsonPointer.compile(ptrExpr));
+ this(JsonPointer.compile(ptrExpr), false);
+ }
+
+ /**
+ * @param pathToMatch Content to extract
+ */
+ public JsonPointerBasedFilter(JsonPointer pathToMatch) {
+ this(pathToMatch, false);
}
- public JsonPointerBasedFilter(JsonPointer match) {
- _pathToMatch = match;
+ /**
+ * @param pathToMatch Content to extract
+ * @param includeAllElements if true array indexes in ptrExpr
are ignored
+ * and all elements will be matched. default: false
+ *
+ * @since 2.16
+ */
+ public JsonPointerBasedFilter(JsonPointer pathToMatch, boolean includeAllElements) {
+ _pathToMatch = pathToMatch;
+ _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 +71,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/com/fasterxml/jackson/core/filter/GeneratorFiltering890Test.java b/src/test/java/com/fasterxml/jackson/core/filter/GeneratorFiltering890Test.java
index c8e7ebc041..579bdabfd2 100644
--- a/src/test/java/com/fasterxml/jackson/core/filter/GeneratorFiltering890Test.java
+++ b/src/test/java/com/fasterxml/jackson/core/filter/GeneratorFiltering890Test.java
@@ -2,6 +2,7 @@
import com.fasterxml.jackson.core.BaseTest;
import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.core.filter.TokenFilter.Inclusion;
import java.io.ByteArrayOutputStream;
@@ -26,7 +27,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(JsonPointer.compile(p), true)).collect(Collectors.toList()));
}
@Override
@@ -69,7 +70,7 @@ private TokenFilter executeDelegates(final UnaryOperator operator)
}
}
- public void testIssue809_singleProperty() throws Exception
+ public void testIssue890_singleProperty() throws Exception
{
// GIVEN
final Set jsonPointers = Stream.of("/0/id").collect(Collectors.toSet());
@@ -91,7 +92,7 @@ public void testIssue809_singleProperty() throws Exception
assertEquals("[{\"id\":1}]", json);
}
- public void testIssue809_twoProperties() throws Exception
+ public void testIssue890_twoProperties() throws Exception
{
// GIVEN
final Set jsonPointers = Stream.of("/0/id", "/0/stuff/0/name").collect(Collectors.toSet());
@@ -113,6 +114,28 @@ public void testIssue809_twoProperties() throws Exception
assertEquals("[{\"id\":1,\"stuff\":[{\"name\":\"first\"}]}]", json);
}
+ public void testIssue890_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();