77import java .math .BigInteger ;
88
99import com .fasterxml .jackson .core .*;
10+ import com .fasterxml .jackson .core .filter .TokenFilter .Inclusion ;
1011import com .fasterxml .jackson .core .util .JsonGeneratorDelegate ;
1112
1213/**
1819 */
1920public class FilteringGeneratorDelegate extends JsonGeneratorDelegate
2021{
22+
2123 /*
2224 /**********************************************************
2325 /* Configuration
@@ -45,18 +47,7 @@ public class FilteringGeneratorDelegate extends JsonGeneratorDelegate
4547 * done and only explicitly included entries are output; if `true` then
4648 * path from main level down to match is also included as necessary.
4749 */
48- protected boolean _includePath ;
49-
50- /* NOTE: this feature is included in the first version (2.6), but
51- * there is no public API to enable it, yet, since there isn't an
52- * actual use case. But it seemed possible need could arise, which
53- * is feature has not yet been removed. If no use is found within
54- * first version or two, just remove.
55- *
56- * Marked as deprecated since its status is uncertain.
57- */
58- @ Deprecated
59- protected boolean _includeImmediateParent ;
50+ protected TokenFilter .Inclusion _inclusion ;
6051
6152 /*
6253 /**********************************************************
@@ -90,16 +81,23 @@ public class FilteringGeneratorDelegate extends JsonGeneratorDelegate
9081 /**********************************************************
9182 */
9283
84+ @ Deprecated
9385 public FilteringGeneratorDelegate (JsonGenerator d , TokenFilter f ,
9486 boolean includePath , boolean allowMultipleMatches )
87+ {
88+ this (d , f , includePath ? Inclusion .INCLUDE_ALL_AND_PATH : Inclusion .ONLY_INCLUDE_ALL , allowMultipleMatches );
89+ }
90+
91+ public FilteringGeneratorDelegate (JsonGenerator d , TokenFilter f ,
92+ TokenFilter .Inclusion inclusion , boolean allowMultipleMatches )
9593 {
9694 // By default, do NOT delegate copy methods
9795 super (d , false );
9896 rootFilter = f ;
9997 // and this is the currently active filter for root values
10098 _itemFilter = f ;
10199 _filterContext = TokenFilterContext .createRootContext (f );
102- _includePath = includePath ;
100+ _inclusion = inclusion ;
103101 _allowMultipleMatches = allowMultipleMatches ;
104102 }
105103
@@ -170,6 +168,10 @@ public void writeStartArray() throws IOException
170168 _checkParentPath ();
171169 _filterContext = _filterContext .createChildArrayContext (_itemFilter , true );
172170 delegate .writeStartArray ();
171+ } else if (_itemFilter != null && _inclusion == Inclusion .INCLUDE_NON_NULL ) {
172+ _checkParentPath (false /* isMatch */ );
173+ _filterContext = _filterContext .createChildArrayContext (_itemFilter , true );
174+ delegate .writeStartArray ();
173175 } else {
174176 _filterContext = _filterContext .createChildArrayContext (_itemFilter , false );
175177 }
@@ -200,6 +202,10 @@ public void writeStartArray(int size) throws IOException
200202 _checkParentPath ();
201203 _filterContext = _filterContext .createChildArrayContext (_itemFilter , true );
202204 delegate .writeStartArray (size );
205+ } else if (_itemFilter != null && _inclusion == Inclusion .INCLUDE_NON_NULL ) {
206+ _checkParentPath (false /* isMatch */ );
207+ _filterContext = _filterContext .createChildArrayContext (_itemFilter , true );
208+ delegate .writeStartArray (size );
203209 } else {
204210 _filterContext = _filterContext .createChildArrayContext (_itemFilter , false );
205211 }
@@ -298,6 +304,10 @@ public void writeStartObject() throws IOException
298304 _checkParentPath ();
299305 _filterContext = _filterContext .createChildObjectContext (f , true );
300306 delegate .writeStartObject ();
307+ } else if (f != null && _inclusion == Inclusion .INCLUDE_NON_NULL ) {
308+ _checkParentPath (false /* isMatch */ );
309+ _filterContext = _filterContext .createChildObjectContext (f , true );
310+ delegate .writeStartObject ();
301311 } else { // filter out
302312 _filterContext = _filterContext .createChildObjectContext (f , false );
303313 }
@@ -328,6 +338,10 @@ public void writeStartObject(Object forValue) throws IOException
328338 _checkParentPath ();
329339 _filterContext = _filterContext .createChildObjectContext (f , true );
330340 delegate .writeStartObject (forValue );
341+ } else if (f != null && _inclusion == Inclusion .INCLUDE_NON_NULL ) {
342+ _checkParentPath (false /* isMatch */ );
343+ _filterContext = _filterContext .createChildObjectContext (f , true );
344+ delegate .writeStartObject (forValue );
331345 } else { // filter out
332346 _filterContext = _filterContext .createChildObjectContext (f , false );
333347 }
@@ -441,7 +455,7 @@ public void writeString(String value) throws IOException
441455 }
442456 }
443457 _checkParentPath ();
444- }
458+ }
445459 delegate .writeString (value );
446460 }
447461
@@ -463,7 +477,7 @@ public void writeString(char[] text, int offset, int len) throws IOException
463477 }
464478 }
465479 _checkParentPath ();
466- }
480+ }
467481 delegate .writeString (text , offset , len );
468482 }
469483
@@ -484,7 +498,7 @@ public void writeString(SerializableString value) throws IOException
484498 }
485499 }
486500 _checkParentPath ();
487- }
501+ }
488502 delegate .writeString (value );
489503 }
490504
@@ -637,7 +651,7 @@ public void writeNumber(short v) throws IOException
637651 }
638652 }
639653 _checkParentPath ();
640- }
654+ }
641655 delegate .writeNumber (v );
642656 }
643657
@@ -658,7 +672,7 @@ public void writeNumber(int v) throws IOException
658672 }
659673 }
660674 _checkParentPath ();
661- }
675+ }
662676 delegate .writeNumber (v );
663677 }
664678
@@ -679,7 +693,7 @@ public void writeNumber(long v) throws IOException
679693 }
680694 }
681695 _checkParentPath ();
682- }
696+ }
683697 delegate .writeNumber (v );
684698 }
685699
@@ -700,7 +714,7 @@ public void writeNumber(BigInteger v) throws IOException
700714 }
701715 }
702716 _checkParentPath ();
703- }
717+ }
704718 delegate .writeNumber (v );
705719 }
706720
@@ -721,7 +735,7 @@ public void writeNumber(double v) throws IOException
721735 }
722736 }
723737 _checkParentPath ();
724- }
738+ }
725739 delegate .writeNumber (v );
726740 }
727741
@@ -742,7 +756,7 @@ public void writeNumber(float v) throws IOException
742756 }
743757 }
744758 _checkParentPath ();
745- }
759+ }
746760 delegate .writeNumber (v );
747761 }
748762
@@ -763,7 +777,7 @@ public void writeNumber(BigDecimal v) throws IOException
763777 }
764778 }
765779 _checkParentPath ();
766- }
780+ }
767781 delegate .writeNumber (v );
768782 }
769783
@@ -826,7 +840,7 @@ public void writeBoolean(boolean v) throws IOException
826840 }
827841 }
828842 _checkParentPath ();
829- }
843+ }
830844 delegate .writeBoolean (v );
831845 }
832846
@@ -847,7 +861,7 @@ public void writeNull() throws IOException
847861 }
848862 }
849863 _checkParentPath ();
850- }
864+ }
851865 delegate .writeNull ();
852866 }
853867
@@ -970,13 +984,23 @@ public void copyCurrentStructure(JsonParser jp) throws IOException {
970984
971985 protected void _checkParentPath () throws IOException
972986 {
973- ++_matchCount ;
987+ _checkParentPath (true );
988+ }
989+
990+ protected void _checkParentPath (boolean isMatch ) throws IOException
991+ {
992+ if (isMatch ) {
993+ ++_matchCount ;
994+ }
974995 // only need to construct path if parent wasn't written
975- if (_includePath ) {
996+ if (_inclusion == Inclusion . INCLUDE_ALL_AND_PATH ) {
976997 _filterContext .writePath (delegate );
998+ } else if (_inclusion == Inclusion .INCLUDE_NON_NULL ) {
999+ // path has already been written, except for maybe field name
1000+ _filterContext .ensureFieldNameWritten (delegate );
9771001 }
9781002 // also: if no multiple matches desired, short-cut checks
979- if (!_allowMultipleMatches ) {
1003+ if (isMatch && !_allowMultipleMatches ) {
9801004 // Mark parents as "skip" so that further check calls are not made
9811005 _filterContext .skipParentChecks ();
9821006 }
@@ -990,12 +1014,11 @@ protected void _checkParentPath() throws IOException
9901014 protected void _checkPropertyParentPath () throws IOException
9911015 {
9921016 ++_matchCount ;
993- if (_includePath ) {
1017+ if (_inclusion == Inclusion . INCLUDE_ALL_AND_PATH ) {
9941018 _filterContext .writePath (delegate );
995- } else if (_includeImmediateParent ) {
996- // 21-Apr-2015, tatu: Note that there is no API to enable this currently...
997- // retained for speculative future use
998- _filterContext .writeImmediatePath (delegate );
1019+ } else if (_inclusion == Inclusion .INCLUDE_NON_NULL ) {
1020+ // path has already been written, except for maybe field name
1021+ _filterContext .ensureFieldNameWritten (delegate );
9991022 }
10001023
10011024 // also: if no multiple matches desired, short-cut checks
0 commit comments