Skip to content

Commit 9236000

Browse files
committed
Minor reworking to use 2.5-added JsonParser methods for (slightly) more efficient bean deserialization
1 parent 560bd80 commit 9236000

File tree

5 files changed

+64
-99
lines changed

5 files changed

+64
-99
lines changed

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

Lines changed: 46 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,13 @@ public class BeanDeserializer
2020
{
2121
/* TODOs for future versions:
2222
*
23-
* For 2.6
24-
*
25-
* - Start using new (2.5) methods in JsonParser, like
26-
* * 'hasTokenId(xxx)'
27-
* * 'nextFieldName()'
28-
*
29-
* for slightly more efficient property lookups, handling
30-
* (2-3% faster deserialization)
31-
* Not done for 2.5 since it was just introduced, trying to
32-
* keep some level of compatibility between "adjacent" minor
33-
* versions.
34-
* Also: need to ensure efficient impl of those methods for Smile, CBOR
35-
* at least (in addition to JSON)
23+
* For 2.6?
3624
*
25+
* - New method in JsonDeserializer (deserializeNext()) to allow use of more
26+
* efficient 'nextXxx()' method `JsonParser` provides.
27+
*
28+
* Also: need to ensure efficient impl of those methods for Smile, CBOR
29+
* at least (in addition to JSON)
3730
*/
3831

3932
private static final long serialVersionUID = 1L;
@@ -47,8 +40,7 @@ public class BeanDeserializer
4740
/**
4841
* Constructor used by {@link BeanDeserializerBuilder}.
4942
*/
50-
public BeanDeserializer(BeanDeserializerBuilder builder,
51-
BeanDescription beanDesc,
43+
public BeanDeserializer(BeanDeserializerBuilder builder, BeanDescription beanDesc,
5244
BeanPropertyMap properties, Map<String, SettableBeanProperty> backRefs,
5345
HashSet<String> ignorableProps, boolean ignoreAllUnknown,
5446
boolean hasViews)
@@ -126,12 +118,10 @@ protected BeanDeserializerBase asArrayDeserializer() {
126118
* like Afterburner change definition.
127119
*/
128120
@Override
129-
public Object deserialize(JsonParser p, DeserializationContext ctxt)
130-
throws IOException
121+
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
131122
{
132-
JsonToken t = p.getCurrentToken();
133123
// common case first
134-
if (t == JsonToken.START_OBJECT) { // TODO: in 2.6, use 'p.hasTokenId()'
124+
if (p.isExpectedStartObjectToken()) {
135125
if (_vanillaProcessing) {
136126
return vanillaDeserialize(p, ctxt, p.nextToken());
137127
}
@@ -141,6 +131,7 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt)
141131
}
142132
return deserializeFromObject(p, ctxt);
143133
}
134+
JsonToken t = p.getCurrentToken();
144135
return _deserializeOther(p, ctxt, t);
145136
}
146137

@@ -177,9 +168,7 @@ protected final Object _deserializeOther(JsonParser p, DeserializationContext ct
177168
}
178169
}
179170

180-
protected Object _missingToken(JsonParser p, DeserializationContext ctxt)
181-
throws JsonProcessingException
182-
{
171+
protected Object _missingToken(JsonParser p, DeserializationContext ctxt) throws IOException {
183172
throw ctxt.endOfInputException(handledType());
184173
}
185174

@@ -189,8 +178,7 @@ protected Object _missingToken(JsonParser p, DeserializationContext ctxt)
189178
* after collecting some or all of the properties to set.
190179
*/
191180
@Override
192-
public Object deserialize(JsonParser p, DeserializationContext ctxt, Object bean)
193-
throws IOException
181+
public Object deserialize(JsonParser p, DeserializationContext ctxt, Object bean) throws IOException
194182
{
195183
// [databind#631]: Assign current value, to be accessible by custom serializers
196184
p.setCurrentValue(bean);
@@ -203,24 +191,33 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt, Object bean
203191
if (_externalTypeIdHandler != null) {
204192
return deserializeWithExternalTypeId(p, ctxt, bean);
205193
}
206-
JsonToken t = p.getCurrentToken();
194+
String propName;
195+
207196
// 23-Mar-2010, tatu: In some cases, we start with full JSON object too...
208-
if (t == JsonToken.START_OBJECT) {
209-
t = p.nextToken();
197+
if (p.isExpectedStartObjectToken()) {
198+
propName = p.nextFieldName();
199+
if (propName == null) {
200+
return bean;
201+
}
202+
} else {
203+
if (p.hasTokenId(JsonTokenId.ID_FIELD_NAME)) {
204+
propName = p.getCurrentName();
205+
} else {
206+
return bean;
207+
}
210208
}
211209
if (_needViewProcesing) {
212210
Class<?> view = ctxt.getActiveView();
213211
if (view != null) {
214212
return deserializeWithView(p, ctxt, bean, view);
215213
}
216214
}
217-
for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
218-
String propName = p.getCurrentName();
215+
do {
219216
p.nextToken();
220217
if (!_beanProperties.findDeserializeAndSet(p, ctxt, bean, propName)) {
221218
handleUnknownVanilla(p, ctxt, bean, propName);
222219
}
223-
}
220+
} while ((propName = p.nextFieldName()) != null);
224221
return bean;
225222
}
226223

@@ -241,17 +238,6 @@ private final Object vanillaDeserialize(JsonParser p,
241238
final Object bean = _valueInstantiator.createUsingDefault(ctxt);
242239
// [databind#631]: Assign current value, to be accessible by custom serializers
243240
p.setCurrentValue(bean);
244-
245-
for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
246-
String propName = p.getCurrentName();
247-
p.nextToken();
248-
if (!_beanProperties.findDeserializeAndSet(p, ctxt, bean, propName)) {
249-
handleUnknownVanilla(p, ctxt, bean, propName);
250-
}
251-
}
252-
253-
// 13-Dec-2014, tatu: For 2.6, we'll do:
254-
/*
255241
if (p.hasTokenId(JsonTokenId.ID_FIELD_NAME)) {
256242
String propName = p.getCurrentName();
257243
do {
@@ -261,7 +247,6 @@ private final Object vanillaDeserialize(JsonParser p,
261247
}
262248
} while ((propName = p.nextFieldName()) != null);
263249
}
264-
*/
265250
return bean;
266251
}
267252

@@ -280,7 +265,7 @@ public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) t
280265
*/
281266
if (_objectIdReader != null && _objectIdReader.maySerializeAsObject()) {
282267
// TODO: in 2.6, use 'p.hasTokenId()'
283-
if ((p.getCurrentTokenId() == JsonTokenId.ID_FIELD_NAME)
268+
if (p.hasTokenId(JsonTokenId.ID_FIELD_NAME)
284269
&& _objectIdReader.isValidReferencePropertyName(p.getCurrentName(), p)) {
285270
return deserializeFromObjectId(p, ctxt);
286271
}
@@ -328,16 +313,6 @@ public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) t
328313
return deserializeWithView(p, ctxt, bean, view);
329314
}
330315
}
331-
JsonToken t = p.getCurrentToken();
332-
for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
333-
String propName = p.getCurrentName();
334-
p.nextToken();
335-
if (!_beanProperties.findDeserializeAndSet(p, ctxt, bean, propName)) {
336-
handleUnknownVanilla(p, ctxt, bean, propName);
337-
}
338-
}
339-
// 13-Dec-2014, tatu: For 2.6, we'll do:
340-
/*
341316
if (p.hasTokenId(JsonTokenId.ID_FIELD_NAME)) {
342317
String propName = p.getCurrentName();
343318
do {
@@ -347,7 +322,6 @@ public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) t
347322
}
348323
} while ((propName = p.nextFieldName()) != null);
349324
}
350-
*/
351325
return bean;
352326
}
353327

