Skip to content

Commit d121d96

Browse files
committed
Fixed #1347
1 parent c0ceefd commit d121d96

File tree

10 files changed

+151
-66
lines changed

10 files changed

+151
-66
lines changed

release-notes/VERSION

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Project: jackson-databind
2121
(proposed by Jan L)
2222
#1341: `DeserializationFeature.FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY`
2323
(contributed by Connor K)
24+
#1347: Extend `ObjectMapper.configOverrides()` to allow changing visibility rules
2425
#1356: Differentiate between input and code exceptions on deserialization
2526
(suggested by Nick B)
2627
#1369: Improve `@JsonCreator` detection via `AnnotationIntrospector`

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

+12-11
Original file line numberDiff line numberDiff line change
@@ -1207,19 +1207,12 @@ public VisibilityChecker<?> getVisibilityChecker() {
12071207
}
12081208

12091209
/**
1210-
* @deprecated Since 2.6 use {@link #setVisibility(VisibilityChecker)} instead.
1211-
*/
1212-
@Deprecated
1213-
public void setVisibilityChecker(VisibilityChecker<?> vc) {
1214-
setVisibility(vc);
1215-
}
1216-
1217-
/**
1218-
* Method for setting currently configured {@link VisibilityChecker},
1210+
* Method for setting currently configured default {@link VisibilityChecker},
12191211
* object used for determining whether given property element
12201212
* (method, field, constructor) can be auto-detected or not.
1221-
* This default checker is used if no per-class overrides
1222-
* are defined.
1213+
* This default checker is used as the base visibility:
1214+
* per-class overrides (both via annotations and per-type config overrides)
1215+
* can further change these settings.
12231216
*
12241217
* @since 2.6
12251218
*/
@@ -1347,6 +1340,14 @@ public ObjectMapper setDefaultPrettyPrinter(PrettyPrinter pp) {
13471340
return this;
13481341
}
13491342

1343+
/**
1344+
* @deprecated Since 2.6 use {@link #setVisibility(VisibilityChecker)} instead.
1345+
*/
1346+
@Deprecated
1347+
public void setVisibilityChecker(VisibilityChecker<?> vc) {
1348+
setVisibility(vc);
1349+
}
1350+
13501351
/*
13511352
/**********************************************************
13521353
/* Configuration: global-default/per-type override settings

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

+13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.fasterxml.jackson.databind.cfg;
22

3+
import com.fasterxml.jackson.annotation.JsonAutoDetect;
34
import com.fasterxml.jackson.annotation.JsonFormat;
45
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
56
import com.fasterxml.jackson.annotation.JsonInclude;
@@ -39,6 +40,13 @@ public abstract class ConfigOverride
3940
*/
4041
protected JsonSetter.Value _setterInfo;
4142

43+
/**
44+
* Overrides for auto-detection visibility rules for this type.
45+
*
46+
* @since 2.9
47+
*/
48+
protected JsonAutoDetect.Value _visibility;
49+
4250
/**
4351
* Flag that indicates whether "is ignorable type" is specified for this type;
4452
* and if so, is it to be ignored (true) or not ignored (false); `null` is
@@ -72,6 +80,11 @@ public static ConfigOverride empty() {
7280
*/
7381
public JsonSetter.Value getSetterInfo() { return _setterInfo; }
7482

83+
/**
84+
* @since 2.9
85+
*/
86+
public JsonAutoDetect.Value getVisibility() { return _visibility; }
87+
7588
public JsonIgnoreProperties.Value getIgnorals() { return _ignorals; }
7689

