Skip to content

Commit

Permalink
last coercions (float, double), before rearranging
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Jun 13, 2020
1 parent ab06279 commit c305e60
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -450,16 +450,21 @@ public FloatDeserializer(Class<Float> cls, Float nvl) {
@Override
public Float deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
{
if (_primitive) {
return _parseFloatPrimitive(ctxt, p);
}
return _parseFloat(p, ctxt);
}

protected final Float _parseFloat(JsonParser p, DeserializationContext ctxt)
throws IOException
{
// We accept couple of different types; obvious ones first:
JsonToken t = p.currentToken();

if (t == JsonToken.VALUE_NUMBER_FLOAT || t == JsonToken.VALUE_NUMBER_INT) { // coercing should work too
if (p.hasToken(JsonToken.VALUE_NUMBER_FLOAT)) {
return p.getFloatValue();
}
final JsonToken t = p.currentToken();
if (t == JsonToken.VALUE_NUMBER_INT) { // safe coercion
return p.getFloatValue();
}
// And finally, let's allow Strings to be converted too
Expand Down Expand Up @@ -534,13 +539,20 @@ public Double deserialize(JsonParser p, DeserializationContext ctxt) throws IOEx
public Double deserializeWithType(JsonParser p, DeserializationContext ctxt,
TypeDeserializer typeDeserializer) throws IOException
{
if (_primitive) {
return _parseDoublePrimitive(ctxt, p);
}
return _parseDouble(p, ctxt);
}

protected final Double _parseDouble(JsonParser p, DeserializationContext ctxt) throws IOException
{
JsonToken t = p.currentToken();
if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) { // coercing should work too
// We accept couple of different types; obvious ones first:
if (p.hasToken(JsonToken.VALUE_NUMBER_FLOAT)) {
return p.getDoubleValue();
}
final JsonToken t = p.currentToken();
if (t == JsonToken.VALUE_NUMBER_INT) { // safe coercion
return p.getDoubleValue();
}
if (t == JsonToken.VALUE_STRING) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ public float[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOE
continue;
}
}
float value = _parseFloatPrimitive(p, ctxt);
float value = _parseFloatPrimitive(ctxt, p);
if (ix >= chunk.length) {
chunk = builder.appendCompletedChunk(chunk, ix);
ix = 0;
Expand All @@ -846,7 +846,7 @@ public float[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOE
@Override
protected float[] handleSingleElementUnwrapped(JsonParser p,
DeserializationContext ctxt) throws IOException {
return new float[] { _parseFloatPrimitive(p, ctxt) };
return new float[] { _parseFloatPrimitive(ctxt, p) };
}

@Override
Expand Down Expand Up @@ -900,7 +900,7 @@ public double[] deserialize(JsonParser p, DeserializationContext ctxt) throws IO
continue;
}
}
double value = _parseDoublePrimitive(p, ctxt);
double value = _parseDoublePrimitive(ctxt, p);
if (ix >= chunk.length) {
chunk = builder.appendCompletedChunk(chunk, ix);
ix = 0;
Expand All @@ -916,7 +916,7 @@ public double[] deserialize(JsonParser p, DeserializationContext ctxt) throws IO
@Override
protected double[] handleSingleElementUnwrapped(JsonParser p,
DeserializationContext ctxt) throws IOException {
return new double[] { _parseDoublePrimitive(p, ctxt) };
return new double[] { _parseDoublePrimitive(ctxt, p) };
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -978,29 +978,43 @@ protected final Long _parseLong(DeserializationContext ctxt, JsonParser p,
return (Long) ctxt.handleUnexpectedToken(ctxt.constructType(targetType), p);
}

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

protected final float _parseFloatPrimitive(DeserializationContext ctxt, JsonParser p)
throws IOException
{
if (p.hasToken(JsonToken.VALUE_NUMBER_FLOAT)) {
return p.getFloatValue();
}
CoercionAction act;
switch (p.currentTokenId()) {
case JsonTokenId.ID_STRING:
String text = p.getText().trim();
if (_isEmptyOrTextualNull(text)) {
_verifyNullForPrimitiveCoercion(ctxt, text);
return 0.0f;
}
return _parseFloatPrimitive(ctxt, text);
case JsonTokenId.ID_NUMBER_INT:
case JsonTokenId.ID_NUMBER_FLOAT:
return p.getFloatValue();
case JsonTokenId.ID_NULL:
_verifyNullForPrimitive(ctxt);
return 0.0f;
return 0f;
case JsonTokenId.ID_STRING:
String text = p.getText();
act = _checkFromStringCoercion(ctxt, text,
LogicalType.Integer, Float.TYPE);
if (act == CoercionAction.AsNull) {
return 0.0f; // no need to check as does not come from `null`, explicit coercion
}
if (act == CoercionAction.AsEmpty) {
return 0.0f;
}
text = text.trim();
if (_hasTextualNull(text)) {
_verifyNullForPrimitiveCoercion(ctxt, text);
return 0.0f;
}
return _parseFloatPrimitive(ctxt, text);
case JsonTokenId.ID_START_ARRAY:
if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
p.nextToken();
final float parsed = _parseFloatPrimitive(p, ctxt);
final float parsed = _parseFloatPrimitive(ctxt, p);
_verifyEndArrayForSingle(p, ctxt);
return parsed;
}
Expand Down Expand Up @@ -1039,29 +1053,43 @@ protected final float _parseFloatPrimitive(DeserializationContext ctxt, String t
return _nonNullNumber(v).floatValue();
}

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

protected final double _parseDoublePrimitive(DeserializationContext ctxt, JsonParser p)
throws IOException
{
if (p.hasToken(JsonToken.VALUE_NUMBER_FLOAT)) {
return p.getDoubleValue();
}
CoercionAction act;
switch (p.currentTokenId()) {
case JsonTokenId.ID_STRING:
String text = p.getText().trim();
if (_isEmptyOrTextualNull(text)) {
_verifyNullForPrimitiveCoercion(ctxt, text);
return 0.0;
}
return _parseDoublePrimitive(ctxt, text);
case JsonTokenId.ID_NUMBER_INT:
case JsonTokenId.ID_NUMBER_FLOAT:
return p.getDoubleValue();
case JsonTokenId.ID_NULL:
_verifyNullForPrimitive(ctxt);
return 0.0;
case JsonTokenId.ID_STRING:
String text = p.getText();
act = _checkFromStringCoercion(ctxt, text,
LogicalType.Integer, Double.TYPE);
if (act == CoercionAction.AsNull) {
return 0.0; // no need to check as does not come from `null`, explicit coercion
}
if (act == CoercionAction.AsEmpty) {
return 0.0;
}
text = text.trim();
if (_hasTextualNull(text)) {
_verifyNullForPrimitiveCoercion(ctxt, text);
return 0.0;
}
return _parseDoublePrimitive(ctxt, text);
case JsonTokenId.ID_START_ARRAY:
if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
p.nextToken();
final double parsed = _parseDoublePrimitive(p, ctxt);
final double parsed = _parseDoublePrimitive(ctxt, p);
_verifyEndArrayForSingle(p, ctxt);
return parsed;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -541,31 +541,6 @@ 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(double.class, Double.valueOf(0.0));
_testEmptyToNullCoercion(float.class, Float.valueOf(0.0f));
}

private void _testEmptyToNullCoercion(Class<?> primType, Object emptyValue) throws Exception
{
final String EMPTY = "\"\"";

// as per [databind#1095] should only allow coercion from empty String,
// if `null` is acceptable
ObjectReader intR = MAPPER.readerFor(primType);
assertEquals(emptyValue, intR.readValue(EMPTY));
try {
intR.with(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)
.readValue("\"\"");
fail("Should not have passed");
} catch (MismatchedInputException e) {
verifyException(e, "Cannot map `null` into type ");
}
}

public void testBase64Variants() throws Exception
{
final byte[] INPUT = "abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890X".getBytes("UTF-8");
Expand Down Expand Up @@ -700,33 +675,6 @@ public void testEmptyStringFailForBooleanPrimitive() throws IOException
}
}

public void testEmptyStringFailForPrimitives() throws IOException
{
// 12-Jun-2020, tatu: Empty String coercion is not same as explicit
// `null`, so some of these do not apply:
// _verifyEmptyStringFailForPrimitives("byteValue");
_verifyEmptyStringFailForPrimitives("charValue");
// _verifyEmptyStringFailForPrimitives("shortValue");
// _verifyEmptyStringFailForPrimitives("intValue");
// _verifyEmptyStringFailForPrimitives("longValue");
_verifyEmptyStringFailForPrimitives("floatValue");
_verifyEmptyStringFailForPrimitives("doubleValue");
}

private void _verifyEmptyStringFailForPrimitives(String propName) throws IOException
{
final ObjectReader reader = MAPPER
.readerFor(PrimitivesBean.class)
.with(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES);
try {
reader.readValue(aposToQuotes("{'"+propName+"':''}"));
fail("Expected failure for '"+propName+"' + empty String");
} catch (JsonMappingException e) {
verifyException(e, "Cannot map `null` into type");
verifyException(e, "FAIL_ON_NULL_FOR_PRIMITIVES");
}
}

/*
/**********************************************************
/* Null handling for scalars in POJO
Expand Down

0 comments on commit c305e60

Please sign in to comment.