@@ -459,30 +433,31 @@ protected Object _deserializeUsingPropertyBased(final JsonParser p, final Deseri
459433
/* Deserializing when we have to consider an active View
460434
/**********************************************************
461435
*/
462-
436+
463437
protected final Object deserializeWithView(JsonParser p, DeserializationContext ctxt,
464438
Object bean, Class<?> activeView)
465439
throws IOException
466440
{
467-
JsonToken t = p.getCurrentToken();
468-
for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
441+
if (p.hasTokenId(JsonTokenId.ID_FIELD_NAME)) {
469442
String propName = p.getCurrentName();
470-
// Skip field name:
471-
p.nextToken();
472-
SettableBeanProperty prop = _beanProperties.find(propName);
473-
if (prop != null) {
474-
if (!prop.visibleInView(activeView)) {
475-
p.skipChildren();
443+
do {
444+
p.nextToken();
445+
// TODO: 06-Jan-2015, tatu: try streamlining call sequences here as well
446+
SettableBeanProperty prop = _beanProperties.find(propName);
447+
if (prop != null) {
448+
if (!prop.visibleInView(activeView)) {
449+
p.skipChildren();
450+
continue;
451+
}
452+
try {
453+
prop.deserializeAndSet(p, ctxt, bean);
454+
} catch (Exception e) {
455+
wrapAndThrow(e, bean, propName, ctxt);
456+
}
476457
continue;
477458
}
478-
try {
479-
prop.deserializeAndSet(p, ctxt, bean);
480-
} catch (Exception e) {
481-
wrapAndThrow(e, bean, propName, ctxt);
482-
}
483-
continue;
484-
}
485-
handleUnknownVanilla(p, ctxt, bean, propName);
459+
handleUnknownVanilla(p, ctxt, bean, propName);
460+
} while ((propName = p.nextFieldName()) != null);
486461
}
487462
return bean;
488463
}

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@
66
import com.fasterxml.jackson.core.JsonParser;
77
import com.fasterxml.jackson.core.JsonProcessingException;
88
import com.fasterxml.jackson.databind.DeserializationContext;
9-
import com.fasterxml.jackson.databind.JavaType;
10-
import com.fasterxml.jackson.databind.JsonDeserializer;
11-
import com.fasterxml.jackson.databind.PropertyMetadata;
12-
import com.fasterxml.jackson.databind.PropertyName;
9+
import com.fasterxml.jackson.databind.*;
1310
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
1411
import com.fasterxml.jackson.databind.introspect.AnnotatedParameter;
1512
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;

src/main/java/com/fasterxml/jackson/databind/deser/impl/ManagedReferenceProperty.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import java.util.Map;
77

88
import com.fasterxml.jackson.core.JsonParser;
9-
import com.fasterxml.jackson.core.JsonProcessingException;
9+
1010
import com.fasterxml.jackson.databind.DeserializationContext;
1111
import com.fasterxml.jackson.databind.JsonDeserializer;
1212
import com.fasterxml.jackson.databind.PropertyName;
@@ -95,20 +95,20 @@ public <A extends Annotation> A getAnnotation(Class<A> acls) {
9595
*/
9696

9797
@Override
98-
public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt, Object instance)
99-
throws IOException, JsonProcessingException {
100-
set(instance, _managedProperty.deserialize(jp, ctxt));
98+
public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object instance)
99+
throws IOException {
100+
set(instance, _managedProperty.deserialize(p, ctxt));
101101
}
102102

103103
@Override
104-
public Object deserializeSetAndReturn(JsonParser jp, DeserializationContext ctxt, Object instance)
105-
throws IOException, JsonProcessingException {
106-
return setAndReturn(instance, deserialize(jp, ctxt));
104+
public Object deserializeSetAndReturn(JsonParser p, DeserializationContext ctxt, Object instance)
105+
throws IOException {
106+
return setAndReturn(instance, deserialize(p, ctxt));
107107
}
108108

109109
@Override
110110
public final void set(Object instance, Object value) throws IOException {
111-
setAndReturn(instance, value);
111+
setAndReturn(instance, value);
112112
}
113113

114114
@Override

src/main/java/com/fasterxml/jackson/databind/deser/impl/ObjectIdReferenceProperty.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,20 +58,19 @@ public AnnotatedMember getMember() {
5858
}
5959

6060
@Override
61-
public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt, Object instance) throws IOException {
62-
deserializeSetAndReturn(jp, ctxt, instance);
61+
public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object instance) throws IOException {
62+
deserializeSetAndReturn(p, ctxt, instance);
6363
}
6464

6565
@Override
66-
public Object deserializeSetAndReturn(JsonParser jp, DeserializationContext ctxt, Object instance)
67-
throws IOException
66+
public Object deserializeSetAndReturn(JsonParser p, DeserializationContext ctxt, Object instance) throws IOException
6867
{
6968
try {
70-
return setAndReturn(instance, deserialize(jp, ctxt));
69+
return setAndReturn(instance, deserialize(p, ctxt));
7170
} catch (UnresolvedForwardReference reference) {
7271
boolean usingIdentityInfo = (_objectIdInfo != null) || (_valueDeserializer.getObjectIdReader() != null);
7372
if (!usingIdentityInfo) {
74-
throw JsonMappingException.from(jp, "Unresolved forward reference but no identity info.", reference);
73+
throw JsonMappingException.from(p, "Unresolved forward reference but no identity info.", reference);
7574
}
7675
reference.getRoid().appendReferring(new PropertyReferring(this, reference, _type.getRawClass(), instance));
7776
return null;

src/main/java/com/fasterxml/jackson/databind/deser/impl/ObjectIdValueProperty.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,10 @@ protected ObjectIdValueProperty(ObjectIdValueProperty src, JsonDeserializer<?> d
3434
_objectIdReader = src._objectIdReader;
3535
}
3636

37-
@Deprecated // since 2.3
3837
protected ObjectIdValueProperty(ObjectIdValueProperty src, PropertyName newName) {
3938
super(src, newName);
4039
_objectIdReader = src._objectIdReader;
4140
}
42-
43-
@Deprecated // since 2.3
44-
protected ObjectIdValueProperty(ObjectIdValueProperty src, String newName) {
45-
this(src, new PropertyName(newName));
46-
}
4741

4842
@Override
4943
public ObjectIdValueProperty withName(PropertyName newName) {
@@ -71,18 +65,18 @@ public <A extends Annotation> A getAnnotation(Class<A> acls) {
7165
*/
7266

7367
@Override
74-
public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt,
68+
public void deserializeAndSet(JsonParser p, DeserializationContext ctxt,
7569
Object instance) throws IOException
7670
{
77-
deserializeSetAndReturn(jp, ctxt, instance);
71+
deserializeSetAndReturn(p, ctxt, instance);
7872
}
7973

8074
@Override
81-
public Object deserializeSetAndReturn(JsonParser jp,
75+
public Object deserializeSetAndReturn(JsonParser p,
8276
DeserializationContext ctxt, Object instance) throws IOException
8377
{
8478
// note: no null checks (unlike usually); deserializer should fail if one found
85-
Object id = _valueDeserializer.deserialize(jp, ctxt);
79+
Object id = _valueDeserializer.deserialize(p, ctxt);
8680
ReadableObjectId roid = ctxt.findObjectId(id, _objectIdReader.generator, _objectIdReader.resolver);
8781
roid.bindItem(instance);
8882
// also: may need to set a property value as well

0 commit comments

Comments
 (0)