7790
public Boolean getIsIgnoredType() {

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

+25-12
Original file line numberDiff line numberDiff line change
@@ -239,17 +239,6 @@ public AnnotationIntrospector getAnnotationIntrospector() {
239239
return NopAnnotationIntrospector.instance;
240240
}
241241

242-
/**
243-
* Accessor for object used for determining whether specific property elements
244-
* (method, constructors, fields) can be auto-detected based on
245-
* their visibility (access modifiers). Can be changed to allow
246-
* different minimum visibility levels for auto-detection. Note
247-
* that this is the global handler; individual types (classes)
248-
* can further override active checker used (using
249-
* {@link JsonAutoDetect} annotation)
250-
*/
251-
public abstract VisibilityChecker<?> getDefaultVisibilityChecker();
252-
253242
public final PropertyNamingStrategy getPropertyNamingStrategy() {
254243
return _base.getPropertyNamingStrategy();
255244
}
@@ -380,7 +369,7 @@ public final BeanDescription introspectDirectClassAnnotations(JavaType type) {
380369
* @return Override object to use for the type, never null (but may be empty)
381370
*/
382371
public abstract ConfigOverride getConfigOverride(Class<?> type);
383-
372+
384373
/**
385374
* Accessor for default property inclusion to use for serialization,
386375
* used unless overridden by per-type or per-property overrides.
@@ -446,6 +435,30 @@ public JsonInclude.Value getDefaultPropertyInclusion(Class<?> baseType,
446435
public abstract JsonIgnoreProperties.Value getDefaultPropertyIgnorals(Class<?> baseType,
447436
AnnotatedClass actualClass);
448437

438+
/**
439+
* Accessor for object used for determining whether specific property elements
440+
* (method, constructors, fields) can be auto-detected based on
441+
* their visibility (access modifiers). Can be changed to allow
442+
* different minimum visibility levels for auto-detection. Note
443+
* that this is the global handler; individual types (classes)
444+
* can further override active checker used (using
445+
* {@link JsonAutoDetect} annotation)
446+
*/
447+
public abstract VisibilityChecker<?> getDefaultVisibilityChecker();
448+
449+
/**
450+
* Accessor for object used for determining whether specific property elements
451+
* (method, constructors, fields) can be auto-detected based on
452+
* their visibility (access modifiers). This is based on global defaults
453+
* (as would be returned by {@link #getDefaultVisibilityChecker()}, but
454+
* then modified by possible class annotation (see {@link JsonAutoDetect})
455+
* and/or per-type config override (see {@link ConfigOverride#getVisibility()}).
456+
*
457+
* @since 2.9
458+
*/
459+
public abstract VisibilityChecker<?> getDefaultVisibilityChecker(Class<?> baseType,
460+
AnnotatedClass actualClass);
461+
449462
/**
450463
* Accessor for the baseline setter info used as the global baseline,
451464
* not considering possible per-type overrides.

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

+52-24
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@ public abstract class MapperConfigBase<CFG extends ConfigFeature,
3131

3232
private final static int DEFAULT_MAPPER_FEATURES = collectFeatureDefaults(MapperFeature.class);
3333

34+
/**
35+
* @since 2.9
36+
*/
37+
private final static int AUTO_DETECT_MASK =
38+
MapperFeature.AUTO_DETECT_FIELDS.getMask()
39+
| MapperFeature.AUTO_DETECT_GETTERS.getMask()
40+
| MapperFeature.AUTO_DETECT_IS_GETTERS.getMask()
41+
| MapperFeature.AUTO_DETECT_SETTERS.getMask()
42+
| MapperFeature.AUTO_DETECT_CREATORS.getMask()
43+
;
44+
3445
/*
3546
/**********************************************************
3647
/* Immutable config
@@ -576,29 +587,6 @@ public final ContextAttributes getAttributes() {
576587
return _attributes;
577588
}
578589

579-
@Override
580-
public VisibilityChecker<?> getDefaultVisibilityChecker()
581-
{
582-
VisibilityChecker<?> vchecker = _configOverrides.getDefaultVisibility();
583-
// then global overrides (disabling)
584-
if (!isEnabled(MapperFeature.AUTO_DETECT_SETTERS)) {
585-
vchecker = vchecker.withSetterVisibility(Visibility.NONE);
586-
}
587-
if (!isEnabled(MapperFeature.AUTO_DETECT_CREATORS)) {
588-
vchecker = vchecker.withCreatorVisibility(Visibility.NONE);
589-
}
590-
if (!isEnabled(MapperFeature.AUTO_DETECT_GETTERS)) {
591-
vchecker = vchecker.withGetterVisibility(Visibility.NONE);
592-
}
593-
if (!isEnabled(MapperFeature.AUTO_DETECT_IS_GETTERS)) {
594-
vchecker = vchecker.withIsGetterVisibility(Visibility.NONE);
595-
}
596-
if (!isEnabled(MapperFeature.AUTO_DETECT_FIELDS)) {
597-
vchecker = vchecker.withFieldVisibility(Visibility.NONE);
598-
}
599-
return vchecker;
600-
}
601-
602590
/*
603591
/**********************************************************
604592
/* Configuration access; default/overrides
@@ -669,7 +657,47 @@ public final JsonIgnoreProperties.Value getDefaultPropertyIgnorals(Class<?> base
669657
}
670658

671659
@Override
672-
public JsonSetter.Value getDefaultSetterInfo() {
660+
public final VisibilityChecker<?> getDefaultVisibilityChecker()
661+
{
662+
VisibilityChecker<?> vchecker = _configOverrides.getDefaultVisibility();
663+
// then global overrides (disabling)
664+
if ((_mapperFeatures & AUTO_DETECT_MASK) != 0) {
665+
if (!isEnabled(MapperFeature.AUTO_DETECT_FIELDS)) {
666+
vchecker = vchecker.withFieldVisibility(Visibility.NONE);
667+
}
668+
if (!isEnabled(MapperFeature.AUTO_DETECT_GETTERS)) {
669+
vchecker = vchecker.withGetterVisibility(Visibility.NONE);
670+
}
671+
if (!isEnabled(MapperFeature.AUTO_DETECT_IS_GETTERS)) {
672+
vchecker = vchecker.withIsGetterVisibility(Visibility.NONE);
673+
}
674+
if (!isEnabled(MapperFeature.AUTO_DETECT_SETTERS)) {
675+
vchecker = vchecker.withSetterVisibility(Visibility.NONE);
676+
}
677+
if (!isEnabled(MapperFeature.AUTO_DETECT_CREATORS)) {
678+
vchecker = vchecker.withCreatorVisibility(Visibility.NONE);
679+
}
680+
}
681+
return vchecker;
682+
}
683+
684+
@Override // since 2.9
685+
public final VisibilityChecker<?> getDefaultVisibilityChecker(Class<?> baseType,
686+
AnnotatedClass actualClass) {
687+
VisibilityChecker<?> vc = getDefaultVisibilityChecker();
688+
AnnotationIntrospector intr = getAnnotationIntrospector();
689+
if (intr != null) {
690+
vc = intr.findAutoDetectVisibility(actualClass, vc);
691+
}
692+
ConfigOverride overrides = _configOverrides.findOverride(baseType);
693+
if (overrides != null) {
694+
vc = vc.withOverrides(overrides.getVisibility()); // ok to pass null
695+
}
696+
return vc;
697+
}
698+
699+
@Override
700+
public final JsonSetter.Value getDefaultSetterInfo() {
673701
return _configOverrides.getDefaultSetterInfo();
674702
}
675703

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

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.fasterxml.jackson.databind.cfg;
22

3+
import com.fasterxml.jackson.annotation.JsonAutoDetect;
34
import com.fasterxml.jackson.annotation.JsonFormat;
45
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
56
import com.fasterxml.jackson.annotation.JsonInclude;
@@ -40,11 +41,6 @@ public MutableConfigOverride setInclude(JsonInclude.Value v) {
4041
return this;
4142
}
4243

43-
public MutableConfigOverride setSetterInfo(JsonSetter.Value v) {
44-
_setterInfo = v;
45-
return this;
46-
}
47-
4844
public MutableConfigOverride setIgnorals(JsonIgnoreProperties.Value v) {
4945
_ignorals = v;
5046
return this;
@@ -54,4 +50,20 @@ public MutableConfigOverride setIsIgnoredType(Boolean v) {
5450
_isIgnoredType = v;
5551
return this;
5652
}
53+
54+
/**
55+
* @since 2.9
56+
*/
57+
public MutableConfigOverride setSetterInfo(JsonSetter.Value v) {
58+
_setterInfo = v;
59+
return this;
60+
}
61+
62+
/**
63+
* @since 2.9
64+
*/
65+
public MutableConfigOverride setVisibility(JsonAutoDetect.Value v) {
66+
_visibility = v;
67+
return this;
68+
}
5769
}

src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,8 @@ protected ValueInstantiator _constructDefaultValueInstantiator(DeserializationCo
299299

300300
// need to construct suitable visibility checker:
301301
final DeserializationConfig config = ctxt.getConfig();
302-
VisibilityChecker<?> vchecker = config.getDefaultVisibilityChecker();
303-
vchecker = intr.findAutoDetectVisibility(beanDesc.getClassInfo(), vchecker);
302+
VisibilityChecker<?> vchecker = config.getDefaultVisibilityChecker(beanDesc.getBeanClass(),
303+
beanDesc.getClassInfo());
304304

305305
/* 24-Sep-2014, tatu: Tricky part first; need to merge resolved property information
306306
* (which has creator parameters sprinkled around) with actual creator

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

+2-6
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,8 @@ protected POJOPropertiesCollector(MapperConfig<?> config, boolean forSerializati
125125
_mutatorPrefix = (mutatorPrefix == null) ? "set" : mutatorPrefix;
126126
_annotationIntrospector = config.isAnnotationProcessingEnabled() ?
127127
_config.getAnnotationIntrospector() : null;
128-
if (_annotationIntrospector == null) {
129-
_visibilityChecker = _config.getDefaultVisibilityChecker();
130-
} else {
131-
_visibilityChecker = _annotationIntrospector.findAutoDetectVisibility(classDef,
132-
_config.getDefaultVisibilityChecker());
133-
}
128+
_visibilityChecker = _config.getDefaultVisibilityChecker(type.getRawClass(),
129+
classDef);
134130
}
135131

136132
/*

src/test/java/com/fasterxml/jackson/databind/deser/jdk/BaseDecodingTest.java renamed to src/test/java/com/fasterxml/jackson/databind/deser/jdk/Base64DecodingTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
// Mostly for [databind#1425]; not in optimal place (as it also has
99
// tree-access tests), but has to do for now
10-
public class BaseDecodingTest extends BaseMapTest
10+
public class Base64DecodingTest extends BaseMapTest
1111
{
1212
private final ObjectMapper MAPPER = objectMapper();
1313

src/test/java/com/fasterxml/jackson/databind/introspect/TestAutoDetect.java

+26-5
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ static class Feature1347DeserBean {
3131
int value;
3232

3333
public void setValue(int x) {
34-
throw new RuntimeException("Should NOT get called");
34+
throw new IllegalArgumentException("Should NOT get called");
3535
}
3636
}
3737

@@ -67,17 +67,38 @@ public void testPrivateCtor() throws Exception
6767
public void testVisibilityConfigOverridesForSer() throws Exception
6868
{
6969
// first, by default, both field/method should be visible
70-
String json = MAPPER.writeValueAsString(new Feature1347SerBean());
71-
assertEquals(aposToQuotes("{'field':2,'value':3}"), json);
70+
final Feature1347SerBean input = new Feature1347SerBean();
71+
assertEquals(aposToQuotes("{'field':2,'value':3}"),
72+
MAPPER.writeValueAsString(input));
7273

7374
ObjectMapper mapper = new ObjectMapper();
7475
mapper.configOverride(Feature1347SerBean.class)
75-
// !!! TODO
76-
;
76+
.setVisibility(JsonAutoDetect.Value.construct(PropertyAccessor.GETTER,
77+
Visibility.NONE));
78+
assertEquals(aposToQuotes("{'field':2}"),
79+
mapper.writeValueAsString(input));
7780
}
7881

7982
// [databind#1347]
8083
public void testVisibilityConfigOverridesForDeser() throws Exception
8184
{
85+
final String JSON = aposToQuotes("{'value':3}");
86+
87+
// by default, should throw exception
88+
try {
89+
/*Feature1347DeserBean bean =*/
90+
MAPPER.readValue(JSON, Feature1347DeserBean.class);
91+
fail("Should not pass");
92+
} catch (JsonMappingException e) {
93+
verifyException(e, "Should NOT get called");
94+
}
95+
96+
// but when instructed to ignore setter, should work
97+
ObjectMapper mapper = new ObjectMapper();
98+
mapper.configOverride(Feature1347DeserBean.class)
99+
.setVisibility(JsonAutoDetect.Value.construct(PropertyAccessor.SETTER,
100+
Visibility.NONE));
101+
Feature1347DeserBean result = mapper.readValue(JSON, Feature1347DeserBean.class);
102+
assertEquals(3, result.value);
82103
}
83104
}

0 commit comments

Comments
 (0)