Skip to content

Commit

Permalink
coercion for long/Long
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Jun 13, 2020
1 parent 7678ce4 commit ab06279
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import java.util.HashSet;

import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.io.NumberInput;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.cfg.CoercionAction;
Expand Down Expand Up @@ -428,47 +427,10 @@ public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOExce
if (p.hasToken(JsonToken.VALUE_NUMBER_INT)) {
return p.getLongValue();
}
return _parseLong(p, ctxt);
}

protected final Long _parseLong(JsonParser p, DeserializationContext ctxt) throws IOException
{
switch (p.currentTokenId()) {
// NOTE: caller assumed to usually check VALUE_NUMBER_INT in fast path
case JsonTokenId.ID_NUMBER_INT:
return p.getLongValue();
case JsonTokenId.ID_NUMBER_FLOAT:
if (!ctxt.isEnabled(DeserializationFeature.ACCEPT_FLOAT_AS_INT)) {
_failDoubleToIntCoercion(p, ctxt, "Long");
}
return p.getValueAsLong();
case JsonTokenId.ID_STRING:
String text = p.getText();
CoercionAction act = _checkFromStringCoercion(ctxt, text);
if (act == CoercionAction.AsNull) {
return (Long) getNullValue(ctxt);
}
if (act == CoercionAction.AsEmpty) {
return (Long) getEmptyValue(ctxt);
}
text = text.trim();
if (_hasTextualNull(text)) {
return (Long) _coerceTextualNull(ctxt, _primitive);
}
// let's allow Strings to be converted too
try {
return Long.valueOf(NumberInput.parseLong(text));
} catch (IllegalArgumentException iae) { }
return (Long) ctxt.handleWeirdStringValue(_valueClass, text,
"not a valid Long value");
// fall-through
case JsonTokenId.ID_NULL:
return (Long) _coerceNullToken(ctxt, _primitive);
case JsonTokenId.ID_START_ARRAY:
return _deserializeFromArray(p, ctxt);
if (_primitive) {
return _parseLongPrimitive(ctxt, p);
}
// Otherwise, no can do:
return (Long) ctxt.handleUnexpectedToken(_valueClass, p);
return _parseLong(ctxt, p, _valueClass);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ public long[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOEx
_verifyNullForPrimitive(ctxt);
value = 0L;
} else {
value = _parseLongPrimitive(p, ctxt);
value = _parseLongPrimitive(ctxt, p);
}
if (ix >= chunk.length) {
chunk = builder.appendCompletedChunk(chunk, ix);
Expand All @@ -775,7 +775,7 @@ public long[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOEx
@Override
protected long[] handleSingleElementUnwrapped(JsonParser p,
DeserializationContext ctxt) throws IOException {
return new long[] { _parseLongPrimitive(p, ctxt) };
return new long[] { _parseLongPrimitive(ctxt, p) };
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -727,10 +727,10 @@ protected Short _parseShort(DeserializationContext ctxt, JsonParser p,
return (Short) ctxt.handleUnexpectedToken(ctxt.constructType(targetType), p);
}

// @Deprecated // since 2.12, use overloaded variant
// protected final short _parseIntPrimitive(JsonParser p, DeserializationContext ctxt) throws IOException {
// return _parseIntPrimitive(ctxt, p);
// }
@Deprecated // since 2.12, use overloaded variant
protected final int _parseIntPrimitive(JsonParser p, DeserializationContext ctxt) throws IOException {
return _parseIntPrimitive(ctxt, p);
}

protected final int _parseIntPrimitive(DeserializationContext ctxt, JsonParser p)
throws IOException
Expand Down Expand Up @@ -805,11 +805,6 @@ protected final int _parseIntPrimitive(DeserializationContext ctxt, String text)
}
}

@Deprecated // since 2.12, use overloaded variant
protected final Integer _parseInteger(JsonParser p, DeserializationContext ctxt) throws IOException {
return _parseInteger(ctxt, p, _valueClass);
}

// @since 2.12
protected final Integer _parseInteger(DeserializationContext ctxt, JsonParser p,
Class<?> targetType) throws IOException
Expand Down Expand Up @@ -867,36 +862,56 @@ protected final Integer _parseInteger(DeserializationContext ctxt, JsonParser p,
return (Integer) ctxt.handleUnexpectedToken(ctxt.constructType(targetType), p);
}

@Deprecated // since 2.12, use overloaded variant
protected final long _parseLongPrimitive(JsonParser p, DeserializationContext ctxt)
throws IOException
throws IOException {
return _parseLongPrimitive(ctxt, p);
}

protected final long _parseLongPrimitive(DeserializationContext ctxt, JsonParser p)
throws IOException
{
if (p.hasToken(JsonToken.VALUE_NUMBER_INT)) {
return p.getLongValue();
}
CoercionAction act;
switch (p.currentTokenId()) {
case JsonTokenId.ID_NUMBER_INT:
return p.getLongValue();
case JsonTokenId.ID_NULL:
_verifyNullForPrimitive(ctxt);
return 0L;
case JsonTokenId.ID_STRING:
String text = p.getText().trim();
if (_isEmptyOrTextualNull(text)) {
String text = p.getText();
act = _checkFromStringCoercion(ctxt, text,
LogicalType.Integer, Long.TYPE);
if (act == CoercionAction.AsNull) {
return 0L; // no need to check as does not come from `null`, explicit coercion
}
if (act == CoercionAction.AsEmpty) {
return 0L;
}
text = text.trim();
if (_hasTextualNull(text)) {
_verifyNullForPrimitiveCoercion(ctxt, text);
return 0L;
}
return _parseLongPrimitive(ctxt, text);
case JsonTokenId.ID_NUMBER_FLOAT:
if (!ctxt.isEnabled(DeserializationFeature.ACCEPT_FLOAT_AS_INT)) {
_failDoubleToIntCoercion(p, ctxt, "long");
act = _checkFloatToIntCoercion(ctxt, p, Integer.TYPE);
if (act == CoercionAction.AsNull) {
return 0L;
}
if (act == CoercionAction.AsEmpty) {
return 0L;
}
return p.getValueAsLong();
case JsonTokenId.ID_NULL:
_verifyNullForPrimitive(ctxt);
return 0L;
case JsonTokenId.ID_START_ARRAY:
if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
p.nextToken();
final long parsed = _parseLongPrimitive(p, ctxt);
final long parsed = _parseLongPrimitive(ctxt, p);
_verifyEndArrayForSingle(p, ctxt);
return parsed;
}
break;
default:
}
return ((Number) ctxt.handleUnexpectedToken(_valueClass, p)).longValue();
}
Expand All @@ -916,6 +931,53 @@ protected final long _parseLongPrimitive(DeserializationContext ctxt, String tex
}
}

// @since 2.12
protected final Long _parseLong(DeserializationContext ctxt, JsonParser p,
Class<?> targetType) throws IOException
{
CoercionAction act;
switch (p.currentTokenId()) {
// NOTE: caller assumed to usually check VALUE_NUMBER_INT in fast path
case JsonTokenId.ID_NUMBER_INT:
return p.getLongValue();
case JsonTokenId.ID_NULL:
return (Long) _coerceNullToken(ctxt, false);
case JsonTokenId.ID_STRING:
String text = p.getText();
act = _checkFromStringCoercion(ctxt, text,
LogicalType.Integer, targetType);
if (act == CoercionAction.AsNull) {
return (Long) getNullValue(ctxt);
}
if (act == CoercionAction.AsEmpty) {
return (Long) getEmptyValue(ctxt);
}
text = text.trim();
if (_hasTextualNull(text)) {
return (Long) _coerceTextualNull(ctxt, false);
}
// let's allow Strings to be converted too
try {
return Long.valueOf(NumberInput.parseLong(text));
} catch (IllegalArgumentException iae) { }
return (Long) ctxt.handleWeirdStringValue(targetType, text,
"not a valid Long value");
case JsonTokenId.ID_NUMBER_FLOAT:
act = _checkFloatToIntCoercion(ctxt, p, targetType);
if (act == CoercionAction.AsNull) {
return (Long) getNullValue(ctxt);
}
if (act == CoercionAction.AsEmpty) {
return (Long) getEmptyValue(ctxt);
}
return p.getValueAsLong();
case JsonTokenId.ID_START_ARRAY:
return (Long) _deserializeFromArray(p, ctxt);
}
// Otherwise, no can do:
return (Long) ctxt.handleUnexpectedToken(ctxt.constructType(targetType), p);
}

protected final float _parseFloatPrimitive(JsonParser p, DeserializationContext ctxt)
throws IOException
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ public void testFloatPrimitiveNonNumeric() throws Exception
public void testEmptyToNullCoercionForPrimitives() throws Exception {
// 12-Jun-2020, tatu: Not valid any more, null <> empty String
// _testEmptyToNullCoercion(int.class, Integer.valueOf(0));
_testEmptyToNullCoercion(long.class, Long.valueOf(0));
// _testEmptyToNullCoercion(long.class, Long.valueOf(0));
_testEmptyToNullCoercion(double.class, Double.valueOf(0.0));
_testEmptyToNullCoercion(float.class, Float.valueOf(0.0f));
}
Expand Down Expand Up @@ -708,7 +708,7 @@ public void testEmptyStringFailForPrimitives() throws IOException
_verifyEmptyStringFailForPrimitives("charValue");
// _verifyEmptyStringFailForPrimitives("shortValue");
// _verifyEmptyStringFailForPrimitives("intValue");
_verifyEmptyStringFailForPrimitives("longValue");
// _verifyEmptyStringFailForPrimitives("longValue");
_verifyEmptyStringFailForPrimitives("floatValue");
_verifyEmptyStringFailForPrimitives("doubleValue");
}
Expand Down

0 comments on commit ab06279

Please sign in to comment.