Skip to content

Commit

Permalink
Merge branch '2.12'
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Jun 13, 2020
2 parents 62df953 + 4b0d5bc commit 19f4b19
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1872,8 +1872,9 @@ protected String _shapeForToken(JsonToken t) {
return "Embedded Object";

case VALUE_NUMBER_FLOAT:
return "Floating-point value";
case VALUE_NUMBER_INT:
return "Number value";
return "Integer value";
case VALUE_STRING:
return "String value";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,10 @@ public Byte deserialize(JsonParser p, DeserializationContext ctxt) throws IOExce
if (p.hasToken(JsonToken.VALUE_NUMBER_INT)) {
return p.getByteValue();
}
return _parseByte(p, ctxt, _valueClass);
// if (_primitive) {
// return _parseBytePrimitive(ctxt, p, _valueClass);
// }
return _parseByte(ctxt, p, _valueClass);
}
}

Expand All @@ -273,55 +276,13 @@ public ShortDeserializer(Class<Short> cls, Short nvl)
public Short deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException
{
return _parseShort(p, ctxt);
}

protected Short _parseShort(JsonParser p, DeserializationContext ctxt) throws IOException
{
JsonToken t = p.currentToken();
if (t == JsonToken.VALUE_NUMBER_INT) {
return p.getShortValue();
}
if (t == JsonToken.VALUE_STRING) { // let's do implicit re-parse
String text = p.getText();
CoercionAction act = _checkFromStringCoercion(ctxt, text);
if (act == CoercionAction.AsNull) {
return (Short) getNullValue(ctxt);
}
if (act == CoercionAction.AsEmpty) {
return (Short) getEmptyValue(ctxt);
}
text = text.trim();
if (_hasTextualNull(text)) {
return (Short) _coerceTextualNull(ctxt, _primitive);
}
int value;
try {
value = NumberInput.parseInt(text);
} catch (IllegalArgumentException iae) {
return (Short) ctxt.handleWeirdStringValue(_valueClass, text,
"not a valid Short value");
}
// So far so good: but does it fit?
if (_shortOverflow(value)) {
return (Short) ctxt.handleWeirdStringValue(_valueClass, text,
"overflow, value cannot be represented as 16-bit value");
}
return Short.valueOf((short) value);
}
if (t == JsonToken.VALUE_NUMBER_FLOAT) {
if (!ctxt.isEnabled(DeserializationFeature.ACCEPT_FLOAT_AS_INT)) {
_failDoubleToIntCoercion(p, ctxt, "Short");
}
if (p.hasToken(JsonToken.VALUE_NUMBER_INT)) {
return p.getShortValue();
}
if (t == JsonToken.VALUE_NULL) {
return (Short) _coerceNullToken(ctxt, _primitive);
}
if (t == JsonToken.START_ARRAY) {
return _deserializeFromArray(p, ctxt);
}
return (Short) ctxt.handleUnexpectedToken(getValueType(ctxt), p);
// if (_primitive) {
// return _parseShortPrimitive(ctxt, p, _valueClass);
// }
return _parseShort(ctxt, p, _valueClass);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ public byte[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOEx
_verifyNullForPrimitive(ctxt);
value = (byte) 0;
} else {
value = _parseBytePrimitive(ctxt, p, handledType());
value = _parseBytePrimitive(ctxt, p, Byte.TYPE);
}
}
if (ix >= chunk.length) {
Expand Down Expand Up @@ -584,7 +584,7 @@ public short[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOE
_verifyNullForPrimitive(ctxt);
value = (short) 0;
} else {
value = _parseShortPrimitive(p, ctxt);
value = _parseShortPrimitive(ctxt, p, Short.TYPE);
}
if (ix >= chunk.length) {
chunk = builder.appendCompletedChunk(chunk, ix);
Expand All @@ -601,7 +601,7 @@ public short[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOE
@Override
protected short[] handleSingleElementUnwrapped(JsonParser p,
DeserializationContext ctxt) throws IOException {
return new short[] { _parseShortPrimitive(p, ctxt) };
return new short[] { _parseShortPrimitive(ctxt, p, Short.TYPE) };
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,14 @@ protected T _deserializeWrappedValue(JsonParser p, DeserializationContext ctxt)
/**********************************************************************
*/

/**
* @param ctxt Deserialization context for accessing configuration
* @param p Underlying parser
* @param targetType Actual type that is being deserialized, typically
* same as {@link #handledType}, and not necessarily {@code boolean}
* (may be {@code boolean[]} or {@code AtomicBoolean} for example);
* used for coercion config access
*/
protected final boolean _parseBooleanPrimitive(DeserializationContext ctxt,
JsonParser p, Class<?> targetType)
throws IOException
Expand Down Expand Up @@ -406,35 +414,21 @@ protected final Boolean _parseBoolean(DeserializationContext ctxt,
return (Boolean) ctxt.handleUnexpectedToken(ctxt.constructType(targetType), p);
}

@Deprecated // since 2.12
protected boolean _parseBooleanFromInt(JsonParser p, DeserializationContext ctxt)
throws IOException
{
// 13-Oct-2016, tatu: As per [databind#1324], need to be careful wrt
// degenerate case of huge integers, legal in JSON.
// ... this is, on the other hand, probably wrong/sub-optimal for non-JSON
// input. For now, no rea
_verifyNumberForScalarCoercion(ctxt, p);
// Anyway, note that since we know it's valid (JSON) integer, it can't have
// extra whitespace to trim.
return !"0".equals(p.getText());
}

protected final byte _parseBytePrimitive(DeserializationContext ctxt, JsonParser p,
Class<?> targetType)
throws IOException
{
final JsonToken t = p.currentToken();
if (t == JsonToken.VALUE_NUMBER_INT) return p.getByteValue();
if (t == JsonToken.VALUE_NULL) {
return (Byte) _coerceNullToken(ctxt, true);
_verifyNullForPrimitive(ctxt);
return (byte) 0;
}
if (t == JsonToken.VALUE_STRING) { // let's do implicit re-parse
String text = p.getText();
CoercionAction act = _checkFromStringCoercion(ctxt, text,
LogicalType.Integer, targetType);
if (act == CoercionAction.AsNull) {
// _verifyNullForPrimitiveCoercion(ctxt, text);
return (byte) 0; // no need to check as does not come from `null`, explicit coercion
}
if (act == CoercionAction.AsEmpty) {
Expand Down Expand Up @@ -481,7 +475,10 @@ protected final byte _parseBytePrimitive(DeserializationContext ctxt, JsonParser
return ((Byte) ctxt.handleUnexpectedToken(ctxt.constructType(targetType), p)).byteValue();
}

protected Byte _parseByte(JsonParser p, DeserializationContext ctxt,
/**
* @since 2.12
*/
protected Byte _parseByte(DeserializationContext ctxt, JsonParser p,
Class<?> targetType) throws IOException
{
final JsonToken t = p.currentToken();
Expand All @@ -507,13 +504,13 @@ protected Byte _parseByte(JsonParser p, DeserializationContext ctxt,
try {
value = NumberInput.parseInt(text);
} catch (IllegalArgumentException iae) {
return (Byte) ctxt.handleWeirdStringValue(_valueClass, text,
return (Byte) ctxt.handleWeirdStringValue(targetType, text,
"not a valid Byte value");
}
// So far so good: but does it fit?
// as per [JACKSON-804], allow range up to 255, inclusive
if (_byteOverflow(value)) {
return (Byte) ctxt.handleWeirdStringValue(_valueClass, text,
return (Byte) ctxt.handleWeirdStringValue(targetType, text,
"overflow, value cannot be represented as 8-bit value");
// fall-through for deferred fails
}
Expand All @@ -535,22 +532,106 @@ protected Byte _parseByte(JsonParser p, DeserializationContext ctxt,
return (Byte) ctxt.handleUnexpectedToken(ctxt.constructType(targetType), p);
}

protected final short _parseShortPrimitive(JsonParser p, DeserializationContext ctxt)
/**
* @since 2.12
*/
protected final short _parseShortPrimitive(DeserializationContext ctxt, JsonParser p,
Class<?> targetType)
throws IOException
{
final JsonToken t = p.currentToken();
if (t == JsonToken.VALUE_NUMBER_INT) return p.getShortValue();
if (t == JsonToken.VALUE_NULL) {
return (Byte) _coerceNullToken(ctxt, true);
_verifyNullForPrimitive(ctxt);
return (short) 0;
}
if (t == JsonToken.VALUE_STRING) { // let's do implicit re-parse
String text = p.getText();
CoercionAction act = _checkFromStringCoercion(ctxt, text,
LogicalType.Integer, targetType);
if (act == CoercionAction.AsNull) {
return (short) 0; // no need to check as does not come from `null`, explicit coercion
}
if (act == CoercionAction.AsEmpty) {
return (short) 0;
}
text = text.trim();
if (_hasTextualNull(text)) {
_verifyNullForPrimitiveCoercion(ctxt, text);
return (short) 0;
}
int value;
try {
value = NumberInput.parseInt(text);
} catch (IllegalArgumentException iae) {
return (Short) ctxt.handleWeirdStringValue(targetType, text,
"not a valid Short value");
}
if (_shortOverflow(value)) {
return (Short) ctxt.handleWeirdStringValue(targetType, text,
"overflow, value cannot be represented as 16-bit value");
}
return (short) value;
}
// 12-Jun-2020, tatu: For some reason calling `_deserializeFromArray()` won't work so:
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
p.nextToken();
final short parsed = _parseShortPrimitive(ctxt, p, targetType);
_verifyEndArrayForSingle(p, ctxt);
return parsed;
}
return ((Short) ctxt.handleUnexpectedToken(ctxt.constructType(targetType), p)).shortValue();
}

protected Short _parseShort(DeserializationContext ctxt, JsonParser p,
Class<?> targetType) throws IOException
{
final JsonToken t = p.currentToken();
if (t == JsonToken.VALUE_NUMBER_INT) return p.getShortValue();
if (t == JsonToken.VALUE_NULL) {
return (Short) _coerceNullToken(ctxt, false);
}
if (t == JsonToken.VALUE_STRING) { // let's do implicit re-parse
String text = p.getText();
CoercionAction act = _checkFromStringCoercion(ctxt, text);
if (act == CoercionAction.AsNull) {
return (Short) getNullValue(ctxt);
}
if (act == CoercionAction.AsEmpty) {
return (Short) getEmptyValue(ctxt);
}
text = text.trim();
if (_hasTextualNull(text)) {
return (Short) _coerceTextualNull(ctxt, false);
}
int value;
try {
value = NumberInput.parseInt(text);
} catch (IllegalArgumentException iae) {
return (Short) ctxt.handleWeirdStringValue(_valueClass, text,
"not a valid Short value");
}
// So far so good: but does it fit?
if (_shortOverflow(value)) {
return (Short) ctxt.handleWeirdStringValue(_valueClass, text,
"overflow, value cannot be represented as 16-bit value");
}
return Short.valueOf((short) value);
}
if (t == JsonToken.VALUE_NUMBER_FLOAT) {
CoercionAction act = _checkFloatToIntCoercion(ctxt, p, targetType);
if (act == CoercionAction.AsNull) {
return (Short) getNullValue(ctxt);
}
if (act == CoercionAction.AsEmpty) {
return (Short) getEmptyValue(ctxt);
}
return p.getShortValue();
}
int value = _parseIntPrimitive(p, ctxt);
// So far so good: but does it fit?
if (_shortOverflow(value)) {
Number v = (Number) ctxt.handleWeirdStringValue(_valueClass, String.valueOf(value),
"overflow, value cannot be represented as 16-bit value");
return _nonNullNumber(v).shortValue();
if (t == JsonToken.START_ARRAY) {
return (Short)_deserializeFromArray(p, ctxt);
}
return (short) value;
return (Short) ctxt.handleUnexpectedToken(ctxt.constructType(targetType), p);
}

protected final int _parseIntPrimitive(JsonParser p, DeserializationContext ctxt)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ public void testLegacyFailDoubleToInt() throws Exception
_verifyCoerceFail(READER_LEGACY_FAIL, LongWrapper.class, "{\"l\": 7.7 }");
_verifyCoerceFail(READER_LEGACY_FAIL, long[].class, "[ -1.35 ]");

_verifyCoerceFail(READER_LEGACY_FAIL, Short.class, "0.5");
_verifyCoerceFail(READER_LEGACY_FAIL, Short.TYPE, "-2.5");
_verifyCoerceFail(READER_LEGACY_FAIL, short[].class, "[ -1.35 ]");
_verifyCoerceFailShort(READER_LEGACY_FAIL, Short.class, "0.5");
_verifyCoerceFailShort(READER_LEGACY_FAIL, Short.TYPE, "-2.5");
_verifyCoerceFailShort(READER_LEGACY_FAIL, short[].class, "[ -1.35 ]");

_verifyCoerceFail(READER_LEGACY_FAIL, BigInteger.class, "25236.256");
}
Expand All @@ -74,6 +74,19 @@ private void _verifyCoerceFail(ObjectReader r, Class<?> targetType,
verifyException(e, "Cannot coerce a floating-point");
}
}

private void _verifyCoerceFailShort(ObjectReader r, Class<?> targetType,
String doc) throws Exception
{
try {
r.forType(targetType).readValue(doc);
fail("Should not pass");
} catch (MismatchedInputException e) {
verifyException(e,
"Cannot deserialize value of type `short` from Floating-point value",
"Cannot coerce Floating-point");
}
}

public void testDoubleToLong() throws Exception
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -929,7 +929,7 @@ public void testInvalidStringCoercionFail() throws IOException

// char[] is special, cannot use generalized test here
// _testInvalidStringCoercionFail(char[].class);
_testInvalidStringCoercionFail(short[].class);
_testInvalidStringCoercionFail(short[].class, "short");
_testInvalidStringCoercionFail(int[].class);
_testInvalidStringCoercionFail(long[].class);
_testInvalidStringCoercionFail(float[].class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ public void testSimpleMismatch() throws Exception
mapper.readValue(" 123 ", ArrayNode.class);
fail("Should not pass");
} catch (MismatchedInputException e) {
verifyException(e, "from Number value (token `JsonToken.VALUE_NUMBER_INT`)");
verifyException(e, "from Integer value (token `JsonToken.VALUE_NUMBER_INT`)");
}
}
}

0 comments on commit 19f4b19

Please sign in to comment.