Skip to content

Commit f77e77d

Browse files
committed
Initial #888 implementation, minus tests, probably not fully working yet
1 parent e60e9b3 commit f77e77d

File tree

12 files changed

+112
-14
lines changed

12 files changed

+112
-14
lines changed

pom.xml

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
<dependency>
4949
<groupId>com.fasterxml.jackson.core</groupId>
5050
<artifactId>jackson-annotations</artifactId>
51+
<!-- temporarily, until updating parent -->
52+
<version>2.9.0-SNAPSHOT</version>
5153
</dependency>
5254
<dependency>
5355
<groupId>com.fasterxml.jackson.core</groupId>

release-notes/VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Project: jackson-databind
66

77
2.9.0 (not yet released)
88

9-
#1341: FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY
9+
#1341: `DeserializationFeature.FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY`
1010
(contributed by Connor K)
1111
#1356: Differentiate between input and code exceptions on deserialization
1212
(suggested by Nick B)

src/main/java/com/fasterxml/jackson/databind/JsonSerializer.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ public void serializeWithType(T value, JsonGenerator gen, SerializerProvider ser
157157
if (clz == null) {
158158
clz = value.getClass();
159159
}
160-
serializers.reportDefinitionProblem(clz, String.format(
160+
serializers.reportBadDefinition(clz, String.format(
161161
"Type id handling not implemented for type %s (by serializer of type %s)",
162162
clz.getName(), getClass().getName()));
163163
}

src/main/java/com/fasterxml/jackson/databind/SerializerProvider.java

+22-1
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,17 @@ public abstract JsonSerializer<Object> serializerInstance(Annotated annotated,
925925
Object serDef)
926926
throws JsonMappingException;
927927

928+
/**
929+
* Method that can be called to construct and configure {@link JsonInclude}
930+
* filter instance,
931+
* given a {@link Class} to instantiate (with default constructor, by default).
932+
*
933+
* @since 2.9
934+
*/
935+
public abstract Object includeFilterInstance(BeanPropertyDefinition forProperty,
936+
Class<?> filterClass)
937+
throws JsonMappingException;
938+
928939
/*
929940
/**********************************************************
930941
/* Support for contextualization
@@ -1156,10 +1167,20 @@ public <T> T reportBadDefinition(JavaType type, String msg) throws JsonMappingEx
11561167
*
11571168
* @since 2.9
11581169
*/
1159-
public <T> T reportDefinitionProblem(Class<?> type, String msg) throws JsonMappingException {
1170+
public <T> T reportBadDefinition(Class<?> type, String msg) throws JsonMappingException {
11601171
throw InvalidDefinitionException.from(getGenerator(), msg, constructType(type));
11611172
}
11621173

1174+
/**
1175+
* @since 2.9
1176+
*/
1177+
public <T> T reportBadDefinition(JavaType type, String msg, Throwable cause)
1178+
throws JsonMappingException {
1179+
InvalidDefinitionException e = InvalidDefinitionException.from(getGenerator(), msg, type);
1180+
e.initCause(cause);
1181+
throw e;
1182+
}
1183+
11631184
/**
11641185
* Helper method called to indicate problem; default behavior is to construct and
11651186
* throw a {@link JsonMappingException}, but in future may collect more than one

src/main/java/com/fasterxml/jackson/databind/cfg/HandlerInstantiator.java

+19
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.fasterxml.jackson.databind.*;
66
import com.fasterxml.jackson.databind.deser.ValueInstantiator;
77
import com.fasterxml.jackson.databind.introspect.Annotated;
8+
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
89
import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
910
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
1011
import com.fasterxml.jackson.databind.ser.VirtualBeanPropertyWriter;
@@ -160,4 +161,22 @@ public VirtualBeanPropertyWriter virtualPropertyWriterInstance(MapperConfig<?> c
160161
Class<?> implClass) {
161162
return null;
162163
}
164+
165+
/**
166+
* Method called to construct a Filter (any Object with implementation of
167+
* <code>equals(Object)</code> that determines if given value is to be
168+
* excluded (true) or included (false)) to be used based on
169+
* {@link com.fasterxml.jackson.annotation.JsonInclude} annotation (or
170+
* equivalent).
171+
*<p>
172+
* Default implementation returns `null` to indicate that default instantiation
173+
* (use zero-arg constructor of the <code>filterClass</code>) should be
174+
* used.
175+
*
176+
* @since 2.9
177+
*/
178+
public Object includeFilterInstance(SerializationConfig config,
179+
BeanPropertyDefinition forProperty, Class<?> filterClass) {
180+
return null;
181+
}
163182
}

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

+25-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.fasterxml.jackson.databind.*;
1010
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
1111
import com.fasterxml.jackson.databind.introspect.Annotated;
12+
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
1213
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
1314
import com.fasterxml.jackson.databind.jsonschema.SchemaAware;
1415
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
@@ -100,7 +101,8 @@ public DefaultSerializerProvider copy() {
100101
*/
101102

102103
@Override
103-
public JsonSerializer<Object> serializerInstance(Annotated annotated, Object serDef) throws JsonMappingException
104+
public JsonSerializer<Object> serializerInstance(Annotated annotated, Object serDef)
105+
throws JsonMappingException
104106
{
105107
if (serDef == null) {
106108
return null;
@@ -110,11 +112,11 @@ public JsonSerializer<Object> serializerInstance(Annotated annotated, Object ser
110112
if (serDef instanceof JsonSerializer) {
111113
ser = (JsonSerializer<?>) serDef;
112114
} else {
113-
/* Alas, there's no way to force return type of "either class
114-
* X or Y" -- need to throw an exception after the fact
115-
*/
115+
// Alas, there's no way to force return type of "either class
116+
// X or Y" -- need to throw an exception after the fact
116117
if (!(serDef instanceof Class)) {
117-
throw new IllegalStateException("AnnotationIntrospector returned serializer definition of type "
118+
reportBadDefinition(annotated.getType(),
119+
"AnnotationIntrospector returned serializer definition of type "
118120
+serDef.getClass().getName()+"; expected type JsonSerializer or Class<JsonSerializer> instead");
119121
}
120122
Class<?> serClass = (Class<?>)serDef;
@@ -123,7 +125,8 @@ public JsonSerializer<Object> serializerInstance(Annotated annotated, Object ser
123125
return null;
124126
}
125127
if (!JsonSerializer.class.isAssignableFrom(serClass)) {
126-
throw new IllegalStateException("AnnotationIntrospector returned Class "
128+
reportBadDefinition(annotated.getType(),
129+
"AnnotationIntrospector returned Class "
127130
+serClass.getName()+"; expected Class<JsonSerializer>");
128131
}
129132
HandlerInstantiator hi = _config.getHandlerInstantiator();
@@ -136,6 +139,22 @@ public JsonSerializer<Object> serializerInstance(Annotated annotated, Object ser
136139
return (JsonSerializer<Object>) _handleResolvable(ser);
137140
}
138141

142+
@Override
143+
public Object includeFilterInstance(BeanPropertyDefinition forProperty,
144+
Class<?> filterClass)
145+
{
146+
if (filterClass == null) {
147+
return null;
148+
}
149+
HandlerInstantiator hi = _config.getHandlerInstantiator();
150+
Object filter = (hi == null) ? null : hi.includeFilterInstance(_config, forProperty, filterClass);
151+
if (filter == null) {
152+
filter = (JsonSerializer<?>) ClassUtil.createInstance(filterClass,
153+
_config.canOverrideAccessModifiers());
154+
}
155+
return filter;
156+
}
157+
139158
/*
140159
/**********************************************************
141160
/* Object Id handling

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

+17-1
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,28 @@ protected BeanPropertyWriter buildWriter(SerializerProvider prov,
184184
// but possibly also 'empty' values:
185185
valueToSuppress = BeanPropertyWriter.MARKER_FOR_EMPTY;
186186
break;
187+
case CUSTOM: // new with 2.9
188+
valueToSuppress = prov.includeFilterInstance(propDef, inclV.getValueFilter());
189+
if (valueToSuppress == null) { // is this legal?
190+
suppressNulls = true;
191+
} else {
192+
// should let filter decide what to do with nulls:
193+
// But just case, let's handle unexpected (from our perspective) problems explicitly
194+
try {
195+
suppressNulls = valueToSuppress.equals(null);
196+
} catch (Throwable t) {
197+
prov.reportBadDefinition(_beanDesc.getType(),
198+
"Problem determining whether `null` values are to be suppressed: "+t.getMessage(),
199+
t);
200+
}
201+
}
202+
break;
187203
case NON_NULL:
188204
suppressNulls = true;
189205
// fall through
190206
case ALWAYS: // default
191207
default:
192-
// we may still want to suppress empty collections, as per [JACKSON-254]:
208+
// we may still want to suppress empty collections
193209
if (actualType.isContainerType()
194210
&& !_config.isEnabled(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS)) {
195211
valueToSuppress = BeanPropertyWriter.MARKER_FOR_EMPTY;

src/main/java/com/fasterxml/jackson/databind/ser/impl/UnknownSerializer.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType t
6666

6767
protected void failForEmpty(SerializerProvider prov, Object value)
6868
throws JsonMappingException {
69-
prov.reportDefinitionProblem(handledType(), String.format(
69+
prov.reportBadDefinition(handledType(), String.format(
7070
"No serializer found for class %s and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)",
7171
value.getClass().getName()));
7272
}

src/main/java/com/fasterxml/jackson/databind/ser/impl/UnwrappingBeanSerializer.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public void serializeWithType(Object bean, JsonGenerator gen, SerializerProvider
126126
TypeSerializer typeSer) throws IOException
127127
{
128128
if (provider.isEnabled(SerializationFeature.FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS)) {
129-
provider.reportDefinitionProblem(handledType(),
129+
provider.reportBadDefinition(handledType(),
130130
"Unwrapped property requires use of type information: can not serialize without disabling `SerializationFeature.FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS`");
131131
}
132132
gen.setCurrentValue(bean); // [databind#631]

src/main/java/com/fasterxml/jackson/databind/ser/std/StdSerializer.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ protected PropertyFilter findPropertyFilter(SerializerProvider provider,
438438
FilterProvider filters = provider.getFilterProvider();
439439
// Not ok to miss the provider, if a filter is declared to be needed.
440440
if (filters == null) {
441-
provider.reportDefinitionProblem(handledType(),
441+
provider.reportBadDefinition(handledType(),
442442
"Can not resolve PropertyFilter with id '"+filterId+"'; no FilterProvider configured");
443443
}
444444
// But whether unknown ids are ok just depends on filter provider; if we get null that's fine
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.fasterxml.jackson.databind.filter;
2+
3+
import com.fasterxml.jackson.databind.BaseMapTest;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
6+
// Tests for [databind#888]
7+
public class JsonIncludeCustomTest extends BaseMapTest
8+
{
9+
/*
10+
/**********************************************************
11+
/* Test methods
12+
/**********************************************************
13+
*/
14+
15+
final private ObjectMapper MAPPER = new ObjectMapper();
16+
17+
public void testSimpleCustomFilter() throws Exception
18+
{
19+
20+
}
21+
}

src/test/java/com/fasterxml/jackson/databind/filter/JsonIncludeTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ static class EmptyListMapBean
129129

130130
/*
131131
/**********************************************************
132-
/* Unit tests
132+
/* Test methods
133133
/**********************************************************
134134
*/
135135

0 commit comments

Comments
 (0)