Skip to content

Commit 1571c6e

Browse files
committed
refactoring; fix 2 broken tests wrt visibility defaults
1 parent a3601f5 commit 1571c6e

File tree

5 files changed

+258
-207
lines changed

5 files changed

+258
-207
lines changed

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -268,9 +268,8 @@ public VisibilityChecker<?> getDefaultVisibilityChecker() {
268268
vchecker = vchecker.withFieldVisibility(Visibility.NONE);
269269
}
270270
return vchecker;
271-
272271
}
273-
272+
274273
public final PropertyNamingStrategy getPropertyNamingStrategy() {
275274
return _base.getPropertyNamingStrategy();
276275
}

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

+57-61
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@ public interface VisibilityChecker<T extends VisibilityChecker<T>>
2929
public T with(JsonAutoDetect ann);
3030

3131
/**
32-
* Method that can be used for merging default values from given
33-
* source with values from this instance, and either return `this`
34-
* instance (if no changes), or a new instance with applicable defaults.
32+
* Method that can be used for merging default values from `this`
33+
* instance with specified overrides; and either return `this`
34+
* if overrides had no effect (that is, result would be equal),
35+
* or a new instance with merged visibility settings.
3536
*
3637
* @since 2.9
3738
*/
38-
public T withDefaults(VisibilityChecker<?> defaults);
39-
39+
public T withOverrides(JsonAutoDetect.Value vis);
40+
4041
/**
4142
* Builder method that will create and return an instance that has specified
4243
* {@link Visibility} value to use for all property elements.
@@ -149,23 +150,7 @@ public interface VisibilityChecker<T extends VisibilityChecker<T>>
149150
* methods. As a result, type is declared is funky recursive generic
150151
* type, to allow for sub-classing of build methods with property type
151152
* co-variance.
152-
*<p>
153-
* Note on <code>JsonAutoDetect</code> annotation: it is used to
154-
* access default minimum visibility access definitions.
155153
*/
156-
@JsonAutoDetect(
157-
getterVisibility = Visibility.PUBLIC_ONLY,
158-
isGetterVisibility = Visibility.PUBLIC_ONLY,
159-
setterVisibility = Visibility.ANY,
160-
/**
161-
* By default, all matching single-arg constructed are found,
162-
* regardless of visibility. Does not apply to factory methods,
163-
* they can not be auto-detected; ditto for multiple-argument
164-
* constructors.
165-
*/
166-
creatorVisibility = Visibility.ANY,
167-
fieldVisibility = Visibility.PUBLIC_ONLY
168-
)
169154
public static class Std
170155
implements VisibilityChecker<Std>,
171156
java.io.Serializable
@@ -176,7 +161,13 @@ public static class Std
176161
* This is the canonical base instance, configured with default
177162
* visibility values
178163
*/
179-
protected final static Std DEFAULT = new Std(Std.class.getAnnotation(JsonAutoDetect.class));
164+
protected final static Std DEFAULT = new Std(
165+
Visibility.PUBLIC_ONLY, // getter
166+
Visibility.PUBLIC_ONLY, // is-getter
167+
Visibility.ANY, // setter
168+
Visibility.ANY, // creator -- legacy, to support single-arg ctors
169+
Visibility.PUBLIC_ONLY // field
170+
);
180171

181172
protected final Visibility _getterMinLevel;
182173
protected final Visibility _isGetterMinLevel;
@@ -246,44 +237,49 @@ public Std(Visibility v)
246237
/********************************************************
247238
*/
248239

240+
protected Std _with(Visibility g, Visibility isG, Visibility s,
241+
Visibility cr, Visibility f) {
242+
if ((g == _getterMinLevel)
243+
&& (isG == _isGetterMinLevel)
244+
&& (s == _setterMinLevel)
245+
&& (cr == _creatorMinLevel)
246+
&& (f == _fieldMinLevel)
247+
) {
248+
return this;
249+
}
250+
return new Std(g, isG, s, cr, f);
251+
}
252+
249253
@Override
250254
public Std with(JsonAutoDetect ann)
251255
{
252256
Std curr = this;
253257
if (ann != null) {
254-
curr = curr.withGetterVisibility(ann.getterVisibility());
255-
curr = curr.withIsGetterVisibility(ann.isGetterVisibility());
256-
curr = curr.withSetterVisibility(ann.setterVisibility());
257-
curr = curr.withCreatorVisibility(ann.creatorVisibility());
258-
curr = curr.withFieldVisibility(ann.fieldVisibility());
258+
return _with(
259+
_defaultOrOverride(_getterMinLevel, ann.getterVisibility()),
260+
_defaultOrOverride(_isGetterMinLevel, ann.isGetterVisibility()),
261+
_defaultOrOverride(_setterMinLevel, ann.setterVisibility()),
262+
_defaultOrOverride(_creatorMinLevel, ann.creatorVisibility()),
263+
_defaultOrOverride(_fieldMinLevel, ann.fieldVisibility())
264+
);
259265
}
260266
return curr;
261267
}
262268

