1
1
package com .fasterxml .jackson .databind .introspect ;
2
2
3
+ import java .util .HashSet ;
4
+ import java .util .Set ;
5
+
3
6
import com .fasterxml .jackson .databind .AnnotationIntrospector ;
4
7
import com .fasterxml .jackson .databind .BeanDescription ;
5
8
import com .fasterxml .jackson .databind .MapperFeature ;
6
9
import com .fasterxml .jackson .databind .annotation .JsonPOJOBuilder ;
7
10
import com .fasterxml .jackson .databind .cfg .MapperConfig ;
11
+ import com .fasterxml .jackson .databind .jdk14 .JDK14Util ;
8
12
9
13
/**
10
14
* Default {@link AccessorNamingStrategy} used by Jackson: to be used either as-is,
@@ -20,19 +24,23 @@ public class DefaultAccessorNamingStrategy
20
24
21
25
protected final boolean _stdBeanNaming ;
22
26
27
+ protected final String _getterPrefix ;
28
+
23
29
/**
24
30
* Prefix used by auto-detected mutators ("setters"): usually "set",
25
31
* but differs for builder objects ("with" by default).
26
32
*/
27
33
protected final String _mutatorPrefix ;
28
34
29
35
protected DefaultAccessorNamingStrategy (MapperConfig <?> config , AnnotatedClass forClass ,
30
- String mutatorPrefix ) {
36
+ String mutatorPrefix , String getterPrefix )
37
+ {
31
38
_config = config ;
32
39
_forClass = forClass ;
33
40
34
41
_stdBeanNaming = config .isEnabled (MapperFeature .USE_STD_BEAN_NAMING );
35
42
_mutatorPrefix = mutatorPrefix ;
43
+ _getterPrefix = getterPrefix ;
36
44
}
37
45
38
46
@ Override
@@ -52,7 +60,7 @@ public String findNameForIsGetter(AnnotatedMethod am, String name)
52
60
@ Override
53
61
public String findNameForRegularGetter (AnnotatedMethod am , String name )
54
62
{
55
- if (name .startsWith ("get" )) {
63
+ if (( _getterPrefix != null ) && name .startsWith (_getterPrefix )) {
56
64
// 16-Feb-2009, tatu: To handle [JACKSON-53], need to block CGLib-provided
57
65
// method "getCallbacks". Not sure of exact safe criteria to get decent
58
66
// coverage without false matches; but for now let's assume there is
@@ -68,16 +76,16 @@ public String findNameForRegularGetter(AnnotatedMethod am, String name)
68
76
}
69
77
}
70
78
return _stdBeanNaming
71
- ? stdManglePropertyName (name , 3 )
72
- : legacyManglePropertyName (name , 3 );
79
+ ? stdManglePropertyName (name , _getterPrefix . length () )
80
+ : legacyManglePropertyName (name , _getterPrefix . length () );
73
81
}
74
82
return null ;
75
83
}
76
84
77
85
@ Override
78
86
public String findNameForMutator (AnnotatedMethod am , String name )
79
87
{
80
- if (name .startsWith (_mutatorPrefix )) {
88
+ if (( _mutatorPrefix != null ) && name .startsWith (_mutatorPrefix )) {
81
89
return _stdBeanNaming
82
90
? stdManglePropertyName (name , _mutatorPrefix .length ())
83
91
: legacyManglePropertyName (name , _mutatorPrefix .length ());
@@ -210,7 +218,8 @@ public final static class Provider
210
218
@ Override
211
219
public AccessorNamingStrategy forPOJO (MapperConfig <?> config , AnnotatedClass targetClass )
212
220
{
213
- return new DefaultAccessorNamingStrategy (config , targetClass , "set" );
221
+ return new DefaultAccessorNamingStrategy (config , targetClass ,
222
+ "set" , "get" );
214
223
}
215
224
216
225
@ Override
@@ -220,13 +229,49 @@ public AccessorNamingStrategy forBuilder(MapperConfig<?> config,
220
229
AnnotationIntrospector ai = config .isAnnotationProcessingEnabled () ? config .getAnnotationIntrospector () : null ;
221
230
JsonPOJOBuilder .Value builderConfig = (ai == null ) ? null : ai .findPOJOBuilderConfig (builderClass );
222
231
String mutatorPrefix = (builderConfig == null ) ? JsonPOJOBuilder .DEFAULT_WITH_PREFIX : builderConfig .withPrefix ;
223
- return new DefaultAccessorNamingStrategy (config , builderClass , mutatorPrefix );
232
+ return new DefaultAccessorNamingStrategy (config , builderClass ,
233
+ mutatorPrefix , "get" );
224
234
}
225
235
226
236
@ Override
227
237
public AccessorNamingStrategy forRecord (MapperConfig <?> config , AnnotatedClass recordClass )
228
238
{
229
- return new DefaultAccessorNamingStrategy (config , recordClass , "set" );
239
+ return new RecordNaming (config , recordClass );
240
+ }
241
+ }
242
+
243
+ public static class RecordNaming
244
+ extends DefaultAccessorNamingStrategy
245
+ {
246
+ /**
247
+ * Names of actual Record fields from definition; auto-detected.
248
+ */
249
+ protected final Set <String > _fieldNames ;
250
+
251
+ public RecordNaming (MapperConfig <?> config , AnnotatedClass forClass ) {
252
+ super (config , forClass ,
253
+ // no setters for (immutable) Records:
254
+ null ,
255
+ // trickier: regular fields are ok (handled differently), but should
256
+ // we also allow getter discovery? For now let's do so
257
+ "get" );
258
+ _fieldNames = new HashSet <>();
259
+ for (String name : JDK14Util .getRecordFieldNames (forClass .getRawType ())) {
260
+ _fieldNames .add (name );
261
+ }
262
+ }
263
+
264
+ @ Override
265
+ public String findNameForRegularGetter (AnnotatedMethod am , String name )
266
+ {
267
+ // By default, field names are un-prefixed, but verify so that we will not
268
+ // include "toString()" or additional custom methods (unless latter are
269
+ // annotated for inclusion)
270
+ if (_fieldNames .contains (name )) {
271
+ return name ;
272
+ }
273
+ // but also allow auto-detecting additional getters, if any?
274
+ return super .findNameForRegularGetter (am , name );
230
275
}
231
276
}
232
277
}
0 commit comments