Skip to content

Commit 529f126

Browse files
author
tiago.martins
committed
Support BigInteger and BigDecimal in StdValueInstantiator
1 parent ef628ca commit 529f126

File tree

7 files changed

+229
-43
lines changed

7 files changed

+229
-43
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.fasterxml.jackson.databind.deser;
22

33
import java.io.Serializable;
4+
import java.math.BigDecimal;
5+
import java.math.BigInteger;
46
import java.util.*;
57
import java.util.concurrent.*;
68
import java.util.concurrent.atomic.AtomicReference;
@@ -948,6 +950,16 @@ protected boolean _handleSingleArgumentCreator(CreatorCollector creators,
948950
}
949951
return true;
950952
}
953+
if (type == BigInteger.class) {
954+
if (isCreator || isVisible) {
955+
creators.addBigIntegerCreator(ctor, isCreator);
956+
}
957+
}
958+
if (type == BigDecimal.class) {
959+
if (isCreator || isVisible) {
960+
creators.addBigDecimalCreator(ctor, isCreator);
961+
}
962+
}
951963
// Delegating Creator ok iff it has @JsonCreator (etc)
952964
if (isCreator) {
953965
creators.addDelegatingCreator(ctor, isCreator, null, 0);

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

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,15 +1390,19 @@ public Object deserializeFromNumber(JsonParser p, DeserializationContext ctxt)
13901390
}
13911391
return _valueInstantiator.createFromLong(ctxt, p.getLongValue());
13921392
}
1393-
// actually, could also be BigInteger, so:
1394-
if (delegateDeser != null) {
1395-
Object bean = _valueInstantiator.createUsingDelegate(ctxt,
1396-
delegateDeser.deserialize(p, ctxt));
1397-
if (_injectables != null) {
1398-
injectValues(ctxt, bean);
1393+
if (nt == NumberType.BIG_INTEGER) {
1394+
if (delegateDeser != null) {
1395+
if (!_valueInstantiator.canCreateFromBigInteger()) {
1396+
Object bean = _valueInstantiator.createUsingDelegate(ctxt, delegateDeser.deserialize(p, ctxt));
1397+
if (_injectables != null) {
1398+
injectValues(ctxt, bean);
1399+
}
1400+
return bean;
1401+
}
13991402
}
1400-
return bean;
1403+
return _valueInstantiator.createFromBigInteger(ctxt, p.getBigIntegerValue());
14011404
}
1405+
14021406
return ctxt.handleMissingInstantiator(handledType(), getValueInstantiator(), p,
14031407
"no suitable creator method found to deserialize from Number value (%s)",
14041408
p.getNumberValue());
@@ -1449,12 +1453,22 @@ public Object deserializeFromDouble(JsonParser p, DeserializationContext ctxt) t
14491453
}
14501454
return _valueInstantiator.createFromDouble(ctxt, p.getDoubleValue());
14511455
}
1452-
// actually, could also be BigDecimal, so:
1453-
JsonDeserializer<Object> delegateDeser = _delegateDeserializer();
1454-
if (delegateDeser != null) {
1455-
return _valueInstantiator.createUsingDelegate(ctxt,
1456-
delegateDeser.deserialize(p, ctxt));
1456+
1457+
if (t == NumberType.BIG_DECIMAL) {
1458+
JsonDeserializer<Object> delegateDeser = _delegateDeserializer();
1459+
if (delegateDeser != null) {
1460+
if (!_valueInstantiator.canCreateFromBigDecimal()) {
1461+
Object bean = _valueInstantiator.createUsingDelegate(ctxt, delegateDeser.deserialize(p, ctxt));
1462+
if (_injectables != null) {
1463+
injectValues(ctxt, bean);
1464+
}
1465+
return bean;
1466+
}
1467+
}
1468+
1469+
return _valueInstantiator.createFromBigDecimal(ctxt, p.getDecimalValue());
14571470
}
1471+
14581472
return ctxt.handleMissingInstantiator(handledType(), getValueInstantiator(), p,
14591473
"no suitable creator method found to deserialize from Number value (%s)",
14601474
p.getNumberValue());

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

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import com.fasterxml.jackson.databind.deser.impl.PropertyValueBuffer;
99
import com.fasterxml.jackson.databind.introspect.AnnotatedWithParams;
1010
import com.fasterxml.jackson.databind.type.LogicalType;
11+
import java.math.BigDecimal;
12+
import java.math.BigInteger;
1113

1214
/**
1315
* Class that defines simple API implemented by objects that create value
@@ -137,18 +139,31 @@ public boolean canInstantiate() {
137139
*/
138140
public boolean canCreateFromLong() { return false; }
139141

142+
/**
143+
* Method that can be called to check whether a BigInteger based creator is available
144+
* to use (to call {@link #createFromBigInteger}). +
145+
*/
146+
public boolean canCreateFromBigInteger() { return false; }
147+
140148
/**
141149
* Method that can be called to check whether a double (double / Double) based
142150
* creator is available to use (to call {@link #createFromDouble}).
143151
*/
144152
public boolean canCreateFromDouble() { return false; }
145153

154+
/**
155+
* Method that can be called to check whether a BigDecimal based creator is available
156+
* to use (to call {@link #createFromBigDecimal}).
157+
*/
158+
public boolean canCreateFromBigDecimal() { return false; }
159+
146160
/**
147161
* Method that can be called to check whether a double (boolean / Boolean) based
148162
* creator is available to use (to call {@link #createFromDouble}).
149163
*/
150164
public boolean canCreateFromBoolean() { return false; }
151165

166+
152167
/**
153168
* Method that can be called to check whether a default creator (constructor,
154169
* or no-arg static factory method)
@@ -263,7 +278,7 @@ public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) t
263278
* {@link PropertyValueBuffer#getParameter(SettableBeanProperty)} to safely
264279
* read the present properties only, and to have some other behavior for the
265280
* missing properties.
266-
*
281+
*
267282
* @since 2.8
268283
*/
269284
public Object createFromObjectWith(DeserializationContext ctxt,
@@ -316,12 +331,28 @@ public Object createFromLong(DeserializationContext ctxt, long value) throws IOE
316331
value);
317332
}
318333

