12
12
import com .fasterxml .jackson .core .util .*;
13
13
import com .fasterxml .jackson .databind .cfg .ContextAttributes ;
14
14
import com .fasterxml .jackson .databind .jsonFormatVisitors .JsonFormatVisitorWrapper ;
15
+ import com .fasterxml .jackson .databind .jsontype .TypeSerializer ;
15
16
import com .fasterxml .jackson .databind .ser .*;
16
17
import com .fasterxml .jackson .databind .type .TypeFactory ;
17
18
@@ -62,29 +63,23 @@ public class ObjectWriter
62
63
*/
63
64
64
65
/**
65
- * Specified root serialization type to use; can be same
66
- * as runtime type, but usually one of its super types
66
+ * Container for settings that need to be passed to {@link JsonGenerator}
67
+ * constructed for serializing values.
68
+ *
69
+ * @since 2.5
67
70
*/
68
- protected final JavaType _rootType ;
71
+ protected final GeneratorSettings _generatorSettings ;
69
72
70
73
/**
71
74
* We may pre-fetch serializer if {@link #_rootType}
72
75
* is known, and if so, reuse it afterwards.
73
76
* This allows avoiding further serializer lookups and increases
74
77
* performance a bit on cases where readers are reused.
75
- *
76
- * @since 2.1
77
- */
78
- protected final JsonSerializer <Object > _rootSerializer ;
79
-
80
- /**
81
- * Container for settings that need to be passed to {@link JsonGenerator}
82
- * constructed for serializing values.
83
78
*
84
79
* @since 2.5
85
80
*/
86
- protected final GeneratorSettings _generatorSettings ;
87
-
81
+ protected final Prefetch _prefetch ;
82
+
88
83
/*
89
84
/**********************************************************
90
85
/* Life-cycle, constructors
@@ -106,11 +101,10 @@ protected ObjectWriter(ObjectMapper mapper, SerializationConfig config,
106
101
107
102
// 29-Apr-2014, tatu: There is no "untyped serializer", so:
108
103
if (rootType == null || rootType .hasRawClass (Object .class )) {
109
- _rootType = null ;
110
- _rootSerializer = null ;
104
+ _prefetch = Prefetch .empty ;
111
105
} else {
112
- _rootType = rootType .withStaticTyping ();
113
- _rootSerializer = _prefetchRootSerializer (config , _rootType );
106
+ rootType = rootType .withStaticTyping ();
107
+ _prefetch = _prefetchRootSerializer (config , rootType );
114
108
}
115
109
}
116
110
@@ -124,8 +118,7 @@ protected ObjectWriter(ObjectMapper mapper, SerializationConfig config)
124
118
_serializerFactory = mapper ._serializerFactory ;
125
119
_generatorFactory = mapper ._jsonFactory ;
126
120
127
- _rootType = null ;
128
- _rootSerializer = null ;
121
+ _prefetch = Prefetch .empty ;
129
122
_generatorSettings = GeneratorSettings .empty ;
130
123
}
131
124
@@ -141,8 +134,7 @@ protected ObjectWriter(ObjectMapper mapper, SerializationConfig config,
141
134
_serializerFactory = mapper ._serializerFactory ;
142
135
_generatorFactory = mapper ._jsonFactory ;
143
136
144
- _rootType = null ;
145
- _rootSerializer = null ;
137
+ _prefetch = Prefetch .empty ;
146
138
_generatorSettings = (s == null ) ? GeneratorSettings .empty
147
139
: new GeneratorSettings (null , s , null );
148
140
}
@@ -151,18 +143,16 @@ protected ObjectWriter(ObjectMapper mapper, SerializationConfig config,
151
143
* Copy constructor used for building variations.
152
144
*/
153
145
protected ObjectWriter (ObjectWriter base , SerializationConfig config ,
154
- JavaType rootType , JsonSerializer <Object > rootSer ,
155
- GeneratorSettings genSettings )
146
+ GeneratorSettings genSettings , Prefetch prefetch )
156
147
{
157
148
_config = config ;
158
149
159
150
_serializerProvider = base ._serializerProvider ;
160
151
_serializerFactory = base ._serializerFactory ;
161
152
_generatorFactory = base ._generatorFactory ;
162
153
163
- _rootType = rootType ;
164
- _rootSerializer = rootSer ;
165
154
_generatorSettings = genSettings ;
155
+ _prefetch = prefetch ;
166
156
}
167
157
168
158
/**
@@ -176,9 +166,7 @@ protected ObjectWriter(ObjectWriter base, SerializationConfig config)
176
166
_serializerFactory = base ._serializerFactory ;
177
167
_generatorFactory = base ._generatorFactory ;
178
168
_generatorSettings = base ._generatorSettings ;
179
-
180
- _rootType = base ._rootType ;
181
- _rootSerializer = base ._rootSerializer ;
169
+ _prefetch = base ._prefetch ;
182
170
}
183
171
184
172
/**
@@ -194,9 +182,7 @@ protected ObjectWriter(ObjectWriter base, JsonFactory f)
194
182
_serializerFactory = base ._serializerFactory ;
195
183
_generatorFactory = base ._generatorFactory ;
196
184
_generatorSettings = base ._generatorSettings ;
197
-
198
- _rootType = base ._rootType ;
199
- _rootSerializer = base ._rootSerializer ;
185
+ _prefetch = base ._prefetch ;
200
186
}
201
187
202
188
/**
@@ -241,9 +227,8 @@ protected ObjectWriter _new(ObjectWriter base, SerializationConfig config) {
241
227
*
242
228
* @since 2.5
243
229
*/
244
- protected ObjectWriter _new (JavaType rootType , JsonSerializer <Object > rootSer ,
245
- GeneratorSettings genSettings ) {
246
- return new ObjectWriter (this , _config , rootType , rootSer , genSettings );
230
+ protected ObjectWriter _new (GeneratorSettings genSettings , Prefetch prefetch ) {
231
+ return new ObjectWriter (this , _config , genSettings , prefetch );
247
232
}
248
233
249
234
/**
@@ -258,7 +243,7 @@ protected SequenceWriter _newSequenceWriter(boolean wrapInArray,
258
243
throws IOException
259
244
{
260
245
return new SequenceWriter (_serializerProvider (_config ),
261
- _configureGenerator (gen ), managedInput , _rootType , _rootSerializer )
246
+ _configureGenerator (gen ), managedInput , _prefetch )
262
247
.init (wrapInArray );
263
248
}
264
249
@@ -405,7 +390,7 @@ public ObjectWriter with(PrettyPrinter pp) {
405
390
if (genSet == _generatorSettings ) {
406
391
return this ;
407
392
}
408
- return _new (_rootType , _rootSerializer , genSet );
393
+ return _new (genSet , _prefetch );
409
394
}
410
395
411
396
/**
@@ -434,7 +419,7 @@ public ObjectWriter with(FormatSchema schema) {
434
419
return this ;
435
420
}
436
421
_verifySchemaType (schema );
437
- return _new (_rootType , _rootSerializer , genSet );
422
+ return _new (genSet , _prefetch );
438
423
}
439
424
440
425
/**
@@ -457,16 +442,15 @@ public ObjectWriter withSchema(FormatSchema schema) {
457
442
*/
458
443
public ObjectWriter forType (JavaType rootType )
459
444
{
460
- JsonSerializer < Object > rootSer ;
445
+ Prefetch pf ;
461
446
if (rootType == null || rootType .hasRawClass (Object .class )) {
462
- rootType = null ;
463
- rootSer = null ;
447
+ pf = Prefetch .empty ;
464
448
} else {
465
449
// 15-Mar-2013, tatu: Important! Indicate that static typing is needed:
466
450
rootType = rootType .withStaticTyping ();
467
- rootSer = _prefetchRootSerializer (_config , rootType );
451
+ pf = _prefetchRootSerializer (_config , rootType );
468
452
}
469
- return _new ( rootType , rootSer , _generatorSettings );
453
+ return ( pf == _prefetch ) ? this : _new ( _generatorSettings , pf );
470
454
}
471
455
472
456
/**
@@ -553,7 +537,7 @@ public ObjectWriter with(CharacterEscapes escapes) {
553
537
if (genSet == _generatorSettings ) {
554
538
return this ;
555
539
}
556
- return _new (_rootType , _rootSerializer , genSet );
540
+ return _new (genSet , _prefetch );
557
541
}
558
542
559
543
/**
@@ -806,7 +790,7 @@ public TypeFactory getTypeFactory() {
806
790
* @since 2.2
807
791
*/
808
792
public boolean hasPrefetchedSerializer () {
809
- return _rootSerializer != null ;
793
+ return _prefetch . hasSerializer () ;
810
794
}
811
795
812
796
/**
@@ -834,10 +818,13 @@ public void writeValue(JsonGenerator gen, Object value)
834
818
&& (value instanceof Closeable )) {
835
819
_writeCloseableValue (gen , value , _config );
836
820
} else {
837
- if (_rootType == null ) {
838
- _serializerProvider (_config ).serializeValue (gen , value );
821
+ if (_prefetch .valueSerializer != null ) {
822
+ _serializerProvider (_config ).serializeValue (gen , value , _prefetch .rootType ,
823
+ _prefetch .valueSerializer );
824
+ } else if (_prefetch .typeSerializer != null ) {
825
+ _serializerProvider (_config ).serializePolymorphic (gen , value , _prefetch .typeSerializer );
839
826
} else {
840
- _serializerProvider (_config ).serializeValue (gen , value , _rootType , _rootSerializer );
827
+ _serializerProvider (_config ).serializeValue (gen , value );
841
828
}
842
829
if (_config .isEnabled (SerializationFeature .FLUSH_AFTER_WRITE_VALUE )) {
843
830
gen .flush ();
@@ -1032,10 +1019,13 @@ protected final void _configAndWriteValue(JsonGenerator gen, Object value) throw
1032
1019
}
1033
1020
boolean closed = false ;
1034
1021
try {
1035
- if (_rootType == null ) {
1036
- _serializerProvider (_config ).serializeValue (gen , value );
1022
+ if (_prefetch .valueSerializer != null ) {
1023
+ _serializerProvider (_config ).serializeValue (gen , value , _prefetch .rootType ,
1024
+ _prefetch .valueSerializer );
1025
+ } else if (_prefetch .typeSerializer != null ) {
1026
+ _serializerProvider (_config ).serializePolymorphic (gen , value , _prefetch .typeSerializer );
1037
1027
} else {
1038
- _serializerProvider (_config ).serializeValue (gen , value , _rootType , _rootSerializer );
1028
+ _serializerProvider (_config ).serializeValue (gen , value );
1039
1029
}
1040
1030
closed = true ;
1041
1031
gen .close ();
@@ -1064,10 +1054,13 @@ private final void _writeCloseable(JsonGenerator gen, Object value, Serializatio
1064
1054
{
1065
1055
Closeable toClose = (Closeable ) value ;
1066
1056
try {
1067
- if (_rootType == null ) {
1068
- _serializerProvider (cfg ).serializeValue (gen , value );
1057
+ if (_prefetch .valueSerializer != null ) {
1058
+ _serializerProvider (cfg ).serializeValue (gen , value , _prefetch .rootType ,
1059
+ _prefetch .valueSerializer );
1060
+ } else if (_prefetch .typeSerializer != null ) {
1061
+ _serializerProvider (cfg ).serializePolymorphic (gen , value , _prefetch .typeSerializer );
1069
1062
} else {
1070
- _serializerProvider (cfg ).serializeValue (gen , value , _rootType , _rootSerializer );
1063
+ _serializerProvider (cfg ).serializeValue (gen , value );
1071
1064
}
1072
1065
JsonGenerator tmpGen = gen ;
1073
1066
gen = null ;
@@ -1105,10 +1098,13 @@ private final void _writeCloseableValue(JsonGenerator gen, Object value, Seriali
1105
1098
{
1106
1099
Closeable toClose = (Closeable ) value ;
1107
1100
try {
1108
- if (_rootType == null ) {
1109
- _serializerProvider (cfg ).serializeValue (gen , value );
1101
+ if (_prefetch .valueSerializer != null ) {
1102
+ _serializerProvider (cfg ).serializeValue (gen , value , _prefetch .rootType ,
1103
+ _prefetch .valueSerializer );
1104
+ } else if (_prefetch .typeSerializer != null ) {
1105
+ _serializerProvider (cfg ).serializePolymorphic (gen , value , _prefetch .typeSerializer );
1110
1106
} else {
1111
- _serializerProvider (cfg ).serializeValue (gen , value , _rootType , _rootSerializer );
1107
+ _serializerProvider (cfg ).serializeValue (gen , value );
1112
1108
}
1113
1109
if (_config .isEnabled (SerializationFeature .FLUSH_AFTER_WRITE_VALUE )) {
1114
1110
gen .flush ();
@@ -1130,18 +1126,23 @@ private final void _writeCloseableValue(JsonGenerator gen, Object value, Seriali
1130
1126
* by configuration. Method also is NOT to throw an exception if
1131
1127
* access fails.
1132
1128
*/
1133
- protected JsonSerializer <Object > _prefetchRootSerializer (
1134
- SerializationConfig config , JavaType valueType )
1129
+ protected Prefetch _prefetchRootSerializer (SerializationConfig config , JavaType valueType )
1135
1130
{
1136
- if (valueType == null || !_config .isEnabled (SerializationFeature .EAGER_SERIALIZER_FETCH )) {
1137
- return null ;
1138
- }
1139
- try {
1140
- return _serializerProvider (config ).findTypedValueSerializer (valueType , true , null );
1141
- } catch (JsonProcessingException e ) {
1142
- // need to swallow?
1143
- return null ;
1131
+ if (valueType != null && _config .isEnabled (SerializationFeature .EAGER_SERIALIZER_FETCH )) {
1132
+ try {
1133
+ TypeSerializer typeSer = _serializerFactory .createTypeSerializer (_config , valueType );
1134
+ // Polymorphic type? If so, can only do partial resolution
1135
+ if (typeSer != null ) {
1136
+ return Prefetch .construct (valueType , typeSer );
1137
+ }
1138
+ JsonSerializer <Object > ser = _serializerProvider (config ).findValueSerializer (valueType , null );
1139
+ return Prefetch .construct (valueType , ser );
1140
+ } catch (JsonProcessingException e ) {
1141
+ // need to swallow?
1142
+ ;
1143
+ }
1144
1144
}
1145
+ return Prefetch .empty ;
1145
1146
}
1146
1147
1147
1148
/**
@@ -1259,4 +1260,64 @@ public GeneratorSettings with(CharacterEscapes esc) {
1259
1260
: new GeneratorSettings (prettyPrinter , schema , esc );
1260
1261
}
1261
1262
}
1263
+
1264
+ /**
1265
+ * As a minor optimization, we will make an effort to pre-fetch a serializer,
1266
+ * or at least relevant <code>TypeSerializer</code>, if given enough
1267
+ * information.
1268
+ *
1269
+ * @since 2.5
1270
+ */
1271
+ public final static class Prefetch
1272
+ implements java .io .Serializable
1273
+ {
1274
+ private static final long serialVersionUID = 1L ;
1275
+
1276
+ public final static Prefetch empty = new Prefetch (null , null , null );
1277
+
1278
+ /**
1279
+ * Specified root serialization type to use; can be same
1280
+ * as runtime type, but usually one of its super types
1281
+ */
1282
+ public final JavaType rootType ;
1283
+
1284
+ /**
1285
+ * We may pre-fetch serializer if {@link #rootType}
1286
+ * is known, and if so, reuse it afterwards.
1287
+ * This allows avoiding further serializer lookups and increases
1288
+ * performance a bit on cases where readers are reused.
1289
+ */
1290
+ public final JsonSerializer <Object > valueSerializer ;
1291
+
1292
+ /**
1293
+ * When dealing with polymorphic types, we can not pre-fetch
1294
+ * serializer, but we can pre-fetch {@link TypeSerializer}.
1295
+ */
1296
+ public final TypeSerializer typeSerializer ;
1297
+
1298
+ private Prefetch (JavaType type , JsonSerializer <Object > ser , TypeSerializer typeSer )
1299
+ {
1300
+ rootType = type ;
1301
+ valueSerializer = ser ;
1302
+ typeSerializer = typeSer ;
1303
+ }
1304
+
1305
+ public static Prefetch construct (JavaType type , JsonSerializer <Object > ser ) {
1306
+ if (type == null && ser == null ) {
1307
+ return empty ;
1308
+ }
1309
+ return new Prefetch (type , ser , null );
1310
+ }
1311
+
1312
+ public static Prefetch construct (JavaType type , TypeSerializer typeSer ) {
1313
+ if (type == null && typeSer == null ) {
1314
+ return empty ;
1315
+ }
1316
+ return new Prefetch (type , null , typeSer );
1317
+ }
1318
+
1319
+ public boolean hasSerializer () {
1320
+ return (valueSerializer != null ) || (typeSerializer != null );
1321
+ }
1322
+ }
1262
1323
}
0 commit comments