Skip to content

Commit 0c4e156

Browse files
committed
More work for #888, simple custom filter appears to work now.
1 parent f77e77d commit 0c4e156

File tree

4 files changed

+76
-18
lines changed

4 files changed

+76
-18
lines changed

src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java

+10-10
Original file line numberDiff line numberDiff line change
@@ -723,31 +723,31 @@ public JsonInclude.Include findSerializationInclusionForContent(Annotated a, Jso
723723
public JsonInclude.Value findPropertyInclusion(Annotated a)
724724
{
725725
JsonInclude inc = _findAnnotation(a, JsonInclude.class);
726-
JsonInclude.Include valueIncl = (inc == null) ? JsonInclude.Include.USE_DEFAULTS : inc.value();
727-
if (valueIncl == JsonInclude.Include.USE_DEFAULTS) {
726+
JsonInclude.Value value = (inc == null) ? JsonInclude.Value.empty() : JsonInclude.Value.from(inc);
727+
728+
// only consider deprecated variant if we didn't have non-deprecated one:
729+
if (value.getValueInclusion() == JsonInclude.Include.USE_DEFAULTS) {
728730
JsonSerialize ann = _findAnnotation(a, JsonSerialize.class);
729731
if (ann != null) {
730-
JsonSerialize.Inclusion i2 = ann.include();
731-
switch (i2) {
732+
switch (ann.include()) {
732733
case ALWAYS:
733-
valueIncl = JsonInclude.Include.ALWAYS;
734+
value = value.withValueInclusion(JsonInclude.Include.ALWAYS);
734735
break;
735736
case NON_NULL:
736-
valueIncl = JsonInclude.Include.NON_NULL;
737+
value = value.withValueInclusion(JsonInclude.Include.NON_NULL);
737738
break;
738739
case NON_DEFAULT:
739-
valueIncl = JsonInclude.Include.NON_DEFAULT;
740+
value = value.withValueInclusion(JsonInclude.Include.NON_DEFAULT);
740741
break;
741742
case NON_EMPTY:
742-
valueIncl = JsonInclude.Include.NON_EMPTY;
743+
value = value.withValueInclusion(JsonInclude.Include.NON_EMPTY);
743744
break;
744745
case DEFAULT_INCLUSION:
745746
default:
746747
}
747748
}
748749
}
749-
JsonInclude.Include contentIncl = (inc == null) ? JsonInclude.Include.USE_DEFAULTS : inc.content();
750-
return JsonInclude.Value.construct(valueIncl, contentIncl);
750+
return value;
751751
}
752752

753753
@Override

src/main/java/com/fasterxml/jackson/databind/ser/DefaultSerializerProvider.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ public Object includeFilterInstance(BeanPropertyDefinition forProperty,
149149
HandlerInstantiator hi = _config.getHandlerInstantiator();
150150
Object filter = (hi == null) ? null : hi.includeFilterInstance(_config, forProperty, filterClass);
151151
if (filter == null) {
152-
filter = (JsonSerializer<?>) ClassUtil.createInstance(filterClass,
152+
filter = ClassUtil.createInstance(filterClass,
153153
_config.canOverrideAccessModifiers());
154154
}
155155
return filter;

src/main/java/com/fasterxml/jackson/databind/ser/PropertyBuilder.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,10 @@ protected BeanPropertyWriter buildWriter(SerializerProvider prov,
140140

141141
inclV = inclV.withOverrides(propDef.findInclusion());
142142
JsonInclude.Include inclusion = inclV.getValueInclusion();
143-
144143
if (inclusion == JsonInclude.Include.USE_DEFAULTS) { // should not occur but...
145144
inclusion = JsonInclude.Include.ALWAYS;
146145
}
147-
146+
148147
switch (inclusion) {
149148
case NON_DEFAULT:
150149
// 11-Nov-2015, tatu: This is tricky because semantics differ between cases,
@@ -186,6 +185,7 @@ protected BeanPropertyWriter buildWriter(SerializerProvider prov,
186185
break;
187186
case CUSTOM: // new with 2.9
188187
valueToSuppress = prov.includeFilterInstance(propDef, inclV.getValueFilter());
188+
189189
if (valueToSuppress == null) { // is this legal?
190190
suppressNulls = true;
191191
} else {
@@ -194,9 +194,10 @@ protected BeanPropertyWriter buildWriter(SerializerProvider prov,
194194
try {
195195
suppressNulls = valueToSuppress.equals(null);
196196
} catch (Throwable t) {
197-
prov.reportBadDefinition(_beanDesc.getType(),
198-
"Problem determining whether `null` values are to be suppressed: "+t.getMessage(),
199-
t);
197+
String msg = String.format(
198+
"Problem determining whether filter of type '%s' should filter out `null` values: (%s) %s",
199+
valueToSuppress.getClass().getName(), t.getClass().getName(), t.getMessage());
200+
prov.reportBadDefinition(_beanDesc.getType(), msg, t);
200201
}
201202
}
202203
break;
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,78 @@
11
package com.fasterxml.jackson.databind.filter;
22

3+
import com.fasterxml.jackson.annotation.*;
4+
35
import com.fasterxml.jackson.databind.BaseMapTest;
46
import com.fasterxml.jackson.databind.ObjectMapper;
7+
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
58

69
// Tests for [databind#888]
710
public class JsonIncludeCustomTest extends BaseMapTest
811
{
12+
static class FooFilter {
13+
@Override
14+
public boolean equals(Object other) {
15+
if (other == null) { // do NOT filter out nulls
16+
return false;
17+
}
18+
// in fact, only filter out exact String "foo"
19+
return "foo".equals(other);
20+
}
21+
}
22+
23+
// for testing prob with `equals(null)` which SHOULD be allowed
24+
static class BrokenFilter {
25+
@Override
26+
public boolean equals(Object other) {
27+
/*String str = */ other.toString();
28+
return false;
29+
}
30+
}
31+
32+
static class FooBean {
33+
@JsonInclude(value=JsonInclude.Include.CUSTOM,
34+
valueFilter=FooFilter.class)
35+
public String value;
36+
37+
public FooBean(String v) { value = v; }
38+
}
39+
40+
static class BrokenBean {
41+
@JsonInclude(value=JsonInclude.Include.CUSTOM,
42+
valueFilter=BrokenFilter.class)
43+
public String value;
44+
45+
public BrokenBean(String v) { value = v; }
46+
}
47+
948
/*
1049
/**********************************************************
11-
/* Test methods
50+
/* Test methods, success
1251
/**********************************************************
1352
*/
1453

1554
final private ObjectMapper MAPPER = new ObjectMapper();
1655

1756
public void testSimpleCustomFilter() throws Exception
1857
{
19-
58+
assertEquals(aposToQuotes("{'value':'x'}"), MAPPER.writeValueAsString(new FooBean("x")));
59+
assertEquals("{}", MAPPER.writeValueAsString(new FooBean("foo")));
60+
}
61+
62+
/*
63+
/**********************************************************
64+
/* Test methods, fail handling
65+
/**********************************************************
66+
*/
67+
68+
public void testBrokenFilter() throws Exception
69+
{
70+
try {
71+
String json = MAPPER.writeValueAsString(new BrokenBean("foo"));
72+
fail("Should not pass, produced: "+json);
73+
} catch (InvalidDefinitionException e) {
74+
verifyException(e, "Problem determining whether filter of type");
75+
verifyException(e, "filter out `null`");
76+
}
2077
}
2178
}

0 commit comments

Comments
 (0)