334+
public Object createFromBigInteger(DeserializationContext ctxt, BigInteger value) throws IOException
335+
{
336+
return ctxt.handleMissingInstantiator(getValueClass(),this,null,
337+
"no BigInteger-argument constructor/factory method to deserialize from Number value (%s)",
338+
value
339+
);
340+
}
341+
319342
public Object createFromDouble(DeserializationContext ctxt, double value) throws IOException {
320343
return ctxt.handleMissingInstantiator(getValueClass(), this, null,
321344
"no double/Double-argument constructor/factory method to deserialize from Number value (%s)",
322345
value);
323346
}
324347

348+
public Object createFromBigDecimal(DeserializationContext ctxt, BigDecimal value) throws IOException
349+
{
350+
return ctxt.handleMissingInstantiator(getValueClass(),this,null,
351+
"no BigDecimal/double/Double-argument constructor/factory method to deserialize from Number value (%s)",
352+
value
353+
);
354+
}
355+
325356
public Object createFromBoolean(DeserializationContext ctxt, boolean value) throws IOException {
326357
return ctxt.handleMissingInstantiator(getValueClass(), this, null,
327358
"no boolean/Boolean-argument constructor/factory method to deserialize from boolean value (%s)",
@@ -444,7 +475,7 @@ public Base(Class<?> type) {
444475
public Base(JavaType type) {
445476
_valueType = type.getRawClass();
446477
}
447-
478+
448479
@Override
449480
public String getValueTypeDesc() {
450481
return _valueType.getName();
@@ -468,7 +499,7 @@ public static class Delegating extends ValueInstantiator
468499
private static final long serialVersionUID = 1L;
469500

470501
protected final ValueInstantiator _delegate;
471-
502+
472503
protected Delegating(ValueInstantiator delegate) {
473504
_delegate = delegate;
474505
}

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

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,17 @@ public class CreatorCollector {
2121
protected final static int C_STRING = 1;
2222
protected final static int C_INT = 2;
2323
protected final static int C_LONG = 3;
24-
protected final static int C_DOUBLE = 4;
25-
protected final static int C_BOOLEAN = 5;
26-
protected final static int C_DELEGATE = 6;
27-
protected final static int C_PROPS = 7;
28-
protected final static int C_ARRAY_DELEGATE = 8;
24+
protected final static int C_BIG_INTEGER = 4;
25+
protected final static int C_DOUBLE = 5;
26+
protected final static int C_BIG_DECIMAL = 6;
27+
protected final static int C_BOOLEAN = 7;
28+
protected final static int C_DELEGATE = 8;
29+
protected final static int C_PROPS = 9;
30+
protected final static int C_ARRAY_DELEGATE = 10;
2931

3032
protected final static String[] TYPE_DESCS = new String[] { "default",
31-
"from-String", "from-int", "from-long", "from-double",
32-
"from-boolean", "delegate", "property-based", "array-delegate"
33+
"from-String", "from-int", "from-long", "from-big-integer", "from-double",
34+
"from-big-decimal", "from-boolean", "delegate", "property-based", "array-delegate"
3335
};
3436

3537
// Type of bean being created
@@ -47,7 +49,7 @@ public class CreatorCollector {
4749
*
4850
* @since 2.5
4951
*/
50-
final protected AnnotatedWithParams[] _creators = new AnnotatedWithParams[9];
52+
final protected AnnotatedWithParams[] _creators = new AnnotatedWithParams[11];
5153

5254
/**
5355
* Bitmask of creators that were explicitly marked as creators; false for
@@ -99,7 +101,9 @@ public ValueInstantiator constructValueInstantiator(DeserializationContext ctxt)
99101
inst.configureFromStringCreator(_creators[C_STRING]);
100102
inst.configureFromIntCreator(_creators[C_INT]);
101103
inst.configureFromLongCreator(_creators[C_LONG]);
104+
inst.configureFromBigIntegerCreator(_creators[C_BIG_INTEGER]);
102105
inst.configureFromDoubleCreator(_creators[C_DOUBLE]);
106+
inst.configureFromBigDecimalCreator(_creators[C_BIG_DECIMAL]);
103107
inst.configureFromBooleanCreator(_creators[C_BOOLEAN]);
104108
return inst;
105109
}
@@ -136,10 +140,18 @@ public void addLongCreator(AnnotatedWithParams creator, boolean explicit) {
136140
verifyNonDup(creator, C_LONG, explicit);
137141
}
138142

143+
public void addBigIntegerCreator(AnnotatedWithParams creator, boolean explicit) {
144+
verifyNonDup(creator, C_BIG_INTEGER, explicit);
145+
}
146+
139147
public void addDoubleCreator(AnnotatedWithParams creator, boolean explicit) {
140148
verifyNonDup(creator, C_DOUBLE, explicit);
141149
}
142150

151+
public void addBigDecimalCreator(AnnotatedWithParams creator, boolean explicit) {
152+
verifyNonDup(creator, C_BIG_DECIMAL, explicit);
153+
}
154+
143155
public void addBooleanCreator(AnnotatedWithParams creator, boolean explicit) {
144156
verifyNonDup(creator, C_BOOLEAN, explicit);
145157
}

0 commit comments

Comments
 (0)