Skip to content

Commit 58cd0eb

Browse files
authored
PR for using @JsonApplyView (#5745) (#5754)
1 parent 15b34c5 commit 58cd0eb

8 files changed

Lines changed: 307 additions & 17 deletions

File tree

release-notes/CREDITS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,10 @@ Martin Uhlen (@MartinUhlen)
496496
absent field same as explicit `null`
497497
[3.2.0]
498498

499+
Frederic Aubert (@f-aubert)
500+
* Contributed #5745: Ability to change active JsonView on submodels (with `@JsonApplyView`)
501+
[3.2.0]
502+
499503
David Nelson (@eatdrinksleepcode)
500504
* Reported #5814: Enum deserialization does not respect
501505
`JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_VALUES` override

release-notes/VERSION

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ Versions: 3.x (for earlier see VERSION-2.x)
180180
#5734: `DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES` treats
181181
absent field same as explicit `null`
182182
(reported by Martin U)
183+
#5745: Ability to change active JsonView on submodels (with `@JsonApplyView`)
184+
(contributed by Frederic A)
183185
#5821: Fix dead code and side-effect bug in `BeanPropertyWriter.toString()`
184186
(fix by @pjfanning)
185187
#5851: Regression of `JsonTypeInfo.Id.MINIMAL_CLASS` in the 3.x branch

src/main/java/tools/jackson/databind/introspect/AnnotationIntrospectorPair.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,6 @@ public Class<?>[] findViews(MapperConfig<?> config, Annotated a) {
380380
@Override
381381
public Class<?> findApplyView(MapperConfig<?> config, Annotated a)
382382
{
383-
/* Theoretically this could be trickier, if multiple introspectors
384-
* return non-null entries. For now, though, we'll just consider
385-
* first one to return non-null to win.
386-
*/
387383
Class<?> result = _primary.findApplyView(config, a);
388384
if (result == null) {
389385
result = _secondary.findApplyView(config, a);

src/main/java/tools/jackson/databind/introspect/BeanPropertyDefinition.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,23 @@ public AnnotatedMember getNonConstructorMutator() {
241241
*/
242242
public Class<?>[] findViews() { return null; }
243243

244+
/**
245+
* Method used to find an override view that should be activated when
246+
* processing this property's value (and any nested values reached through
247+
* it), as configured by {@code @JsonApplyView}.
248+
*<p>
249+
* Unlike {@link #findViews()} (which lists views in which the property
250+
* itself is included), this returns the view to make active while the
251+
* value is being serialized. Special marker
252+
* {@code JsonApplyView.NONE} indicates that view processing should be
253+
* disabled (active view set to {@code null}) for the property and its subtree.
254+
*
255+
* @return Override view to apply, or {@code null} if no override is configured
256+
*
257+
* @since 3.2
258+
*/
259+
public Class<?> findApplyView() { return null; }
260+
244261
/**
245262
* Method used to find whether property is part of a bi-directional
246263
* reference.

src/main/java/tools/jackson/databind/introspect/POJOPropertyBuilder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,11 @@ public Class<?>[] findViews() {
826826
return _annotationIntrospector.findViews(_config, getPrimaryMember());
827827
}
828828

829+
@Override
830+
public Class<?> findApplyView() {
831+
return _annotationIntrospector.findApplyView(_config, getPrimaryMember());
832+
}
833+
829834
@Override
830835
public AnnotationIntrospector.ReferenceProperty findReferenceType() {
831836
// 30-Mar-2017, tatu: Access lazily but retain information since it needs

src/main/java/tools/jackson/databind/ser/BeanPropertyWriter.java

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.lang.reflect.Field;
77
import java.util.HashMap;
88

9+
import com.fasterxml.jackson.annotation.JsonApplyView;
910
import com.fasterxml.jackson.annotation.JsonInclude;
1011

1112
import tools.jackson.core.JacksonException;
@@ -177,6 +178,13 @@ public class BeanPropertyWriter
177178
*/
178179
protected final Class<?>[] _includeInViews;
179180

181+
/**
182+
* View to apply for this property when applyView is available for the Bean.
183+
*
184+
* @since 3.2
185+
*/
186+
protected final Class<?> _applyView;
187+
180188
/**
181189
* Inclusion settings for this property, pre-computed in {@code PropertyBuilder}
182190
* by merging global defaults, type defaults, and property-level annotations,
@@ -214,21 +222,39 @@ public BeanPropertyWriter(BeanPropertyDefinition propDef,
214222
{
215223
this(propDef, member, contextAnnotations, declaredType,
216224
ser, typeSer, serType, suppressNulls, suppressableValue,
217-
includeInViews, null);
225+
includeInViews, null, null);
226+
}
227+
228+
/**
229+
* @deprecated Since 3.2 use {@link #BeanPropertyWriter(BeanPropertyDefinition,
230+
* AnnotatedMember, Annotations, JavaType, ValueSerializer, TypeSerializer,
231+
* JavaType, boolean, Object, Class[], JsonInclude.Value, Class)} instead.
232+
*/
233+
@Deprecated // @since 3.2
234+
public BeanPropertyWriter(BeanPropertyDefinition propDef,
235+
AnnotatedMember member, Annotations contextAnnotations,
236+
JavaType declaredType,
237+
ValueSerializer<?> ser, TypeSerializer typeSer, JavaType serType,
238+
boolean suppressNulls, Object suppressableValue,
239+
Class<?>[] includeInViews, JsonInclude.Value inclusion)
240+
{
241+
this(propDef, member, contextAnnotations, declaredType,
242+
ser, typeSer, serType, suppressNulls, suppressableValue,
243+
includeInViews, inclusion, null);
218244
}
219245

220246
/**
221-
* Constructor with additional inclusion parameter.
247+
* Constructor with additional inclusion and applyView parameter.
222248
*
223-
* @since 3.1
249+
* @since 3.2
224250
*/
225251
@SuppressWarnings("unchecked")
226252
public BeanPropertyWriter(BeanPropertyDefinition propDef,
227253
AnnotatedMember member, Annotations contextAnnotations,
228254
JavaType declaredType,
229255
ValueSerializer<?> ser, TypeSerializer typeSer, JavaType serType,
230256
boolean suppressNulls, Object suppressableValue,
231-
Class<?>[] includeInViews, JsonInclude.Value inclusion)
257+
Class<?>[] includeInViews, JsonInclude.Value inclusion, Class<?> applyView)
232258
{
233259
super(propDef);
234260
_member = member;
@@ -260,6 +286,7 @@ public BeanPropertyWriter(BeanPropertyDefinition propDef,
260286
// this will be resolved later on, unless nulls are to be suppressed
261287
_nullSerializer = null;
262288
_includeInViews = includeInViews;
289+
_applyView = applyView;
263290
_inclusion = (inclusion == null) ? JsonInclude.Value.empty() : inclusion;
264291
}
265292

@@ -276,6 +303,7 @@ protected BeanPropertyWriter() {
276303
_name = null;
277304
_wrapperName = null;
278305
_includeInViews = null;
306+
_applyView = null;
279307

280308
_declaredType = null;
281309
_serializer = null;
@@ -323,6 +351,7 @@ protected BeanPropertyWriter(BeanPropertyWriter base, PropertyName name) {
323351
_suppressNulls = base._suppressNulls;
324352
_suppressableValue = base._suppressableValue;
325353
_includeInViews = base._includeInViews;
354+
_applyView = base._applyView;
326355
_typeSerializer = base._typeSerializer;
327356
_nonTrivialBaseType = base._nonTrivialBaseType;
328357
_inclusion = base._inclusion;
@@ -347,6 +376,7 @@ protected BeanPropertyWriter(BeanPropertyWriter base, SerializedString name) {
347376
_suppressNulls = base._suppressNulls;
348377
_suppressableValue = base._suppressableValue;
349378
_includeInViews = base._includeInViews;
379+
_applyView = base._applyView;
350380
_typeSerializer = base._typeSerializer;
351381
_nonTrivialBaseType = base._nonTrivialBaseType;
352382
_inclusion = base._inclusion;
@@ -660,10 +690,12 @@ public void serializeAsProperty(Object bean, JsonGenerator g, SerializationConte
660690
}
661691
}
662692
g.writeName(_name);
663-
if (_typeSerializer == null) {
664-
ser.serialize(value, g, ctxt);
693+
if (_applyView == null) {
694+
_serialize(value, g, ctxt, ser);
665695
} else {
666-
ser.serializeWithType(value, g, ctxt, _typeSerializer);
696+
ValueSerializer<Object> actualSer = ser;
697+
ctxt.withActiveView(_applyView != JsonApplyView.NONE.class ? _applyView : null,
698+
() -> _serialize(value, g, ctxt, actualSer));
667699
}
668700
}
669701

@@ -728,10 +760,13 @@ public void serializeAsElement(Object bean, JsonGenerator g, SerializationContex
728760
return;
729761
}
730762
}
731-
if (_typeSerializer == null) {
732-
ser.serialize(value, g, ctxt);
763+
764+
if (_applyView == null) {
765+
_serialize(value, g, ctxt, ser);
733766
} else {
734-
ser.serializeWithType(value, g, ctxt, _typeSerializer);
767+
ValueSerializer<Object> actualSer = ser;
768+
ctxt.withActiveView(_applyView != JsonApplyView.NONE.class ? _applyView : null,
769+
() -> _serialize(value, g, ctxt, actualSer));
735770
}
736771
}
737772

@@ -753,6 +788,16 @@ public void serializeAsOmittedElement(Object bean, JsonGenerator g,
753788
}
754789
}
755790

791+
// @since 3.2
792+
private void _serialize(Object value, JsonGenerator g, SerializationContext ctxt,
793+
ValueSerializer<Object> ser) {
794+
if (_typeSerializer == null) {
795+
ser.serialize(value, g, ctxt);
796+
} else {
797+
ser.serializeWithType(value, g, ctxt, _typeSerializer);
798+
}
799+
}
800+
756801
/*
757802
/**********************************************************************
758803
/* PropertyWriter methods (schema generation)

src/main/java/tools/jackson/databind/ser/PropertyBuilder.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,13 +246,15 @@ protected BeanPropertyWriter buildWriter(SerializationContext ctxt,
246246
if (views == null) {
247247
views = _beanDesc.findDefaultViews();
248248
}
249+
Class<?> applyView = propDef.findApplyView();
250+
249251
// [databind#1649]: Pass the computed inclusion value (which includes
250252
// contextual annotations) so BeanPropertyWriter can use it directly
251253
// instead of re-computing in findPropertyInclusion()
252254
BeanPropertyWriter bpw = _constructPropertyWriter(propDef,
253255
am, _beanDesc.getClassAnnotations(), declaredType,
254256
ser, typeSer, serializationType, suppressNulls, valueToSuppress, views,
255-
inclV);
257+
inclV, applyView);
256258

257259
// How about custom null serializer?
258260
Object serDef = _annotationIntrospector.findNullSerializer(_config, am);
@@ -285,12 +287,12 @@ protected BeanPropertyWriter _constructPropertyWriter(BeanPropertyDefinition pro
285287
JavaType declaredType,
286288
ValueSerializer<?> ser, TypeSerializer typeSer, JavaType serType,
287289
boolean suppressNulls, Object suppressableValue,
288-
Class<?>[] includeInViews, JsonInclude.Value inclusion)
290+
Class<?>[] includeInViews, JsonInclude.Value inclusion, Class<?> applyView)
289291
{
290292
return new BeanPropertyWriter(propDef,
291293
member, contextAnnotations, declaredType,
292294
ser, typeSer, serType, suppressNulls, suppressableValue, includeInViews,
293-
inclusion);
295+
inclusion, applyView);
294296
}
295297

296298
/*

0 commit comments

Comments
 (0)