263-
@Override
264-
public Std withDefaults(VisibilityChecker<?> defaults0)
269+
@Override // since 2.9
270+
public Std withOverrides(JsonAutoDetect.Value vis)
265271
{
266-
if (defaults0 == null) {
267-
return this;
268-
}
269-
// !!! 25-Nov-2016, tatu: not optimal, but without generic access
270-
// best we can do. Plan is to rewrite the whole thing for 3.x
271-
Std defaults = (Std) defaults0;
272-
Visibility getterMin = _defaultOrOverride(defaults._getterMinLevel, _getterMinLevel);
273-
Visibility isGetterMin = _defaultOrOverride(defaults._isGetterMinLevel, _isGetterMinLevel);
274-
Visibility setterMin = _defaultOrOverride(defaults._setterMinLevel, _setterMinLevel);
275-
Visibility creatorMin = _defaultOrOverride(defaults._creatorMinLevel, _creatorMinLevel);
276-
Visibility fieldMin = _defaultOrOverride(defaults._fieldMinLevel, _fieldMinLevel);
277-
278-
if ((getterMin == _getterMinLevel)
279-
&& (isGetterMin == _isGetterMinLevel)
280-
&& (setterMin == _setterMinLevel)
281-
&& (creatorMin == _creatorMinLevel)
282-
&& (fieldMin == _fieldMinLevel)
283-
) {
284-
return this;
272+
Std curr = this;
273+
if (vis != null) {
274+
return _with(
275+
_defaultOrOverride(_getterMinLevel, vis.getGetterVisibility()),
276+
_defaultOrOverride(_isGetterMinLevel, vis.getIsGetterVisibility()),
277+
_defaultOrOverride(_setterMinLevel, vis.getSetterVisibility()),
278+
_defaultOrOverride(_creatorMinLevel, vis.getCreatorVisibility()),
279+
_defaultOrOverride(_fieldMinLevel, vis.getFieldVisibility())
280+
);
285281
}
286-
return new Std(getterMin, isGetterMin, setterMin, creatorMin, fieldMin);
282+
return curr;
287283
}
288284

289285
private Visibility _defaultOrOverride(Visibility defaults, Visibility override) {
@@ -292,7 +288,7 @@ private Visibility _defaultOrOverride(Visibility defaults, Visibility override)
292288
}
293289
return override;
294290
}
295-
291+
296292
@Override
297293
public Std with(Visibility v)
298294
{
@@ -327,39 +323,39 @@ public Std withVisibility(PropertyAccessor method, Visibility v)
327323

328324
@Override
329325
public Std withGetterVisibility(Visibility v) {
330-
if (v == Visibility.DEFAULT) v = DEFAULT._getterMinLevel;
326+
if (v == Visibility.DEFAULT) v = DEFAULT._getterMinLevel;
331327
if (_getterMinLevel == v) return this;
332328
return new Std(v, _isGetterMinLevel, _setterMinLevel, _creatorMinLevel, _fieldMinLevel);
333329
}
334330

335331
@Override
336332
public Std withIsGetterVisibility(Visibility v) {
337-
if (v == Visibility.DEFAULT) v = DEFAULT._isGetterMinLevel;
333+
if (v == Visibility.DEFAULT) v = DEFAULT._isGetterMinLevel;
338334
if (_isGetterMinLevel == v) return this;
339335
return new Std(_getterMinLevel, v, _setterMinLevel, _creatorMinLevel, _fieldMinLevel);
340336
}
341337

342338
@Override
343339
public Std withSetterVisibility(Visibility v) {
344-
if (v == Visibility.DEFAULT) v = DEFAULT._setterMinLevel;
340+
if (v == Visibility.DEFAULT) v = DEFAULT._setterMinLevel;
345341
if (_setterMinLevel == v) return this;
346342
return new Std(_getterMinLevel, _isGetterMinLevel, v, _creatorMinLevel, _fieldMinLevel);
347343
}
348-
344+
349345
@Override
350346
public Std withCreatorVisibility(Visibility v) {
351-
if (v == Visibility.DEFAULT) v = DEFAULT._creatorMinLevel;
347+
if (v == Visibility.DEFAULT) v = DEFAULT._creatorMinLevel;
352348
if (_creatorMinLevel == v) return this;
353349
return new Std(_getterMinLevel, _isGetterMinLevel, _setterMinLevel, v, _fieldMinLevel);
354350
}
355-
351+
356352
@Override
357353
public Std withFieldVisibility(Visibility v) {
358354
if (v == Visibility.DEFAULT) v = DEFAULT._fieldMinLevel;
359355
if (_fieldMinLevel == v) return this;
360356
return new Std(_getterMinLevel, _isGetterMinLevel, _setterMinLevel, _creatorMinLevel, v);
361357
}
362-
358+
363359
/*
364360
/********************************************************
365361
/* Public API impl
@@ -370,7 +366,7 @@ public Std withFieldVisibility(Visibility v) {
370366
public boolean isCreatorVisible(Member m) {
371367
return _creatorMinLevel.isVisible(m);
372368
}
373-
369+
374370
@Override
375371
public boolean isCreatorVisible(AnnotatedMember m) {
376372
return isCreatorVisible(m.getMember());
@@ -380,17 +376,17 @@ public boolean isCreatorVisible(AnnotatedMember m) {
380376
public boolean isFieldVisible(Field f) {
381377
return _fieldMinLevel.isVisible(f);
382378
}
383-
379+
384380
@Override
385381
public boolean isFieldVisible(AnnotatedField f) {
386382
return isFieldVisible(f.getAnnotated());
387383
}
388-
384+
389385
@Override
390386
public boolean isGetterVisible(Method m) {
391387
return _getterMinLevel.isVisible(m);
392388
}
393-
389+
394390
@Override
395391
public boolean isGetterVisible(AnnotatedMethod m) {
396392
return isGetterVisible(m.getAnnotated());

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

+40-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.fasterxml.jackson.databind.introspect;
22

33
import com.fasterxml.jackson.annotation.*;
4-
4+
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
55
import com.fasterxml.jackson.core.*;
66
import com.fasterxml.jackson.databind.*;
77
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
@@ -16,13 +16,33 @@ private PrivateBean() { }
1616

1717
private PrivateBean(String a) { this.a = a; }
1818
}
19-
19+
20+
// test for [databind#1347], config overrides for visibility
21+
@JsonPropertyOrder(alphabetic=true)
22+
static class Feature1347SerBean {
23+
public int field = 2;
24+
25+
public int getValue() { return 3; }
26+
}
27+
28+
// let's promote use of fields; but not block setters yet
29+
@JsonAutoDetect(fieldVisibility=Visibility.NON_PRIVATE)
30+
static class Feature1347DeserBean {
31+
int value;
32+
33+
public void setValue(int x) {
34+
throw new RuntimeException("Should NOT get called");
35+
}
36+
}
37+
2038
/*
2139
/********************************************************
2240
/* Unit tests
2341
/********************************************************
2442
*/
25-
43+
44+
private final ObjectMapper MAPPER = new ObjectMapper();
45+
2646
public void testPrivateCtor() throws Exception
2747
{
2848
// first, default settings, with which construction works ok
@@ -43,4 +63,21 @@ public void testPrivateCtor() throws Exception
4363
}
4464
}
4565

66+
// [databind#1347]
67+
public void testVisibilityConfigOverridesForSer() throws Exception
68+
{
69+
// first, by default, both field/method should be visible
70+
String json = MAPPER.writeValueAsString(new Feature1347SerBean());
71+
assertEquals(aposToQuotes("{'field':2,'value':3}"), json);
72+
73+
ObjectMapper mapper = new ObjectMapper();
74+
mapper.configOverride(Feature1347SerBean.class)
75+
// !!! TODO
76+
;
77+
}
78+
79+
// [databind#1347]
80+
public void testVisibilityConfigOverridesForDeser() throws Exception
81+
{
82+
}
4683
}

0 commit comments

Comments
 (0)